Added code generation for immediate->register and register versions of MOV, XCHG, ADD, SUB, AND, OR, XOR, TEST, CMP, INC and DEC.

This commit is contained in:
TomW 2015-01-16 21:22:14 +00:00
commit 630592125c
11 changed files with 1568 additions and 30 deletions

View file

@ -4,7 +4,7 @@ CC = gcc.exe
WINDRES = windres.exe
CFLAGS = -O3 -march=i686 -fomit-frame-pointer
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
codegen.o codegen_timing_486.o codegen_timing_pentium.o codegen_x86.o config.o cpu.o dac.o \
codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_pentium.o codegen_x86.o config.o cpu.o dac.o \
device.o dma.o fdc.o gameport.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o \
intel_flash.o io.o jim.o keyboard.o keyboard_amstrad.o keyboard_at.o keyboard_olim24.o \
keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o model.o mouse.o mouse_ps2.o mouse_serial.o \

View file

@ -72,4 +72,38 @@ extern codegen_timing_t codegen_timing_486;
void codegen_timing_set(codegen_timing_t *timing);
extern int block_current;
extern int block_pos;
#define CPU_BLOCK_END() cpu_block_end = 1
static inline void addbyte(uint8_t val)
{
codeblock[block_current].data[block_pos++] = val;
if (block_pos >= 8000)
{
CPU_BLOCK_END();
}
}
static inline void addword(uint16_t val)
{
*(uint16_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 2;
if (block_pos >= 8000)
{
CPU_BLOCK_END();
}
}
static inline void addlong(uint32_t val)
{
*(uint32_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 4;
if (block_pos >= 8000)
{
CPU_BLOCK_END();
}
}
#endif

64
src/codegen_ops.c Normal file
View file

@ -0,0 +1,64 @@
#ifdef DYNAREC
#include "ibm.h"
#include "x86.h"
#include "x86_ops.h"
#include "x86_flags.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ops.h"
#include "codegen_ops_x86.h"
#include "codegen_ops_arith.h"
#include "codegen_ops_logic.h"
#include "codegen_ops_mov.h"
#include "codegen_ops_xchg.h"
RecompOpFn recomp_opcodes[512] =
{
/*16-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, NULL, NULL, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ ropAND_b_rmw, ropAND_w_rmw, ropAND_b_rm, ropAND_w_rm, ropAND_AL_imm, ropAND_AX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_w_rmw, ropSUB_b_rm, ropSUB_w_rm, ropSUB_AL_imm, ropSUB_AX_imm, NULL, NULL,
/*30*/ ropXOR_b_rmw, ropXOR_w_rmw, ropXOR_b_rm, ropXOR_w_rm, ropXOR_AL_imm, ropXOR_AX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_w_rmw, ropCMP_b_rm, ropCMP_w_rm, ropCMP_AL_imm, ropCMP_AX_imm, NULL, NULL,
/*40*/ ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropINC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw, ropDEC_rw,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_b, ropXCHG_w, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, NULL, NULL, NULL, NULL,
/*90*/ NULL, ropXCHG_AX_CX, ropXCHG_AX_DX, ropXCHG_AX_BX, ropXCHG_AX_SP, ropXCHG_AX_BP, ropXCHG_AX_SI, ropXCHG_AX_DI, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
/*c0*/ NULL, NULL, NULL, NULL, 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
/*00*/ ropADD_b_rmw, ropADD_l_rmw, ropADD_b_rm, ropADD_l_rm, ropADD_AL_imm, ropADD_EAX_imm, NULL, NULL, ropOR_b_rmw, ropOR_l_rmw, ropOR_b_rm, ropOR_l_rm, ropOR_AL_imm, ropOR_EAX_imm, NULL, NULL,
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*20*/ ropAND_b_rmw, ropAND_l_rmw, ropAND_b_rm, ropAND_l_rm, ropAND_AL_imm, ropAND_EAX_imm, NULL, NULL, ropSUB_b_rmw, ropSUB_l_rmw, ropSUB_b_rm, ropSUB_l_rm, ropSUB_AL_imm, ropSUB_EAX_imm, NULL, NULL,
/*30*/ ropXOR_b_rmw, ropXOR_l_rmw, ropXOR_b_rm, ropXOR_l_rm, ropXOR_AL_imm, ropXOR_EAX_imm, NULL, NULL, ropCMP_b_rmw, ropCMP_l_rmw, ropCMP_b_rm, ropCMP_l_rm, ropCMP_AL_imm, ropCMP_EAX_imm, NULL, NULL,
/*40*/ ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropINC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl, ropDEC_rl,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_b, ropXCHG_l, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, NULL, NULL, NULL, NULL,
/*90*/ NULL, ropXCHG_EAX_ECX,ropXCHG_EAX_EDX,ropXCHG_EAX_EBX,ropXCHG_EAX_ESP,ropXCHG_EAX_EBP,ropXCHG_EAX_ESI,ropXCHG_EAX_EDI,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
/*c0*/ NULL, NULL, NULL, NULL, 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, 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,
};
#endif

28
src/codegen_ops.h Normal file
View file

@ -0,0 +1,28 @@
typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block);
extern RecompOpFn recomp_opcodes[512];
#define REG_EAX 0
#define REG_ECX 1
#define REG_EDX 2
#define REG_EBX 3
#define REG_ESP 4
#define REG_EBP 5
#define REG_ESI 6
#define REG_EDI 7
#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_AL 0
#define REG_AH 4
#define REG_CL 1
#define REG_CH 5
#define REG_DL 2
#define REG_DH 6
#define REG_BL 3
#define REG_BH 7

621
src/codegen_ops_arith.h Normal file
View file

@ -0,0 +1,621 @@
static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1);
AND_HOST_REG_IMM(host_reg, 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc;
}
static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc;
}
static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1);
AND_HOST_REG_IMM(host_reg, 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc;
}
static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc;
}
#define ROP_ARITH(name, op, writeback) \
static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_B(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
FLAG_C_COPY(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_W(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
FLAG_C_COPY(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_L(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
op ## _HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
FLAG_C_COPY(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 8); \
src_reg = LOAD_REG_B(fetchdat & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
FLAG_C_COPY(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 16); \
src_reg = LOAD_REG_W(fetchdat & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
FLAG_C_COPY(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 32); \
src_reg = LOAD_REG_L(fetchdat & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
op ## _HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
FLAG_C_COPY(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
}
ROP_ARITH(ADD, ADD, 1)
ROP_ARITH(SUB, SUB, 1)
ROP_ARITH(CMP, SUB, 0)
static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc);
ADD_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 1;
}
static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 2;
}
static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc);
SUB_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 4;
}
static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc);
SUB_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
FLAG_C_COPY();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
uint32_t imm;
if ((fetchdat & 0x30) == 0x10 || (fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B(fetchdat & 7);
imm = (fetchdat >> 8) & 0xff;
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8);
FLAG_C_COPY();
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8);
FLAG_C_COPY();
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
FLAG_C_COPY();
break;
}
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
STORE_REG_B_RELEASE(host_reg);
else
RELEASE_REG(host_reg);
return op_pc + 2;
}
static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
uint32_t imm;
if ((fetchdat & 0x30) == 0x10 || (fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W(fetchdat & 7);
imm = (fetchdat >> 8) & 0xffff;
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16);
FLAG_C_COPY();
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
FLAG_C_COPY();
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
FLAG_C_COPY();
break;
}
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
STORE_REG_W_RELEASE(host_reg);
else
RELEASE_REG(host_reg);
return op_pc + 3;
}
static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
uint32_t imm;
if ((fetchdat & 0x30) == 0x10 || (fetchdat & 0xc0) != 0xc0)
return 0;
imm = fastreadl(cs + op_pc + 1);
host_reg = LOAD_REG_L(fetchdat & 7);
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32);
FLAG_C_COPY();
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
FLAG_C_COPY();
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
FLAG_C_COPY();
break;
}
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
STORE_REG_L_RELEASE(host_reg);
else
RELEASE_REG(host_reg);
return op_pc + 5;
}
static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
uint32_t imm;
if ((fetchdat & 0x30) == 0x10 || (fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W(fetchdat & 7);
imm = (fetchdat >> 8) & 0xff;
if (imm & 0x80)
imm |= 0xff80;
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16);
FLAG_C_COPY();
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
FLAG_C_COPY();
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
FLAG_C_COPY();
break;
}
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
STORE_REG_W_RELEASE(host_reg);
else
RELEASE_REG(host_reg);
return op_pc + 2;
}
static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
uint32_t imm;
if ((fetchdat & 0x30) == 0x10 || (fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_L(fetchdat & 7);
imm = (fetchdat >> 8) & 0xff;
if (imm & 0x80)
imm |= 0xffffff80;
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD32);
FLAG_C_COPY();
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
FLAG_C_COPY();
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
FLAG_C_COPY();
break;
}
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
STORE_REG_L_RELEASE(host_reg);
else
RELEASE_REG(host_reg);
return op_pc + 2;
}

273
src/codegen_ops_logic.h Normal file
View file

@ -0,0 +1,273 @@
#define ROP_LOGIC(name, op, writeback) \
static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_B(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
op ## _HOST_REG_B(dst_reg, src_reg); \
FLAG_C_CLEAR(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_W(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
op ## _HOST_REG_W(dst_reg, src_reg); \
FLAG_C_CLEAR(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_L(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
op ## _HOST_REG_L(dst_reg, src_reg); \
FLAG_C_CLEAR(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); \
src_reg = LOAD_REG_B(fetchdat & 7); \
op ## _HOST_REG_B(dst_reg, src_reg); \
FLAG_C_CLEAR(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); \
src_reg = LOAD_REG_W(fetchdat & 7); \
op ## _HOST_REG_W(dst_reg, src_reg); \
FLAG_C_CLEAR(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
} \
static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); \
src_reg = LOAD_REG_L(fetchdat & 7); \
op ## _HOST_REG_L(dst_reg, src_reg); \
FLAG_C_CLEAR(); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
\
return op_pc + 1; \
}
ROP_LOGIC(AND, AND, 1)
ROP_LOGIC(OR, OR, 1)
ROP_LOGIC(TEST, AND, 0)
ROP_LOGIC(XOR, XOR, 1)
static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
AND_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
OR_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
OR_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}
static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 1;
}
static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 2;
}
static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
AND_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
RELEASE_REG(host_reg);
return op_pc + 4;
}
static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_B(REG_AL);
XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
return op_pc + 1;
}
static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_W(REG_AX);
XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
return op_pc + 2;
}
static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc);
XOR_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
FLAG_C_CLEAR();
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
return op_pc + 4;
}

130
src/codegen_ops_mov.h Normal file
View file

@ -0,0 +1,130 @@
static uint32_t ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff);
return op_pc + 1;
}
static uint32_t ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff);
return op_pc + 2;
}
static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
fetchdat = fastreadl(cs + op_pc);
STORE_IMM_REG_L(opcode & 7, fetchdat);
return op_pc + 4;
}
static uint32_t ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B((fetchdat >> 3) & 7);
STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7);
return op_pc + 1;
}
static uint32_t ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W((fetchdat >> 3) & 7);
STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7);
return op_pc + 1;
}
static uint32_t ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_L((fetchdat >> 3) & 7);
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
return op_pc + 1;
}
static uint32_t ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B(fetchdat & 7);
STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7);
return op_pc + 1;
}
static uint32_t ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W(fetchdat & 7);
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
return op_pc + 1;
}
static uint32_t ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_L(fetchdat & 7);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
return op_pc + 1;
}
static uint32_t ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff);
return op_pc + 2;
}
static uint32_t ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff);
return op_pc + 3;
}
static uint32_t ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t imm = fastreadl(cs + op_pc + 1);
int host_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_REG_L(fetchdat & 7, imm);
return op_pc + 5;
}

305
src/codegen_ops_x86.h Normal file
View file

@ -0,0 +1,305 @@
static inline int find_host_reg()
{
int c;
for (c = 0; c < NR_HOST_REGS; c++)
{
if (host_reg_mapping[c] == -1)
break;
}
if (c == NR_HOST_REGS)
fatal("Out of host regs!\n");
return c;
}
static void STORE_IMM_ADDR_B(uintptr_t addr, uint8_t val)
{
addbyte(0xC6); /*MOVB [addr],val*/
addbyte(0x05);
addlong(addr);
addbyte(val);
}
static void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val)
{
addbyte(0x66); /*MOVW [addr],val*/
addbyte(0xC7);
addbyte(0x05);
addlong(addr);
addword(val);
}
static void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val)
{
addbyte(0xC7); /*MOVL [addr],val*/
addbyte(0x05);
addlong(addr);
addlong(val);
}
static void STORE_IMM_REG_B(int reg, uint8_t val)
{
addbyte(0xC6); /*MOVB [addr],val*/
addbyte(0x05);
if (reg & 4)
addlong((uint32_t)&regs[reg & 3].b.h);
else
addlong((uint32_t)&regs[reg & 3].b.l);
addbyte(val);
}
static void STORE_IMM_REG_W(int reg, uint16_t val)
{
addbyte(0x66); /*MOVW [addr],val*/
addbyte(0xC7);
addbyte(0x05);
addlong((uint32_t)&regs[reg & 7].w);
addword(val);
}
static void STORE_IMM_REG_L(int reg, uint32_t val)
{
addbyte(0xC7); /*MOVL [addr],val*/
addbyte(0x05);
addlong((uint32_t)&regs[reg & 7].l);
addlong(val);
}
static int LOAD_REG_B(int reg)
{
int host_reg = find_host_reg();
host_reg_mapping[host_reg] = reg;
addbyte(0x0f); /*MOVZX B[reg],host_reg*/
addbyte(0xb6);
addbyte(0x05 | (host_reg << 3));
if (reg & 4)
addlong((uint32_t)&regs[reg & 3].b.h);
else
addlong((uint32_t)&regs[reg & 3].b.l);
return host_reg;
}
static int LOAD_REG_W(int reg)
{
int host_reg = find_host_reg();
host_reg_mapping[host_reg] = reg;
addbyte(0x0f); /*MOVZX W[reg],host_reg*/
addbyte(0xb7);
addbyte(0x05 | (host_reg << 3));
addlong((uint32_t)&regs[host_reg_mapping[host_reg]].w);
return host_reg;
}
static int LOAD_REG_L(int reg)
{
int host_reg = find_host_reg();
host_reg_mapping[host_reg] = reg;
addbyte(0x8b); /*MOVL host_reg,[reg]*/
addbyte(0x05 | (host_reg << 3));
addlong((uint32_t)&regs[host_reg_mapping[host_reg]].l);
return host_reg;
}
static void STORE_REG_B_RELEASE(int host_reg)
{
addbyte(0x88); /*MOVB [reg],host_reg*/
addbyte(0x05 | (host_reg << 3));
if (host_reg_mapping[host_reg] & 4)
addlong((uint32_t)&regs[host_reg_mapping[host_reg] & 3].b.h);
else
addlong((uint32_t)&regs[host_reg_mapping[host_reg] & 3].b.l);
host_reg_mapping[host_reg] = -1;
}
static void STORE_REG_W_RELEASE(int host_reg)
{
addbyte(0x66); /*MOVW [reg],host_reg*/
addbyte(0x89);
addbyte(0x05 | (host_reg << 3));
addlong((uint32_t)&regs[host_reg_mapping[host_reg]].w);
host_reg_mapping[host_reg] = -1;
}
static void STORE_REG_L_RELEASE(int host_reg)
{
addbyte(0x89); /*MOVL [reg],host_reg*/
addbyte(0x05 | (host_reg << 3));
addlong((uint32_t)&regs[host_reg_mapping[host_reg]].l);
host_reg_mapping[host_reg] = -1;
}
static void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg)
{
addbyte(0x88); /*MOVB [guest_reg],host_reg*/
addbyte(0x05 | (host_reg << 3));
if (guest_reg & 4)
addlong((uint32_t)&regs[guest_reg & 3].b.h);
else
addlong((uint32_t)&regs[guest_reg & 3].b.l);
host_reg_mapping[host_reg] = -1;
}
static void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg)
{
addbyte(0x66); /*MOVB [guest_reg],host_reg*/
addbyte(0x89);
addbyte(0x05 | (host_reg << 3));
addlong((uint32_t)&regs[guest_reg & 7].w);
host_reg_mapping[host_reg] = -1;
}
static void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg)
{
addbyte(0x89); /*MOVB [guest_reg],host_reg*/
addbyte(0x05 | (host_reg << 3));
addlong((uint32_t)&regs[guest_reg & 7].l);
host_reg_mapping[host_reg] = -1;
}
static void RELEASE_REG(int host_reg)
{
host_reg_mapping[host_reg] = -1;
}
static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg)
{
addbyte(0x89); /*MOVL [reg],host_reg*/
addbyte(0x05 | (host_reg << 3));
addlong(addr);
}
static void ADD_HOST_REG_B(int dst_reg, int src_reg)
{
addbyte(0x00); /*ADDB dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void ADD_HOST_REG_W(int dst_reg, int src_reg)
{
addbyte(0x66); /*ADDW dst_reg, src_reg*/
addbyte(0x01);
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void ADD_HOST_REG_L(int dst_reg, int src_reg)
{
addbyte(0x01); /*ADDL dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm)
{
addbyte(0x80); /*ADDB host_reg, imm*/
addbyte(0xC0 | host_reg);
addbyte(imm);
}
static void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm)
{
addbyte(0x66); /*ADDW host_reg, imm*/
addbyte(0x81);
addbyte(0xC0 | host_reg);
addword(imm);
}
static void ADD_HOST_REG_IMM(int host_reg, uint32_t imm)
{
addbyte(0x81); /*ADDL host_reg, imm*/
addbyte(0xC0 | host_reg);
addlong(imm);
}
#define AND_HOST_REG_B AND_HOST_REG_L
#define AND_HOST_REG_W AND_HOST_REG_L
static void AND_HOST_REG_L(int dst_reg, int src_reg)
{
addbyte(0x21); /*ANDL dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void AND_HOST_REG_IMM(int host_reg, uint32_t imm)
{
addbyte(0x81); /*ANDL host_reg, imm*/
addbyte(0xE0 | host_reg);
addlong(imm);
}
#define OR_HOST_REG_B OR_HOST_REG_L
#define OR_HOST_REG_W OR_HOST_REG_L
static void OR_HOST_REG_L(int dst_reg, int src_reg)
{
addbyte(0x09); /*ORL dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void OR_HOST_REG_IMM(int host_reg, uint32_t imm)
{
addbyte(0x81); /*ORL host_reg, imm*/
addbyte(0xC8 | host_reg);
addlong(imm);
}
static void SUB_HOST_REG_B(int dst_reg, int src_reg)
{
addbyte(0x28); /*SUBB dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void SUB_HOST_REG_W(int dst_reg, int src_reg)
{
addbyte(0x66); /*SUBW dst_reg, src_reg*/
addbyte(0x29);
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void SUB_HOST_REG_L(int dst_reg, int src_reg)
{
addbyte(0x29); /*SUBL dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm)
{
addbyte(0x80); /*SUBB host_reg, imm*/
addbyte(0xE8 | host_reg);
addbyte(imm);
}
static void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm)
{
addbyte(0x66); /*SUBW host_reg, imm*/
addbyte(0x81);
addbyte(0xE8 | host_reg);
addword(imm);
}
static void SUB_HOST_REG_IMM(int host_reg, uint32_t imm)
{
addbyte(0x81); /*SUBL host_reg, imm*/
addbyte(0xE8 | host_reg);
addlong(imm);
}
#define XOR_HOST_REG_B XOR_HOST_REG_L
#define XOR_HOST_REG_W XOR_HOST_REG_L
static void XOR_HOST_REG_L(int dst_reg, int src_reg)
{
addbyte(0x31); /*XORL dst_reg, src_reg*/
addbyte(0xc0 | dst_reg | (src_reg << 3));
}
static void XOR_HOST_REG_IMM(int host_reg, uint32_t imm)
{
addbyte(0x81); /*XORL host_reg, imm*/
addbyte(0xF0 | host_reg);
addlong(imm);
}
static void FLAG_C_CLEAR()
{
addbyte(0x83); /*ANDL [flags],~1*/
addbyte(0x25);
addlong((uint32_t)&flags);
addbyte(0xfe);
}
static void FLAG_C_COPY()
{
addbyte(0x8a); /*MOVB DL, [flags]*/
addbyte(0x05 | (REG_DL << 3));
addlong((uint32_t)&flags);
addbyte(0x0f); /*SETB DH*/
addbyte(0x92);
addbyte(0xc0 | REG_DH);
addbyte(0x80); /*AND DL, ~1*/
addbyte(0xe0 | REG_DL);
addbyte(0xfe);
addbyte(0x08); /*OR DL, DH*/
addbyte(0xc0 | REG_DL | (REG_DH << 3));
addbyte(0x88); /*MOVB [flags],DL*/
addbyte(0x05 | (REG_DL << 3));
addlong((uint32_t)&flags);
}

84
src/codegen_ops_xchg.h Normal file
View file

@ -0,0 +1,84 @@
#define OP_XCHG_AX_(reg) \
static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int ax_reg, host_reg; \
\
ax_reg = LOAD_REG_W(REG_AX); \
host_reg = LOAD_REG_W(REG_ ## reg); \
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); \
\
return op_pc; \
}
OP_XCHG_AX_(BX)
OP_XCHG_AX_(CX)
OP_XCHG_AX_(DX)
OP_XCHG_AX_(SI)
OP_XCHG_AX_(DI)
OP_XCHG_AX_(SP)
OP_XCHG_AX_(BP)
#define OP_XCHG_EAX_(reg) \
static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int eax_reg, host_reg; \
\
eax_reg = LOAD_REG_L(REG_EAX); \
host_reg = LOAD_REG_L(REG_ ## reg); \
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \
STORE_REG_TARGET_L_RELEASE(host_reg, REG_EAX); \
\
return op_pc; \
}
OP_XCHG_EAX_(EBX)
OP_XCHG_EAX_(ECX)
OP_XCHG_EAX_(EDX)
OP_XCHG_EAX_(ESI)
OP_XCHG_EAX_(EDI)
OP_XCHG_EAX_(ESP)
OP_XCHG_EAX_(EBP)
static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
dst_reg = LOAD_REG_B(fetchdat & 7);
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
STORE_REG_TARGET_B_RELEASE(src_reg, fetchdat & 7);
return op_pc + 1;
}
static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
dst_reg = LOAD_REG_W(fetchdat & 7);
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
STORE_REG_TARGET_W_RELEASE(src_reg, fetchdat & 7);
return op_pc + 1;
}
static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int src_reg, dst_reg;
if ((fetchdat & 0xc0) != 0xc0)
return 0;
dst_reg = LOAD_REG_L(fetchdat & 7);
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
STORE_REG_TARGET_L_RELEASE(src_reg, fetchdat & 7);
return op_pc + 1;
}

View file

@ -7,20 +7,19 @@
#include "ibm.h"
#include "cpu.h"
#include "x86.h"
#include "x86_flags.h"
#include "x86_ops.h"
#include "x87.h"
#include "codegen.h"
#include "codegen_ops.h"
#include "codegen_ops_x86.h"
#include "386_common.h"
#define BLOCK_EXIT_OFFSET 0x1ff0
#define CPU_BLOCK_END() cpu_block_end = 1
int host_reg_mapping[NR_HOST_REGS];
codeblock_t *codeblock;
codeblock_t **codeblock_hash;
@ -33,9 +32,9 @@ page_t *pages;
uint8_t *codeblock_page_dirty;
static int block_current = 0;
int block_current = 0;
static int block_num;
static int block_pos;
int block_pos;
int cpu_recomp_flushes, cpu_recomp_flushes_latched;
int cpu_recomp_evicted, cpu_recomp_evicted_latched;
@ -51,28 +50,6 @@ static uint32_t last_op32;
static x86seg *last_ea_seg;
static int last_ssegs;
static inline void addbyte(uint8_t val)
{
// pclog("Addbyte %02X at %i %i\n", val, block_pos, cpu_block_end);
codeblock[block_current].data[block_pos++] = val;
if (block_pos >= 8000)
{
CPU_BLOCK_END();
}
}
static inline void addlong(uint32_t val)
{
// pclog("Addlong %08X at %i %i\n", val, block_pos, cpu_block_end);
*(uint32_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 4;
if (block_pos >= 8000)
{
CPU_BLOCK_END();
}
}
void codegen_init()
{
int c;
@ -696,6 +673,10 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
int over = 0;
int pc_off = 0;
int test_modrm = 1;
int c;
for (c = 0; c < NR_HOST_REGS; c++)
host_reg_mapping[c] = -1;
codegen_timing_start();
@ -819,6 +800,21 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
generate_call:
codegen_timing_opcode(opcode, fetchdat, op_32);
if (op_table == x86_dynarec_opcodes && recomp_opcodes[(opcode | op_32) & 0x1ff])
{
uint32_t new_pc = recomp_opcodes[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
if (new_pc)
{
STORE_IMM_ADDR_L((uintptr_t)&pc, new_pc);
codegen_block_ins++;
block->ins++;
codegen_endpc = (cs + pc) + 8;
return;
}
}
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output)
// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);

View file

@ -11,3 +11,6 @@ enum
{
OP_RET = 0xc3
};
#define NR_HOST_REGS 3
extern int host_reg_mapping[NR_HOST_REGS];