Added lazy flags for ROL and ROR.

This commit is contained in:
SarahW 2019-03-30 14:41:02 +00:00
commit e2a1ae696f
3 changed files with 85 additions and 26 deletions

View file

@ -189,7 +189,7 @@ static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, u
if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr))
{ {
if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) if (!codegen_flags_changed || !flags_res_valid())
{ {
uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET);
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
@ -205,7 +205,7 @@ static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, u
} }
else else
{ {
if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) if (!codegen_flags_changed || !flags_res_valid())
{ {
uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET);
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
@ -226,7 +226,7 @@ int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_
if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr))
{ {
if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) if (!codegen_flags_changed || !flags_res_valid())
{ {
uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET);
jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
@ -242,7 +242,7 @@ int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_
} }
else else
{ {
if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) if (!codegen_flags_changed || !flags_res_valid())
{ {
uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET);
jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);
@ -954,7 +954,7 @@ uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
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);
} }
if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) if (!codegen_flags_changed || !flags_res_valid())
{ {
uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET);
jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0);
@ -990,7 +990,7 @@ uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
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);
} }
if (!codegen_flags_changed || (cpu_state.flags_op == FLAGS_UNKNOWN)) if (!codegen_flags_changed || !flags_res_valid())
{ {
uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET);
jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0);

View file

@ -28,6 +28,14 @@ enum
FLAGS_SAR16, FLAGS_SAR16,
FLAGS_SAR32, FLAGS_SAR32,
FLAGS_ROL8,
FLAGS_ROL16,
FLAGS_ROL32,
FLAGS_ROR8,
FLAGS_ROR16,
FLAGS_ROR32,
FLAGS_INC8, FLAGS_INC8,
FLAGS_INC16, FLAGS_INC16,
FLAGS_INC32, FLAGS_INC32,
@ -81,6 +89,12 @@ static inline int ZF_SET()
case FLAGS_SBC32: case FLAGS_SBC32:
return !cpu_state.flags_res; return !cpu_state.flags_res;
case FLAGS_ROL8:
case FLAGS_ROL16:
case FLAGS_ROL32:
case FLAGS_ROR8:
case FLAGS_ROR16:
case FLAGS_ROR32:
case FLAGS_UNKNOWN: case FLAGS_UNKNOWN:
return cpu_state.flags & Z_FLAG; return cpu_state.flags & Z_FLAG;
} }
@ -127,6 +141,12 @@ static inline int NF_SET()
case FLAGS_SBC32: case FLAGS_SBC32:
return cpu_state.flags_res & 0x80000000; return cpu_state.flags_res & 0x80000000;
case FLAGS_ROL8:
case FLAGS_ROL16:
case FLAGS_ROL32:
case FLAGS_ROR8:
case FLAGS_ROR16:
case FLAGS_ROR32:
case FLAGS_UNKNOWN: case FLAGS_UNKNOWN:
return cpu_state.flags & N_FLAG; return cpu_state.flags & N_FLAG;
} }
@ -169,6 +189,12 @@ static inline int PF_SET()
case FLAGS_SBC32: case FLAGS_SBC32:
return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; return znptable8[cpu_state.flags_res & 0xff] & P_FLAG;
case FLAGS_ROL8:
case FLAGS_ROL16:
case FLAGS_ROL32:
case FLAGS_ROR8:
case FLAGS_ROR16:
case FLAGS_ROR32:
case FLAGS_UNKNOWN: case FLAGS_UNKNOWN:
return cpu_state.flags & P_FLAG; return cpu_state.flags & P_FLAG;
} }
@ -227,6 +253,20 @@ static inline int VF_SET()
case FLAGS_SHR32: case FLAGS_SHR32:
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000));
case FLAGS_ROL8:
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1;
case FLAGS_ROL16:
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1;
case FLAGS_ROL32:
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1;
case FLAGS_ROR8:
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40;
case FLAGS_ROR16:
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000;
case FLAGS_ROR32:
return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000;
case FLAGS_UNKNOWN: case FLAGS_UNKNOWN:
return cpu_state.flags & V_FLAG; return cpu_state.flags & V_FLAG;
} }
@ -283,6 +323,12 @@ static inline int AF_SET()
return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) ||
((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0);
case FLAGS_ROL8:
case FLAGS_ROL16:
case FLAGS_ROL32:
case FLAGS_ROR8:
case FLAGS_ROR16:
case FLAGS_ROR32:
case FLAGS_UNKNOWN: case FLAGS_UNKNOWN:
return cpu_state.flags & A_FLAG; return cpu_state.flags & A_FLAG;
} }
@ -345,6 +391,18 @@ static inline int CF_SET()
case FLAGS_ZN32: case FLAGS_ZN32:
return 0; return 0;
case FLAGS_ROL8:
case FLAGS_ROL16:
case FLAGS_ROL32:
return cpu_state.flags_res & 1;
case FLAGS_ROR8:
return (cpu_state.flags_res & 0x80) ? 1 : 0;
case FLAGS_ROR16:
return (cpu_state.flags_res & 0x8000) ? 1 :0;
case FLAGS_ROR32:
return (cpu_state.flags_res & 0x80000000) ? 1 : 0;
case FLAGS_DEC8: case FLAGS_DEC8:
case FLAGS_DEC16: case FLAGS_DEC16:
case FLAGS_DEC32: case FLAGS_DEC32:
@ -396,6 +454,15 @@ static inline void flags_rebuild_c()
} }
} }
static inline int flags_res_valid()
{
if (cpu_state.flags_op == FLAGS_UNKNOWN ||
(cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32))
return 0;
return 1;
}
static inline void setznp8(uint8_t val) static inline void setznp8(uint8_t val)
{ {
cpu_state.flags_op = FLAGS_ZN8; cpu_state.flags_op = FLAGS_ZN8;
@ -418,6 +485,10 @@ static inline void setznp32(uint32_t val)
cpu_state.flags_op1 = orig; \ cpu_state.flags_op1 = orig; \
cpu_state.flags_op2 = shift; cpu_state.flags_op2 = shift;
#define set_flags_rotate(op, res) \
cpu_state.flags_op = op; \
cpu_state.flags_res = res;
static inline void setadd8(uint8_t a, uint8_t b) static inline void setadd8(uint8_t a, uint8_t b)
{ {
cpu_state.flags_op1 = a; cpu_state.flags_op1 = a;

View file

@ -8,18 +8,14 @@
case 0x00: /*ROL b, c*/ \ case 0x00: /*ROL b, c*/ \
temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \
seteab(temp); if (cpu_state.abrt) return 1; \ seteab(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \ set_flags_rotate(FLAGS_ROL8, temp); \
if (temp & 1) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \ break; \
case 0x08: /*ROR b,CL*/ \ case 0x08: /*ROR b,CL*/ \
temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \
seteab(temp); if (cpu_state.abrt) return 1; \ seteab(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \ set_flags_rotate(FLAGS_ROR8, temp); \
if (temp & 0x80) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \ break; \
@ -89,18 +85,14 @@
case 0x00: /*ROL w, c*/ \ case 0x00: /*ROL w, c*/ \
temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \
seteaw(temp); if (cpu_state.abrt) return 1; \ seteaw(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \ set_flags_rotate(FLAGS_ROL16, temp); \
if (temp & 1) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \ break; \
case 0x08: /*ROR w,CL*/ \ case 0x08: /*ROR w,CL*/ \
temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \
seteaw(temp); if (cpu_state.abrt) return 1; \ seteaw(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \ set_flags_rotate(FLAGS_ROR16, temp); \
if (temp & 0x8000) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \ break; \
@ -170,18 +162,14 @@
case 0x00: /*ROL l, c*/ \ case 0x00: /*ROL l, c*/ \
temp = (temp << c) | (temp >> (32-c)); \ temp = (temp << c) | (temp >> (32-c)); \
seteal(temp); if (cpu_state.abrt) return 1; \ seteal(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \ set_flags_rotate(FLAGS_ROL32, temp); \
if (temp & 1) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \ break; \
case 0x08: /*ROR l,CL*/ \ case 0x08: /*ROR l,CL*/ \
temp = (temp >> c) | (temp << (32-c)); \ temp = (temp >> c) | (temp << (32-c)); \
seteal(temp); if (cpu_state.abrt) return 1; \ seteal(temp); if (cpu_state.abrt) return 1; \
cpu_state.flags &= ~(C_FLAG | V_FLAG); \ set_flags_rotate(FLAGS_ROR32, temp); \
if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
break; \ break; \