Added recompiled versions of JMP indirect, JMP far, RETF, LxS, XLAT and LEAVE.
This commit is contained in:
parent
1aadfd436d
commit
592b07be63
14 changed files with 475 additions and 19 deletions
|
|
@ -602,6 +602,36 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_W(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff);
|
||||
}
|
||||
else
|
||||
fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm64_mov_imm(block, REG_ARG0, uop->imm_data);
|
||||
|
|
@ -690,6 +720,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0);
|
||||
if (uop->imm_data)
|
||||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size))
|
||||
{
|
||||
host_arm64_call(block, codegen_mem_load_byte);
|
||||
|
|
@ -763,6 +795,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0);
|
||||
if (uop->imm_data)
|
||||
host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data);
|
||||
if (REG_IS_B(src_size))
|
||||
{
|
||||
host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff);
|
||||
|
|
@ -1460,6 +1494,11 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0,
|
||||
[UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1,
|
||||
[UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2,
|
||||
[UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
|
||||
|
|
|
|||
|
|
@ -676,6 +676,36 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_W(src_size))
|
||||
{
|
||||
host_arm_UXTH(block, REG_ARG0, src_reg, 0);
|
||||
}
|
||||
else
|
||||
fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data);
|
||||
|
|
@ -761,6 +791,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||
if (REG_IS_B(dest_size) || REG_IS_BH(dest_size))
|
||||
{
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_load_byte);
|
||||
|
|
@ -832,6 +864,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data);
|
||||
if (REG_IS_B(src_size))
|
||||
{
|
||||
host_arm_MOV_REG(block, REG_R1, src_reg);
|
||||
|
|
@ -1540,6 +1574,11 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0,
|
||||
[UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1,
|
||||
[UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2,
|
||||
[UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
|
||||
|
|
|
|||
|
|
@ -531,6 +531,40 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_W(src_size))
|
||||
{
|
||||
#if WIN64
|
||||
host_x86_MOV16_REG_REG(block, REG_ECX, src_reg);
|
||||
#else
|
||||
host_x86_MOV16_REG_REG(block, REG_EDI, src_reg);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
#if WIN64
|
||||
|
|
@ -624,6 +658,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_CALL(block, codegen_mem_load_byte);
|
||||
|
|
@ -729,6 +765,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
if (REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, REG_ECX, src_reg);
|
||||
|
|
@ -1241,6 +1279,11 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0,
|
||||
[UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1,
|
||||
[UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2,
|
||||
[UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
|
||||
|
|
|
|||
|
|
@ -542,6 +542,36 @@ static int codegen_JMP(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int src_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
int src_size = IREG_GET_SIZE(uop->src_reg_a_real);
|
||||
|
||||
if (REG_IS_W(src_size))
|
||||
{
|
||||
host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg);
|
||||
}
|
||||
else
|
||||
fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data);
|
||||
|
|
@ -622,6 +652,8 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
host_x86_CALL(block, codegen_mem_load_byte);
|
||||
|
|
@ -689,6 +721,8 @@ static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop)
|
|||
int src_size = IREG_GET_SIZE(uop->src_reg_c_real);
|
||||
|
||||
host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg);
|
||||
if (uop->imm_data)
|
||||
host_x86_ADD32_REG_IMM(block, REG_ESI, REG_ESI, uop->imm_data);
|
||||
if (REG_IS_B(src_size))
|
||||
{
|
||||
host_x86_MOV8_REG_REG(block, REG_ECX, src_reg);
|
||||
|
|
@ -1234,6 +1268,11 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0,
|
||||
[UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1,
|
||||
[UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2,
|
||||
[UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3,
|
||||
|
||||
[UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
|
||||
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM,
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@
|
|||
#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01)
|
||||
#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02)
|
||||
#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03)
|
||||
#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08)
|
||||
#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09)
|
||||
#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a)
|
||||
#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b)
|
||||
#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER)
|
||||
#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER)
|
||||
#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER)
|
||||
#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER)
|
||||
#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER)
|
||||
/*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/
|
||||
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER)
|
||||
|
|
@ -333,6 +333,17 @@ static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_re
|
|||
uop->src_reg_c = codegen_reg_read(src_reg_c);
|
||||
}
|
||||
|
||||
static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm)
|
||||
{
|
||||
uop_t *uop = uop_alloc(ir);
|
||||
|
||||
uop->type = uop_type;
|
||||
uop->src_reg_a = codegen_reg_read(src_reg_a);
|
||||
uop->src_reg_b = codegen_reg_read(src_reg_b);
|
||||
uop->src_reg_c = codegen_reg_read(src_reg_c);
|
||||
uop->imm_data = imm;
|
||||
}
|
||||
|
||||
static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm)
|
||||
{
|
||||
uop_t *uop = uop_alloc(ir);
|
||||
|
|
@ -377,7 +388,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
|
|||
uop->imm_data = imm;
|
||||
}
|
||||
|
||||
#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1_arg(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg)
|
||||
#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg)
|
||||
|
||||
#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm)
|
||||
|
||||
|
|
@ -427,9 +438,11 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
|
|||
#define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p)
|
||||
|
||||
#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm)
|
||||
#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg)
|
||||
#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0)
|
||||
#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset)
|
||||
#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm)
|
||||
#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg)
|
||||
#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0)
|
||||
#define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset)
|
||||
#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm)
|
||||
#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm)
|
||||
#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm)
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ 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*/ 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*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*c0*/ ropC0, ropC1_w, ropRET_imm_16, ropRET_16, ropLES_16, ropLDS_16, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, ropRETF_imm_16, ropRETF_16, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, ropJMP_far_16, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_16, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_16,
|
||||
|
||||
/*32-bit data*/
|
||||
|
|
@ -52,9 +52,9 @@ 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*/ 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*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*c0*/ ropC0, ropC1_l, ropRET_imm_32, ropRET_32, ropLES_32, ropLDS_32, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, ropRETF_imm_32, ropRETF_32, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_32, NULL, NULL, NULL, NULL, NULL, NULL, ropINCDEC, ropFF_32
|
||||
};
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ RecompOpFn recomp_opcodes_0f[512] =
|
|||
/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16,
|
||||
/*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, 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, ropMOVSX_16_8, NULL,
|
||||
/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
@ -98,7 +98,7 @@ RecompOpFn recomp_opcodes_0f[512] =
|
|||
/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32,
|
||||
/*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, 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, ropMOVSX_32_8, ropMOVSX_32_16,
|
||||
/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "x86.h"
|
||||
#include "386_common.h"
|
||||
#include "386.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
|
|
@ -30,6 +31,33 @@ uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t new_pc = fastreadw(cs + op_pc);
|
||||
uint16_t new_cs = fastreadw(cs + op_pc + 2);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
uop_MOV_IMM(ir, IREG_pc, new_pc);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4);
|
||||
uop_CALL_FUNC(ir, loadcsjmp);
|
||||
|
||||
return -1;
|
||||
}
|
||||
uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint32_t new_pc = fastreadl(cs + op_pc);
|
||||
uint16_t new_cs = fastreadw(cs + op_pc + 4);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
uop_MOV_IMM(ir, IREG_pc, new_pc);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4);
|
||||
uop_CALL_FUNC(ir, loadcsjmp);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc);
|
||||
|
|
@ -128,3 +156,111 @@ uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
if ((msw&1) && !(eflags&VM_FLAG))
|
||||
return 0;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
{
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2);
|
||||
}
|
||||
uop_MOVZX(ir, IREG_pc, IREG_temp0_W);
|
||||
uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W);
|
||||
uop_CALL_FUNC(ir, loadcs);
|
||||
ADD_SP(ir, 4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
if ((msw&1) && !(eflags&VM_FLAG))
|
||||
return 0;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
{
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4);
|
||||
}
|
||||
uop_MOV(ir, IREG_pc, IREG_temp0);
|
||||
uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W);
|
||||
uop_CALL_FUNC(ir, loadcs);
|
||||
ADD_SP(ir, 8);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t offset;
|
||||
|
||||
if ((msw&1) && !(eflags&VM_FLAG))
|
||||
return 0;
|
||||
|
||||
offset = fastreadw(cs + op_pc);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
{
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2);
|
||||
}
|
||||
uop_MOVZX(ir, IREG_pc, IREG_temp0_W);
|
||||
uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W);
|
||||
uop_CALL_FUNC(ir, loadcs);
|
||||
ADD_SP(ir, 4+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uint16_t offset;
|
||||
|
||||
if ((msw&1) && !(eflags&VM_FLAG))
|
||||
return 0;
|
||||
|
||||
offset = fastreadw(cs + op_pc);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
{
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr);
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4);
|
||||
}
|
||||
uop_MOV(ir, IREG_pc, IREG_temp0);
|
||||
uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W);
|
||||
uop_CALL_FUNC(ir, loadcs);
|
||||
ADD_SP(ir, 8+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
|
|||
uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
|
|
@ -10,3 +13,9 @@ uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
|
|||
|
||||
uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "x86.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
#include "386.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
|
|
@ -264,11 +265,15 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
x86seg *target_seg = NULL;
|
||||
int src_reg, sp_reg;
|
||||
|
||||
if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30)
|
||||
if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30)
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
if ((fetchdat & 0x38) == 0x28)
|
||||
return 0;
|
||||
src_reg = IREG_16(fetchdat & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
|
@ -342,6 +347,14 @@ uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
uop_MOVZX(ir, IREG_pc, src_reg);
|
||||
return -1;
|
||||
|
||||
case 0x28: /*JMP far*/
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2);
|
||||
uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc);
|
||||
uop_CALL_FUNC(ir, loadcsjmp);
|
||||
uop_MOVZX(ir, IREG_pc, src_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
|
@ -358,11 +371,15 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
x86seg *target_seg = NULL;
|
||||
int src_reg, sp_reg;
|
||||
|
||||
if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30)
|
||||
if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30)
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
if ((fetchdat & 0x38) == 0x28)
|
||||
return 0;
|
||||
src_reg = IREG_32(fetchdat & 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
|
@ -436,6 +453,14 @@ uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
uop_MOV(ir, IREG_pc, src_reg);
|
||||
return -1;
|
||||
|
||||
case 0x28: /*JMP far*/
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4);
|
||||
uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W);
|
||||
uop_LOAD_FUNC_ARG_IMM(ir, 1, cpu_state.oldpc);
|
||||
uop_CALL_FUNC(ir, loadcsjmp);
|
||||
uop_MOV(ir, IREG_pc, src_reg);
|
||||
return -1;
|
||||
|
||||
case 0x30: /*PUSH*/
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
|
@ -476,3 +501,53 @@ uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
#define ropLxS(name, seg) \
|
||||
uint32_t rop ## name ## _16(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 dest_reg = (fetchdat >> 3) & 7; \
|
||||
\
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
return 0; \
|
||||
\
|
||||
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_read(block, ir, target_seg); \
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \
|
||||
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
|
||||
uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \
|
||||
\
|
||||
if (seg == &cpu_state.seg_ss) \
|
||||
CPU_BLOCK_END(); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
} \
|
||||
uint32_t rop ## name ## _32(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 dest_reg = (fetchdat >> 3) & 7; \
|
||||
\
|
||||
if ((fetchdat & 0xc0) == 0xc0) \
|
||||
return 0; \
|
||||
\
|
||||
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_read(block, ir, target_seg); \
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \
|
||||
uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \
|
||||
uop_LOAD_SEG(ir, seg, IREG_temp1_W); \
|
||||
uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \
|
||||
\
|
||||
if (seg == &cpu_state.seg_ss) \
|
||||
CPU_BLOCK_END(); \
|
||||
\
|
||||
return op_pc + 1; \
|
||||
}
|
||||
|
||||
ropLxS(LDS, &cpu_state.seg_ds)
|
||||
ropLxS(LES, &cpu_state.seg_es)
|
||||
ropLxS(LFS, &cpu_state.seg_fs)
|
||||
ropLxS(LGS, &cpu_state.seg_gs)
|
||||
ropLxS(LSS, &cpu_state.seg_ss)
|
||||
|
|
|
|||
|
|
@ -14,3 +14,14 @@ uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc
|
|||
uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropLDS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLDS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLES_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLES_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLFS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLFS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLGS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLGS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLSS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLSS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
|
|
@ -696,3 +696,17 @@ uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_AL);
|
||||
uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX);
|
||||
if (!(op_32 & 0x200))
|
||||
uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff);
|
||||
|
||||
uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,3 +39,5 @@ uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
|
|
@ -255,3 +255,36 @@ ROP_POP_SEG(DS, cpu_state.seg_ds)
|
|||
ROP_POP_SEG(ES, cpu_state.seg_es)
|
||||
ROP_POP_SEG(FS, cpu_state.seg_fs)
|
||||
ROP_POP_SEG(GS, cpu_state.seg_gs)
|
||||
|
||||
uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_BP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2);
|
||||
uop_MOV(ir, IREG_BP, IREG_temp0_W);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_BP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4);
|
||||
uop_MOV(ir, IREG_EBP, IREG_temp0);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,3 +35,6 @@ uint32_t ropPOP_DS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
uint32_t ropPOP_ES_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPOP_FS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPOP_GS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
Loading…
Reference in a new issue