Added recompiled versions of SHL, SHR, SAR, SHLD and SHRD.
This commit is contained in:
parent
2783471daa
commit
872a2da788
18 changed files with 1923 additions and 20 deletions
|
|
@ -244,6 +244,8 @@ x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat,
|
|||
cpu_reg = (fetchdat >> 3) & 7;
|
||||
cpu_rm = fetchdat & 7;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
return NULL;
|
||||
if (op_32 & 0x200)
|
||||
return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset);
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_AND_ROR (0x056 << 21)
|
||||
#define OPCODE_ANDS_LSL (0x350 << 21)
|
||||
#define OPCODE_EOR_LSL (0x250 << 21)
|
||||
#define OPCODE_ORR_ASR (0x154 << 21)
|
||||
#define OPCODE_ORR_LSL (0x150 << 21)
|
||||
#define OPCODE_ORR_LSR (0x152 << 21)
|
||||
#define OPCODE_ORRX_LSL (0x550 << 21)
|
||||
|
|
@ -80,11 +81,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_SUB_LSR (0x25a << 21)
|
||||
#define OPCODE_SUBX_LSL (0x658 << 21)
|
||||
|
||||
#define OPCODE_ASR (0x1ac02800)
|
||||
#define OPCODE_BLR (0xd63f0000)
|
||||
#define OPCODE_LDR_REG (0xb8606800)
|
||||
#define OPCODE_LDRB_REG (0x38606800)
|
||||
#define OPCODE_LDRH_REG (0x78606800)
|
||||
#define OPCODE_LDRX_REG_LSL3 (0xf8607800)
|
||||
#define OPCODE_LSL (0x1ac02000)
|
||||
#define OPCODE_LSR (0x1ac02400)
|
||||
#define OPCODE_NOP (0xd503201f)
|
||||
#define OPCODE_RET (0xd65f0000)
|
||||
#define OPCODE_STR_REG (0xb8206800)
|
||||
|
|
@ -271,6 +275,11 @@ void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_
|
|||
}
|
||||
}
|
||||
|
||||
void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg));
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
@ -447,9 +456,24 @@ void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, in
|
|||
codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
}
|
||||
|
||||
void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg));
|
||||
}
|
||||
|
||||
void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg));
|
||||
}
|
||||
|
||||
void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift)
|
||||
{
|
||||
if (dst_reg != src_m_reg)
|
||||
if (dst_reg != src_m_reg || shift)
|
||||
codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int
|
|||
|
||||
void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data);
|
||||
|
||||
void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg);
|
||||
|
||||
void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width);
|
||||
|
||||
void host_arm64_BLR(codeblock_t *block, int addr_reg);
|
||||
|
|
@ -46,6 +48,10 @@ void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int off
|
|||
|
||||
void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg);
|
||||
void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg);
|
||||
|
||||
void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift);
|
||||
void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift);
|
||||
void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift);
|
||||
|
||||
|
|
|
|||
|
|
@ -553,10 +553,10 @@ static int codegen_OR(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
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)
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff);
|
||||
host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
host_arm64_ORR_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) && dest_reg == src_reg_a)
|
||||
{
|
||||
|
|
@ -610,6 +610,201 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_SAR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_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_ASR(block, dest_reg, src_reg, shift_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16);
|
||||
host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24);
|
||||
host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 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_MOV_REG(block, REG_TEMP, src_reg, 16);
|
||||
host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SAR_IMM(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_L(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16);
|
||||
host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24);
|
||||
host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 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_MOV_REG(block, REG_TEMP, src_reg, 16);
|
||||
host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL(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), shift_reg = HOST_REG_GET(uop->src_reg_b_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_LSL(block, dest_reg, src_reg, shift_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8);
|
||||
host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL_IMM(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_L(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG(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_MOV_REG(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))
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8);
|
||||
host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_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_LSR(block, dest_reg, src_reg, shift_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff);
|
||||
host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff);
|
||||
host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8);
|
||||
host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR_IMM(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_L(src_size))
|
||||
{
|
||||
host_arm64_MOV_REG_LSR(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, REG_TEMP, src_reg, 0xffff);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 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_AND_IMM(block, REG_TEMP, src_reg, 0xff);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 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))
|
||||
{
|
||||
host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8);
|
||||
host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_W16, uop->imm_data);
|
||||
|
|
@ -828,6 +1023,13 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_XOR & UOP_MASK] = codegen_XOR,
|
||||
[UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM,
|
||||
|
||||
[UOP_SAR & UOP_MASK] = codegen_SAR,
|
||||
[UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM,
|
||||
[UOP_SHL & UOP_MASK] = codegen_SHL,
|
||||
[UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM,
|
||||
[UOP_SHR & UOP_MASK] = codegen_SHR,
|
||||
[UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM,
|
||||
|
||||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
}
|
||||
|
||||
#define Rm(x) (x)
|
||||
#define Rs(x) ((x) << 8)
|
||||
#define Rd(x) ((x) << 12)
|
||||
#define Rn(x) ((x) << 16)
|
||||
|
||||
|
|
@ -94,9 +95,14 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define SHIFT_TYPE_REG (1 << 4)
|
||||
|
||||
#define SHIFT_IMM_SHIFT 7
|
||||
#define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT))
|
||||
#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 SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x))
|
||||
#define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x))
|
||||
#define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x))
|
||||
|
||||
#define BFI_lsb(lsb) ((lsb) << 7)
|
||||
#define BFI_msb(msb) ((msb) << 16)
|
||||
|
||||
|
|
@ -427,14 +433,30 @@ void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm)
|
|||
}
|
||||
}
|
||||
|
||||
void host_arm_MOV_REG_ASR(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_ASR_IMM(shift));
|
||||
}
|
||||
void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg));
|
||||
}
|
||||
void host_arm_MOV_REG_LSL(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_LSL_IMM(shift));
|
||||
}
|
||||
void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg));
|
||||
}
|
||||
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_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg));
|
||||
}
|
||||
|
||||
void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,8 +46,12 @@ void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset
|
|||
|
||||
void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm);
|
||||
#define host_arm_MOV_REG(block, dst_reg, src_reg) host_arm_MOV_REG_LSL(block, dst_reg, src_reg, 0)
|
||||
void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift);
|
||||
void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg);
|
||||
void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift);
|
||||
void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg);
|
||||
void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift);
|
||||
void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg);
|
||||
void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm);
|
||||
void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm);
|
||||
|
||||
|
|
|
|||
|
|
@ -635,10 +635,10 @@ static int codegen_OR(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
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)
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b))
|
||||
{
|
||||
host_arm_UXTH(block, REG_TEMP, src_reg_b, 0);
|
||||
host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0);
|
||||
host_arm_ORR_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) && dest_reg == src_reg_a)
|
||||
{
|
||||
|
|
@ -692,6 +692,201 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_SAR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_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_ASR_REG(block, dest_reg, src_reg, shift_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16);
|
||||
host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24);
|
||||
host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24);
|
||||
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_LSL(block, REG_TEMP, src_reg, 16);
|
||||
host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SAR_IMM(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_L(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16);
|
||||
host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24);
|
||||
host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24);
|
||||
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_LSL(block, REG_TEMP, src_reg, 16);
|
||||
host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL(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), shift_reg = HOST_REG_GET(uop->src_reg_b_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_REG(block, dest_reg, src_reg, shift_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg, 8);
|
||||
host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL_IMM(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_L(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSL(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_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg, 8);
|
||||
host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_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_LSR_REG(block, dest_reg, src_reg, shift_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_UXTH(block, REG_TEMP, src_reg, 0);
|
||||
host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg, 0);
|
||||
host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg, 8);
|
||||
host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR_IMM(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_L(src_size))
|
||||
{
|
||||
host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_UXTH(block, REG_TEMP, src_reg, 0);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 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_UXTB(block, REG_TEMP, src_reg, 0);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size))
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg, 8);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_R0, uop->imm_data);
|
||||
|
|
@ -911,6 +1106,13 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_XOR & UOP_MASK] = codegen_XOR,
|
||||
[UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM,
|
||||
|
||||
[UOP_SAR & UOP_MASK] = codegen_SAR,
|
||||
[UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM,
|
||||
[UOP_SHL & UOP_MASK] = codegen_SHL,
|
||||
[UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM,
|
||||
[UOP_SHR & UOP_MASK] = codegen_SHR,
|
||||
[UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM,
|
||||
|
||||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
#define RM_OP_XOR 0x30
|
||||
#define RM_OP_CMP 0x38
|
||||
|
||||
#define RM_OP_SHL 0x20
|
||||
#define RM_OP_SHR 0x28
|
||||
#define RM_OP_SAR 0x38
|
||||
|
||||
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
|
||||
{
|
||||
|
|
@ -811,10 +813,117 @@ void host_x86_RET(codeblock_t *block)
|
|||
codegen_addbyte(block, 0xc3); /*RET*/
|
||||
}
|
||||
|
||||
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SAR8 CL & 8\n");
|
||||
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SAR16_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SAR16 CL & 8\n");
|
||||
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SAR32_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SAR32 CL & 8\n");
|
||||
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/
|
||||
}
|
||||
|
||||
void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SAR8 imm & 8\n");
|
||||
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SAR16 imm & 8\n");
|
||||
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SAR32 imm & 8\n");
|
||||
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/
|
||||
}
|
||||
|
||||
void host_x86_SHL8_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHL8 CL & 8\n");
|
||||
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHL16_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHL16 CL & 8\n");
|
||||
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHL32_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHL32 CL & 8\n");
|
||||
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/
|
||||
}
|
||||
|
||||
void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHL8 imm & 8\n");
|
||||
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHL16 imm & 8\n");
|
||||
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHL32 imm & 8\n");
|
||||
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/
|
||||
}
|
||||
|
||||
void host_x86_SHR8_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHR8 CL & 8\n");
|
||||
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHR16_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHR16 CL & 8\n");
|
||||
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHR32_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHR32 CL & 8\n");
|
||||
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/
|
||||
}
|
||||
|
||||
void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHR8 imm & 8\n");
|
||||
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHR16 imm & 8\n");
|
||||
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
if (dst_reg & 8)
|
||||
fatal("SHR32_IMM reg & 8\n");
|
||||
fatal("SHR32 imm & 8\n");
|
||||
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,28 @@ void host_x86_PUSH(codeblock_t *block, int src_reg);
|
|||
|
||||
void host_x86_RET(codeblock_t *block);
|
||||
|
||||
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SAR16_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SAR32_CL(codeblock_t *block, int dst_reg);
|
||||
|
||||
void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
|
||||
void host_x86_SHL8_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHL16_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHL32_CL(codeblock_t *block, int dst_reg);
|
||||
|
||||
void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
|
||||
void host_x86_SHR8_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHR16_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHR32_CL(codeblock_t *block, int dst_reg);
|
||||
|
||||
void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
|
||||
void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
|
||||
|
|
|
|||
|
|
@ -473,11 +473,15 @@ static int codegen_OR(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
if (dest_reg != src_reg_a)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_OR32_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))
|
||||
{
|
||||
host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
if (dest_reg != src_reg_a)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_OR16_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))
|
||||
{
|
||||
|
|
@ -511,6 +515,178 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_SAR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR32_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR16_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR8_CL(block, dest_reg);
|
||||
}
|
||||
else
|
||||
fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SAR_IMM(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_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR32_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR16_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR8_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL32_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL16_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL8_CL(block, dest_reg);
|
||||
}
|
||||
else
|
||||
fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL_IMM(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_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL32_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL16_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL8_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR32_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR16_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR8_CL(block, dest_reg);
|
||||
}
|
||||
else
|
||||
fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR_IMM(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_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR32_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR16_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR8_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
if (((uintptr_t)uop->p) >> 32)
|
||||
|
|
@ -668,6 +844,13 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_XOR & UOP_MASK] = codegen_XOR,
|
||||
[UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM,
|
||||
|
||||
[UOP_SAR & UOP_MASK] = codegen_SAR,
|
||||
[UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM,
|
||||
[UOP_SHL & UOP_MASK] = codegen_SHL,
|
||||
[UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM,
|
||||
[UOP_SHR & UOP_MASK] = codegen_SHR,
|
||||
[UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM,
|
||||
|
||||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
#define RM_OP_XOR 0x30
|
||||
#define RM_OP_CMP 0x38
|
||||
|
||||
#define RM_OP_SHL 0x20
|
||||
#define RM_OP_SHR 0x28
|
||||
#define RM_OP_SAR 0x38
|
||||
|
||||
static inline void codegen_addbyte(codeblock_t *block, uint8_t val)
|
||||
{
|
||||
|
|
@ -707,6 +709,79 @@ void host_x86_RET(codeblock_t *block)
|
|||
|
||||
#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3))
|
||||
|
||||
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SAR16_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SAR32_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/
|
||||
}
|
||||
|
||||
void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/
|
||||
}
|
||||
|
||||
void host_x86_SHL8_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHL16_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHL32_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/
|
||||
}
|
||||
|
||||
void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/
|
||||
}
|
||||
|
||||
void host_x86_SHR8_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHR16_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/
|
||||
}
|
||||
void host_x86_SHR32_CL(codeblock_t *block, int dst_reg)
|
||||
{
|
||||
codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/
|
||||
}
|
||||
|
||||
void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
|
||||
}
|
||||
void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift)
|
||||
{
|
||||
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
|
||||
|
|
|
|||
|
|
@ -89,6 +89,28 @@ void host_x86_PUSH(codeblock_t *block, int src_reg);
|
|||
|
||||
void host_x86_RET(codeblock_t *block);
|
||||
|
||||
void host_x86_SAR8_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SAR16_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SAR32_CL(codeblock_t *block, int dst_reg);
|
||||
|
||||
void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
|
||||
void host_x86_SHL8_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHL16_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHL32_CL(codeblock_t *block, int dst_reg);
|
||||
|
||||
void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
|
||||
void host_x86_SHR8_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHR16_CL(codeblock_t *block, int dst_reg);
|
||||
void host_x86_SHR32_CL(codeblock_t *block, int dst_reg);
|
||||
|
||||
void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift);
|
||||
|
||||
void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
|
||||
|
|
|
|||
|
|
@ -470,11 +470,15 @@ static int codegen_OR(codeblock_t *block, uop_t *uop)
|
|||
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b))
|
||||
{
|
||||
host_x86_OR32_REG_REG(block, dest_reg, src_reg_a, src_reg_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_OR32_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))
|
||||
{
|
||||
host_x86_OR16_REG_REG(block, dest_reg, src_reg_a, src_reg_b);
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a);
|
||||
host_x86_OR16_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))
|
||||
{
|
||||
|
|
@ -508,6 +512,178 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_SAR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR32_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR16_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR8_CL(block, dest_reg);
|
||||
}
|
||||
else
|
||||
fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SAR_IMM(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_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR32_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR16_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SAR8_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL32_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL16_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL8_CL(block, dest_reg);
|
||||
}
|
||||
else
|
||||
fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHL_IMM(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_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL32_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL16_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHL8_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR(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), shift_reg = HOST_REG_GET(uop->src_reg_b_real);
|
||||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg);
|
||||
if (REG_IS_L(dest_size) && REG_IS_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR32_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR16_CL(block, dest_reg);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR8_CL(block, dest_reg);
|
||||
}
|
||||
else
|
||||
fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_SHR_IMM(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_L(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR32_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_W(dest_size) && REG_IS_W(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV16_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR16_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size))
|
||||
{
|
||||
if (uop->dest_reg_a_real != uop->src_reg_a_real)
|
||||
host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
|
||||
host_x86_SHR8_IMM(block, dest_reg, uop->imm_data);
|
||||
}
|
||||
else
|
||||
fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data);
|
||||
|
|
@ -660,7 +836,14 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM,
|
||||
[UOP_XOR & UOP_MASK] = codegen_XOR,
|
||||
[UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM,
|
||||
|
||||
|
||||
[UOP_SAR & UOP_MASK] = codegen_SAR,
|
||||
[UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM,
|
||||
[UOP_SHL & UOP_MASK] = codegen_SHL,
|
||||
[UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM,
|
||||
[UOP_SHR & UOP_MASK] = codegen_SHR,
|
||||
[UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM,
|
||||
|
||||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -89,7 +89,20 @@
|
|||
/*UOP_CMP_JZ - if (src_reg_a == imm_data) then jump to ptr*/
|
||||
#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER)
|
||||
|
||||
#define UOP_MAX 0x49
|
||||
/*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/
|
||||
#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50)
|
||||
/*UOP_SAR_IMM - dest_reg = src_reg_a >> immediate*/
|
||||
#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51)
|
||||
/*UOP_SHL - dest_reg = src_reg_a << src_reg_b*/
|
||||
#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52)
|
||||
/*UOP_SHL_IMM - dest_reg = src_reg_a << immediate*/
|
||||
#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53)
|
||||
/*UOP_SHR - dest_reg = src_reg_a >> src_reg_b*/
|
||||
#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54)
|
||||
/*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/
|
||||
#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55)
|
||||
|
||||
#define UOP_MAX 0x56
|
||||
|
||||
#define UOP_MASK 0xffff
|
||||
|
||||
|
|
@ -287,6 +300,13 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
|
|||
#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b)
|
||||
#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm)
|
||||
|
||||
#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg)
|
||||
#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm)
|
||||
#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg)
|
||||
#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm)
|
||||
#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg)
|
||||
#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm)
|
||||
|
||||
#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)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "codegen_ops_logic.h"
|
||||
#include "codegen_ops_misc.h"
|
||||
#include "codegen_ops_mov.h"
|
||||
#include "codegen_ops_shift.h"
|
||||
#include "codegen_ops_stack.h"
|
||||
|
||||
RecompOpFn recomp_opcodes[512] =
|
||||
|
|
@ -28,8 +29,8 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, 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, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, 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,
|
||||
/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16,
|
||||
|
||||
|
|
@ -50,8 +51,8 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,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_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, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, 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,
|
||||
/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32
|
||||
};
|
||||
|
|
@ -73,7 +74,7 @@ RecompOpFn recomp_opcodes_0f[512] =
|
|||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
@ -95,7 +96,7 @@ RecompOpFn recomp_opcodes_0f[512] =
|
|||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
|
|||
809
src/codegen_ops_shift.c
Normal file
809
src/codegen_ops_shift.c
Normal file
|
|
@ -0,0 +1,809 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_backend.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_shift.h"
|
||||
|
||||
static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count)
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B);
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B);
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count)
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W);
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W);
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count)
|
||||
{
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp1);
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp1);
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, count);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
||||
uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
uint8_t imm;
|
||||
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (imm)
|
||||
return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1;
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
uint8_t imm;
|
||||
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (imm)
|
||||
return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1;
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
uint8_t imm;
|
||||
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (imm)
|
||||
return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1;
|
||||
return op_pc+1;
|
||||
}
|
||||
|
||||
uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
|
||||
return shift_common_8(ir, fetchdat, op_pc, target_seg, 1);
|
||||
}
|
||||
uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
|
||||
return shift_common_16(ir, fetchdat, op_pc, target_seg, 1);
|
||||
}
|
||||
uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
|
||||
return shift_common_32(ir, fetchdat, op_pc, target_seg, 1);
|
||||
}
|
||||
|
||||
uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if (!(CL & 0x1f) || !block->ins)
|
||||
return 0;
|
||||
|
||||
uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B);
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B);
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if (!(CL & 0x1f) || !block->ins)
|
||||
return 0;
|
||||
|
||||
uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W);
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W);
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
if (!(fetchdat & 0x20)) /*ROL/ROR/RCL/RCR*/
|
||||
return 0;
|
||||
|
||||
if (!(CL & 0x1f) || !block->ins)
|
||||
return 0;
|
||||
|
||||
uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f);
|
||||
uop_CMP_IMM_JZ(ir, IREG_temp2, 0, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x20: case 0x30: /*SHL*/
|
||||
uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp1);
|
||||
break;
|
||||
|
||||
case 0x28: /*SHR*/
|
||||
uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp1);
|
||||
break;
|
||||
|
||||
case 0x38: /*SAR*/
|
||||
uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
uop_MOV(ir, IREG_flags_op2, IREG_temp2);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
uint8_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (!imm)
|
||||
return op_pc+2;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm);
|
||||
uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm);
|
||||
uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm);
|
||||
uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm);
|
||||
uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16);
|
||||
}
|
||||
return op_pc+2;
|
||||
}
|
||||
uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
uint8_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (!imm)
|
||||
return op_pc+2;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm);
|
||||
uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm);
|
||||
uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm);
|
||||
uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm);
|
||||
uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
|
||||
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp0);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32);
|
||||
}
|
||||
return op_pc+2;
|
||||
}
|
||||
uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
uint8_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (!imm)
|
||||
return op_pc+2;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm);
|
||||
uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm);
|
||||
uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm);
|
||||
uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm);
|
||||
uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
|
||||
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W);
|
||||
uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16);
|
||||
}
|
||||
return op_pc+2;
|
||||
}
|
||||
uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg = NULL;
|
||||
int src_reg = (fetchdat >> 3) & 7;
|
||||
uint8_t imm;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
}
|
||||
imm = fastreadb(cs + op_pc + 1) & 0x1f;
|
||||
|
||||
if (!imm)
|
||||
return op_pc+2;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int dest_reg = fetchdat & 7;
|
||||
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm);
|
||||
uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm);
|
||||
uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg));
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
|
||||
uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm);
|
||||
uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm);
|
||||
uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1);
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
|
||||
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_temp2);
|
||||
uop_MOV(ir, IREG_flags_res, IREG_temp0);
|
||||
uop_MOV_IMM(ir, IREG_flags_op2, imm);
|
||||
uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32);
|
||||
}
|
||||
return op_pc+2;
|
||||
}
|
||||
16
src/codegen_ops_shift.h
Normal file
16
src/codegen_ops_shift.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
@ -93,6 +93,7 @@ enum
|
|||
|
||||
IREG_temp0_W = IREG_temp0 + IREG_SIZE_W,
|
||||
IREG_temp1_W = IREG_temp1 + IREG_SIZE_W,
|
||||
IREG_temp2_W = IREG_temp2 + IREG_SIZE_W,
|
||||
|
||||
IREG_temp0_B = IREG_temp0 + IREG_SIZE_B,
|
||||
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B,
|
||||
|
|
|
|||
Loading…
Reference in a new issue