|
@@ -846,142 +846,6 @@ void fpu_fst80p(int32_t addr)
|
|
|
fpu_pop();
|
|
|
}
|
|
|
|
|
|
-void fpu_op_DB_reg(int32_t imm8)
|
|
|
-{
|
|
|
- dbg_log_fpu_op(0xDB, imm8);
|
|
|
-
|
|
|
- int32_t mod = imm8 >> 3 & 7;
|
|
|
- int32_t low = imm8 & 7;
|
|
|
-
|
|
|
- switch(mod)
|
|
|
- {
|
|
|
- case 0:
|
|
|
- // fcmovnb
|
|
|
- if(!test_b())
|
|
|
- {
|
|
|
- fpu_st[*fpu_stack_ptr] = fpu_get_sti(low);
|
|
|
- *fpu_stack_empty &= ~(1 << *fpu_stack_ptr);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 1:
|
|
|
- // fcmovne
|
|
|
- if(!test_z())
|
|
|
- {
|
|
|
- fpu_st[*fpu_stack_ptr] = fpu_get_sti(low);
|
|
|
- *fpu_stack_empty &= ~(1 << *fpu_stack_ptr);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- // fcmovnbe
|
|
|
- if(!test_be())
|
|
|
- {
|
|
|
- fpu_st[*fpu_stack_ptr] = fpu_get_sti(low);
|
|
|
- *fpu_stack_empty &= ~(1 << *fpu_stack_ptr);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- // fcmovnu
|
|
|
- if(!test_p())
|
|
|
- {
|
|
|
- fpu_st[*fpu_stack_ptr] = fpu_get_sti(low);
|
|
|
- *fpu_stack_empty &= ~(1 << *fpu_stack_ptr);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 4:
|
|
|
- if(imm8 == 0xE3)
|
|
|
- {
|
|
|
- fpu_finit();
|
|
|
- }
|
|
|
- else if(imm8 == 0xE4)
|
|
|
- {
|
|
|
- // fsetpm
|
|
|
- // treat as nop
|
|
|
- }
|
|
|
- else if(imm8 == 0xE1)
|
|
|
- {
|
|
|
- // fdisi
|
|
|
- // also treat as nop
|
|
|
- }
|
|
|
- else if(imm8 == 0xE2)
|
|
|
- {
|
|
|
- // fclex
|
|
|
- *fpu_status_word = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- dbg_log("%x", imm8);
|
|
|
- fpu_unimpl();
|
|
|
- }
|
|
|
- break;
|
|
|
- case 5:
|
|
|
- fpu_fucomi(low);
|
|
|
- break;
|
|
|
- case 6:
|
|
|
- fpu_fcomi(low);
|
|
|
- break;
|
|
|
- default:
|
|
|
- dbg_log("%x", mod);
|
|
|
- fpu_unimpl();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void fpu_op_DB_mem(int32_t mod, int32_t addr)
|
|
|
-{
|
|
|
- dbg_log_fpu_op(0xDB, mod);
|
|
|
-
|
|
|
- switch(mod)
|
|
|
- {
|
|
|
- case 0:
|
|
|
- // fild
|
|
|
- {
|
|
|
- int32_t data = safe_read32s(addr);
|
|
|
- fpu_push(data);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- // fist
|
|
|
- {
|
|
|
- double_t st0 = fpu_integer_round(fpu_get_st0());
|
|
|
- int32_t i = convert_f64_to_i32(st0);
|
|
|
- if(i == (int32_t)0x80000000)
|
|
|
- {
|
|
|
- // XXX: Probably not correct if st0 == 0x80000000
|
|
|
- fpu_invalid_arithmetic();
|
|
|
- }
|
|
|
- safe_write32(addr, i);
|
|
|
- }
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- // fistp
|
|
|
- {
|
|
|
- double_t st0 = fpu_integer_round(fpu_get_st0());
|
|
|
- int32_t i = convert_f64_to_i32(st0);
|
|
|
- if(i == (int32_t)0x80000000)
|
|
|
- {
|
|
|
- // XXX: Probably not correct if st0 == 0x80000000
|
|
|
- // (input fits, but same value as error value)
|
|
|
- fpu_invalid_arithmetic();
|
|
|
- }
|
|
|
- safe_write32(addr, i);
|
|
|
- fpu_pop();
|
|
|
- }
|
|
|
- break;
|
|
|
- case 5:
|
|
|
- // fld
|
|
|
- fpu_push(fpu_load_m80(addr));
|
|
|
- break;
|
|
|
- case 7:
|
|
|
- // fstp
|
|
|
- writable_or_pagefault(addr, 10);
|
|
|
- fpu_store_m80(addr, fpu_get_st0());
|
|
|
- fpu_pop();
|
|
|
- break;
|
|
|
- default:
|
|
|
- dbg_log("%x", mod);
|
|
|
- fpu_unimpl();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
void fpu_op_DC_reg(int32_t imm8)
|
|
|
{
|
|
|
dbg_log_fpu_op(0xDC, imm8);
|