Added recompiled versions of JMP, CALL, RET, PUSH and POP.

This commit is contained in:
SarahW 2018-08-05 16:24:15 +01:00
commit f1df9be8f6
33 changed files with 1062 additions and 102 deletions

View file

@ -24,7 +24,8 @@ wx-resources.cpp : pc.xrc
# PCem # 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 \ 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 \ 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 \ 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 \ joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \

View file

@ -238,14 +238,14 @@ static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uin
return op_ea_seg; 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_mod = (fetchdat >> 6) & 3;
cpu_reg = (fetchdat >> 3) & 7; cpu_reg = (fetchdat >> 3) & 7;
cpu_rm = fetchdat & 7; cpu_rm = fetchdat & 7;
if (op_32 & 0x200) 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); 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: case 0x0f:
op_table = x86_dynarec_opcodes_0f; op_table = x86_dynarec_opcodes_0f;
recomp_op_table = NULL;//recomp_opcodes_0f; recomp_op_table = recomp_opcodes_0f;
over = 1; over = 1;
break; break;

View file

@ -264,7 +264,7 @@ void codegen_set_op32();
void codegen_flush(); void codegen_flush();
void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr);
struct ir_data_t; 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_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); void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg);

View file

@ -56,11 +56,13 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_BFI (0x0cc << 22) #define OPCODE_BFI (0x0cc << 22)
#define OPCODE_LDR_IMM_W (0x2e5 << 22) #define OPCODE_LDR_IMM_W (0x2e5 << 22)
#define OPCODE_LDRB_IMM_W (0x0e5 << 22) #define OPCODE_LDRB_IMM_W (0x0e5 << 22)
#define OPCODE_LDRH_IMM (0x1e5 << 22)
#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22)
#define OPCODE_STP_PREIDX_X (0x2a6 << 22) #define OPCODE_STP_PREIDX_X (0x2a6 << 22)
#define OPCODE_STR_IMM_W (0x2e4 << 22) #define OPCODE_STR_IMM_W (0x2e4 << 22)
#define OPCODE_STR_IMM_Q (0x3e4 << 22) #define OPCODE_STR_IMM_Q (0x3e4 << 22)
#define OPCODE_STRB_IMM (0x0e4 << 22) #define OPCODE_STRB_IMM (0x0e4 << 22)
#define OPCODE_STRH_IMM (0x1e4 << 22)
#define OPCODE_UBFX (0x14c << 22) #define OPCODE_UBFX (0x14c << 22)
#define OPCODE_ADD_LSL (0x058 << 21) #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 OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0)
#define OFFSET12_B(offset) (offset << 10) #define OFFSET12_B(offset) (offset << 10)
#define OFFSET12_H(offset) ((offset >> 1) << 10)
#define OFFSET12_W(offset) ((offset >> 2) << 10) #define OFFSET12_W(offset) ((offset >> 2) << 10)
#define OFFSET12_Q(offset) ((offset >> 3) << 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)); 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) 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)); 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)); 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) 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)); codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg));

View file

@ -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_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_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_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); 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_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_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_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); 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_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7))
#define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) #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_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3))
#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) #define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7))

View file

@ -208,6 +208,23 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
return 0; 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) 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); 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] = const uOpFn uop_handlers[UOP_MAX] =
{ {
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, [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_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_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 else
fatal("codegen_direct_read_8 - not in range\n"); 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) void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
{ {
if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) 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 else
fatal("codegen_direct_write_8 - not in range\n"); 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) void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
{ {
if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) 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"); 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) void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
{ {
if (in_range12_w(stack_offset)) if (in_range12_w(stack_offset))

View file

@ -71,7 +71,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_BFI 0xe7c00010 #define OPCODE_BFI 0xe7c00010
#define OPCODE_BLX 0xe12fff30 #define OPCODE_BLX 0xe12fff30
#define OPCODE_LDRH_IMM 0xe1d000b0
#define OPCODE_LDRH_REG 0xe19000b0 #define OPCODE_LDRH_REG 0xe19000b0
#define OPCODE_STRH_IMM 0xe1c000b0
#define OPCODE_STRH_REG 0xe18000b0 #define OPCODE_STRH_REG 0xe18000b0
#define OPCODE_UADD8 0xe6500f90 #define OPCODE_UADD8 0xe6500f90
#define OPCODE_UADD16 0xe6500f10 #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)); 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) 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)); 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) 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)); 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)); 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) 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)); codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg));

View file

@ -1,6 +1,7 @@
void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); 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) #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_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_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); 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) #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_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_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); 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) #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_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_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); void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm);

View file

@ -47,6 +47,15 @@ static inline int in_range(void *addr, void *base)
return 1; 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) void host_arm_call(codeblock_t *block, void *dst_addr)
{ {
host_arm_MOV_IMM(block, REG_R3, (uintptr_t)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_UXTB(block, REG_TEMP, src_reg_b, 8);
host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); 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) else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a)
{ {
host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); host_arm_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; 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) 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); 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) 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); host_arm_MOV_IMM(block, REG_R0, uop->imm_data);
if (in_range(uop->p, &cpu_state)) 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)) 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, src_reg_a, 8);
host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 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); host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
} }
else else
@ -789,6 +817,8 @@ const uOpFn uop_handlers[UOP_MAX] =
{ {
[UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, [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_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_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_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 [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) void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
{ {
if (in_range(p, &cpu_state)) if (in_range(p, &cpu_state))
@ -841,7 +881,16 @@ void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg)
else else
fatal("codegen_direct_write_8 - not in range\n"); 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) void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
{ {
if (in_range(p, &cpu_state)) 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"); 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) void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset)
{ {
if (stack_offset >= 0 && stack_offset < 4096) if (stack_offset >= 0 && stack_offset < 4096)

View file

@ -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_EAX 0
#define REG_ECX 1 #define REG_ECX 1
#define REG_EDX 2 #define REG_EDX 2

View file

@ -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); 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) 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); 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*/ 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) void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
{ {
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); 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]*/ 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) 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)) 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) if (offset >= -128 && offset < 127)
{ {

View file

@ -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_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_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_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); 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_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_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_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_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_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_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_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); 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_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_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_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); void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data);

View file

@ -191,6 +191,27 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
return 0; 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) 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); 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_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_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_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_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 [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) void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOV32_REG_ABS(block, host_reg, 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); 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) void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
{ {
host_x86_MOV32_ABS_REG(block, p, 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); 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) 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); host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset);

View file

@ -364,6 +364,20 @@ void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg)
codegen_addlong(block, (uint32_t)p); 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) void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg)
{ {
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); 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*/ 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) void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
{ {
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); 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]*/ 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) void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset)
{ {
if (offset >= -128 && offset < 127) 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); 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) void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg)
{ {
if (offset >= -128 && offset < 127) if (offset >= -128 && offset < 127)

View file

@ -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_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_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_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_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_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOV32_BASE_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_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(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_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift);
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOV32_REG_BASE_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_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_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_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); 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_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); void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);

View file

@ -194,6 +194,22 @@ static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop)
return 0; 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) 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); 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_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_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_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM,
[UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_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 [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) void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOV32_REG_ABS(block, host_reg, 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); 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) void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
{ {
host_x86_MOV32_ABS_REG(block, p, 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); 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) 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); host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset);

View file

@ -39,6 +39,8 @@
#define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) #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 (UOP_TYPE_PARAMS_IMM | 0x12)
#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) #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*/ /*UOP_MOV_PTR - dest_reg = p*/
#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20)
/*UOP_MOV_IMM - dest_reg = imm_data*/ /*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; 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) 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); 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_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_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm)
#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg) #define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2(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) #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(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) #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_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_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_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_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_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); void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg);

View file

@ -3,52 +3,103 @@
#include "codegen_ir.h" #include "codegen_ir.h"
#include "codegen_ops.h" #include "codegen_ops.h"
#include "codegen_ops_arith.h" #include "codegen_ops_arith.h"
#include "codegen_ops_jump.h"
#include "codegen_ops_logic.h" #include "codegen_ops_logic.h"
#include "codegen_ops_misc.h"
#include "codegen_ops_mov.h" #include "codegen_ops_mov.h"
#include "codegen_ops_stack.h"
RecompOpFn recomp_opcodes[512] = RecompOpFn recomp_opcodes[512] =
{ {
/*16-bit data*/ /*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /* 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, /*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 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, /*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, /*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, /*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, /*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, /*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, /*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, /*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, /*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*/ 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, /*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, /*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, /*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,
/*32-bit data*/ /*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /* 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, /*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, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 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, /*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, /*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, /*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, /*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, /*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, /*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, /*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*/ 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, /*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, /*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, /*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,
}; };

View file

@ -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); 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[512];
/*extern RecompOpFn recomp_opcodes_0f[512]; extern RecompOpFn recomp_opcodes_0f[512];
extern RecompOpFn recomp_opcodes_d8[512]; /*extern RecompOpFn recomp_opcodes_d8[512];
extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_d9[512];
extern RecompOpFn recomp_opcodes_da[512]; extern RecompOpFn recomp_opcodes_da[512];
extern RecompOpFn recomp_opcodes_db[512]; extern RecompOpFn recomp_opcodes_db[512];

View file

@ -64,7 +64,7 @@ uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
x86seg *target_seg; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); 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)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOV(ir, IREG_flags_op1, IREG_temp0); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); 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)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); 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; uint8_t imm;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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*/ if ((fetchdat & 0x38) == 0x38) /*CMP*/
codegen_check_seg_read(block, ir, target_seg); codegen_check_seg_read(block, ir, target_seg);
else 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; uint16_t imm;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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*/ if ((fetchdat & 0x38) == 0x38) /*CMP*/
codegen_check_seg_read(block, ir, target_seg); codegen_check_seg_read(block, ir, target_seg);
else 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; uint32_t imm;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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*/ if ((fetchdat & 0x38) == 0x38) /*CMP*/
codegen_check_seg_read(block, ir, target_seg); codegen_check_seg_read(block, ir, target_seg);
else 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; uint16_t imm;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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*/ if ((fetchdat & 0x38) == 0x38) /*CMP*/
codegen_check_seg_read(block, ir, target_seg); codegen_check_seg_read(block, ir, target_seg);
else 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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*/ if ((fetchdat & 0x38) == 0x38) /*CMP*/
codegen_check_seg_read(block, ir, target_seg); codegen_check_seg_read(block, ir, target_seg);
else else

43
src/codegen_ops_helpers.h Normal file
View 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
View 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
View 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);

View file

@ -56,7 +56,7 @@ uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
x86seg *target_seg; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
@ -198,7 +198,7 @@ uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
x86seg *target_seg; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0);
@ -608,7 +608,7 @@ uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_
x86seg *target_seg; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);

101
src/codegen_ops_misc.c Normal file
View 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
View 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);

View file

@ -48,7 +48,7 @@ uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t
x86seg *target_seg; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); 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; x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); 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 else
{ {
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
imm = fastreadb(cs + op_pc + 1); imm = fastreadb(cs + op_pc + 1);
uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); 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 else
{ {
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
imm = fastreadw(cs + op_pc + 1); imm = fastreadw(cs + op_pc + 1);
uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); 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 else
{ {
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); 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); codegen_check_seg_write(block, ir, target_seg);
imm = fastreadl(cs + op_pc + 1); imm = fastreadl(cs + op_pc + 1);
uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm);

207
src/codegen_ops_stack.c Normal file
View 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
View 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);

View file

@ -64,6 +64,13 @@ struct
[IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base}, [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base},
[IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.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 /*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 be preserved across uOPs. They will not be written back if they will
not be read again.*/ 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) 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: case REG_DWORD:
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) 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); 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]); codegen_direct_write_8(block, p, codegen_host_reg_list[c]);
break; 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: case REG_DWORD:
if ((uintptr_t)p < 256) if ((uintptr_t)p < 256)
codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]); codegen_direct_write_32_stack(block, (int)p, codegen_host_reg_list[c]);

View file

@ -49,13 +49,20 @@ enum
IREG_GS_base = 25, IREG_GS_base = 25,
IREG_SS_base = 26, 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 /*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 be preserved across uOPs. They will not be written back if they will
not be read again.*/ not be read again.*/
IREG_temp0 = 27, IREG_temp0 = 33,
IREG_temp1 = 28, IREG_temp1 = 34,
IREG_temp2 = 29, IREG_temp2 = 35,
IREG_temp3 = 30, IREG_temp3 = 36,
IREG_COUNT, IREG_COUNT,
@ -88,7 +95,16 @@ enum
IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, IREG_temp1_W = IREG_temp1 + IREG_SIZE_W,
IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, 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)) #define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL))

View file

@ -236,7 +236,7 @@ uint8_t *pccache2;
#define CPL ((cpu_state.seg_cs.access>>5)&3) #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); void loadcs(uint16_t seg);
union union

View file

@ -309,7 +309,7 @@ static void check_seg_valid(x86seg *s)
loadseg(0, s); loadseg(0, s);
} }
void loadseg(uint16_t seg, x86seg *s) int loadseg(uint16_t seg, x86seg *s)
{ {
uint16_t segdat[4]; uint16_t segdat[4];
uint32_t addr; uint32_t addr;
@ -324,7 +324,7 @@ void loadseg(uint16_t seg, x86seg *s)
{ {
pclog("SS selector = NULL!\n"); pclog("SS selector = NULL!\n");
x86ss(NULL,0); x86ss(NULL,0);
return; return 1;
// dumpregs(); // dumpregs();
// exit(-1); // exit(-1);
} }
@ -335,7 +335,7 @@ void loadseg(uint16_t seg, x86seg *s)
if (s == &cpu_state.seg_ds) if (s == &cpu_state.seg_ds)
cpu_cur_status |= CPU_STATUS_NOTFLATDS; 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); // 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); // if (s==&_ss) pclog("Load SS %04X\n",seg);
// pclog("Protected mode seg load!\n"); // pclog("Protected mode seg load!\n");
@ -349,7 +349,7 @@ void loadseg(uint16_t seg, x86seg *s)
// dumpregs(); // dumpregs();
// exit(-1); // exit(-1);
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
return; return 1;
} }
addr+=ldt.base; addr+=ldt.base;
} }
@ -361,7 +361,7 @@ void loadseg(uint16_t seg, x86seg *s)
// dumpregs(); // dumpregs();
// exit(-1); // exit(-1);
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
return; return 1;
} }
addr+=gdt.base; addr+=gdt.base;
} }
@ -369,7 +369,7 @@ void loadseg(uint16_t seg, x86seg *s)
segdat[0]=readmemw(0,addr); segdat[0]=readmemw(0,addr);
segdat[1]=readmemw(0,addr+2); segdat[1]=readmemw(0,addr+2);
segdat[2]=readmemw(0,addr+4); 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; dpl=(segdat[2]>>13)&3;
if (s==&cpu_state.seg_ss) if (s==&cpu_state.seg_ss)
{ {
@ -377,14 +377,14 @@ void loadseg(uint16_t seg, x86seg *s)
{ {
pclog("Load SS null selector\n"); pclog("Load SS null selector\n");
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
return; return 1;
} }
if ((seg&3)!=CPL || dpl!=CPL) if ((seg&3)!=CPL || dpl!=CPL)
{ {
pclog("Invalid SS permiss\n"); pclog("Invalid SS permiss\n");
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
// x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC); // x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC);
return; return 1;
} }
switch ((segdat[2]>>8)&0x1F) switch ((segdat[2]>>8)&0x1F)
{ {
@ -394,13 +394,13 @@ void loadseg(uint16_t seg, x86seg *s)
pclog("Invalid SS type\n"); pclog("Invalid SS type\n");
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
// x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC); // x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC);
return; return 1;
} }
if (!(segdat[2]&0x8000)) if (!(segdat[2]&0x8000))
{ {
pclog("Load SS not present!\n"); pclog("Load SS not present!\n");
x86ss(NULL,seg&~3); x86ss(NULL,seg&~3);
return; return 1;
} }
set_stack32((segdat[3] & 0x40) ? 1 : 0); set_stack32((segdat[3] & 0x40) ? 1 : 0);
// pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]); // 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]); pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]);
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
// x86abort("Data segment load - level too low!\n",seg&0xFFFC); // x86abort("Data segment load - level too low!\n",seg&0xFFFC);
return; return 1;
} }
break; break;
case 0x1E: case 0x1F: /*Readable conforming code*/ case 0x1E: case 0x1F: /*Readable conforming code*/
@ -428,14 +428,14 @@ void loadseg(uint16_t seg, x86seg *s)
default: default:
pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]); pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]);
x86gpf(NULL,seg&~3); x86gpf(NULL,seg&~3);
return; return 1;
} }
} }
if (!(segdat[2] & 0x8000)) if (!(segdat[2] & 0x8000))
{ {
x86np("Load data seg not present", seg & 0xfffc); x86np("Load data seg not present", seg & 0xfffc);
return; return 1;
} }
s->seg = seg; s->seg = seg;
do_seg_load(s, segdat); do_seg_load(s, segdat);
@ -486,6 +486,8 @@ void loadseg(uint16_t seg, x86seg *s)
else else
cpu_cur_status |= CPU_STATUS_NOTFLATSS; cpu_cur_status |= CPU_STATUS_NOTFLATSS;
} }
return cpu_state.abrt;
} }
#define DPL ((segdat[2]>>13)&3) #define DPL ((segdat[2]>>13)&3)