Fix the FXSAVE/FXRSTOR instructions.
This commit is contained in:
@@ -819,6 +819,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
int pc_off = 0;
|
||||
int test_modrm = 1;
|
||||
int c;
|
||||
uint16_t op87 = 0x0000;
|
||||
|
||||
op_ea_seg = &cpu_state.seg_ds;
|
||||
op_ssegs = 0;
|
||||
@@ -872,6 +873,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
|
||||
opcode_shift = 3;
|
||||
@@ -882,6 +884,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xd9:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
|
||||
opcode_mask = 0xff;
|
||||
@@ -891,6 +894,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xda:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
|
||||
opcode_mask = 0xff;
|
||||
@@ -900,6 +904,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdb:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
|
||||
opcode_mask = 0xff;
|
||||
@@ -909,6 +914,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdc:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
|
||||
opcode_shift = 3;
|
||||
@@ -919,6 +925,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdd:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
|
||||
opcode_mask = 0xff;
|
||||
@@ -928,6 +935,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xde:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
|
||||
opcode_mask = 0xff;
|
||||
@@ -937,6 +945,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdf:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
|
||||
opcode_mask = 0xff;
|
||||
@@ -1000,6 +1009,10 @@ generate_call:
|
||||
recomp_op_table = recomp_opcodes;
|
||||
}
|
||||
|
||||
if (op87 != 0x0000) {
|
||||
STORE_IMM_ADDR_W((uintptr_t) &x87_op, op87);
|
||||
}
|
||||
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
|
||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
if (new_pc) {
|
||||
|
||||
@@ -1858,6 +1858,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
int pc_off = 0;
|
||||
int test_modrm = 1;
|
||||
int c;
|
||||
uint16_t op87 = 0x0000;
|
||||
|
||||
op_ea_seg = &cpu_state.seg_ds;
|
||||
op_ssegs = 0;
|
||||
@@ -1912,6 +1913,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
|
||||
opcode_shift = 3;
|
||||
@@ -1922,6 +1924,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xd9:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
|
||||
opcode_mask = 0xff;
|
||||
@@ -1931,6 +1934,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xda:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
|
||||
opcode_mask = 0xff;
|
||||
@@ -1940,6 +1944,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdb:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
|
||||
opcode_mask = 0xff;
|
||||
@@ -1949,6 +1954,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdc:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
|
||||
opcode_shift = 3;
|
||||
@@ -1959,6 +1965,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdd:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
|
||||
opcode_mask = 0xff;
|
||||
@@ -1968,6 +1975,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xde:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
|
||||
opcode_mask = 0xff;
|
||||
@@ -1977,6 +1985,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
block->flags |= CODEBLOCK_HAS_FPU;
|
||||
break;
|
||||
case 0xdf:
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
|
||||
opcode_mask = 0xff;
|
||||
@@ -2041,6 +2050,10 @@ generate_call:
|
||||
recomp_op_table = recomp_opcodes;
|
||||
}
|
||||
|
||||
if (op87 != 0x0000) {
|
||||
STORE_IMM_ADDR_W((uintptr_t) &x87_op, op87);
|
||||
}
|
||||
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) {
|
||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
if (new_pc) {
|
||||
|
||||
@@ -396,6 +396,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
int test_modrm = 1;
|
||||
int pc_off = 0;
|
||||
uint32_t next_pc = 0;
|
||||
uint16_t op87 = 0x0000;
|
||||
#ifdef DEBUG_EXTRA
|
||||
uint8_t last_prefix = 0;
|
||||
#endif
|
||||
@@ -451,6 +452,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xd8;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
|
||||
opcode_shift = 3;
|
||||
@@ -464,6 +466,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xd9;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
|
||||
opcode_mask = 0xff;
|
||||
@@ -476,6 +479,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xda;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
|
||||
opcode_mask = 0xff;
|
||||
@@ -488,6 +492,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xdb;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
|
||||
opcode_mask = 0xff;
|
||||
@@ -500,6 +505,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xdc;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
|
||||
opcode_shift = 3;
|
||||
@@ -513,6 +519,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xdd;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
|
||||
opcode_mask = 0xff;
|
||||
@@ -525,6 +532,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xde;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
|
||||
opcode_mask = 0xff;
|
||||
@@ -537,6 +545,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
|
||||
#ifdef DEBUG_EXTRA
|
||||
last_prefix = 0xdf;
|
||||
#endif
|
||||
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
|
||||
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
|
||||
opcode_mask = 0xff;
|
||||
@@ -657,6 +666,9 @@ generate_call:
|
||||
}
|
||||
}
|
||||
codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off);
|
||||
if (op87 != 0x0000) {
|
||||
uop_MOV_IMM(ir, IREG_x87_op, op87);
|
||||
}
|
||||
/* It is apparently a prefixed instruction. */
|
||||
#if 0
|
||||
if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48))
|
||||
|
||||
@@ -170,6 +170,7 @@ struct
|
||||
[IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT},
|
||||
|
||||
[IREG_eaa16] = { REG_WORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT},
|
||||
[IREG_x87_op] = { REG_WORD, &x87_op, REG_INTEGER, REG_PERMANENT},
|
||||
|
||||
/*Temporary registers are stored on the stack, and are not guaranteed to
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
|
||||
@@ -133,8 +133,9 @@ enum {
|
||||
IREG_SS_limit_high = 87,
|
||||
|
||||
IREG_eaa16 = 88,
|
||||
IREG_x87_op = 89,
|
||||
|
||||
IREG_COUNT = 89,
|
||||
IREG_COUNT = 90,
|
||||
|
||||
IREG_INVALID = 255,
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ uint8_t is_smint = 0;
|
||||
uint16_t io_port = 0x0000;
|
||||
uint32_t io_val = 0x00000000;
|
||||
|
||||
uint16_t x87_op = 0x0000;
|
||||
|
||||
int opcode_has_modrm[256] = {
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/
|
||||
|
||||
@@ -784,6 +784,8 @@ typedef struct {
|
||||
uint32_t smhr;
|
||||
} cyrix_t;
|
||||
|
||||
extern uint16_t x87_op;
|
||||
|
||||
extern uint32_t addr64;
|
||||
extern uint32_t addr64_2;
|
||||
extern uint32_t addr64a[8];
|
||||
|
||||
@@ -4,88 +4,104 @@
|
||||
static int
|
||||
opESCAPE_d8_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_d8_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_d9_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_d9_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_da_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_da_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_db_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_db_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_dc_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_dc_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_dd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_dd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_de_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_de_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_df_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_df_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,88 +4,104 @@
|
||||
static int
|
||||
opESCAPE_d8_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_d8_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_d9_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_d9_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_da_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_da_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_db_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_db_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_dc_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_dc_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_dd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_dd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_de_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_de_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
static int
|
||||
opESCAPE_df_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
static int
|
||||
opESCAPE_df_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
|
||||
return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,6 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
if (CPUID < 0x650)
|
||||
return ILLEGAL(fetchdat);
|
||||
|
||||
FP_ENTER();
|
||||
|
||||
if (bits == 32) {
|
||||
fetch_ea_32(fetchdat);
|
||||
} else {
|
||||
@@ -82,12 +80,18 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
/* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */
|
||||
fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF;
|
||||
|
||||
if (bits == 32)
|
||||
fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8);
|
||||
else
|
||||
fpu_state.fip = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
fpu_state.fcs = readmemw(easeg, cpu_state.eaaddr + 12);
|
||||
|
||||
tag_byte = readmemb(easeg, cpu_state.eaaddr + 4);
|
||||
|
||||
if (bits == 32)
|
||||
fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16);
|
||||
else
|
||||
fpu_state.fdp = readmemw(easeg, cpu_state.eaaddr + 16);
|
||||
fpu_state.fds = readmemw(easeg, cpu_state.eaaddr + 20);
|
||||
|
||||
/* load i387 register file */
|
||||
@@ -110,7 +114,6 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
|
||||
}
|
||||
|
||||
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
/* FXSAVE */
|
||||
@@ -132,7 +135,10 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
* x87 CS FPU IP Selector
|
||||
* + 16 bit, in 16/32 bit mode only
|
||||
*/
|
||||
if (bits == 32)
|
||||
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip);
|
||||
else
|
||||
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip & 0xffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs);
|
||||
|
||||
/*
|
||||
@@ -145,7 +151,10 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
* x87 DS FPU Instruction Operand (Data) Pointer Selector
|
||||
* + 16 bit, in 16/32 bit mode only
|
||||
*/
|
||||
if (bits == 32)
|
||||
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp);
|
||||
else
|
||||
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp & 0xffff);
|
||||
writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds);
|
||||
|
||||
/* store i387 register file */
|
||||
@@ -256,8 +265,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
FP_ENTER();
|
||||
|
||||
old_eaaddr = cpu_state.eaaddr;
|
||||
|
||||
if (fxinst == 1) {
|
||||
@@ -269,13 +276,19 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
cpu_state.TOP = (fpus >> 11) & 7;
|
||||
cpu_state.npxs &= fpus & ~0x3800;
|
||||
|
||||
if (bits == 32)
|
||||
x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8);
|
||||
else
|
||||
x87_pc_off = readmemw(easeg, cpu_state.eaaddr + 8);
|
||||
x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12);
|
||||
|
||||
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
|
||||
x87_op = readmemw(easeg, cpu_state.eaaddr + 6) & 0x07ff;
|
||||
|
||||
if (bits == 32)
|
||||
x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16);
|
||||
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16;
|
||||
else
|
||||
x87_op_off = readmemw(easeg, cpu_state.eaaddr +16);
|
||||
x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20);
|
||||
|
||||
for (i = 0; i <= 7; i++) {
|
||||
@@ -320,7 +333,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
}
|
||||
}
|
||||
|
||||
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
CLOCK_CYCLES(1);
|
||||
} else {
|
||||
/* FXSAVE */
|
||||
@@ -345,11 +357,17 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
|
||||
writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs);
|
||||
writememb(easeg, cpu_state.eaaddr + 4, ftwb);
|
||||
|
||||
writememw(easeg, cpu_state.eaaddr + 6, (x87_op_off >> 16) << 12);
|
||||
writememw(easeg, cpu_state.eaaddr + 6, x87_op);
|
||||
if (bits == 32)
|
||||
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off);
|
||||
else
|
||||
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off & 0xffff);
|
||||
writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg);
|
||||
|
||||
if (bits == 32)
|
||||
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off);
|
||||
else
|
||||
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off & 0xffff);
|
||||
writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg);
|
||||
|
||||
if (cpu_state.ismmx) {
|
||||
|
||||
Reference in New Issue
Block a user