Fix the FXSAVE/FXRSTOR instructions.

This commit is contained in:
OBattler
2025-04-22 09:13:38 +02:00
parent ac25b87e48
commit 8790395a05
10 changed files with 111 additions and 17 deletions

View File

@@ -819,6 +819,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
int pc_off = 0; int pc_off = 0;
int test_modrm = 1; int test_modrm = 1;
int c; int c;
uint16_t op87 = 0x0000;
op_ea_seg = &cpu_state.seg_ds; op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 0; op_ssegs = 0;
@@ -872,6 +873,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break; break;
case 0xd8: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
opcode_shift = 3; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xd9: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xda: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdb: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdc: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
opcode_shift = 3; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdd: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xde: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdf: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
opcode_mask = 0xff; opcode_mask = 0xff;
@@ -1000,6 +1009,10 @@ generate_call:
recomp_op_table = recomp_opcodes; 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]) { 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); uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
if (new_pc) { if (new_pc) {

View File

@@ -1858,6 +1858,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
int pc_off = 0; int pc_off = 0;
int test_modrm = 1; int test_modrm = 1;
int c; int c;
uint16_t op87 = 0x0000;
op_ea_seg = &cpu_state.seg_ds; op_ea_seg = &cpu_state.seg_ds;
op_ssegs = 0; op_ssegs = 0;
@@ -1912,6 +1913,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
break; break;
case 0xd8: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
opcode_shift = 3; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xd9: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xda: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdb: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdc: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
opcode_shift = 3; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdd: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xde: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
opcode_mask = 0xff; 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; block->flags |= CODEBLOCK_HAS_FPU;
break; break;
case 0xdf: 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; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
opcode_mask = 0xff; opcode_mask = 0xff;
@@ -2041,6 +2050,10 @@ generate_call:
recomp_op_table = recomp_opcodes; 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]) { 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); uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
if (new_pc) { if (new_pc) {

View File

@@ -396,6 +396,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
int test_modrm = 1; int test_modrm = 1;
int pc_off = 0; int pc_off = 0;
uint32_t next_pc = 0; uint32_t next_pc = 0;
uint16_t op87 = 0x0000;
#ifdef DEBUG_EXTRA #ifdef DEBUG_EXTRA
uint8_t last_prefix = 0; uint8_t last_prefix = 0;
#endif #endif
@@ -451,6 +452,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p
#ifdef DEBUG_EXTRA #ifdef DEBUG_EXTRA
last_prefix = 0xd8; last_prefix = 0xd8;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d8;
opcode_shift = 3; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xd9; last_prefix = 0xd9;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9;
opcode_mask = 0xff; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xda; last_prefix = 0xda;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da;
opcode_mask = 0xff; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xdb; last_prefix = 0xdb;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db;
opcode_mask = 0xff; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xdc; last_prefix = 0xdc;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dc;
opcode_shift = 3; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xdd; last_prefix = 0xdd;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd;
opcode_mask = 0xff; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xde; last_prefix = 0xde;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de;
opcode_mask = 0xff; 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 #ifdef DEBUG_EXTRA
last_prefix = 0xdf; last_prefix = 0xdf;
#endif #endif
op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff);
op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16;
recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df; recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df;
opcode_mask = 0xff; opcode_mask = 0xff;
@@ -657,6 +666,9 @@ generate_call:
} }
} }
codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off); 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. */ /* It is apparently a prefixed instruction. */
#if 0 #if 0
if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48))

View File

@@ -170,6 +170,7 @@ struct
[IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, [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_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 /*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 be preserved across uOPs. They will not be written back if they will

View File

@@ -133,8 +133,9 @@ enum {
IREG_SS_limit_high = 87, IREG_SS_limit_high = 87,
IREG_eaa16 = 88, IREG_eaa16 = 88,
IREG_x87_op = 89,
IREG_COUNT = 89, IREG_COUNT = 90,
IREG_INVALID = 255, IREG_INVALID = 255,

View File

@@ -113,6 +113,8 @@ uint8_t is_smint = 0;
uint16_t io_port = 0x0000; uint16_t io_port = 0x0000;
uint32_t io_val = 0x00000000; uint32_t io_val = 0x00000000;
uint16_t x87_op = 0x0000;
int opcode_has_modrm[256] = { 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, /*00*/
1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/

View File

@@ -784,6 +784,8 @@ typedef struct {
uint32_t smhr; uint32_t smhr;
} cyrix_t; } cyrix_t;
extern uint16_t x87_op;
extern uint32_t addr64; extern uint32_t addr64;
extern uint32_t addr64_2; extern uint32_t addr64_2;
extern uint32_t addr64a[8]; extern uint32_t addr64a[8];

View File

@@ -4,88 +4,104 @@
static int static int
opESCAPE_d8_a16(uint32_t fetchdat) opESCAPE_d8_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_d8_a32(uint32_t fetchdat) opESCAPE_d8_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_d9_a16(uint32_t fetchdat) opESCAPE_d9_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_d9_a32(uint32_t fetchdat) opESCAPE_d9_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_da_a16(uint32_t fetchdat) opESCAPE_da_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_da_a32(uint32_t fetchdat) opESCAPE_da_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_db_a16(uint32_t fetchdat) opESCAPE_db_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_db_a32(uint32_t fetchdat) opESCAPE_db_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_dc_a16(uint32_t fetchdat) opESCAPE_dc_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_dc_a32(uint32_t fetchdat) opESCAPE_dc_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_dd_a16(uint32_t fetchdat) opESCAPE_dd_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_dd_a32(uint32_t fetchdat) opESCAPE_dd_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_de_a16(uint32_t fetchdat) opESCAPE_de_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_de_a32(uint32_t fetchdat) opESCAPE_de_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_df_a16(uint32_t fetchdat) opESCAPE_df_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_df_a32(uint32_t fetchdat) opESCAPE_df_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat);
} }

View File

@@ -4,88 +4,104 @@
static int static int
opESCAPE_d8_a16(uint32_t fetchdat) opESCAPE_d8_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); return x86_2386_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_d8_a32(uint32_t fetchdat) opESCAPE_d8_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); return x86_2386_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_d9_a16(uint32_t fetchdat) opESCAPE_d9_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_d9_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_d9_a32(uint32_t fetchdat) opESCAPE_d9_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_d9_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_da_a16(uint32_t fetchdat) opESCAPE_da_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_da_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_da_a32(uint32_t fetchdat) opESCAPE_da_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_da_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_db_a16(uint32_t fetchdat) opESCAPE_db_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_db_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_db_a32(uint32_t fetchdat) opESCAPE_db_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_db_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_dc_a16(uint32_t fetchdat) opESCAPE_dc_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); return x86_2386_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_dc_a32(uint32_t fetchdat) opESCAPE_dc_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); return x86_2386_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat);
} }
static int static int
opESCAPE_dd_a16(uint32_t fetchdat) opESCAPE_dd_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_dd_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_dd_a32(uint32_t fetchdat) opESCAPE_dd_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_dd_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_de_a16(uint32_t fetchdat) opESCAPE_de_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_de_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_de_a32(uint32_t fetchdat) opESCAPE_de_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_de_a32[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_df_a16(uint32_t fetchdat) opESCAPE_df_a16(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_df_a16[fetchdat & 0xff](fetchdat);
} }
static int static int
opESCAPE_df_a32(uint32_t fetchdat) opESCAPE_df_a32(uint32_t fetchdat)
{ {
x87_op = ((opcode & 0x07) << 8) | (fetchdat & 0xff);
return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat); return x86_2386_opcodes_df_a32[fetchdat & 0xff](fetchdat);
} }

View File

@@ -46,8 +46,6 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
if (CPUID < 0x650) if (CPUID < 0x650)
return ILLEGAL(fetchdat); return ILLEGAL(fetchdat);
FP_ENTER();
if (bits == 32) { if (bits == 32) {
fetch_ea_32(fetchdat); fetch_ea_32(fetchdat);
} else { } 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 */ /* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */
fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF;
fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8); 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); fpu_state.fcs = readmemw(easeg, cpu_state.eaaddr + 12);
tag_byte = readmemb(easeg, cpu_state.eaaddr + 4); tag_byte = readmemb(easeg, cpu_state.eaaddr + 4);
fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16); 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); fpu_state.fds = readmemw(easeg, cpu_state.eaaddr + 20);
/* load i387 register file */ /* 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); fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward);
} }
// CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
CLOCK_CYCLES(1); CLOCK_CYCLES(1);
} else { } else {
/* FXSAVE */ /* FXSAVE */
@@ -132,7 +135,10 @@ sf_fx_save_stor_common(uint32_t fetchdat, int bits)
* x87 CS FPU IP Selector * x87 CS FPU IP Selector
* + 16 bit, in 16/32 bit mode only * + 16 bit, in 16/32 bit mode only
*/ */
writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip); 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); 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 * x87 DS FPU Instruction Operand (Data) Pointer Selector
* + 16 bit, in 16/32 bit mode only * + 16 bit, in 16/32 bit mode only
*/ */
writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp); 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); writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds);
/* store i387 register file */ /* store i387 register file */
@@ -256,8 +265,6 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
return cpu_state.abrt; return cpu_state.abrt;
} }
FP_ENTER();
old_eaaddr = cpu_state.eaaddr; old_eaaddr = cpu_state.eaaddr;
if (fxinst == 1) { if (fxinst == 1) {
@@ -269,13 +276,19 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
cpu_state.TOP = (fpus >> 11) & 7; cpu_state.TOP = (fpus >> 11) & 7;
cpu_state.npxs &= fpus & ~0x3800; cpu_state.npxs &= fpus & ~0x3800;
x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8); 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); x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12);
ftwb = readmemb(easeg, cpu_state.eaaddr + 4); ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
x87_op = readmemw(easeg, cpu_state.eaaddr + 6) & 0x07ff;
x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16); if (bits == 32)
x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16);
else
x87_op_off = readmemw(easeg, cpu_state.eaaddr +16);
x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20); x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20);
for (i = 0; i <= 7; i++) { 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); CLOCK_CYCLES(1);
} else { } else {
/* FXSAVE */ /* FXSAVE */
@@ -345,11 +357,17 @@ fx_save_stor_common(uint32_t fetchdat, int bits)
writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs);
writememb(easeg, cpu_state.eaaddr + 4, ftwb); 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);
writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off); 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); writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg);
writememl(easeg, cpu_state.eaaddr + 16, x87_op_off); 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); writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg);
if (cpu_state.ismmx) { if (cpu_state.ismmx) {