From fc27be592cbf548168853b37ffc08c159ed72f8c Mon Sep 17 00:00:00 2001 From: SarahW Date: Sun, 8 Jul 2018 16:36:11 +0100 Subject: [PATCH] Added recompiled versions of immediate->reg and reg->reg versions of MOV, ADD, SUB, CMP, AND, OR and XOR. --- src/Makefile.am | 2 +- src/codegen.c | 39 ++-- src/codegen_backend_arm64_uops.c | 116 +++++++++++- src/codegen_backend_arm_uops.c | 107 ++++++++++- src/codegen_backend_x86-64_uops.c | 175 +++++++++++++++++- src/codegen_backend_x86_uops.c | 218 ++++++++++++++++++++--- src/codegen_ir_defs.h | 25 ++- src/codegen_ops.c | 54 ++++++ src/codegen_ops.h | 10 +- src/codegen_ops_arith.c | 285 ++++++++++++++++++++++++++++++ src/codegen_ops_arith.h | 14 ++ src/codegen_ops_logic.c | 129 ++++++++++++++ src/codegen_ops_logic.h | 11 ++ src/codegen_ops_mov.c | 48 +++++ src/codegen_ops_mov.h | 3 + src/codegen_reg.c | 2 +- src/codegen_reg.h | 2 + 17 files changed, 1169 insertions(+), 71 deletions(-) create mode 100644 src/codegen_ops.c create mode 100644 src/codegen_ops_arith.c create mode 100644 src/codegen_ops_arith.h create mode 100644 src/codegen_ops_logic.c create mode 100644 src/codegen_ops_logic.h create mode 100644 src/codegen_ops_mov.c create mode 100644 src/codegen_ops_mov.h diff --git a/src/Makefile.am b/src/Makefile.am index e0b6458..ab44ff7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ wx-resources.cpp : pc.xrc # PCem pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acc2036.c acer386sx.c ali1429.c amstrad.c cbm_io.c cdrom-image.cc cdrom-null.c \ -cmd640.c codegen.c codegen_accumulate.c codegen_backend.c codegen_ir.c codegen_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_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 \ dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c esdi_at.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c hdd_file.c headland.c i430lx.c i430fx.c i430vx.c ide.c ide_atapi.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ diff --git a/src/codegen.c b/src/codegen.c index 87184da..2255d85 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -9,6 +9,7 @@ #include "codegen_accumulate.h" #include "codegen_backend.h" #include "codegen_ir.h" +#include "codegen_ops.h" int has_ea; @@ -252,6 +253,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t ir_data_t *ir = codegen_get_ir_data(); uint32_t op_pc = new_pc; OpFn *op_table = x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; int opcode_shift = 0; int opcode_mask = 0x3ff; uint32_t op_32 = use32; @@ -271,7 +273,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t { case 0x0f: op_table = x86_dynarec_opcodes_0f; -// recomp_op_table = recomp_opcodes_0f; + recomp_op_table = NULL;//recomp_opcodes_0f; over = 1; break; @@ -309,7 +311,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xd8: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; -// recomp_op_table = recomp_opcodes_d8; + recomp_op_table = NULL;//recomp_opcodes_d8; opcode_shift = 3; opcode_mask = 0x1f; over = 1; @@ -319,7 +321,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xd9: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; -// recomp_op_table = recomp_opcodes_d9; + recomp_op_table = NULL;//recomp_opcodes_d9; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -328,7 +330,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xda: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; -// recomp_op_table = recomp_opcodes_da; + recomp_op_table = NULL;//recomp_opcodes_da; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -337,7 +339,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdb: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; -// recomp_op_table = recomp_opcodes_db; + recomp_op_table = NULL;//recomp_opcodes_db; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -346,7 +348,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdc: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; -// recomp_op_table = recomp_opcodes_dc; + recomp_op_table = NULL;//recomp_opcodes_dc; opcode_shift = 3; opcode_mask = 0x1f; over = 1; @@ -356,7 +358,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdd: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; -// recomp_op_table = recomp_opcodes_dd; + recomp_op_table = NULL;//recomp_opcodes_dd; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -365,7 +367,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xde: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; -// recomp_op_table = recomp_opcodes_de; + recomp_op_table = NULL;//recomp_opcodes_de; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -374,7 +376,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xdf: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; -// recomp_op_table = recomp_opcodes_df; + recomp_op_table = NULL;//recomp_opcodes_df; opcode_mask = 0xff; over = 1; pc_off = -1; @@ -387,11 +389,11 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t case 0xf2: /*REPNE*/ op_table = x86_dynarec_opcodes_REPNE; -// recomp_op_table = recomp_opcodes_REPNE; + recomp_op_table = NULL;//recomp_opcodes_REPNE; break; case 0xf3: /*REPE*/ op_table = x86_dynarec_opcodes_REPE; -// recomp_op_table = recomp_opcodes_REPE; + recomp_op_table = NULL;//recomp_opcodes_REPE; break; default: @@ -421,8 +423,21 @@ generate_call: (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) codegen_accumulate_flush(ir); +// pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) + { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](block, ir, opcode, fetchdat, op_32, op_pc); + if (new_pc) + { + if (new_pc != -1) + uop_MOV_IMM(ir, IREG_pc, new_pc); - //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + codegen_endpc = (cs + cpu_state.pc) + 8; + + return; + } + } + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; if (!test_modrm || diff --git a/src/codegen_backend_arm64_uops.c b/src/codegen_backend_arm64_uops.c index f52b465..e838e4f 100644 --- a/src/codegen_backend_arm64_uops.c +++ b/src/codegen_backend_arm64_uops.c @@ -40,8 +40,10 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_AND_IMM (0x024 << 23) +#define OPCODE_EOR_IMM (0x0a4 << 23) #define OPCODE_MOVK_W (0x0e5 << 23) #define OPCODE_MOVZ_W (0x0a5 << 23) +#define OPCODE_ORR_IMM (0x064 << 23) #define OPCODE_LDR_IMM_W (0x2e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) @@ -52,6 +54,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_ADD_LSL (0x058 << 21) #define OPCODE_AND_LSL (0x050 << 21) +#define OPCODE_EOR_LSL (0x250 << 21) #define OPCODE_ORR_LSL (0x150 << 21) #define OPCODE_SUB_LSL (0x258 << 21) @@ -138,19 +141,26 @@ static inline int imm_is_imm12(uint32_t imm_data) return 0; } +void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift); void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0) + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) { host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); } else if (!(imm_data & 0xff000000)) { if (imm_data & 0xfff) + { codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); } else @@ -177,6 +187,10 @@ void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); } } +void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_BLR(codeblock_t *block, int addr_reg) { @@ -191,6 +205,23 @@ void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); } +void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { if (!in_range7_x(offset)) @@ -226,7 +257,8 @@ void host_arm64_LDR_LITERAL_X(codeblock_t *block, int dest_reg, int literal_offs void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) @@ -262,6 +294,23 @@ void host_arm64_NOP(codeblock_t *block) codegen_addlong(block, OPCODE_NOP); } +void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +{ + if (imm_data == 0xffff) /*Quick hack until proper immediate generation is written */ + { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMMN(0) | IMMR(0) | IMMS(0x0f)); + } + else + { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} + void host_arm64_RET(codeblock_t *block, int reg) { codegen_addlong(block, OPCODE_RET | Rn(reg)); @@ -295,15 +344,21 @@ void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int off void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0) + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) { host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); } else if (!(imm_data & 0xff000000)) { if (imm_data & 0xfff) + { codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } + else if (imm_data & 0xfff000) codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); } else @@ -313,6 +368,10 @@ void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); } } +void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +{ + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} void host_arm64_call(codeblock_t *block, void *dst_addr) { @@ -351,6 +410,11 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_arm64_AND_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_arm64_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -410,6 +474,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_arm64_ORR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_arm64_mov_imm(block, REG_W16, uop->imm_data); @@ -433,6 +508,28 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + host_arm64_SUB_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_arm64_EOR_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm64_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -452,7 +549,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_arm_uops.c b/src/codegen_backend_arm_uops.c index a4611d0..8215caa 100644 --- a/src/codegen_backend_arm_uops.c +++ b/src/codegen_backend_arm_uops.c @@ -34,10 +34,16 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) #define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) #define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) #define OPCODE_B (0xa0 << OPCODE_SHIFT) +#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) +#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) +#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) +#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) #define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) #define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) #define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) #define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) +#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) #define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) #define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) #define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) @@ -132,13 +138,15 @@ static inline int in_range(void *addr, void *base) 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_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { uint32_t arm_imm; - if ((int32_t)imm < 0) + if ((int32_t)imm < 0 && imm != 0x80000000) { host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); } @@ -167,6 +175,10 @@ void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm { codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); } + else if (get_arm_imm(~imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { int offset = add_literal(block, imm); @@ -195,6 +207,27 @@ void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); } +void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); @@ -225,6 +258,27 @@ void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } +void host_arm_ORR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +{ + uint32_t arm_imm; + + if (get_arm_imm(imm, &arm_imm)) + { + codegen_addlong(block, COND_AL | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } + else + { + int offset = add_literal(block, imm); + host_arm_LDR_IMM(block, REG_TEMP, REG_LITERAL, offset); + host_arm_ORR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} + +void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +{ + codegen_addlong(block, COND_AL | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} + void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); @@ -244,7 +298,7 @@ void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm { uint32_t arm_imm; - if ((int32_t)imm < 0) + if ((int32_t)imm < 0 && imm != 0x80000000) { host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); } @@ -288,19 +342,22 @@ static int codegen_ADD(codeblock_t *block, uop_t *uop) host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); return 0; } - static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); return 0; } - static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_arm_AND_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_arm_AND_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -398,6 +455,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_arm_ORR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_ORR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { uint32_t arm_imm; @@ -427,6 +495,28 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_SUB_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_arm_EOR_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_EOR_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -446,7 +536,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86-64_uops.c b/src/codegen_backend_x86-64_uops.c index d0b3e00..4e0d50c 100644 --- a/src/codegen_backend_x86-64_uops.c +++ b/src/codegen_backend_x86-64_uops.c @@ -11,6 +11,12 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) +#define RM_OP_ADD 0x00 +#define RM_OP_OR 0x08 +#define RM_OP_AND 0x20 +#define RM_OP_SUB 0x28 +#define RM_OP_XOR 0x30 + static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { block->data[block_pos++] = val; @@ -118,7 +124,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, if (is_imm8(imm_data)) { - codegen_addbyte3(block, 0x83, 0xc0 | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ } else { @@ -129,11 +135,18 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, } else { - codegen_addbyte2(block, 0x81, 0xc0 | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ codegen_addlong(block, imm_data); } } } +static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*ADD dst_reg, src_reg_b*/ +} static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) { @@ -142,7 +155,7 @@ static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, if (is_imm8(imm_data)) { - codegen_addbyte3(block, 0x83, 0xe0 | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ } else { @@ -153,18 +166,17 @@ static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, } else { - codegen_addbyte2(block, 0x81, 0xe0 | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ codegen_addlong(block, imm_data); } } } - -static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) - fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg_a\n"); - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | (src_reg_b & 7)); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*AND dst_reg, src_reg_b*/ } static void host_x86_CALL(codeblock_t *block, void *p) @@ -348,6 +360,68 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ } } +static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} +static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*OR dst_reg, src_reg_b*/ +} + +static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} +static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*SUB dst_reg, src_reg_b*/ +} + #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) @@ -357,6 +431,37 @@ static void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ } +static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} +static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a || (dst_reg & 8) || (src_reg_b & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg_b & 7) << 3)); /*XOR dst_reg, src_reg_b*/ +} + static int codegen_ADD(codeblock_t *block, uop_t *uop) { @@ -382,6 +487,12 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} + static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -442,6 +553,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { if (((uintptr_t)uop->p) >> 32) @@ -457,6 +579,34 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -476,7 +626,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index b437185..9dac085 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -11,6 +11,12 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) +#define RM_OP_ADD 0x00 +#define RM_OP_OR 0x08 +#define RM_OP_AND 0x20 +#define RM_OP_SUB 0x28 +#define RM_OP_XOR 0x30 + static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { block->data[block_pos++] = val; @@ -101,7 +107,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, if (is_imm8(imm_data)) { - codegen_addbyte3(block, 0x83, 0xc0 | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ } else { @@ -112,31 +118,7 @@ static void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, } else { - codegen_addbyte2(block, 0x81, 0xc0 | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } - } -} - -static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) -{ - if (dst_reg != src_reg) - fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); - - if (is_imm8(imm_data)) - { - codegen_addbyte3(block, 0x83, 0xe0 | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else - { - if (dst_reg == REG_EAX) - { - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_addbyte2(block, 0x81, 0xe0 | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ codegen_addlong(block, imm_data); } } @@ -147,7 +129,39 @@ static void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_ if (dst_reg != src_reg_a) fatal("host_x86_ADD32_REG_IMM - dst_reg != src_reg_a\n"); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | src_reg_b); /*ADD dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg_b << 3)); /*ADD dst_reg, src_reg_b*/ +} + +static void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_AND32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_AND32_REG_REG - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg_b << 3)); /*AND dst_reg, src_reg_b*/ } static void host_x86_CALL(codeblock_t *block, void *p) @@ -284,13 +298,109 @@ static void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_ } } +static void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg_b << 3)); /*OR dst_reg, src_reg_b*/ +} +static void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_OR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +static void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + +static void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_SUB32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg_b << 3)); /*SUB dst_reg, src_reg_b*/ +} + static void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } +static void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if (dst_reg != src_reg_a) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg_a\n"); + + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg_b << 3)); /*XOR dst_reg, src_reg_b*/ +} + +static void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data) +{ + if (dst_reg != src_reg) + fatal("host_x86_XOR32_REG_IMM - dst_reg != src_reg\n"); + + if (is_imm8(imm_data)) + { + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } + else + { + if (dst_reg == REG_EAX) + { + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } + else + { + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } + } +} + + /*void codegen_debug() { pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); @@ -320,6 +430,12 @@ static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_AND(codeblock_t *block, uop_t *uop) +{ + host_x86_AND32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} + static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { host_x86_AND32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); @@ -373,6 +489,17 @@ static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_OR(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_OR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); @@ -384,6 +511,34 @@ static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) return 0; } +static int codegen_SUB(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_REG(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real); + + host_x86_SUB32_REG_IMM(block, uop->dest_reg_a_real, uop->dest_reg_a_real, uop->imm_data); + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_XOR32_REG_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + return 0; +} + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, @@ -403,7 +558,14 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_ADD & UOP_MASK] = codegen_ADD, [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM }; void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index d64e926..bac0ab6 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -35,10 +35,17 @@ #define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) #define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) #define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) -#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) -#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) +#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) +#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) +#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) +#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) +#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) -#define UOP_MAX 0x34 +#define UOP_MAX 0x3b #define UOP_MASK 0xffff @@ -175,9 +182,16 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) #define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) #define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) #define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) @@ -189,6 +203,7 @@ static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p #define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) #define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) + void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); diff --git a/src/codegen_ops.c b/src/codegen_ops.c new file mode 100644 index 0000000..728c659 --- /dev/null +++ b/src/codegen_ops.c @@ -0,0 +1,54 @@ +#include "ibm.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_arith.h" +#include "codegen_ops_logic.h" +#include "codegen_ops_mov.h" + +RecompOpFn recomp_opcodes[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ 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*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, ropADD_l_rmw, NULL, ropADD_l_rm, NULL, ropADD_EAX_imm, NULL, NULL, NULL, ropOR_l_rmw, NULL, ropOR_l_rm, NULL, ropOR_EAX_imm, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, ropAND_l_rmw, NULL, ropAND_l_rm, NULL, ropAND_EAX_imm, NULL, NULL, NULL, ropSUB_l_rmw, NULL, ropSUB_l_rm, NULL, ropSUB_EAX_imm, NULL, NULL, +/*30*/ NULL, ropXOR_l_rmw, NULL, ropXOR_l_rm, NULL, ropXOR_EAX_imm, NULL, NULL, NULL, ropCMP_l_rmw, NULL, ropCMP_l_rm, NULL, ropCMP_EAX_imm, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ NULL, rop81_l, NULL, rop83_l, NULL, NULL, NULL, NULL, NULL, ropMOV_l_r, NULL, ropMOV_r_l, NULL, NULL, NULL, NULL, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 7060238..1229ce4 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -3,10 +3,12 @@ #include "codegen.h" -typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block); +struct ir_data_t; + +typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); extern RecompOpFn recomp_opcodes[512]; -extern RecompOpFn recomp_opcodes_0f[512]; +/*extern RecompOpFn recomp_opcodes_0f[512]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; @@ -15,8 +17,8 @@ extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; extern RecompOpFn recomp_opcodes_de[512]; extern RecompOpFn recomp_opcodes_df[512]; -RecompOpFn recomp_opcodes_REPE[512]; -RecompOpFn recomp_opcodes_REPNE[512]; +extern RecompOpFn recomp_opcodes_REPE[512]; +extern RecompOpFn recomp_opcodes_REPNE[512];*/ #define REG_EAX 0 #define REG_ECX 1 diff --git a/src/codegen_ops_arith.c b/src/codegen_ops_arith.c new file mode 100644 index 0000000..d516152 --- /dev/null +++ b/src/codegen_ops_arith.c @@ -0,0 +1,285 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_arith.h" + +uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint32_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = fastreadl(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = fastreadl(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = fastreadl(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = fastreadl(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = fastreadl(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = fastreadl(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 5; +} +uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + uint32_t imm; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + switch (fetchdat & 0x38) + { + case 0x00: /*ADD*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + + codegen_flags_changed = 1; + return op_pc + 2; +} diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h new file mode 100644 index 0000000..f219318 --- /dev/null +++ b/src/codegen_ops_arith.h @@ -0,0 +1,14 @@ +uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_logic.c b/src/codegen_ops_logic.c new file mode 100644 index 0000000..c4aca26 --- /dev/null +++ b/src/codegen_ops_logic.c @@ -0,0 +1,129 @@ +#include "ibm.h" + +#include "x86.h" +#include "x86_flags.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_logic.h" + +uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; +} +uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = fetchdat & 7, dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7, dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} diff --git a/src/codegen_ops_logic.h b/src/codegen_ops_logic.h new file mode 100644 index 0000000..127f4c1 --- /dev/null +++ b/src/codegen_ops_logic.h @@ -0,0 +1,11 @@ +uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); + +uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_ops_mov.c b/src/codegen_ops_mov.c new file mode 100644 index 0000000..2266602 --- /dev/null +++ b/src/codegen_ops_mov.c @@ -0,0 +1,48 @@ +#include "ibm.h" + +#include "x86.h" +#include "386_common.h" +#include "codegen.h" +#include "codegen_ir.h" +#include "codegen_ops.h" +#include "codegen_ops_mov.h" + +uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); + + return op_pc + 4; +} + + + +uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = fetchdat & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = (fetchdat >> 3) & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + return 0; + + return op_pc + 1; +} +uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } + else + return 0; + + return op_pc + 1; +} diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h new file mode 100644 index 0000000..c9bafdc --- /dev/null +++ b/src/codegen_ops_mov.h @@ -0,0 +1,3 @@ +uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_reg.c b/src/codegen_reg.c index e8e1410..164a190 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -200,13 +200,13 @@ ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg) host_regs_locked |= (1 << c); // fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); // codegen_reg_writeback(block, c); + host_reg_dirty[c] = 0; } reg_version_refcount[host_regs[c].reg][host_regs[c].version]--; if (reg_version_refcount[host_regs[c].reg][host_regs[c].version] < 0) fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); - host_reg_dirty[c] = 0; // pclog(" codegen_reg_alloc_read_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); return codegen_host_reg_list[c]; } diff --git a/src/codegen_reg.h b/src/codegen_reg.h index e854fe1..e1b4965 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -48,6 +48,8 @@ enum IREG_INVALID = 255 }; +#define IREG_32(reg) ((reg) + IREG_EAX) + extern uint8_t reg_last_version[IREG_COUNT]; extern uint8_t reg_version_refcount[IREG_COUNT][256];