Added recompiled versions of 8 and 16 bit immediate->reg and reg->reg versions of MOV, ADD, SUB, CMP, AND, OR and XOR.
This commit is contained in:
parent
e4e0f76d5c
commit
648aa0e3e8
17 changed files with 3006 additions and 231 deletions
|
|
@ -58,7 +58,7 @@ static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uin
|
|||
{
|
||||
int base_reg, index_reg, offset;
|
||||
|
||||
switch (cpu_rm)
|
||||
switch (cpu_rm & 7)
|
||||
{
|
||||
case 0: case 1: case 7:
|
||||
base_reg = IREG_EBX;
|
||||
|
|
|
|||
|
|
@ -73,4 +73,6 @@
|
|||
|
||||
#define REG_CPUSTATE REG_X29
|
||||
|
||||
#define REG_TEMP REG_X7
|
||||
|
||||
#define CODEGEN_HOST_REGS 5
|
||||
|
|
@ -45,18 +45,25 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_MOVZ_W (0x0a5 << 23)
|
||||
#define OPCODE_ORR_IMM (0x064 << 23)
|
||||
|
||||
#define OPCODE_BFI (0x0cc << 22)
|
||||
#define OPCODE_LDR_IMM_W (0x2e5 << 22)
|
||||
#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22)
|
||||
#define OPCODE_STP_PREIDX_X (0x2a6 << 22)
|
||||
#define OPCODE_STR_IMM_W (0x2e4 << 22)
|
||||
#define OPCODE_STR_IMM_Q (0x3e4 << 22)
|
||||
#define OPCODE_STRB_IMM (0x0e4 << 22)
|
||||
#define OPCODE_UBFX (0x14c << 22)
|
||||
|
||||
#define OPCODE_ADD_LSL (0x058 << 21)
|
||||
#define OPCODE_ADD_LSR (0x05a << 21)
|
||||
#define OPCODE_AND_ASR (0x054 << 21)
|
||||
#define OPCODE_AND_LSL (0x050 << 21)
|
||||
#define OPCODE_AND_ROR (0x056 << 21)
|
||||
#define OPCODE_EOR_LSL (0x250 << 21)
|
||||
#define OPCODE_ORR_LSL (0x150 << 21)
|
||||
#define OPCODE_ORR_LSR (0x152 << 21)
|
||||
#define OPCODE_SUB_LSL (0x258 << 21)
|
||||
#define OPCODE_SUB_LSR (0x25a << 21)
|
||||
|
||||
#define OPCODE_BLR (0xd63f0000)
|
||||
#define OPCODE_NOP (0xd503201f)
|
||||
|
|
@ -174,13 +181,33 @@ void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_
|
|||
{
|
||||
codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
//12001c00 S=0 R=7
|
||||
void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data)
|
||||
{
|
||||
if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */
|
||||
if (imm_data == 0xff) /*Quick hack until proper immediate generation is written */
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x07));
|
||||
}
|
||||
else if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f));
|
||||
}
|
||||
else if (imm_data == 0xffffff00)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17));
|
||||
}
|
||||
else if (imm_data == 0xffff00ff)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17));
|
||||
}
|
||||
else if (imm_data == 0x0000ff00)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x07));
|
||||
}
|
||||
else
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_W16, imm_data);
|
||||
|
|
@ -191,6 +218,19 @@ void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_
|
|||
{
|
||||
codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31));
|
||||
}
|
||||
|
||||
void host_arm64_BLR(codeblock_t *block, int addr_reg)
|
||||
{
|
||||
|
|
@ -261,6 +301,11 @@ void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shif
|
|||
codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data)
|
||||
{
|
||||
int hw;
|
||||
|
|
@ -300,6 +345,18 @@ void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t
|
|||
{
|
||||
codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f));
|
||||
}
|
||||
else if (imm_data == 0xffff0000)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x0f));
|
||||
}
|
||||
else if (imm_data == 0xffffff00)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(24) | IMMS(0x17));
|
||||
}
|
||||
else if (imm_data == 0xffff00ff)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(16) | IMMS(0x17));
|
||||
}
|
||||
else
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_W16, imm_data);
|
||||
|
|
@ -372,6 +429,15 @@ void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_
|
|||
{
|
||||
codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31));
|
||||
}
|
||||
|
||||
void host_arm64_call(codeblock_t *block, void *dst_addr)
|
||||
{
|
||||
|
|
@ -391,16 +457,83 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data)
|
|||
}
|
||||
}
|
||||
|
||||
#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f)
|
||||
|
||||
#define REG_IS_L(size) (size == IREG_SIZE_L)
|
||||
#define REG_IS_W(size) (size == IREG_SIZE_W)
|
||||
#define REG_IS_B(size) (size == IREG_SIZE_B)
|
||||
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
|
||||
|
||||
static int codegen_ADD(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm64_ADD_REG(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))
|
||||
{
|
||||
host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm64_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))
|
||||
{
|
||||
host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm64_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))
|
||||
{
|
||||
host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00);
|
||||
host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -412,12 +545,67 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_AND(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_AND_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm64_AND_REG(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)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000);
|
||||
host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00);
|
||||
host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff);
|
||||
host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00);
|
||||
host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff);
|
||||
host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else
|
||||
fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_AND_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff);
|
||||
}
|
||||
else
|
||||
fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -456,13 +644,65 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_MOV_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(block, dest_reg, src_reg, 0);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_BFI(block, dest_reg, src_reg, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_BFI(block, dest_reg, src_reg, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_BFI(block, dest_reg, src_reg, 8, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_mov_imm(block, uop->dest_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size))
|
||||
{
|
||||
host_arm64_mov_imm(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size))
|
||||
{
|
||||
host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size))
|
||||
{
|
||||
host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("MOV_IMM %x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -474,14 +714,92 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_UBFX(block, dest_reg, src_reg, 8, 8);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff);
|
||||
}
|
||||
else
|
||||
fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_ORR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm64_ORR_REG(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)
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff);
|
||||
host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff);
|
||||
host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8);
|
||||
host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff);
|
||||
host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8);
|
||||
host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else
|
||||
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm64_ORR_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)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8);
|
||||
}
|
||||
else
|
||||
fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -510,23 +828,157 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_SUB(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_SUB_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm64_SUB_REG(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))
|
||||
{
|
||||
host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm64_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))
|
||||
{
|
||||
host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm64_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))
|
||||
{
|
||||
host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8);
|
||||
host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8);
|
||||
host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_SUB_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))
|
||||
{
|
||||
host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_XOR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_EOR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm64_EOR_REG(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)
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff);
|
||||
host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff);
|
||||
host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8);
|
||||
host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff);
|
||||
host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8);
|
||||
host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else
|
||||
fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm64_EOR_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)
|
||||
{
|
||||
host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8);
|
||||
}
|
||||
else
|
||||
fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -545,7 +997,8 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
[UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT,
|
||||
|
|
|
|||
|
|
@ -41,9 +41,12 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT)
|
||||
#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT)
|
||||
#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT)
|
||||
#define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT)
|
||||
#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT)
|
||||
#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT)
|
||||
#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT)
|
||||
#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT)
|
||||
#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT)
|
||||
#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT)
|
||||
#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT)
|
||||
#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT)
|
||||
|
|
@ -51,7 +54,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT)
|
||||
#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT)
|
||||
|
||||
#define OPCODE_BLX 0xe12fff30
|
||||
#define OPCODE_BFI 0xe7c00010
|
||||
#define OPCODE_BLX 0xe12fff30
|
||||
#define OPCODE_UADD8 0xe6500f90
|
||||
#define OPCODE_UADD16 0xe6500f10
|
||||
#define OPCODE_USUB8 0xe6500ff0
|
||||
#define OPCODE_USUB16 0xe6500f70
|
||||
#define OPCODE_UXTB 0xe6ef0070
|
||||
#define OPCODE_UXTH 0xe6ff0070
|
||||
|
||||
#define B_OFFSET(x) (((x) >> 2) & 0xffffff)
|
||||
|
||||
|
|
@ -66,6 +76,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
|
||||
#define SHIFT_IMM_SHIFT 7
|
||||
#define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT))
|
||||
#define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT))
|
||||
|
||||
#define BFI_lsb(lsb) ((lsb) << 7)
|
||||
#define BFI_msb(msb) ((msb) << 16)
|
||||
|
||||
#define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10)
|
||||
|
||||
#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4))
|
||||
|
||||
static int literal_offset = 0;
|
||||
void codegen_reset_literal_pool(codeblock_t *block)
|
||||
|
|
@ -201,6 +219,20 @@ void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr
|
|||
codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1));
|
||||
}
|
||||
|
||||
void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_BLX(codeblock_t *block, int addr_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_BLX | Rm(addr_reg));
|
||||
|
|
@ -266,6 +298,20 @@ void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif
|
|||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm));
|
||||
}
|
||||
|
||||
void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm)
|
||||
{
|
||||
|
|
@ -288,6 +334,11 @@ void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr
|
|||
codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask);
|
||||
|
|
@ -327,12 +378,45 @@ void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr
|
|||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2));
|
||||
}
|
||||
|
||||
void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b));
|
||||
}
|
||||
|
||||
void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b));
|
||||
}
|
||||
|
||||
void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b));
|
||||
}
|
||||
|
||||
void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b));
|
||||
}
|
||||
|
||||
void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate));
|
||||
}
|
||||
|
||||
void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate));
|
||||
}
|
||||
|
||||
void host_arm_call(codeblock_t *block, void *dst_addr)
|
||||
{
|
||||
|
|
@ -346,15 +430,85 @@ void host_arm_nop(codeblock_t *block)
|
|||
host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0);
|
||||
}
|
||||
|
||||
#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf)
|
||||
|
||||
#define REG_IS_L(size) (size == IREG_SIZE_L)
|
||||
#define REG_IS_W(size) (size == IREG_SIZE_W)
|
||||
#define REG_IS_B(size) (size == IREG_SIZE_B)
|
||||
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
|
||||
|
||||
static int codegen_ADD(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
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)
|
||||
{
|
||||
host_arm_UXTH(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_UADD16(block, dest_reg, src_reg_a, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00);
|
||||
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
// host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
// return 0;
|
||||
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
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)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data);
|
||||
host_arm_UADD16(block, dest_reg, src_reg, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && src_reg == dest_reg)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data);
|
||||
host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8);
|
||||
host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
|
|
@ -364,12 +518,69 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_AND(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_AND_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm_AND_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)
|
||||
{
|
||||
host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16);
|
||||
host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 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)
|
||||
{
|
||||
host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24);
|
||||
host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16);
|
||||
host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00);
|
||||
host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00);
|
||||
host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else
|
||||
fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_AND_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm_AND_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)
|
||||
{
|
||||
host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff);
|
||||
}
|
||||
else
|
||||
fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -437,22 +648,75 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_BFI(block, dest_reg, src_reg, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_BFI(block, dest_reg, src_reg, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_BFI(block, dest_reg, src_reg, 8, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
uint32_t arm_imm;
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (get_arm_imm(uop->imm_data, &arm_imm))
|
||||
host_arm_MOV_IMM(block, uop->dest_reg_a_real, uop->imm_data);
|
||||
else
|
||||
if (REG_IS_L(dest_size))
|
||||
{
|
||||
int offset = add_literal(block, uop->imm_data);
|
||||
host_arm_LDR_IMM(block, uop->dest_reg_a_real, REG_LITERAL, offset);
|
||||
uint32_t arm_imm;
|
||||
|
||||
if (get_arm_imm(uop->imm_data, &arm_imm))
|
||||
host_arm_MOV_IMM(block, dest_reg, uop->imm_data);
|
||||
else
|
||||
{
|
||||
int offset = add_literal(block, uop->imm_data);
|
||||
host_arm_LDR_IMM(block, dest_reg, REG_LITERAL, offset);
|
||||
}
|
||||
}
|
||||
else if (REG_IS_W(dest_size))
|
||||
{
|
||||
host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff);
|
||||
host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size))
|
||||
{
|
||||
host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00);
|
||||
host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8);
|
||||
}
|
||||
else
|
||||
fatal("MOV_IMM %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -464,14 +728,92 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, dest_reg, src_reg, 0);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, dest_reg, src_reg, 8);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_UXTH(block, dest_reg, src_reg, 0);
|
||||
}
|
||||
else
|
||||
fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_ORR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm_ORR_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)
|
||||
{
|
||||
host_arm_UXTH(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else
|
||||
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm_ORR_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)
|
||||
{
|
||||
host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8);
|
||||
}
|
||||
else
|
||||
fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -506,23 +848,158 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_SUB(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm_SUB_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))
|
||||
{
|
||||
host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
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))
|
||||
{
|
||||
host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
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))
|
||||
{
|
||||
host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
|
||||
// host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
// return 0;
|
||||
}
|
||||
static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_SUB_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))
|
||||
{
|
||||
host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_XOR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_EOR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_arm_EOR_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)
|
||||
{
|
||||
host_arm_UXTH(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8);
|
||||
}
|
||||
else
|
||||
fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_arm_EOR_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)
|
||||
{
|
||||
host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg)
|
||||
{
|
||||
host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8);
|
||||
}
|
||||
else
|
||||
fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -541,6 +1018,7 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
|
|
|
|||
|
|
@ -117,29 +117,66 @@ static inline void call(codeblock_t *block, uintptr_t func)
|
|||
}
|
||||
}
|
||||
|
||||
static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
static 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");
|
||||
|
||||
codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
static 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");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
static 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))
|
||||
|
|
@ -148,29 +185,66 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_
|
|||
codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_AND8_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_AND8_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_AND16_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_AND16_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_AND32_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))
|
||||
|
|
@ -316,6 +390,19 @@ static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
|||
}
|
||||
}
|
||||
|
||||
static void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data)
|
||||
{
|
||||
if (reg >= 8)
|
||||
fatal("host_x86_MOV8_REG_IMM reg >= 4\n");
|
||||
codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/
|
||||
}
|
||||
static void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data)
|
||||
{
|
||||
if (reg & 8)
|
||||
fatal("host_x86_MOV16_REG_IMM reg & 8\n");
|
||||
codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
static void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data)
|
||||
{
|
||||
if (reg & 8)
|
||||
|
|
@ -332,6 +419,20 @@ static void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_dat
|
|||
codegen_addquad(block, imm_data);
|
||||
}
|
||||
|
||||
static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
if ((dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_MOV8_REG_REG - bad reg\n");
|
||||
|
||||
codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3));
|
||||
}
|
||||
static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
if ((dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_MOV16_REG_REG - bad reg\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3));
|
||||
}
|
||||
static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
if ((dst_reg & 8) || (src_reg & 8))
|
||||
|
|
@ -360,29 +461,79 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_
|
|||
}
|
||||
}
|
||||
|
||||
static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
if ((dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_MOVZX_REG_32_8 - bad reg\n");
|
||||
codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/
|
||||
}
|
||||
static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
if ((dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_MOVZX_REG_16_8 - bad reg\n");
|
||||
codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/
|
||||
}
|
||||
|
||||
static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_OR8_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_OR8_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_OR16_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_OR16_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_OR32_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))
|
||||
|
|
@ -391,33 +542,70 @@ static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a
|
|||
codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_SUB8_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_SUB8_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_SUB16_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_SUB16_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_SUB32_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_SUB32_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
|
|
@ -431,29 +619,66 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg)
|
|||
codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/
|
||||
}
|
||||
|
||||
static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))
|
||||
fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_XOR8_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_XOR8_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_XOR16_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_XOR16_REG_IMM - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_XOR32_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))
|
||||
|
|
@ -462,16 +687,56 @@ static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_
|
|||
codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7))
|
||||
|
||||
#define REG_IS_L(size) (size == IREG_SIZE_L)
|
||||
#define REG_IS_W(size) (size == IREG_SIZE_W)
|
||||
#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH)
|
||||
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
|
||||
|
||||
static int codegen_ADD(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -489,13 +754,47 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_AND(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_AND32_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_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_AND_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -539,12 +838,46 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else
|
||||
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size))
|
||||
{
|
||||
host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size))
|
||||
{
|
||||
host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("MOV_IMM %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
||||
|
|
@ -552,15 +885,66 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg);
|
||||
}
|
||||
else
|
||||
fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_OR32_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_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -581,29 +965,103 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_SUB(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
if (dest_reg != src_reg_a)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
|
||||
{
|
||||
if (dest_reg != src_reg_a)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_SUB16_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))
|
||||
{
|
||||
if (dest_reg != src_reg_a)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (dest_reg != src_reg)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (dest_reg != src_reg)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (dest_reg != src_reg)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_XOR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_XOR32_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_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -622,7 +1080,8 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
[UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT,
|
||||
|
|
|
|||
|
|
@ -100,30 +100,67 @@ static int is_imm8(uint32_t imm_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_ADD8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_ADD16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
|
||||
static 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");
|
||||
|
||||
codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
static 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");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
static 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)
|
||||
|
|
@ -132,30 +169,67 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_
|
|||
codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_AND8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_AND16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void host_x86_AND8_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_AND8_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_AND16_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_AND16_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
if (dst_reg != src_reg_a)
|
||||
|
|
@ -260,6 +334,23 @@ static void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
|||
codegen_addlong(block, (uint32_t)p);
|
||||
}
|
||||
}
|
||||
|
||||
static 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*/
|
||||
}
|
||||
static void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data)
|
||||
{
|
||||
if (!imm_data)
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data)
|
||||
{
|
||||
if (!imm_data)
|
||||
|
|
@ -273,6 +364,14 @@ static void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm
|
|||
}
|
||||
}
|
||||
|
||||
static void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3));
|
||||
}
|
||||
static void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3));
|
||||
}
|
||||
static void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3));
|
||||
|
|
@ -298,6 +397,29 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_
|
|||
}
|
||||
}
|
||||
|
||||
static void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/
|
||||
}
|
||||
static void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/
|
||||
}
|
||||
|
||||
static void host_x86_OR8_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_OR8_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_OR16_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_OR16_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
if (dst_reg != src_reg_a)
|
||||
|
|
@ -305,60 +427,121 @@ static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a
|
|||
|
||||
codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_OR8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_OR16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
|
||||
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
|
||||
|
||||
static void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_SUB8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_SUB16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void host_x86_SUB8_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_SUB8_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_SUB16_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_SUB16_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_SUB32_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_SUB32_REG_IMM - dst_reg != src_reg_a\n");
|
||||
fatal("host_x86_SUB32_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/
|
||||
}
|
||||
|
|
@ -368,6 +551,20 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_ho
|
|||
codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/
|
||||
}
|
||||
|
||||
static void host_x86_XOR8_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_XOR8_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_XOR16_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_XOR16_REG_REG - dst_reg != src_reg_a\n");
|
||||
|
||||
codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
if (dst_reg != src_reg_a)
|
||||
|
|
@ -376,27 +573,50 @@ static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_
|
|||
codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/
|
||||
}
|
||||
|
||||
static void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_XOR8_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (dst_reg == REG_EAX)
|
||||
codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/
|
||||
else
|
||||
codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/
|
||||
}
|
||||
static void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_XOR16_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/
|
||||
codegen_addword(block, imm_data);
|
||||
}
|
||||
}
|
||||
static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data)
|
||||
{
|
||||
if (dst_reg != src_reg)
|
||||
fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n");
|
||||
|
||||
if (is_imm8(imm_data))
|
||||
{
|
||||
codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/
|
||||
else if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dst_reg == REG_EAX)
|
||||
{
|
||||
codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/
|
||||
codegen_addlong(block, imm_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -406,15 +626,61 @@ static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg,
|
|||
pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX);
|
||||
}*/
|
||||
|
||||
#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L)
|
||||
#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W)
|
||||
#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4)
|
||||
#define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4)
|
||||
|
||||
#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7))
|
||||
|
||||
#define REG_IS_L(size) (size == IREG_SIZE_L)
|
||||
#define REG_IS_W(size) (size == IREG_SIZE_W)
|
||||
#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH)
|
||||
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
|
||||
|
||||
static int codegen_ADD(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_ADD32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -432,13 +698,47 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_AND(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_AND32_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_AND16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_x86_AND8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_AND_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_AND32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_AND16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_AND8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -475,12 +775,46 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
}
|
||||
else
|
||||
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size))
|
||||
{
|
||||
host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size))
|
||||
{
|
||||
host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("MOV_IMM %02x\n", uop->dest_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
||||
|
|
@ -488,15 +822,66 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg);
|
||||
}
|
||||
else if (REG_IS_L(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg);
|
||||
}
|
||||
else
|
||||
fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_OR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_OR32_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_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_x86_OR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_OR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_OR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_OR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -513,29 +898,103 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_SUB(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_SUB32_REG_REG(block, dest_reg, dest_reg, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_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_SUB16_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))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_SUB8_REG_REG(block, dest_reg, dest_reg, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (dest_reg != src_reg)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SUB32_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (dest_reg != src_reg)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SUB16_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (dest_reg != src_reg)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SUB8_REG_IMM(block, dest_reg, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_XOR(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_XOR32_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_XOR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b))
|
||||
{
|
||||
host_x86_XOR8_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
}
|
||||
else
|
||||
fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data);
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
host_x86_XOR32_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_XOR16_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_XOR8_REG_IMM(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -554,6 +1013,7 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_MOV & UOP_MASK] = codegen_MOV,
|
||||
[UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR,
|
||||
[UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM,
|
||||
[UOP_MOVZX & UOP_MASK] = codegen_MOVZX,
|
||||
|
||||
[UOP_ADD & UOP_MASK] = codegen_ADD,
|
||||
[UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM,
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block)
|
|||
codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b);
|
||||
if (uop->src_reg_a.reg != IREG_INVALID)
|
||||
{
|
||||
uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a);
|
||||
uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL);
|
||||
}
|
||||
if (uop->src_reg_b.reg != IREG_INVALID)
|
||||
{
|
||||
uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b);
|
||||
uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL);
|
||||
}
|
||||
if (uop->dest_reg_a.reg != IREG_INVALID)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,22 +27,40 @@
|
|||
#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a)
|
||||
#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b)
|
||||
#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER)
|
||||
/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/
|
||||
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER)
|
||||
#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12)
|
||||
#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13)
|
||||
/*UOP_MOV_PTR - dest_reg = p*/
|
||||
#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20)
|
||||
/*UOP_MOV_IMM - dest_reg = imm_data*/
|
||||
#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21)
|
||||
/*UOP_MOV - dest_reg = src_reg_a*/
|
||||
#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22)
|
||||
/*UOP_MOVZX - dest_reg = zero_extend(src_reg_a)*/
|
||||
#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23)
|
||||
/*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/
|
||||
#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30)
|
||||
/*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/
|
||||
#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31)
|
||||
/*UOP_AND - dest_reg = src_reg_a & src_reg_b*/
|
||||
#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32)
|
||||
/*UOP_AND_IMM - dest_reg = src_reg_a & immediate*/
|
||||
#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33)
|
||||
/*UOP_ADD_LSHIFT - dest_reg = src_reg_a + (src_reg_b << imm_data)
|
||||
Intended for EA calcluations, imm_data must be between 0 and 3*/
|
||||
#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34)
|
||||
/*UOP_OR - dest_reg = src_reg_a | src_reg_b*/
|
||||
#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35)
|
||||
/*UOP_OR_IMM - dest_reg = src_reg_a | immediate*/
|
||||
#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36)
|
||||
/*UOP_SUB - dest_reg = src_reg_a - src_reg_b*/
|
||||
#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37)
|
||||
/*UOP_SUB_IMM - dest_reg = src_reg_a - immediate*/
|
||||
#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38)
|
||||
/*UOP_XOR - dest_reg = src_reg_a ^ src_reg_b*/
|
||||
#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39)
|
||||
/*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/
|
||||
#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a)
|
||||
|
||||
#define UOP_MAX 0x3b
|
||||
|
|
@ -81,7 +99,6 @@ static inline uop_t *uop_alloc(ir_data_t *ir)
|
|||
uop->dest_reg_a = invalid_ir_reg;
|
||||
uop->src_reg_a = invalid_ir_reg;
|
||||
uop->src_reg_b = invalid_ir_reg;
|
||||
// uop->src_reg_c = invalid_ir_reg;
|
||||
|
||||
return uop;
|
||||
}
|
||||
|
|
@ -121,6 +138,16 @@ static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int de
|
|||
uop->dest_reg_a = codegen_reg_write(dest_reg);
|
||||
}
|
||||
|
||||
static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm)
|
||||
{
|
||||
uop_t *uop = uop_alloc(ir);
|
||||
|
||||
uop->type = uop_type;
|
||||
uop->src_reg_a = codegen_reg_read(src_reg_a);
|
||||
uop->dest_reg_a = codegen_reg_write(dest_reg);
|
||||
uop->imm_data = imm;
|
||||
}
|
||||
|
||||
static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b)
|
||||
{
|
||||
uop_t *uop = uop_alloc(ir);
|
||||
|
|
@ -196,9 +223,10 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p
|
|||
#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p)
|
||||
#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p)
|
||||
|
||||
#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg)
|
||||
#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm)
|
||||
#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p)
|
||||
#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg)
|
||||
#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm)
|
||||
#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p)
|
||||
#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg)
|
||||
|
||||
#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm)
|
||||
#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm)
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@ RecompOpFn recomp_opcodes[512] =
|
|||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, NULL, NULL, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
@ -32,20 +32,20 @@ RecompOpFn recomp_opcodes[512] =
|
|||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, ropADD_l_rmw, NULL, ropADD_l_rm, NULL, ropADD_EAX_imm, NULL, NULL, NULL, ropOR_l_rmw, NULL, ropOR_l_rm, NULL, ropOR_EAX_imm, NULL, NULL,
|
||||
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, NULL, NULL, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, ropAND_l_rmw, NULL, ropAND_l_rm, NULL, ropAND_EAX_imm, NULL, NULL, NULL, ropSUB_l_rmw, NULL, ropSUB_l_rm, NULL, ropSUB_EAX_imm, NULL, NULL,
|
||||
/*30*/ NULL, ropXOR_l_rmw, NULL, ropXOR_l_rm, NULL, ropXOR_EAX_imm, NULL, NULL, NULL, ropCMP_l_rmw, NULL, ropCMP_l_rm, NULL, ropCMP_EAX_imm, NULL, NULL,
|
||||
/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ NULL, rop81_l, NULL, rop83_l, NULL, NULL, NULL, NULL, NULL, ropMOV_l_r, NULL, ropMOV_r_l, NULL, NULL, NULL, NULL,
|
||||
/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,32 @@
|
|||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_arith.h"
|
||||
|
||||
uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm_data = fastreadb(cs + op_pc);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_AL);
|
||||
uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AL);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm_data = fastreadw(cs + op_pc);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_AX);
|
||||
uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AX);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -21,6 +47,70 @@ uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
uint32_t ropADD_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg));
|
||||
uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropADD_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg));
|
||||
uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropADD_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg));
|
||||
uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropADD_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg));
|
||||
uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropADD_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;
|
||||
|
|
@ -54,6 +144,32 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm_data = fastreadb(cs + op_pc);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_AL);
|
||||
uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm_data = fastreadw(cs + op_pc);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_AX);
|
||||
uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -66,6 +182,70 @@ uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
uint32_t ropCMP_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg));
|
||||
uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg));
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropCMP_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg));
|
||||
uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg));
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropCMP_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg));
|
||||
uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg));
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropCMP_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg));
|
||||
uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg));
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropCMP_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;
|
||||
|
|
@ -97,6 +277,32 @@ uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm_data = fastreadb(cs + op_pc);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_AL);
|
||||
uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AL);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm_data = fastreadw(cs + op_pc);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_AX);
|
||||
uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AX);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -110,6 +316,70 @@ uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
uint32_t ropSUB_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg));
|
||||
uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropSUB_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg));
|
||||
uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropSUB_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg));
|
||||
uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropSUB_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg));
|
||||
uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg));
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropSUB_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;
|
||||
|
|
@ -143,6 +413,148 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
uint8_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ADD*/
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x08: /*OR*/
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x20: /*AND*/
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SUB*/
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x30: /*XOR*/
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*CMP*/
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
uint16_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ADD*/
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x08: /*OR*/
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
|
||||
uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x20: /*AND*/
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
|
||||
uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SUB*/
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x30: /*XOR*/
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
|
||||
uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*CMP*/
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 3;
|
||||
}
|
||||
uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
|
@ -213,6 +625,78 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 5;
|
||||
}
|
||||
|
||||
uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
uint16_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ADD*/
|
||||
imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x08: /*OR*/
|
||||
imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x20: /*AND*/
|
||||
imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SUB*/
|
||||
imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x30: /*XOR*/
|
||||
imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*CMP*/
|
||||
imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,35 @@
|
|||
uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,28 @@
|
|||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_logic.h"
|
||||
|
||||
uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm_data = fastreadb(cs + op_pc);
|
||||
|
||||
uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AL);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm_data = fastreadw(cs + op_pc);
|
||||
|
||||
uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AX);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -19,6 +41,62 @@ uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
|
@ -48,6 +126,28 @@ uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm_data = fastreadb(cs + op_pc);
|
||||
|
||||
uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AL);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm_data = fastreadw(cs + op_pc);
|
||||
|
||||
uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AX);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -59,6 +159,62 @@ uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
|
@ -88,6 +244,28 @@ uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm_data = fastreadb(cs + op_pc);
|
||||
|
||||
uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AL);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm_data = fastreadw(cs + op_pc);
|
||||
|
||||
uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_AX);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -99,6 +277,62 @@ uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3
|
|||
codegen_flags_changed = 1;
|
||||
return op_pc + 4;
|
||||
}
|
||||
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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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_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;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,29 @@
|
|||
uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,22 @@
|
|||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_mov.h"
|
||||
|
||||
uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint8_t imm = fastreadb(cs + op_pc);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_8(opcode & 7), imm);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t imm = fastreadw(cs + op_pc);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_16(opcode & 7), imm);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
|
|
@ -18,6 +34,34 @@ uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32
|
|||
|
||||
|
||||
|
||||
uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg));
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg));
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
|
@ -32,6 +76,34 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = (fetchdat >> 3) & 7;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int src_reg = fetchdat & 7;
|
||||
uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg));
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = (fetchdat >> 3) & 7;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int src_reg = fetchdat & 7;
|
||||
uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg));
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int dest_reg = (fetchdat >> 3) & 7;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
|
|
@ -84,27 +84,28 @@ void codegen_reg_reset()
|
|||
|
||||
static inline int ir_reg_is_invalid(ir_reg_t ir_reg)
|
||||
{
|
||||
return (ir_reg.reg == IREG_INVALID);
|
||||
return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID);
|
||||
}
|
||||
|
||||
static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg)
|
||||
{
|
||||
switch (ireg_data[ir_reg.reg].native_size)
|
||||
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[ir_reg.reg].p);
|
||||
codegen_direct_read_32(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("codegen_reg_load - native_size=%i\n", ireg_data[ir_reg.reg].native_size);
|
||||
fatal("codegen_reg_load - native_size=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size);
|
||||
}
|
||||
|
||||
host_regs[c] = ir_reg;
|
||||
//pclog(" codegen_reg_load: c=%i reg=%02x.%i\n", c, host_regs[c].reg,host_regs[c].version);
|
||||
}
|
||||
|
||||
static void codegen_reg_writeback(codeblock_t *block, int c)
|
||||
{
|
||||
int ir_reg = host_regs[c].reg;
|
||||
int ir_reg = IREG_GET_REG(host_regs[c].reg);
|
||||
|
||||
switch (ireg_data[ir_reg].native_size)
|
||||
{
|
||||
|
|
@ -141,28 +142,28 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_
|
|||
|
||||
if (!ir_reg_is_invalid(dest_reg_a))
|
||||
{
|
||||
if (!ir_reg_is_invalid(src_reg_a) && src_reg_a.reg == dest_reg_a.reg && src_reg_a.version == dest_reg_a.version-1)
|
||||
if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version-1)
|
||||
dest_reference++;
|
||||
if (!ir_reg_is_invalid(src_reg_b) && src_reg_b.reg == dest_reg_a.reg && src_reg_b.version == dest_reg_a.version-1)
|
||||
if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version-1)
|
||||
dest_reference++;
|
||||
}
|
||||
for (c = 0; c < CODEGEN_HOST_REGS; c++)
|
||||
{
|
||||
if (!ir_reg_is_invalid(src_reg_a) && host_regs[c].reg == src_reg_a.reg)
|
||||
if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_a.reg))
|
||||
{
|
||||
if (host_regs[c].version != src_reg_a.version)
|
||||
fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_a.version\n");
|
||||
host_regs_locked |= (1 << c);
|
||||
}
|
||||
if (!ir_reg_is_invalid(src_reg_b) && host_regs[c].reg == src_reg_b.reg)
|
||||
if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(src_reg_b.reg))
|
||||
{
|
||||
if (host_regs[c].version != src_reg_b.version)
|
||||
fatal("codegen_reg_alloc_register - host_regs[c].version != src_reg_b.version\n");
|
||||
host_regs_locked |= (1 << c);
|
||||
}
|
||||
if (!ir_reg_is_invalid(dest_reg_a) && host_regs[c].reg == dest_reg_a.reg)
|
||||
if (!ir_reg_is_invalid(dest_reg_a) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(dest_reg_a.reg))
|
||||
{
|
||||
if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[host_regs[c].reg][host_regs[c].version] == dest_reference))
|
||||
if (host_regs[c].version == dest_reg_a.version || (host_regs[c].version == (dest_reg_a.version-1) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] == dest_reference))
|
||||
host_regs_locked |= (1 << c);
|
||||
else
|
||||
fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", host_regs[c].version, dest_reg_a.version, dest_reference);
|
||||
|
|
@ -170,17 +171,17 @@ void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_
|
|||
}
|
||||
}
|
||||
|
||||
ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg)
|
||||
ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx)
|
||||
{
|
||||
int c;
|
||||
|
||||
/*Search for required register*/
|
||||
for (c = 0; c < CODEGEN_HOST_REGS; c++)
|
||||
{
|
||||
if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg && host_regs[c].version == ir_reg.version)
|
||||
if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg) && host_regs[c].version == ir_reg.version)
|
||||
break;
|
||||
|
||||
if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg && reg_version_refcount[host_regs[c].reg][host_regs[c].version])
|
||||
if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version])
|
||||
fatal("codegen_reg_alloc_read_reg - version mismatch!\n");
|
||||
}
|
||||
|
||||
|
|
@ -196,33 +197,60 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg)
|
|||
fatal("codegen_reg_alloc_read_reg - out of registers\n");
|
||||
if (host_reg_dirty[c])
|
||||
codegen_reg_writeback(block, c);
|
||||
// pclog(" load %i\n", c);
|
||||
codegen_reg_load(block, c, ir_reg);
|
||||
host_regs_locked |= (1 << c);
|
||||
// fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c);
|
||||
// codegen_reg_writeback(block, c);
|
||||
host_reg_dirty[c] = 0;
|
||||
}
|
||||
// else
|
||||
// pclog(" already loaded %i\n", c);
|
||||
|
||||
reg_version_refcount[host_regs[c].reg][host_regs[c].version]--;
|
||||
if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] < 0)
|
||||
reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version]--;
|
||||
if (reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] < 0)
|
||||
fatal("codegen_reg_alloc_read_reg - refcount < 0\n");
|
||||
|
||||
// pclog(" codegen_reg_alloc_read_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]);
|
||||
return codegen_host_reg_list[c];
|
||||
if (host_reg_idx)
|
||||
*host_reg_idx = c;
|
||||
// pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], host_regs[c].reg,host_regs[c].version, c);
|
||||
return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg);
|
||||
}
|
||||
|
||||
ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (IREG_GET_SIZE(ir_reg.reg) != IREG_SIZE_L)
|
||||
{
|
||||
/*Read in parent register so we can do partial accesses to it*/
|
||||
ir_reg_t parent_reg;
|
||||
|
||||
parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L;
|
||||
parent_reg.version = ir_reg.version - 1;
|
||||
|
||||
codegen_reg_alloc_read_reg(block, parent_reg, &c);
|
||||
|
||||
if (IREG_GET_REG(host_regs[c].reg) != IREG_GET_REG(ir_reg.reg) || host_regs[c].version != ir_reg.version-1)
|
||||
fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c,
|
||||
host_regs[c].reg,host_regs[c].version,
|
||||
ir_reg.reg,ir_reg.version);
|
||||
|
||||
host_regs[c].reg = ir_reg.reg;
|
||||
host_regs[c].version = ir_reg.version;
|
||||
host_reg_dirty[c] = 1;
|
||||
// pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]);
|
||||
return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg);
|
||||
}
|
||||
|
||||
/*Search for previous version in host register*/
|
||||
for (c = 0; c < CODEGEN_HOST_REGS; c++)
|
||||
{
|
||||
if (!ir_reg_is_invalid(host_regs[c]) && host_regs[c].reg == ir_reg.reg)
|
||||
if (!ir_reg_is_invalid(host_regs[c]) && IREG_GET_REG(host_regs[c].reg) == IREG_GET_REG(ir_reg.reg))
|
||||
{
|
||||
if (host_regs[c].version == ir_reg.version-1)
|
||||
{
|
||||
if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] != 0)
|
||||
if (reg_version_refcount[IREG_GET_REG(host_regs[c].reg)][host_regs[c].version] != 0)
|
||||
fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n");
|
||||
break;
|
||||
}
|
||||
|
|
@ -257,7 +285,7 @@ ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg)
|
|||
host_regs[c].version = ir_reg.version;
|
||||
host_reg_dirty[c] = 1;
|
||||
// pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]);
|
||||
return codegen_host_reg_list[c];
|
||||
return codegen_host_reg_list[c] | IREG_GET_SIZE(ir_reg.reg);
|
||||
}
|
||||
|
||||
void codegen_reg_flush(ir_data_t *ir, codeblock_t *block)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
#ifndef _CODEGEN_REG_H_
|
||||
#define _CODEGEN_REG_H_
|
||||
|
||||
#define IREG_SIZE_L (0 << 6)
|
||||
#define IREG_SIZE_W (1 << 6)
|
||||
#define IREG_SIZE_B (2 << 6)
|
||||
#define IREG_SIZE_BH (3 << 6)
|
||||
#define IREG_REG_MASK 0x3f
|
||||
#define IREG_SIZE_SHIFT 6
|
||||
#define IREG_SIZE_MASK (3 << IREG_SIZE_SHIFT)
|
||||
|
||||
#define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK)
|
||||
#define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK)
|
||||
|
||||
#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT)
|
||||
#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT)
|
||||
#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT)
|
||||
#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT)
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -45,9 +52,34 @@ enum
|
|||
|
||||
IREG_COUNT,
|
||||
|
||||
IREG_INVALID = 255
|
||||
IREG_INVALID = 63,
|
||||
|
||||
IREG_AX = IREG_EAX + IREG_SIZE_W,
|
||||
IREG_CX = IREG_ECX + IREG_SIZE_W,
|
||||
IREG_DX = IREG_EDX + IREG_SIZE_W,
|
||||
IREG_BX = IREG_EBX + IREG_SIZE_W,
|
||||
IREG_SP = IREG_ESP + IREG_SIZE_W,
|
||||
IREG_BP = IREG_EBP + IREG_SIZE_W,
|
||||
IREG_SI = IREG_ESI + IREG_SIZE_W,
|
||||
IREG_DI = IREG_EDI + IREG_SIZE_W,
|
||||
|
||||
IREG_AL = IREG_EAX + IREG_SIZE_B,
|
||||
IREG_CL = IREG_ECX + IREG_SIZE_B,
|
||||
IREG_DL = IREG_EDX + IREG_SIZE_B,
|
||||
IREG_BL = IREG_EBX + IREG_SIZE_B,
|
||||
|
||||
IREG_AH = IREG_EAX + IREG_SIZE_BH,
|
||||
IREG_CH = IREG_ECX + IREG_SIZE_BH,
|
||||
IREG_DH = IREG_EDX + IREG_SIZE_BH,
|
||||
IREG_BH = IREG_EBX + IREG_SIZE_BH,
|
||||
|
||||
IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W,
|
||||
|
||||
IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B
|
||||
};
|
||||
|
||||
#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))
|
||||
#define IREG_16(reg) ((reg) + IREG_AX)
|
||||
#define IREG_32(reg) ((reg) + IREG_EAX)
|
||||
|
||||
extern uint8_t reg_last_version[IREG_COUNT];
|
||||
|
|
@ -67,13 +99,13 @@ static inline ir_reg_t codegen_reg_read(int reg)
|
|||
{
|
||||
ir_reg_t ireg;
|
||||
|
||||
if (reg == IREG_INVALID)
|
||||
if (IREG_GET_REG(reg) == IREG_INVALID)
|
||||
fatal("codegen_reg_read - IREG_INVALID\n");
|
||||
|
||||
ireg.reg = reg;
|
||||
ireg.version = reg_last_version[reg];
|
||||
reg_version_refcount[ireg.reg][ireg.version]++;
|
||||
if (!reg_version_refcount[ireg.reg][ireg.version])
|
||||
ireg.version = reg_last_version[IREG_GET_REG(reg)];
|
||||
reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]++;
|
||||
if (!reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version])
|
||||
fatal("codegen_reg_read - refcount overflow\n");
|
||||
|
||||
return ireg;
|
||||
|
|
@ -83,15 +115,15 @@ static inline ir_reg_t codegen_reg_write(int reg)
|
|||
{
|
||||
ir_reg_t ireg;
|
||||
|
||||
if (reg == IREG_INVALID)
|
||||
if (IREG_GET_REG(reg) == IREG_INVALID)
|
||||
fatal("codegen_reg_write - IREG_INVALID\n");
|
||||
|
||||
ireg.reg = reg;
|
||||
ireg.version = reg_last_version[reg] + 1;
|
||||
reg_last_version[reg]++;
|
||||
if (!reg_last_version[reg])
|
||||
ireg.version = reg_last_version[IREG_GET_REG(reg)] + 1;
|
||||
reg_last_version[IREG_GET_REG(reg)]++;
|
||||
if (!reg_last_version[IREG_GET_REG(reg)])
|
||||
fatal("codegen_reg_write - version overflow\n");
|
||||
reg_version_refcount[reg][ireg.version] = 0;
|
||||
reg_version_refcount[IREG_GET_REG(reg)][ireg.version] = 0;
|
||||
|
||||
return ireg;
|
||||
}
|
||||
|
|
@ -104,7 +136,7 @@ void codegen_reg_flush(struct ir_data_t *ir, codeblock_t *block);
|
|||
/*Register ir_reg usage for this uOP. This ensures that required registers aren't evicted*/
|
||||
void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b);
|
||||
|
||||
ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg);
|
||||
ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx);
|
||||
ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue