Added recompiled versions of mem->reg, reg->mem and imm->mem versions of ADD, AND, CMP, OR, SUB and XOR.

This commit is contained in:
SarahW 2018-07-27 22:24:34 +01:00
commit e64271f5bb
18 changed files with 1554 additions and 542 deletions

View file

@ -221,7 +221,7 @@ void codegen_backend_prologue(codeblock_t *block)
host_arm_nop(block);
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10);
host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x20);
host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC);
while (block_pos != BLOCK_START)
host_arm_nop(block);
@ -229,7 +229,7 @@ void codegen_backend_prologue(codeblock_t *block)
/*Entry code*/
host_arm_STMDB_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_LR);
host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x10);
host_arm_SUB_IMM(block, REG_SP, REG_SP, 0x20);
host_arm_ADD_IMM(block, REG_LITERAL, REG_PC, ARM_LITERAL_POOL_OFFSET);
host_arm_SUB_IMM(block, REG_LITERAL, REG_LITERAL, 16 + BLOCK_START);
offset = add_literal(block, (uintptr_t)&cpu_state);
@ -238,7 +238,7 @@ void codegen_backend_prologue(codeblock_t *block)
void codegen_backend_epilogue(codeblock_t *block)
{
host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x10);
host_arm_ADD_IMM(block, REG_SP, REG_SP, 0x20);
host_arm_LDMIA_WB(block, REG_SP, REG_MASK_LOCAL | REG_MASK_PC);
if (block_pos > ARM_LITERAL_POOL_OFFSET)

View file

@ -237,7 +237,7 @@ void codegen_backend_prologue(codeblock_t *block)
host_arm64_NOP(block);
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 48);
host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16);
@ -255,7 +255,7 @@ void codegen_backend_prologue(codeblock_t *block)
host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -16);
host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_SP, -48);
offset = add_literal_q(block, (uintptr_t)&cpu_state);
host_arm64_LDR_LITERAL_X(block, REG_CPUSTATE, offset);
@ -263,7 +263,7 @@ void codegen_backend_prologue(codeblock_t *block)
void codegen_backend_epilogue(codeblock_t *block)
{
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_SP, 48);
host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_SP, 16);
host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_SP, 16);

View file

@ -34,6 +34,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_SHIFT 24
#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT)
#define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT)
#define OPCODE_BCOND (0x54 << OPCODE_SHIFT)
#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT)
#define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT)
@ -43,6 +44,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_LDR_LITERAL_W (0x18 << OPCODE_SHIFT)
#define OPCODE_LDR_LITERAL_X (0x58 << OPCODE_SHIFT)
#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT)
#define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT)
#define OPCODE_AND_IMM (0x024 << 23)
#define OPCODE_ANDS_IMM (0x0e4 << 23)
@ -63,6 +65,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_ADD_LSL (0x058 << 21)
#define OPCODE_ADD_LSR (0x05a << 21)
#define OPCODE_ADDX_LSL (0x458 << 21)
#define OPCODE_AND_ASR (0x054 << 21)
#define OPCODE_AND_LSL (0x050 << 21)
#define OPCODE_AND_ROR (0x056 << 21)
@ -70,8 +73,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_EOR_LSL (0x250 << 21)
#define OPCODE_ORR_LSL (0x150 << 21)
#define OPCODE_ORR_LSR (0x152 << 21)
#define OPCODE_ORRX_LSL (0x550 << 21)
#define OPCODE_SUB_LSL (0x258 << 21)
#define OPCODE_SUB_LSR (0x25a << 21)
#define OPCODE_SUBX_LSL (0x658 << 21)
#define OPCODE_BLR (0xd63f0000)
#define OPCODE_LDR_REG (0xb8606800)
@ -444,6 +449,12 @@ void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int
codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
}
void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift)
{
if (dst_reg != src_m_reg)
codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
}
void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data)
{
int hw;

View file

@ -48,6 +48,8 @@ void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, in
void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift);
void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift);
void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift);
void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data);
void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data);

View file

@ -65,17 +65,17 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
{
host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg)
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data);
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg)
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data);
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
}
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg)
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
{
host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8);
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
@ -809,4 +809,20 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
fatal("codegen_direct_write_ptr - not in range\n");
}
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
{
if (in_range12_w(stack_offset))
host_arm64_LDR_IMM_W(block, host_reg, REG_SP, stack_offset);
else
fatal("codegen_direct_read_32_stack - not in range\n");
}
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg)
{
if (in_range12_w(stack_offset))
host_arm64_STR_IMM_W(block, host_reg, REG_SP, stack_offset);
else
fatal("codegen_direct_write_32_stack - not in range\n");
}
#endif

View file

@ -75,15 +75,15 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop)
{
host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a)
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_arm_UXTH(block, REG_TEMP, src_reg_b, 0);
host_arm_UADD16(block, dest_reg, src_reg_a, REG_TEMP);
host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b);
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP);
host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b);
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
{
@ -118,15 +118,15 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
{
host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && src_reg == dest_reg)
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data);
host_arm_UADD16(block, dest_reg, src_reg, REG_TEMP);
host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data);
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && src_reg == dest_reg)
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data);
host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP);
host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data);
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
}
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg)
{
@ -905,4 +905,20 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
fatal("codegen_direct_write_ptr - not in range\n");
}
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
{
if (stack_offset >= 0 && stack_offset < 4096)
host_arm_LDR_IMM(block, host_reg, REG_SP, stack_offset);
else
fatal("codegen_direct_read_32 - not in range\n");
}
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg)
{
if (stack_offset >= 0 && stack_offset < 4096)
host_arm_STR_IMM(block, host_reg, REG_SP, stack_offset);
else
fatal("codegen_direct_write_32 - not in range\n");
}
#endif

View file

@ -174,21 +174,21 @@ void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data)
void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8))
fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
}
void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8))
fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
}
void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8))
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
}
@ -501,6 +501,42 @@ void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int ba
codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/
}
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
{
if ((dst_reg & 8) || (base_reg & 8))
fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n");
if (offset >= -128 && offset < 127)
{
if (base_reg == REG_RSP)
{
codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset);
}
else
codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset);
}
else
fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset);
}
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg)
{
if ((src_reg & 8) || (base_reg & 8))
fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n");
if (offset >= -128 && offset < 127)
{
if (base_reg == REG_RSP)
{
codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset);
}
else
codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset);
}
else
fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset);
}
void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data)
{
if (reg >= 8)

View file

@ -62,11 +62,15 @@ void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_d
void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg);
void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data);
void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data);

View file

@ -26,15 +26,22 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop)
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
if (dest_reg != src_reg_a)
host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
else
host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
if (dest_reg != src_reg_a)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a);
host_x86_ADD16_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
if (dest_reg != src_reg_a)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a);
host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
@ -49,15 +56,22 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
if (dest_reg != src_reg)
host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
else
host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
if (dest_reg != src_reg)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ADD16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
if (dest_reg != src_reg)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else
fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
@ -638,4 +652,14 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
host_x86_MOV64_ABS_REG(block, p, host_reg);
}
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
{
host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset);
}
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg)
{
host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg);
}
#endif

View file

@ -253,18 +253,18 @@ void codegen_backend_prologue(codeblock_t *block)
addbyte(0x55); /*PUSH EBP*/
addbyte(0x56); /*PUSH ESI*/
addbyte(0x57); /*PUSH EDI*/
addbyte(0x83); /*SUBL $16,%esp*/
addbyte(0x83); /*SUBL $32,%esp*/
addbyte(0xEC);
addbyte(0x10);
addbyte(0x20);
addbyte(0xBD); /*MOVL EBP, &cpu_state*/
addlong(((uintptr_t)&cpu_state) + 128);
}
void codegen_backend_epilogue(codeblock_t *block)
{
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0x83); /*ADDL $32,%esp*/
addbyte(0xC4);
addbyte(0x10);
addbyte(0x20);
addbyte(0x5f); /*POP EDI*/
addbyte(0x5e); /*POP ESI*/
addbyte(0x5d); /*POP EBP*/
@ -287,9 +287,9 @@ void codegen_backend_epilogue(codeblock_t *block)
addbyte(0xe8); /*CALL x86gpf*/
addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0x83); /*ADDL $32,%esp*/
addbyte(0xC4);
addbyte(0x10);
addbyte(0x20);
addbyte(0x5f); /*POP EDI*/
addbyte(0x5e); /*POP ESI*/
addbyte(0x5d); /*POP EBP*/

View file

@ -164,21 +164,21 @@ void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32
void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_ADD8_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
}
void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_ADD16_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
}
void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
{
if (dst_reg != src_reg_a)
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n");
fatal("host_x86_ADD32_REG_REG - dst_reg != src_reg_a\n");
codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
}
@ -420,6 +420,36 @@ void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg
codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/
}
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
{
if (offset >= -128 && offset < 127)
{
if (base_reg == REG_ESP)
{
codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset);
}
else
codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset);
}
else
fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset);
}
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg)
{
if (offset >= -128 && offset < 127)
{
if (base_reg == REG_ESP)
{
codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset);
}
else
codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset);
}
else
fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset);
}
void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data)
{
codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/

View file

@ -40,12 +40,16 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg,
void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg);
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift);
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data);
void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data);
void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data);

View file

@ -36,15 +36,22 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop)
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
{
host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
else
host_x86_ADD32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
{
host_x86_ADD16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a);
host_x86_ADD16_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
{
host_x86_ADD8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a);
host_x86_ADD8_REG_REG(block, dest_reg, dest_reg, src_reg_b);
}
else
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
@ -59,15 +66,22 @@ static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
{
host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
else
host_x86_ADD32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
}
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
{
host_x86_ADD16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
host_x86_ADD16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
{
host_x86_ADD8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
if (uop->dest_reg_a_real != uop->src_reg_a_real)
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
host_x86_ADD8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
}
else
fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
@ -636,4 +650,14 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
host_x86_MOV32_ABS_REG(block, p, host_reg);
}
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
{
host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset);
}
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg)
{
host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg);
}
#endif

View file

@ -304,4 +304,8 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg);
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset);
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg);
#endif

File diff suppressed because it is too large Load diff

View file

@ -43,12 +43,25 @@ uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
}
uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B);
}
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
@ -57,26 +70,55 @@ uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
}
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W);
}
uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
@ -85,26 +127,55 @@ uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
}
uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
}
uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
@ -113,14 +184,30 @@ uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
}
uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
@ -161,12 +248,25 @@ uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32
}
uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B);
}
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
@ -175,26 +275,55 @@ uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
}
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W);
}
uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
@ -203,42 +332,87 @@ uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
}
uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
}
uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
uop_MOV(ir, IREG_flags_res, dest_reg);
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
}
uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
@ -279,12 +453,25 @@ uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
}
uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B);
}
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
@ -293,26 +480,55 @@ uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B);
}
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W);
}
uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
@ -321,42 +537,87 @@ uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
}
uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
}
uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7;
int dest_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
}
uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
uop_MOV(ir, IREG_flags_res, dest_reg);
codegen_flags_changed = 1;
return op_pc + 1;
}
uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7;
int src_reg = (fetchdat >> 3) & 7;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
uop_MOV(ir, IREG_flags_res, IREG_temp0);
}
uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg));
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32);
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
codegen_flags_changed = 1;
return op_pc + 1;

View file

@ -67,10 +67,10 @@ struct
/*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.*/
[IREG_temp0] = {REG_DWORD, NULL},
[IREG_temp1] = {REG_DWORD, NULL},
[IREG_temp2] = {REG_DWORD, NULL},
[IREG_temp3] = {REG_DWORD, NULL},
[IREG_temp0] = {REG_DWORD, (void *)16},
[IREG_temp1] = {REG_DWORD, (void *)20},
[IREG_temp2] = {REG_DWORD, (void *)24},
[IREG_temp3] = {REG_DWORD, (void *)28},
};
void codegen_reg_reset()
@ -99,7 +99,10 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg)
switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size)
{
case REG_DWORD:
codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_32_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break;
default:
@ -113,19 +116,27 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg)
static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate)
{
int ir_reg = IREG_GET_REG(host_regs[c].reg);
void *p = ireg_data[ir_reg].p;
switch (ireg_data[ir_reg].native_size)
{
case REG_BYTE:
codegen_direct_write_8(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]);
if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_BYTE %p\n", p);
codegen_direct_write_8(block, p, codegen_host_reg_list[c]);
break;
case REG_DWORD:
codegen_direct_write_32(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]);
if ((uintptr_t)p < 256)
codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]);
else
codegen_direct_write_32(block, p, codegen_host_reg_list[c]);
break;
case REG_POINTER:
codegen_direct_write_ptr(block, ireg_data[ir_reg].p, codegen_host_reg_list[c]);
if ((uintptr_t)p < 256)
fatal("codegen_reg_writeback - REG_POINTER %p\n", p);
codegen_direct_write_ptr(block, p, codegen_host_reg_list[c]);
break;
default:

View file

@ -82,7 +82,13 @@ enum
IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W,
IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B
IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B,
IREG_temp0_W = IREG_temp0 + IREG_SIZE_W,
IREG_temp1_W = IREG_temp1 + IREG_SIZE_W,
IREG_temp0_B = IREG_temp0 + IREG_SIZE_B,
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B
};
#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))