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:
parent
cf508b050f
commit
e64271f5bb
18 changed files with 1554 additions and 542 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in a new issue