Rewrote recompiler implementation of NEG.

This commit is contained in:
TomW 2015-08-08 16:05:05 +01:00
commit f75a24f539
3 changed files with 73 additions and 20 deletions

View file

@ -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) static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{ {
x86seg *target_seg; x86seg *target_seg;
int host_reg, imm_reg; int host_reg;
uint8_t imm; uint8_t imm;
switch (fetchdat & 0x38) 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*/ case 0x18: /*NEG b*/
if ((fetchdat & 0xc0) != 0xc0) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
imm_reg = LOAD_REG_IMM(0);
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB8); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB8);
host_reg = LOAD_REG_B(fetchdat & 7); 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_HOST_REG_ADDR_BL((uintptr_t)&flags_op2, host_reg);
STORE_REG_TARGET_B_RELEASE(imm_reg, fetchdat & 7); NEG_HOST_REG_B(host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, imm_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; 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) 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; x86seg *target_seg;
int host_reg, imm_reg; int host_reg;
uint16_t imm; uint16_t imm;
switch (fetchdat & 0x38) 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*/ case 0x18: /*NEG w*/
if ((fetchdat & 0xc0) != 0xc0) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
imm_reg = LOAD_REG_IMM(0);
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB16); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB16);
host_reg = LOAD_REG_W(fetchdat & 7); 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_HOST_REG_ADDR_WL((uintptr_t)&flags_op2, host_reg);
STORE_REG_TARGET_W_RELEASE(imm_reg, fetchdat & 7); NEG_HOST_REG_W(host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, imm_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; 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) 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; x86seg *target_seg;
int host_reg, imm_reg; int host_reg;
uint32_t imm; uint32_t imm;
switch (fetchdat & 0x38) 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*/ case 0x18: /*NEG l*/
if ((fetchdat & 0xc0) != 0xc0) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
imm_reg = LOAD_REG_IMM(0);
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB32); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB32);
host_reg = LOAD_REG_L(fetchdat & 7); 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_HOST_REG_ADDR((uintptr_t)&flags_op2, host_reg);
STORE_REG_TARGET_L_RELEASE(imm_reg, fetchdat & 7); NEG_HOST_REG_L(host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, imm_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; return op_pc + 1;
} }

View file

@ -217,7 +217,7 @@ static int LOAD_REG_L(int reg)
int host_reg = reg; int host_reg = reg;
// host_reg_mapping[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(0x44); /*MOVZX W[reg],host_reg*/
addbyte(0x8b); addbyte(0x8b);
@ -234,7 +234,7 @@ static int LOAD_REG_IMM(uint32_t imm)
{ {
int host_reg = REG_EBX; int host_reg = REG_EBX;
addbyte(0xbb); /*MOVL EBX, imm*/ addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/
addlong(imm); addlong(imm);
return host_reg; return host_reg;
@ -3239,6 +3239,46 @@ static void SAR_L_IMM(int reg, int count)
addbyte(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() static void FP_ENTER()
{ {
if (codegen_fpu_entered) if (codegen_fpu_entered)

View file

@ -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) static void SUB_HOST_REG_B(int dst_reg, int src_reg)
{ {