Added recompiled versions of JMP, CALL, RET, PUSH and POP.
This commit is contained in:
parent
4ada3382b4
commit
f1df9be8f6
33 changed files with 1062 additions and 102 deletions
|
|
@ -24,7 +24,8 @@ wx-resources.cpp : pc.xrc
|
|||
|
||||
# PCem
|
||||
pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \
|
||||
cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_arith.c codegen_ops_logic.c codegen_ops_mov.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
|
||||
cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_ops.c codegen_ops_arith.c codegen_ops_jump.c codegen_ops_logic.c \
|
||||
codegen_ops_misc.c codegen_ops_mov.c codegen_ops_stack.c codegen_reg.c codegen_timing_486.c codegen_timing_686.c codegen_timing_common.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
|
||||
dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \
|
||||
hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \
|
||||
joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \
|
||||
|
|
|
|||
|
|
@ -238,14 +238,14 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin
|
|||
return op_ea_seg;
|
||||
}
|
||||
|
||||
x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32)
|
||||
x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset)
|
||||
{
|
||||
cpu_mod = (fetchdat >> 6) & 3;
|
||||
cpu_reg = (fetchdat >> 3) & 7;
|
||||
cpu_rm = fetchdat & 7;
|
||||
|
||||
if (op_32 & 0x200)
|
||||
return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, 0);
|
||||
return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset);
|
||||
|
||||
return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc);
|
||||
}
|
||||
|
|
@ -320,7 +320,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
|||
{
|
||||
case 0x0f:
|
||||
op_table = x86_dynarec_opcodes_0f;
|
||||
recomp_op_table = NULL;//recomp_opcodes_0f;
|
||||
recomp_op_table = recomp_opcodes_0f;
|
||||
over = 1;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ void codegen_set_op32();
|
|||
void codegen_flush();
|
||||
void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr);
|
||||
struct ir_data_t;
|
||||
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32);
|
||||
x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset);
|
||||
void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
|
||||
void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,11 +56,13 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_BFI (0x0cc << 22)
|
||||
#define OPCODE_LDR_IMM_W (0x2e5 << 22)
|
||||
#define OPCODE_LDRB_IMM_W (0x0e5 << 22)
|
||||
#define OPCODE_LDRH_IMM (0x1e5 << 22)
|
||||
#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22)
|
||||
#define OPCODE_STP_PREIDX_X (0x2a6 << 22)
|
||||
#define OPCODE_STR_IMM_W (0x2e4 << 22)
|
||||
#define OPCODE_STR_IMM_Q (0x3e4 << 22)
|
||||
#define OPCODE_STRB_IMM (0x0e4 << 22)
|
||||
#define OPCODE_STRH_IMM (0x1e4 << 22)
|
||||
#define OPCODE_UBFX (0x14c << 22)
|
||||
|
||||
#define OPCODE_ADD_LSL (0x058 << 21)
|
||||
|
|
@ -104,6 +106,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0)
|
||||
|
||||
#define OFFSET12_B(offset) (offset << 10)
|
||||
#define OFFSET12_H(offset) ((offset >> 1) << 10)
|
||||
#define OFFSET12_W(offset) ((offset >> 2) << 10)
|
||||
#define OFFSET12_Q(offset) ((offset >> 3) << 10)
|
||||
|
||||
|
|
@ -428,6 +431,12 @@ void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int off
|
|||
codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
}
|
||||
|
||||
void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset)
|
||||
{
|
||||
if (!in_range12_h(offset))
|
||||
fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset);
|
||||
codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg));
|
||||
}
|
||||
void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg));
|
||||
|
|
@ -557,6 +566,12 @@ void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offs
|
|||
codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));
|
||||
}
|
||||
|
||||
void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset)
|
||||
{
|
||||
if (!in_range12_h(offset))
|
||||
fatal("host_arm64_STRH_IMM out of range12 %i\n", offset);
|
||||
codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg));
|
||||
}
|
||||
void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offs
|
|||
void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg);
|
||||
|
|
@ -69,6 +70,7 @@ void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offse
|
|||
void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset);
|
||||
void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg);
|
||||
|
||||
void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data);
|
||||
|
|
@ -85,6 +87,7 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data);
|
|||
|
||||
#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7))
|
||||
#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000))
|
||||
#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) & 1))
|
||||
#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3))
|
||||
#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7))
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,23 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_SEG(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);
|
||||
int offset = add_literal_q(block, (uintptr_t)uop->p);
|
||||
|
||||
if (!REG_IS_W(src_size))
|
||||
fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p);
|
||||
|
||||
host_arm64_LDR_LITERAL_X(block, REG_ARG1, offset);
|
||||
host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff);
|
||||
host_arm64_call(block, (void *)loadseg);
|
||||
host_arm64_CBNZ(block, REG_X0, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -731,6 +748,7 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop)
|
|||
const uOpFn uop_handlers[UOP_MAX] =
|
||||
{
|
||||
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[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,
|
||||
|
|
@ -776,7 +794,13 @@ void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p)
|
|||
else
|
||||
fatal("codegen_direct_read_8 - not in range\n");
|
||||
}
|
||||
|
||||
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state))
|
||||
host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
|
||||
else
|
||||
fatal("codegen_direct_read_16 - not in range\n");
|
||||
}
|
||||
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state))
|
||||
|
|
@ -792,7 +816,13 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg)
|
|||
else
|
||||
fatal("codegen_direct_write_8 - not in range\n");
|
||||
}
|
||||
|
||||
void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state))
|
||||
host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
|
||||
else
|
||||
fatal("codegen_direct_write_16 - not in range\n");
|
||||
}
|
||||
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state))
|
||||
|
|
@ -809,6 +839,13 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
|
|||
fatal("codegen_direct_write_ptr - not in range\n");
|
||||
}
|
||||
|
||||
void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
if (in_range12_h(stack_offset))
|
||||
host_arm64_LDRH_IMM(block, host_reg, REG_SP, stack_offset);
|
||||
else
|
||||
fatal("codegen_direct_read_32_stack - not in range\n");
|
||||
}
|
||||
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
if (in_range12_w(stack_offset))
|
||||
|
|
|
|||
|
|
@ -71,7 +71,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
|
||||
#define OPCODE_BFI 0xe7c00010
|
||||
#define OPCODE_BLX 0xe12fff30
|
||||
#define OPCODE_LDRH_IMM 0xe1d000b0
|
||||
#define OPCODE_LDRH_REG 0xe19000b0
|
||||
#define OPCODE_STRH_IMM 0xe1c000b0
|
||||
#define OPCODE_STRH_REG 0xe18000b0
|
||||
#define OPCODE_UADD8 0xe6500f90
|
||||
#define OPCODE_UADD16 0xe6500f10
|
||||
|
|
@ -210,6 +212,10 @@ void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int sr
|
|||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm)
|
||||
{
|
||||
|
|
@ -398,6 +404,10 @@ void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int of
|
|||
codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset));
|
||||
}
|
||||
void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg));
|
||||
|
|
@ -494,6 +504,10 @@ void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int of
|
|||
codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift));
|
||||
}
|
||||
|
||||
void host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset));
|
||||
}
|
||||
void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg)
|
||||
{
|
||||
codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);
|
||||
#define host_arm_ADD_REG(block, dst_reg, src_reg_n, src_reg_m) host_arm_ADD_REG_LSL(block, dst_reg, src_reg_n, src_reg_m, 0)
|
||||
void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
|
||||
void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
|
||||
|
||||
void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);
|
||||
void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift);
|
||||
|
|
@ -38,6 +39,7 @@ void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset
|
|||
#define host_arm_LDRB_REG(block, dst_reg, addr_reg, offset_reg) host_arm_LDRB_REG_LSL(block, dst_reg, addr_reg, offset_reg, 0)
|
||||
void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift);
|
||||
|
||||
void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset);
|
||||
void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg);
|
||||
|
||||
void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm);
|
||||
|
|
@ -65,6 +67,7 @@ void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset
|
|||
#define host_arm_STRB_REG(block, src_reg, addr_reg, offset_reg) host_arm_STRB_REG_LSL(block, src_reg, addr_reg, offset_reg, 0)
|
||||
void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift);
|
||||
|
||||
void host_arm_STRH_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset);
|
||||
void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg);
|
||||
|
||||
void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,15 @@ static inline int in_range(void *addr, void *base)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline int in_range_h(void *addr, void *base)
|
||||
{
|
||||
int diff = (uintptr_t)addr - (uintptr_t)base;
|
||||
|
||||
if (diff < 0 || diff > 255)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void host_arm_call(codeblock_t *block, void *dst_addr)
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr);
|
||||
|
|
@ -89,6 +98,11 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop)
|
|||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
|
||||
{
|
||||
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0);
|
||||
|
|
@ -258,6 +272,22 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_SEG(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))
|
||||
fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p);
|
||||
host_arm_UXTH(block, REG_ARG0, src_reg, 0);
|
||||
host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p);
|
||||
host_arm_call(block, loadseg);
|
||||
host_arm_TST_REG(block, REG_R0, REG_R0);
|
||||
host_arm_BNE(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -606,8 +636,6 @@ static int codegen_OR_IMM(codeblock_t *block, uop_t *uop)
|
|||
|
||||
static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
uint32_t arm_imm;
|
||||
|
||||
host_arm_MOV_IMM(block, REG_R0, uop->imm_data);
|
||||
|
||||
if (in_range(uop->p, &cpu_state))
|
||||
|
|
@ -670,8 +698,8 @@ static int codegen_SUB(codeblock_t *block, uop_t *uop)
|
|||
}
|
||||
else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b))
|
||||
{
|
||||
host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8);
|
||||
host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8);
|
||||
host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8);
|
||||
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
|
||||
}
|
||||
else
|
||||
|
|
@ -789,6 +817,8 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
{
|
||||
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
|
||||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[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,
|
||||
|
|
@ -826,6 +856,16 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
if (in_range_h(p, &cpu_state))
|
||||
host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
|
||||
else
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state);
|
||||
host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3);
|
||||
}
|
||||
}
|
||||
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
if (in_range(p, &cpu_state))
|
||||
|
|
@ -841,7 +881,16 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg)
|
|||
else
|
||||
fatal("codegen_direct_write_8 - not in range\n");
|
||||
}
|
||||
|
||||
void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
if (in_range_h(p, &cpu_state))
|
||||
host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
|
||||
else
|
||||
{
|
||||
host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state);
|
||||
host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3);
|
||||
}
|
||||
}
|
||||
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
if (in_range(p, &cpu_state))
|
||||
|
|
@ -858,6 +907,13 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
|
|||
fatal("codegen_direct_write_ptr - not in range\n");
|
||||
}
|
||||
|
||||
void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
if (stack_offset >= 0 && stack_offset < 256)
|
||||
host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset);
|
||||
else
|
||||
fatal("codegen_direct_read_32 - not in range\n");
|
||||
}
|
||||
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
if (stack_offset >= 0 && stack_offset < 4096)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
#define REG_AX 0
|
||||
#define REG_CX 1
|
||||
#define REG_DX 2
|
||||
#define REG_BX 3
|
||||
#define REG_SP 4
|
||||
#define REG_BP 5
|
||||
#define REG_SI 6
|
||||
#define REG_DI 7
|
||||
|
||||
#define REG_EAX 0
|
||||
#define REG_ECX 1
|
||||
#define REG_EDX 2
|
||||
|
|
|
|||
|
|
@ -395,6 +395,28 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
|||
codegen_addlong(block, (uint32_t)(uintptr_t)p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
||||
{
|
||||
int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
||||
if (src_reg & 8)
|
||||
fatal("host_x86_MOV16_ABS_REG - bad reg\n");
|
||||
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/
|
||||
}
|
||||
else if (offset < (1ull << 32))
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/
|
||||
codegen_addlong(block, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((uintptr_t)p >> 32)
|
||||
fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
||||
{
|
||||
int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
|
@ -459,6 +481,27 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_r
|
|||
codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/
|
||||
}
|
||||
|
||||
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
||||
if (dst_reg & 8)
|
||||
fatal("host_x86_MOV16_REG_ABS reg & 8\n");
|
||||
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/
|
||||
}
|
||||
else if (offset < (1ull << 32))
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/
|
||||
codegen_addlong(block, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal("host_x86_MOV16_REG_ABS - out of range\n");
|
||||
}
|
||||
}
|
||||
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
|
@ -501,10 +544,28 @@ void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int ba
|
|||
codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/
|
||||
}
|
||||
|
||||
void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
|
||||
{
|
||||
if ((dst_reg & 8) || (base_reg & 8))
|
||||
fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n");
|
||||
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
if (base_reg == REG_RSP)
|
||||
{
|
||||
codegen_addbyte(block, 0x66);
|
||||
codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset);
|
||||
}
|
||||
else
|
||||
codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset);
|
||||
}
|
||||
else
|
||||
fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset);
|
||||
}
|
||||
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
|
||||
{
|
||||
if ((dst_reg & 8) || (base_reg & 8))
|
||||
fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n");
|
||||
fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n");
|
||||
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
|
|||
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
|
||||
|
||||
void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
|
||||
|
|
@ -41,12 +42,16 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg,
|
|||
void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
|
||||
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
|
||||
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
|
||||
void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale);
|
||||
|
||||
void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
|
||||
void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data);
|
||||
void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data);
|
||||
void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data);
|
||||
|
|
@ -69,8 +74,6 @@ void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg);
|
|||
|
||||
void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p);
|
||||
|
||||
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
|
||||
void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
|
||||
void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data);
|
||||
void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data);
|
||||
|
|
|
|||
|
|
@ -191,6 +191,27 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_SEG(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))
|
||||
fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p);
|
||||
#if WIN64
|
||||
host_x86_MOV16_REG_REG(block, REG_CX, src_reg);
|
||||
host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p);
|
||||
#else
|
||||
host_x86_MOV16_REG_REG(block, REG_DI, src_reg);
|
||||
host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t)uop->p);
|
||||
#endif
|
||||
host_x86_CALL(block, (void *)loadseg);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -595,6 +616,8 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
{
|
||||
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
|
||||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[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,
|
||||
|
|
@ -632,6 +655,10 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
host_x86_MOV16_REG_ABS(block, host_reg, p);
|
||||
}
|
||||
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
host_x86_MOV32_REG_ABS(block, host_reg, p);
|
||||
|
|
@ -641,7 +668,10 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg)
|
|||
{
|
||||
host_x86_MOV8_ABS_REG(block, p, host_reg);
|
||||
}
|
||||
|
||||
void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
host_x86_MOV16_ABS_REG(block, p, host_reg);
|
||||
}
|
||||
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
host_x86_MOV32_ABS_REG(block, p, host_reg);
|
||||
|
|
@ -652,6 +682,10 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
|
|||
host_x86_MOV64_ABS_REG(block, p, host_reg);
|
||||
}
|
||||
|
||||
void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset);
|
||||
}
|
||||
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset);
|
||||
|
|
|
|||
|
|
@ -364,6 +364,20 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
|||
codegen_addlong(block, (uint32_t)p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/
|
||||
codegen_addlong(block, (uint32_t)p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
|
@ -393,6 +407,20 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg
|
|||
codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/
|
||||
}
|
||||
|
||||
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/
|
||||
}
|
||||
else
|
||||
{
|
||||
codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/
|
||||
codegen_addlong(block, (uint32_t)p);
|
||||
}
|
||||
}
|
||||
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
|
||||
{
|
||||
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
|
||||
|
|
@ -420,6 +448,21 @@ void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg
|
|||
codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/
|
||||
}
|
||||
|
||||
void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
|
||||
{
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
if (base_reg == REG_ESP)
|
||||
{
|
||||
codegen_addbyte(block, 0x66);
|
||||
codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset);
|
||||
}
|
||||
else
|
||||
codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset);
|
||||
}
|
||||
else
|
||||
fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset);
|
||||
}
|
||||
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
|
||||
{
|
||||
if (offset >= -128 && offset < 127)
|
||||
|
|
@ -435,6 +478,21 @@ void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_re
|
|||
fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset);
|
||||
}
|
||||
|
||||
void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg)
|
||||
{
|
||||
if (offset >= -128 && offset < 127)
|
||||
{
|
||||
if (base_reg == REG_ESP)
|
||||
{
|
||||
codegen_addbyte(block, 0x66);
|
||||
codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset);
|
||||
}
|
||||
else
|
||||
codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset);
|
||||
}
|
||||
else
|
||||
fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset);
|
||||
}
|
||||
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg)
|
||||
{
|
||||
if (offset >= -128 && offset < 127)
|
||||
|
|
|
|||
|
|
@ -34,20 +34,24 @@ void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
|
|||
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
|
||||
|
||||
void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg);
|
||||
|
||||
void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
|
||||
void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg);
|
||||
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg);
|
||||
|
||||
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
|
||||
void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift);
|
||||
|
||||
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
|
||||
void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data);
|
||||
|
|
@ -58,6 +62,8 @@ void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
|||
void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
#define host_x86_MOV16_STACK_REG(block, offset, src_reg) host_x86_MOV16_BASE_OFFSET_REG(block, REG_ESP, offset, src_reg)
|
||||
|
||||
void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data);
|
||||
|
||||
void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
|
|
|||
|
|
@ -194,6 +194,22 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_LOAD_SEG(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))
|
||||
fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p);
|
||||
host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg);
|
||||
host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p);
|
||||
host_x86_CALL(block, loadseg);
|
||||
host_x86_TEST32_REG(block, REG_EAX, REG_EAX);
|
||||
host_x86_JNZ(block, &block->data[BLOCK_EXIT_OFFSET]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop)
|
||||
{
|
||||
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real);
|
||||
|
|
@ -593,6 +609,8 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
{
|
||||
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC,
|
||||
|
||||
[UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG,
|
||||
|
||||
[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,
|
||||
|
|
@ -630,6 +648,10 @@ const uOpFn uop_handlers[UOP_MAX] =
|
|||
[UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ
|
||||
};
|
||||
|
||||
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
host_x86_MOV16_REG_ABS(block, host_reg, p);
|
||||
}
|
||||
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
|
||||
{
|
||||
host_x86_MOV32_REG_ABS(block, host_reg, p);
|
||||
|
|
@ -639,7 +661,10 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg)
|
|||
{
|
||||
host_x86_MOV8_ABS_REG(block, p, host_reg);
|
||||
}
|
||||
|
||||
void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
host_x86_MOV16_ABS_REG(block, p, host_reg);
|
||||
}
|
||||
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
|
||||
{
|
||||
host_x86_MOV32_ABS_REG(block, p, host_reg);
|
||||
|
|
@ -650,6 +675,10 @@ void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg)
|
|||
host_x86_MOV32_ABS_REG(block, p, host_reg);
|
||||
}
|
||||
|
||||
void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset);
|
||||
}
|
||||
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
|
||||
{
|
||||
host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER)
|
||||
#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12)
|
||||
#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13)
|
||||
/*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/
|
||||
#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER)
|
||||
/*UOP_MOV_PTR - dest_reg = p*/
|
||||
#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20)
|
||||
/*UOP_MOV_IMM - dest_reg = imm_data*/
|
||||
|
|
@ -250,6 +252,15 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p
|
|||
uop->imm_data = imm;
|
||||
}
|
||||
|
||||
static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p)
|
||||
{
|
||||
uop_t *uop = uop_alloc(ir);
|
||||
|
||||
uop->type = uop_type;
|
||||
uop->src_reg_a = codegen_reg_read(src_reg_a);
|
||||
uop->p = p;
|
||||
}
|
||||
|
||||
static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm)
|
||||
{
|
||||
uop_t *uop = uop_alloc(ir);
|
||||
|
|
@ -281,6 +292,8 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
|
|||
|
||||
#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm)
|
||||
|
||||
#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_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm)
|
||||
|
|
@ -297,13 +310,15 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
|
|||
#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm)
|
||||
#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm)
|
||||
|
||||
|
||||
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p);
|
||||
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p);
|
||||
|
||||
void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg);
|
||||
void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg);
|
||||
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg);
|
||||
void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg);
|
||||
|
||||
void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset);
|
||||
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset);
|
||||
|
||||
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg);
|
||||
|
|
|
|||
|
|
@ -3,52 +3,103 @@
|
|||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_arith.h"
|
||||
#include "codegen_ops_jump.h"
|
||||
#include "codegen_ops_logic.h"
|
||||
#include "codegen_ops_misc.h"
|
||||
#include "codegen_ops_mov.h"
|
||||
#include "codegen_ops_stack.h"
|
||||
|
||||
RecompOpFn recomp_opcodes[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, NULL, NULL, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_16, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_16, ropPOP_DS_16,
|
||||
/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, ropPOP_W,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
|
||||
|
||||
/*c0*/ NULL, NULL, 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,
|
||||
/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_16,
|
||||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, ropPUSH_ES_32, ropPOP_ES_32, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, ropPUSH_CS_32, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_SS_32, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_DS_32, ropPOP_DS_32,
|
||||
/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, ropPOP_L,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_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,
|
||||
/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFF_32
|
||||
};
|
||||
|
||||
|
||||
RecompOpFn recomp_opcodes_0f[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ rop80, rop81_w, rop80, rop83_w, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL,
|
||||
/*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*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
|
||||
/*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,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, 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,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, NULL, NULL, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, NULL, NULL,
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL,
|
||||
/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ rop80, rop81_l, rop80, rop83_l, NULL, NULL, NULL, NULL, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL,
|
||||
/*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*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_EAX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
|
||||
/*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,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, 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,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ struct ir_data_t;
|
|||
typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
extern RecompOpFn recomp_opcodes[512];
|
||||
/*extern RecompOpFn recomp_opcodes_0f[512];
|
||||
extern RecompOpFn recomp_opcodes_d8[512];
|
||||
extern RecompOpFn recomp_opcodes_0f[512];
|
||||
/*extern RecompOpFn recomp_opcodes_d8[512];
|
||||
extern RecompOpFn recomp_opcodes_d9[512];
|
||||
extern RecompOpFn recomp_opcodes_da[512];
|
||||
extern RecompOpFn recomp_opcodes_db[512];
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
|
|
@ -95,7 +95,7 @@ uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -127,7 +127,7 @@ uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
|
|
@ -158,7 +158,7 @@ uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -190,7 +190,7 @@ uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
|
|
@ -220,7 +220,7 @@ uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -291,7 +291,7 @@ uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
|
|
@ -322,7 +322,7 @@ uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B);
|
||||
|
|
@ -353,7 +353,7 @@ uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
|
|
@ -384,7 +384,7 @@ uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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_MOVZX(ir, IREG_flags_op1, IREG_temp0_W);
|
||||
|
|
@ -415,7 +415,7 @@ uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
|
|
@ -445,7 +445,7 @@ uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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_MOV(ir, IREG_flags_op1, IREG_temp0);
|
||||
|
|
@ -515,7 +515,7 @@ uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg));
|
||||
|
|
@ -546,7 +546,7 @@ uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -578,7 +578,7 @@ uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg));
|
||||
|
|
@ -609,7 +609,7 @@ uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -641,7 +641,7 @@ uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg));
|
||||
|
|
@ -671,7 +671,7 @@ uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -751,7 +751,7 @@ uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetch
|
|||
uint8_t imm;
|
||||
|
||||
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);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
if ((fetchdat & 0x38) == 0x38) /*CMP*/
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
else
|
||||
|
|
@ -880,7 +880,7 @@ uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
uint16_t imm;
|
||||
|
||||
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);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
if ((fetchdat & 0x38) == 0x38) /*CMP*/
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
else
|
||||
|
|
@ -1008,7 +1008,7 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
uint32_t imm;
|
||||
|
||||
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);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
if ((fetchdat & 0x38) == 0x38) /*CMP*/
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
else
|
||||
|
|
@ -1137,7 +1137,7 @@ uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
uint16_t imm;
|
||||
|
||||
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);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
if ((fetchdat & 0x38) == 0x38) /*CMP*/
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
else
|
||||
|
|
@ -1266,7 +1266,7 @@ uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet
|
|||
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);
|
||||
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
|
||||
if ((fetchdat & 0x38) == 0x38) /*CMP*/
|
||||
codegen_check_seg_read(block, ir, target_seg);
|
||||
else
|
||||
|
|
|
|||
43
src/codegen_ops_helpers.h
Normal file
43
src/codegen_ops_helpers.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset);
|
||||
return IREG_eaaddr;
|
||||
}
|
||||
else
|
||||
return IREG_ESP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (offset)
|
||||
{
|
||||
uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset);
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W);
|
||||
return IREG_eaaddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
return IREG_eaaddr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static inline void ADD_SP(ir_data_t *ir, int offset)
|
||||
{
|
||||
if (stack32)
|
||||
uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset);
|
||||
else
|
||||
uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset);
|
||||
}
|
||||
static inline void SUB_SP(ir_data_t *ir, int offset)
|
||||
{
|
||||
if (stack32)
|
||||
uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset);
|
||||
else
|
||||
uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset);
|
||||
}
|
||||
130
src/codegen_ops_jump.c
Normal file
130
src/codegen_ops_jump.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "x86.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_helpers.h"
|
||||
#include "codegen_ops_mov.h"
|
||||
|
||||
uint32_t ropJMP_r8(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)(int8_t)fastreadb(cs + op_pc);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc+1+offset);
|
||||
return -1;
|
||||
}
|
||||
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 offset = (int32_t)(int16_t)fastreadw(cs + op_pc);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc+2+offset);
|
||||
return -1;
|
||||
}
|
||||
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 offset = fastreadl(cs + op_pc);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_pc, op_pc+4+offset);
|
||||
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);
|
||||
uint16_t ret_addr = op_pc + 2;
|
||||
uint16_t dest_addr = ret_addr + offset;
|
||||
int sp_reg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
||||
uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr);
|
||||
SUB_SP(ir, 2);
|
||||
uop_MOV_IMM(ir, IREG_pc, dest_addr);
|
||||
|
||||
return -1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
uint32_t ret_addr = op_pc + 4;
|
||||
uint32_t dest_addr = ret_addr + offset;
|
||||
int sp_reg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -4);
|
||||
uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr);
|
||||
SUB_SP(ir, 4);
|
||||
uop_MOV_IMM(ir, IREG_pc, dest_addr);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t ropRET_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_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
ADD_SP(ir, 2);
|
||||
uop_MOVZX(ir, IREG_pc, IREG_temp0_W);
|
||||
|
||||
return -1;
|
||||
}
|
||||
uint32_t ropRET_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_pc, IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
ADD_SP(ir, 4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
uint16_t 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);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
ADD_SP(ir, 2+offset);
|
||||
uop_MOVZX(ir, IREG_pc, IREG_temp0_W);
|
||||
|
||||
return -1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
uint16_t offset = fastreadw(cs + op_pc);
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
ADD_SP(ir, 4+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
12
src/codegen_ops_jump.h
Normal file
12
src/codegen_ops_jump.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
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 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);
|
||||
|
||||
uint32_t ropRET_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_32(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_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);
|
||||
|
|
@ -56,7 +56,7 @@ uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B);
|
||||
|
|
@ -84,7 +84,7 @@ uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -113,7 +113,7 @@ uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W);
|
||||
|
|
@ -141,7 +141,7 @@ uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -170,7 +170,7 @@ uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
|
||||
|
|
@ -198,7 +198,7 @@ uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -261,7 +261,7 @@ uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B);
|
||||
|
|
@ -289,7 +289,7 @@ uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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);
|
||||
|
|
@ -318,7 +318,7 @@ uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W);
|
||||
|
|
@ -346,7 +346,7 @@ uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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);
|
||||
|
|
@ -375,7 +375,7 @@ uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
|
||||
|
|
@ -403,7 +403,7 @@ uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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);
|
||||
|
|
@ -466,7 +466,7 @@ uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_B, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B);
|
||||
|
|
@ -494,7 +494,7 @@ uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -523,7 +523,7 @@ uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W);
|
||||
|
|
@ -551,7 +551,7 @@ uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
@ -580,7 +580,7 @@ uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
|
||||
|
|
@ -608,7 +608,7 @@ uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
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);
|
||||
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);
|
||||
|
|
|
|||
101
src/codegen_ops_misc.c
Normal file
101
src/codegen_ops_misc.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "x86.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_helpers.h"
|
||||
#include "codegen_ops_misc.h"
|
||||
|
||||
uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int src_reg, sp_reg;
|
||||
|
||||
if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30)
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
src_reg = IREG_16(fetchdat & 7);
|
||||
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_read(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
src_reg = IREG_temp0_W;
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*CALL*/
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
||||
uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1);
|
||||
SUB_SP(ir, 2);
|
||||
uop_MOVZX(ir, IREG_pc, src_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
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);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg);
|
||||
SUB_SP(ir, 2);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int src_reg, sp_reg;
|
||||
|
||||
if ((fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x30)
|
||||
return 0;
|
||||
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
src_reg = IREG_32(fetchdat & 7);
|
||||
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_read(block, ir, target_seg);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
src_reg = IREG_temp0;
|
||||
}
|
||||
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x10: /*CALL*/
|
||||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -4);
|
||||
uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1);
|
||||
SUB_SP(ir, 4);
|
||||
uop_MOV(ir, IREG_pc, src_reg);
|
||||
return -1;
|
||||
|
||||
case 0x20: /*JMP*/
|
||||
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);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -4);
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg);
|
||||
SUB_SP(ir, 4);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
2
src/codegen_ops_misc.h
Normal file
2
src/codegen_ops_misc.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
@ -48,7 +48,7 @@ uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg));
|
||||
}
|
||||
|
|
@ -69,7 +69,7 @@ uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg));
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg));
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
|
|
@ -153,7 +153,7 @@ uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
|
|||
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);
|
||||
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_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
}
|
||||
|
|
@ -268,7 +268,7 @@ uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
else
|
||||
{
|
||||
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);
|
||||
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);
|
||||
imm = fastreadb(cs + op_pc + 1);
|
||||
uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm);
|
||||
|
|
@ -291,7 +291,7 @@ uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
else
|
||||
{
|
||||
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);
|
||||
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);
|
||||
imm = fastreadw(cs + op_pc + 1);
|
||||
uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm);
|
||||
|
|
@ -314,7 +314,7 @@ uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
|
|||
else
|
||||
{
|
||||
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);
|
||||
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);
|
||||
imm = fastreadl(cs + op_pc + 1);
|
||||
uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm);
|
||||
|
|
|
|||
207
src/codegen_ops_stack.c
Normal file
207
src/codegen_ops_stack.c
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
#include "ibm.h"
|
||||
|
||||
#include "x86.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ir.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_ops_helpers.h"
|
||||
#include "codegen_ops_misc.h"
|
||||
|
||||
uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int sp_reg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2);
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7));
|
||||
SUB_SP(ir, 2);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
int sp_reg;
|
||||
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -4);
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7));
|
||||
SUB_SP(ir, 4);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
uint32_t ropPOP_r16(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_16(opcode & 7), IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
if ((opcode & 7) != REG_SP)
|
||||
ADD_SP(ir, 2);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
uint32_t ropPOP_r32(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_32(opcode & 7), IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
if ((opcode & 7) != REG_ESP)
|
||||
ADD_SP(ir, 4);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
uint32_t ropPOP_W(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 ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_temp0, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0);
|
||||
}
|
||||
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W);
|
||||
}
|
||||
|
||||
if ((fetchdat & 0xc7) != (0xc0 | REG_SP))
|
||||
ADD_SP(ir, 2);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
uint32_t ropPOP_L(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 ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4);
|
||||
codegen_check_seg_write(block, ir, target_seg);
|
||||
|
||||
if (stack32)
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP);
|
||||
else
|
||||
{
|
||||
uop_MOVZX(ir, IREG_temp0, IREG_SP);
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0);
|
||||
}
|
||||
|
||||
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
|
||||
}
|
||||
|
||||
if ((fetchdat & 0xc7) != (0xc0 | REG_ESP))
|
||||
ADD_SP(ir, 4);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
#define ROP_PUSH_SEG(seg) \
|
||||
uint32_t ropPUSH_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \
|
||||
{ \
|
||||
int sp_reg; \
|
||||
\
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_ ## seg ## _seg_W); \
|
||||
SUB_SP(ir, 2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
uint32_t ropPUSH_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \
|
||||
{ \
|
||||
int sp_reg; \
|
||||
\
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \
|
||||
sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \
|
||||
uop_MOVZX(ir, IREG_temp0, IREG_ ## seg ## _seg_W); \
|
||||
uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \
|
||||
SUB_SP(ir, 4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
#define ROP_POP_SEG(seg, rseg) \
|
||||
uint32_t ropPOP_ ## seg ## _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_ESP); \
|
||||
else \
|
||||
{ \
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \
|
||||
} \
|
||||
uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \
|
||||
ADD_SP(ir, 2); \
|
||||
\
|
||||
return op_pc; \
|
||||
} \
|
||||
uint32_t ropPOP_ ## seg ## _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_W, IREG_SS_base, IREG_ESP); \
|
||||
else \
|
||||
{ \
|
||||
uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \
|
||||
uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \
|
||||
} \
|
||||
uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \
|
||||
ADD_SP(ir, 4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
|
||||
ROP_PUSH_SEG(CS)
|
||||
ROP_PUSH_SEG(DS)
|
||||
ROP_PUSH_SEG(ES)
|
||||
ROP_PUSH_SEG(FS)
|
||||
ROP_PUSH_SEG(GS)
|
||||
ROP_PUSH_SEG(SS)
|
||||
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)
|
||||
32
src/codegen_ops_stack.h
Normal file
32
src/codegen_ops_stack.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropPUSH_CS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_DS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_ES_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_FS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_GS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_SS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropPUSH_CS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_DS_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPUSH_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 ropPUSH_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 ropPUSH_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 ropPUSH_SS_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_DS_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropPOP_ES_16(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_16(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_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
||||
uint32_t ropPOP_DS_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_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);
|
||||
|
|
@ -64,6 +64,13 @@ struct
|
|||
[IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base},
|
||||
[IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base},
|
||||
|
||||
[IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg},
|
||||
[IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg},
|
||||
[IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg},
|
||||
[IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg},
|
||||
[IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg},
|
||||
[IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg},
|
||||
|
||||
/*Temporary registers are stored on the stack, and are not guaranteed to
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
not be read again.*/
|
||||
|
|
@ -98,6 +105,13 @@ static void codegen_reg_load(codeblock_t *block, int c, ir_reg_t ir_reg)
|
|||
{
|
||||
switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size)
|
||||
{
|
||||
case REG_WORD:
|
||||
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
|
||||
codegen_direct_read_16_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
|
||||
else
|
||||
codegen_direct_read_16(block, codegen_host_reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
|
||||
break;
|
||||
|
||||
case REG_DWORD:
|
||||
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
|
||||
codegen_direct_read_32_stack(block, codegen_host_reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
|
||||
|
|
@ -126,6 +140,12 @@ static void codegen_reg_writeback(codeblock_t *block, int c, int invalidate)
|
|||
codegen_direct_write_8(block, p, codegen_host_reg_list[c]);
|
||||
break;
|
||||
|
||||
case REG_WORD:
|
||||
if ((uintptr_t)p < 256)
|
||||
fatal("codegen_reg_writeback - REG_WORD %p\n", p);
|
||||
codegen_direct_write_16(block, p, codegen_host_reg_list[c]);
|
||||
break;
|
||||
|
||||
case REG_DWORD:
|
||||
if ((uintptr_t)p < 256)
|
||||
codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]);
|
||||
|
|
|
|||
|
|
@ -49,13 +49,20 @@ enum
|
|||
IREG_GS_base = 25,
|
||||
IREG_SS_base = 26,
|
||||
|
||||
IREG_CS_seg = 27,
|
||||
IREG_DS_seg = 28,
|
||||
IREG_ES_seg = 29,
|
||||
IREG_FS_seg = 30,
|
||||
IREG_GS_seg = 31,
|
||||
IREG_SS_seg = 32,
|
||||
|
||||
/*Temporary registers are stored on the stack, and are not guaranteed to
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
not be read again.*/
|
||||
IREG_temp0 = 27,
|
||||
IREG_temp1 = 28,
|
||||
IREG_temp2 = 29,
|
||||
IREG_temp3 = 30,
|
||||
IREG_temp0 = 33,
|
||||
IREG_temp1 = 34,
|
||||
IREG_temp2 = 35,
|
||||
IREG_temp3 = 36,
|
||||
|
||||
IREG_COUNT,
|
||||
|
||||
|
|
@ -88,7 +95,16 @@ enum
|
|||
IREG_temp1_W = IREG_temp1 + IREG_SIZE_W,
|
||||
|
||||
IREG_temp0_B = IREG_temp0 + IREG_SIZE_B,
|
||||
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B
|
||||
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B,
|
||||
|
||||
IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W,
|
||||
|
||||
IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W,
|
||||
IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W,
|
||||
IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W,
|
||||
IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W,
|
||||
IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W,
|
||||
IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W
|
||||
};
|
||||
|
||||
#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ uint8_t *pccache2;
|
|||
|
||||
#define CPL ((cpu_state.seg_cs.access>>5)&3)
|
||||
|
||||
void loadseg(uint16_t seg, x86seg *s);
|
||||
int loadseg(uint16_t seg, x86seg *s);
|
||||
void loadcs(uint16_t seg);
|
||||
|
||||
union
|
||||
|
|
|
|||
28
src/x86seg.c
28
src/x86seg.c
|
|
@ -309,7 +309,7 @@ static void check_seg_valid(x86seg *s)
|
|||
loadseg(0, s);
|
||||
}
|
||||
|
||||
void loadseg(uint16_t seg, x86seg *s)
|
||||
int loadseg(uint16_t seg, x86seg *s)
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
|
|
@ -324,7 +324,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
{
|
||||
pclog("SS selector = NULL!\n");
|
||||
x86ss(NULL,0);
|
||||
return;
|
||||
return 1;
|
||||
// dumpregs();
|
||||
// exit(-1);
|
||||
}
|
||||
|
|
@ -335,7 +335,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
if (s == &cpu_state.seg_ds)
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
// pclog("NULL selector %s%s%s%s %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,pc);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
// if (s==&_ss) pclog("Load SS %04X\n",seg);
|
||||
// pclog("Protected mode seg load!\n");
|
||||
|
|
@ -349,7 +349,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
// dumpregs();
|
||||
// exit(-1);
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
addr+=ldt.base;
|
||||
}
|
||||
|
|
@ -361,7 +361,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
// dumpregs();
|
||||
// exit(-1);
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
addr+=gdt.base;
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
segdat[0]=readmemw(0,addr);
|
||||
segdat[1]=readmemw(0,addr+2);
|
||||
segdat[2]=readmemw(0,addr+4);
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return 1;
|
||||
dpl=(segdat[2]>>13)&3;
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
|
|
@ -377,14 +377,14 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
{
|
||||
pclog("Load SS null selector\n");
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if ((seg&3)!=CPL || dpl!=CPL)
|
||||
{
|
||||
pclog("Invalid SS permiss\n");
|
||||
x86gpf(NULL,seg&~3);
|
||||
// x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
switch ((segdat[2]>>8)&0x1F)
|
||||
{
|
||||
|
|
@ -394,13 +394,13 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
pclog("Invalid SS type\n");
|
||||
x86gpf(NULL,seg&~3);
|
||||
// x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
if (!(segdat[2]&0x8000))
|
||||
{
|
||||
pclog("Load SS not present!\n");
|
||||
x86ss(NULL,seg&~3);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
// pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]);
|
||||
|
|
@ -420,7 +420,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]);
|
||||
x86gpf(NULL,seg&~3);
|
||||
// x86abort("Data segment load - level too low!\n",seg&0xFFFC);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 0x1E: case 0x1F: /*Readable conforming code*/
|
||||
|
|
@ -428,14 +428,14 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
default:
|
||||
pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]);
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(segdat[2] & 0x8000))
|
||||
{
|
||||
x86np("Load data seg not present", seg & 0xfffc);
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
s->seg = seg;
|
||||
do_seg_load(s, segdat);
|
||||
|
|
@ -486,6 +486,8 @@ void loadseg(uint16_t seg, x86seg *s)
|
|||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
}
|
||||
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
#define DPL ((segdat[2]>>13)&3)
|
||||
|
|
|
|||
Loading…
Reference in a new issue