Remove test-USE32-and-mask-PC operation following code block execution. Instead, ensure that all recompiled instructions mask PC correctly.

This commit is contained in:
SarahW 2019-01-27 20:54:22 +00:00
commit ee186dbb0d
3 changed files with 79 additions and 46 deletions

View file

@ -678,7 +678,6 @@ void exec386_dynarec(int cycs)
inrecomp=1; inrecomp=1;
code(); code();
inrecomp=0; inrecomp=0;
if (!use32) cpu_state.pc &= 0xffff;
// cpu_recomp_ins += block->ins; // cpu_recomp_ins += block->ins;
cpu_recomp_blocks++; cpu_recomp_blocks++;
/* ins += codeblock_ins[index]; /* ins += codeblock_ins[index];

View file

@ -19,7 +19,7 @@ static int VF_SET_01()
return VF_SET() ? 1 : 0; return VF_SET() ? 1 : 0;
} }
static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -47,11 +47,11 @@ static void ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -59,7 +59,7 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
{ {
case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32:
/*Overflow is always zero*/ /*Overflow is always zero*/
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
return; return;
@ -81,12 +81,12 @@ static void ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -114,11 +114,11 @@ static void ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -126,7 +126,7 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
{ {
case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32:
/*Carry is always zero*/ /*Carry is always zero*/
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
return; return;
@ -148,12 +148,12 @@ static void ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -166,11 +166,11 @@ static void ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
{ {
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0);
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -183,12 +183,12 @@ void ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t
{ {
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0);
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop, jump_uop2 = -1; int jump_uop, jump_uop2 = -1;
@ -219,11 +219,11 @@ static void ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
} }
if (jump_uop2 != -1) if (jump_uop2 != -1)
uop_set_jump_dest(ir, jump_uop2); uop_set_jump_dest(ir, jump_uop2);
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop, jump_uop2 = -1; int jump_uop, jump_uop2 = -1;
@ -252,14 +252,14 @@ static void ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc,
jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
if (jump_uop2 != -1) if (jump_uop2 != -1)
uop_set_jump_dest(ir, jump_uop2); uop_set_jump_dest(ir, jump_uop2);
} }
static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -304,11 +304,11 @@ static void ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -353,33 +353,33 @@ static void ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET);
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET);
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -413,11 +413,11 @@ static void ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, ui
jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop; int jump_uop;
@ -451,12 +451,12 @@ static void ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop, jump_uop2 = -1; int jump_uop, jump_uop2 = -1;
@ -483,11 +483,11 @@ static void ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, u
} }
if (jump_uop2 != -1) if (jump_uop2 != -1)
uop_set_jump_dest(ir, jump_uop2); uop_set_jump_dest(ir, jump_uop2);
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
} }
static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc, uint32_t offset) static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr)
{ {
int jump_uop, jump_uop2 = -1; int jump_uop, jump_uop2 = -1;
@ -512,7 +512,7 @@ static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc,
jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1);
break; break;
} }
uop_MOV_IMM(ir, IREG_pc, base_pc + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
if (jump_uop2 != -1) if (jump_uop2 != -1)
@ -523,21 +523,29 @@ static void ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t base_pc,
uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \
{ \ { \
uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \
ropJ ## cond ## _common(block, ir, op_pc+1, offset); \ uint32_t dest_addr = op_pc + 1 + offset; \
\
if (!(op_32 & 0x100)) \
dest_addr &= 0xffff; \
ropJ ## cond ## _common(block, ir, dest_addr); \
\ \
return op_pc+1; \ return op_pc+1; \
} \ } \
uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \
{ \ { \
uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \
ropJ ## cond ## _common(block, ir, op_pc+2, offset); \ uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \
\
ropJ ## cond ## _common(block, ir, dest_addr); \
\ \
return op_pc+2; \ return op_pc+2; \
} \ } \
uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \
{ \ { \
uint32_t offset = fastreadl(cs + op_pc); \ uint32_t offset = fastreadl(cs + op_pc); \
ropJ ## cond ## _common(block, ir, op_pc+4, offset); \ uint32_t dest_addr = op_pc + 4 + offset; \
\
ropJ ## cond ## _common(block, ir, dest_addr); \
\ \
return op_pc+4; \ return op_pc+4; \
} }
@ -563,13 +571,17 @@ ropJ(NLE)
uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc + 1 + offset;
int jump_uop; int jump_uop;
if (!(op_32 & 0x100))
dest_addr &= 0xffff;
if (op_32 & 0x200) if (op_32 & 0x200)
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0);
else else
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0);
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
@ -579,8 +591,12 @@ uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc + 1 + offset;
int jump_uop; int jump_uop;
if (!(op_32 & 0x100))
dest_addr &= 0xffff;
if (op_32 & 0x200) if (op_32 & 0x200)
{ {
uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1);
@ -591,7 +607,7 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1);
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0);
} }
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
@ -601,8 +617,12 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc + 1 + offset;
int jump_uop, jump_uop2; int jump_uop, jump_uop2;
if (!(op_32 & 0x100))
dest_addr &= 0xffff;
if (op_32 & 0x200) if (op_32 & 0x200)
{ {
uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1);
@ -622,7 +642,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
{ {
jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0);
} }
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
uop_set_jump_dest(ir, jump_uop2); uop_set_jump_dest(ir, jump_uop2);
@ -632,8 +652,12 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc + 1 + offset;
int jump_uop, jump_uop2; int jump_uop, jump_uop2;
if (!(op_32 & 0x100))
dest_addr &= 0xffff;
if (op_32 & 0x200) if (op_32 & 0x200)
{ {
uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1);
@ -653,7 +677,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
{ {
jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0);
} }
uop_MOV_IMM(ir, IREG_pc, op_pc + 1 + offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
uop_JMP(ir, codegen_exit_rout); uop_JMP(ir, codegen_exit_rout);
uop_set_jump_dest(ir, jump_uop); uop_set_jump_dest(ir, jump_uop);
uop_set_jump_dest(ir, jump_uop2); uop_set_jump_dest(ir, jump_uop2);

View file

@ -12,22 +12,30 @@
uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc);
uint32_t dest_addr = op_pc+1+offset;
uop_MOV_IMM(ir, IREG_pc, op_pc+1+offset); if (!(op_32 & 0x100))
dest_addr &= 0xffff;
uop_MOV_IMM(ir, IREG_pc, dest_addr);
return -1; return -1;
} }
uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc);
uint32_t dest_addr = op_pc+2+offset;
dest_addr &= 0xffff;
uop_MOV_IMM(ir, IREG_pc, op_pc+2+offset); uop_MOV_IMM(ir, IREG_pc, dest_addr);
return -1; return -1;
} }
uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{ {
uint32_t offset = fastreadl(cs + op_pc); uint32_t offset = fastreadl(cs + op_pc);
uint32_t dest_addr = op_pc+4+offset;
uop_MOV_IMM(ir, IREG_pc, op_pc+4+offset);
uop_MOV_IMM(ir, IREG_pc, dest_addr);
return -1; return -1;
} }
@ -65,6 +73,8 @@ uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
uint16_t dest_addr = ret_addr + offset; uint16_t dest_addr = ret_addr + offset;
int sp_reg; int sp_reg;
dest_addr &= 0xffff;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr);