From e012420f90a563f752c6df5622c7ce623d9f1116 Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 09:58:50 +0000 Subject: [PATCH] Added recompiled versions of CLC, CLD, CLI, CMC, STC, STD and STI. --- src/codegen_ops.c | 4 ++-- src/codegen_ops_misc.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/codegen_ops_misc.h | 10 +++++++++ src/codegen_reg.c | 2 ++ src/codegen_reg.h | 8 +++++-- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 8dc433a..3093ee5 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -43,7 +43,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES_16, ropLDS_16, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, ropRETF_imm_16, ropRETF_16, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, ropJMP_far_16, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_16, +/*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_16, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_16, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -65,7 +65,7 @@ RecompOpFn recomp_opcodes[512] = /*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES_32, ropLDS_32, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, ropRETF_imm_32, ropRETF_32, NULL, NULL, NULL, NULL, /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_32 +/*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_32 }; diff --git a/src/codegen_ops_misc.c b/src/codegen_ops_misc.c index e3635e3..8afb20a 100644 --- a/src/codegen_ops_misc.c +++ b/src/codegen_ops_misc.c @@ -551,3 +551,50 @@ ropLxS(LES, &cpu_state.seg_es) ropLxS(LFS, &cpu_state.seg_fs) ropLxS(LGS, &cpu_state.seg_gs) ropLxS(LSS, &cpu_state.seg_ss) + +uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_CALL_FUNC(ir, flags_rebuild); + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); + return op_pc; +} +uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_CALL_FUNC(ir, flags_rebuild); + uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; +} +uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_CALL_FUNC(ir, flags_rebuild); + uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; +} + +uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); + return op_pc; +} +uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); + return op_pc; +} + +uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); + return op_pc; +} +uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + + uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); + return op_pc; +} diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index 20f115d..8f2fd76 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -25,3 +25,13 @@ uint32_t ropLGS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f uint32_t ropLGS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropLSS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropLSS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index 9c19d10..7fa5ff2 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -134,6 +134,8 @@ struct [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER}, [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, + + [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER}, /*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 diff --git a/src/codegen_reg.h b/src/codegen_reg.h index 63a0b6d..aa35ab5 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -115,8 +115,10 @@ enum IREG_NPXCx = 72, IREG_NPXSx = 73, + + IREG_flagsx = 74, - IREG_COUNT = 74, + IREG_COUNT = 75, IREG_INVALID = 255, @@ -181,7 +183,9 @@ enum IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, - IREG_ssegs = IREG_ssegsx + IREG_SIZE_B + IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, + + IREG_flags = IREG_flagsx + IREG_SIZE_W }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))