From f75a24f5399c214d672ae019c4f0cbb0873d64fa Mon Sep 17 00:00:00 2001 From: TomW Date: Sat, 8 Aug 2015 16:05:05 +0100 Subject: [PATCH] Rewrote recompiler implementation of NEG. --- src/codegen_ops_logic.h | 33 ++++++++++++++---------------- src/codegen_ops_x86-64.h | 44 ++++++++++++++++++++++++++++++++++++++-- src/codegen_ops_x86.h | 16 +++++++++++++++ 3 files changed, 73 insertions(+), 20 deletions(-) diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h index 159a5bc..bcd98db 100644 --- a/src/codegen_ops_logic.h +++ b/src/codegen_ops_logic.h @@ -355,7 +355,7 @@ static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { x86seg *target_seg; - int host_reg, imm_reg; + int host_reg; uint8_t imm; switch (fetchdat & 0x38) @@ -391,14 +391,13 @@ static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ case 0x18: /*NEG b*/ if ((fetchdat & 0xc0) != 0xc0) return 0; - imm_reg = LOAD_REG_IMM(0); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB8); host_reg = LOAD_REG_B(fetchdat & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_op1, imm_reg); - SUB_HOST_REG_B(imm_reg, host_reg); STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_op2, host_reg); - STORE_REG_TARGET_B_RELEASE(imm_reg, fetchdat & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, imm_reg); + NEG_HOST_REG_B(host_reg); + STORE_IMM_ADDR_L((uintptr_t)&flags_op1, 0); + STORE_REG_B_RELEASE(host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg); return op_pc + 1; } @@ -407,7 +406,7 @@ static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { x86seg *target_seg; - int host_reg, imm_reg; + int host_reg; uint16_t imm; switch (fetchdat & 0x38) @@ -443,14 +442,13 @@ static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 case 0x18: /*NEG w*/ if ((fetchdat & 0xc0) != 0xc0) return 0; - imm_reg = LOAD_REG_IMM(0); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB16); host_reg = LOAD_REG_W(fetchdat & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_op1, imm_reg); - SUB_HOST_REG_W(imm_reg, host_reg); STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_op2, host_reg); - STORE_REG_TARGET_W_RELEASE(imm_reg, fetchdat & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, imm_reg); + NEG_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t)&flags_op1, 0); + STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg); return op_pc + 1; } @@ -459,7 +457,7 @@ static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { x86seg *target_seg; - int host_reg, imm_reg; + int host_reg; uint32_t imm; switch (fetchdat & 0x38) @@ -495,14 +493,13 @@ static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 case 0x18: /*NEG l*/ if ((fetchdat & 0xc0) != 0xc0) return 0; - imm_reg = LOAD_REG_IMM(0); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB32); host_reg = LOAD_REG_L(fetchdat & 7); - STORE_HOST_REG_ADDR((uintptr_t)&flags_op1, imm_reg); - SUB_HOST_REG_L(imm_reg, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_op2, host_reg); - STORE_REG_TARGET_L_RELEASE(imm_reg, fetchdat & 7); - STORE_HOST_REG_ADDR((uintptr_t)&flags_res, imm_reg); + NEG_HOST_REG_L(host_reg); + STORE_IMM_ADDR_L((uintptr_t)&flags_op1, 0); + STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg); return op_pc + 1; } diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 3b0ab9b..1efb279 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -217,7 +217,7 @@ static int LOAD_REG_L(int reg) int host_reg = reg; // host_reg_mapping[host_reg] = reg; - if (!codegen_reg_loaded[reg & 7])// || CS != 0x1ac7 || pc < 0x1340 || pc >= 0x1354) + if (!codegen_reg_loaded[reg & 7]) { addbyte(0x44); /*MOVZX W[reg],host_reg*/ addbyte(0x8b); @@ -234,7 +234,7 @@ static int LOAD_REG_IMM(uint32_t imm) { int host_reg = REG_EBX; - addbyte(0xbb); /*MOVL EBX, imm*/ + addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ addlong(imm); return host_reg; @@ -3239,6 +3239,46 @@ static void SAR_L_IMM(int reg, int count) addbyte(count); } +static void NEG_HOST_REG_B(int reg) +{ + if (reg & 0x10) + { + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV BX, reg*/ + addbyte(0xc3 | ((reg & 7) << 3)); + addbyte(0xf6); /*NEG BH*/ + addbyte(0xdf); + if (reg & 8) + addbyte(0x41); + addbyte(0x89); /*MOV reg, BX*/ + addbyte(0xd8 | (reg & 7)); + } + else + { + if (reg & 8) + addbyte(0x41); + addbyte(0xf6); + addbyte(0xd8 | (reg & 7)); + } +} +static void NEG_HOST_REG_W(int reg) +{ + addbyte(0x66); + if (reg & 8) + addbyte(0x41); + addbyte(0xf7); + addbyte(0xd8 | (reg & 7)); +} +static void NEG_HOST_REG_L(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xf7); + addbyte(0xd8 | (reg & 7)); +} + + static void FP_ENTER() { if (codegen_fpu_entered) diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index f1fc95f..3a69e20 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -342,6 +342,22 @@ static void OR_HOST_REG_IMM(int host_reg, uint32_t imm) } } +static void NEG_HOST_REG_B(int reg) +{ + addbyte(0xf6); + addbyte(0xd8 | reg); +} +static void NEG_HOST_REG_W(int reg) +{ + addbyte(0x66); + addbyte(0xf7); + addbyte(0xd8 | reg); +} +static void NEG_HOST_REG_L(int reg) +{ + addbyte(0xf7); + addbyte(0xd8 | reg); +} static void SUB_HOST_REG_B(int dst_reg, int src_reg) {