From 335cea3ee1a619f3826e198a5c8b1077ef6b27bd Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 28 Nov 2018 15:19:21 +0000 Subject: [PATCH] Added recompiled versions of PUSHF and PUSHFD. --- src/codegen_ops.c | 4 ++-- src/codegen_ops_stack.c | 40 ++++++++++++++++++++++++++++++++++++++++ src/codegen_ops_stack.h | 3 +++ src/codegen_reg.c | 3 ++- src/codegen_reg.h | 8 +++++--- 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 29a9d39..10b19d2 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -36,7 +36,7 @@ RecompOpFn recomp_opcodes[512] = /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, -/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, NULL, ropPUSHF, NULL, NULL, NULL, /*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, @@ -58,7 +58,7 @@ RecompOpFn recomp_opcodes[512] = /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, /*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, -/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, NULL, NULL, ropPUSHFD, NULL, NULL, NULL, /*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, diff --git a/src/codegen_ops_stack.c b/src/codegen_ops_stack.c index 09485b2..29d2bda 100644 --- a/src/codegen_ops_stack.c +++ b/src/codegen_ops_stack.c @@ -1,6 +1,7 @@ #include "ibm.h" #include "x86.h" +#include "x86_flags.h" #include "386_common.h" #include "codegen.h" #include "codegen_ir.h" @@ -361,3 +362,42 @@ uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t return op_pc; } + +uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + SUB_SP(ir, 2); + + return op_pc; +} +uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int sp_reg; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + + if (cpu_CR4_mask & CR4_VME) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); + else if (CPUID) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); + SUB_SP(ir, 4); + + return op_pc; +} diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h index 085c637..6b9ac57 100644 --- a/src/codegen_ops_stack.h +++ b/src/codegen_ops_stack.h @@ -44,3 +44,6 @@ uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropPUSHFD(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 7fa5ff2..1e2fbb6 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -136,7 +136,8 @@ struct [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER}, [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER}, - + [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, 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 not be read again.*/ diff --git a/src/codegen_reg.h b/src/codegen_reg.h index aa35ab5..2e76936 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -117,8 +117,9 @@ enum IREG_NPXSx = 73, IREG_flagsx = 74, - - IREG_COUNT = 75, + IREG_eflagsx = 75, + + IREG_COUNT = 76, IREG_INVALID = 255, @@ -185,7 +186,8 @@ enum IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, - IREG_flags = IREG_flagsx + IREG_SIZE_W + IREG_flags = IREG_flagsx + IREG_SIZE_W, + IREG_eflags = IREG_eflagsx + IREG_SIZE_W }; #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))