Added code generation for memory versions of MOV, and memory source versions of ADD, SUB, AND, OR, XOR and CMP.

This commit is contained in:
TomW 2015-02-08 17:17:14 +00:00
commit ba715706b6
11 changed files with 997 additions and 85 deletions

View file

@ -21,8 +21,8 @@ int cpu_reps, cpu_reps_latched;
int cpu_notreps, cpu_notreps_latched;
int inrecomp = 0;
int cpu_recomp_blocks, cpu_recomp_ins, cpu_new_blocks;
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_new_blocks_latched;
int cpu_recomp_blocks, cpu_recomp_ins, cpu_recomp_full_ins, cpu_new_blocks;
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
int cpu_block_end = 0;

View file

@ -71,8 +71,8 @@ void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr)
extern int cpu_block_end;
extern int cpu_recomp_blocks, cpu_recomp_ins, cpu_new_blocks;
extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_new_blocks_latched;
extern int cpu_recomp_blocks, cpu_recomp_ins, cpu_recomp_full_ins, cpu_new_blocks;
extern int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
extern int cpu_recomp_flushes, cpu_recomp_flushes_latched;
extern int cpu_recomp_evicted, cpu_recomp_evicted_latched;
extern int cpu_recomp_reuse, cpu_recomp_reuse_latched;
@ -111,7 +111,7 @@ extern int block_pos;
static inline void addbyte(uint8_t val)
{
codeblock[block_current].data[block_pos++] = val;
if (block_pos >= 1850)
if (block_pos >= 1800)
{
CPU_BLOCK_END();
}
@ -121,7 +121,7 @@ static inline void addword(uint16_t val)
{
*(uint16_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 2;
if (block_pos >= 1850)
if (block_pos >= 1800)
{
CPU_BLOCK_END();
}
@ -131,7 +131,7 @@ static inline void addlong(uint32_t val)
{
*(uint32_t *)&codeblock[block_current].data[block_pos] = val;
block_pos += 4;
if (block_pos >= 1850)
if (block_pos >= 1800)
{
CPU_BLOCK_END();
}
@ -139,4 +139,8 @@ static inline void addlong(uint32_t val)
/*Current physical page of block being recompiled. -1 if no recompilation taking place */
extern uint32_t recomp_page;
extern x86seg *op_ea_seg;
extern int op_ssegs;
extern uint32_t op_old_pc;
#endif

View file

@ -30,7 +30,7 @@ RecompOpFn recomp_opcodes[512] =
/*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,
/*a0*/ ropMOV_AL_a, ropMOV_AX_a, ropMOV_a_AL, ropMOV_a_AX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_AX_imm, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm, ropMOV_rw_imm,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@ -52,7 +52,7 @@ RecompOpFn recomp_opcodes[512] =
/*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,
/*a0*/ ropMOV_AL_a, ropMOV_EAX_a, ropMOV_a_AL, ropMOV_a_EAX, NULL, NULL, NULL, NULL, ropTEST_AL_imm, ropTEST_EAX_imm,NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rb_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm, ropMOV_rl_imm,
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,

View file

@ -134,12 +134,19 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
if ((fetchdat & 0xc0) == 0xc0) \
{ \
src_reg = LOAD_REG_B(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
MEM_LOAD_ADDR_EA_B(target_seg); \
src_reg = 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); \
@ -154,12 +161,19 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
if ((fetchdat & 0xc0) == 0xc0) \
{ \
src_reg = LOAD_REG_W(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
MEM_LOAD_ADDR_EA_W(target_seg); \
src_reg = 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); \
@ -174,12 +188,19 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{ \
int src_reg, dst_reg; \
\
if ((fetchdat & 0xc0) != 0xc0) \
return 0; \
if ((fetchdat & 0xc0) == 0xc0) \
{ \
src_reg = LOAD_REG_L(fetchdat & 7); \
} \
else \
{ \
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \
MEM_LOAD_ADDR_EA_L(target_seg); \
src_reg = 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); \

View file

@ -22,109 +22,318 @@ static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
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;
int host_reg = LOAD_REG_B((fetchdat >> 3) & 7);
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B((fetchdat >> 3) & 7);
STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 0);
MEM_STORE_ADDR_EA_B(target_seg, host_reg);
RELEASE_REG(host_reg);
}
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;
int host_reg = LOAD_REG_W((fetchdat >> 3) & 7);
host_reg = LOAD_REG_W((fetchdat >> 3) & 7);
STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 1);
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
RELEASE_REG(host_reg);
}
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);
if ((fetchdat & 0xc0) == 0xc0)
{
STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
CHECK_SEG_LIMITS(target_seg, 3);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
RELEASE_REG(host_reg);
}
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)
{
int host_reg = LOAD_REG_B(fetchdat & 7);
STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_B(fetchdat & 7);
STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_B(target_seg);
STORE_REG_TARGET_B_RELEASE(0, (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)
{
int host_reg = LOAD_REG_W(fetchdat & 7);
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
if ((fetchdat & 0xc0) != 0xc0)
return 0;
host_reg = LOAD_REG_W(fetchdat & 7);
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_W(target_seg);
STORE_REG_TARGET_W_RELEASE(0, (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);
if ((fetchdat & 0xc0) == 0xc0)
{
int host_reg = LOAD_REG_L(fetchdat & 7);
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
}
else
{
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_READ(target_seg);
MEM_LOAD_ADDR_EA_L(target_seg);
STORE_REG_TARGET_L_RELEASE(0, (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)
{
STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff);
}
else
{
// return 0;
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadb(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_B(target_seg, host_reg);
RELEASE_REG(host_reg);
}
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)
{
STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff);
}
else
{
// if ((cs+pc) <= 0xbff70000 || (cs+pc) > 0xbff80000)
// return 0;
// {
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadw(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
//pclog("MOV imm %04x(%08x):%08x %08x %04x\n", CS, cs, pc, op_pc, imm);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
if ((fetchdat & 0xc0) != 0xc0)
return 0;
MEM_STORE_ADDR_EA_W(target_seg, host_reg);
RELEASE_REG(host_reg);
// }
}
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)
{
uint32_t imm = fastreadl(cs + op_pc + 1);
if ((fetchdat & 0xc0) != 0xc0)
return 0;
STORE_IMM_REG_L(fetchdat & 7, imm);
}
else
{
// return 0;
x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32);
uint32_t imm = fastreadl(cs + op_pc + 1);
int host_reg = LOAD_REG_IMM(imm);
STORE_IMM_REG_L(fetchdat & 7, imm);
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
CHECK_SEG_WRITE(target_seg);
MEM_STORE_ADDR_EA_L(target_seg, host_reg);
RELEASE_REG(host_reg);
}
return op_pc + 5;
}
static uint32_t ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_READ(op_ea_seg);
MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr);
STORE_REG_TARGET_B_RELEASE(0, REG_AL);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_READ(op_ea_seg);
MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr);
STORE_REG_TARGET_W_RELEASE(0, REG_AX);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_READ(op_ea_seg);
MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr);
STORE_REG_TARGET_L_RELEASE(0, REG_EAX);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
int host_reg;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_WRITE(op_ea_seg);
host_reg = LOAD_REG_B(REG_AL);
MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg);
RELEASE_REG(host_reg);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
int host_reg;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_WRITE(op_ea_seg);
host_reg = LOAD_REG_W(REG_AX);
MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg);
RELEASE_REG(host_reg);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}
static uint32_t ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint32_t addr;
int host_reg;
if (op_32 & 0x200)
addr = fastreadl(cs + op_pc);
else
addr = fastreadw(cs + op_pc);
CHECK_SEG_WRITE(op_ea_seg);
host_reg = LOAD_REG_L(REG_EAX);
MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg);
RELEASE_REG(host_reg);
return op_pc + ((op_32 & 0x200) ? 4 : 2);
}

View file

@ -1,7 +1,14 @@
/*Register allocation :
EBX, ECX, EDX - emulated registers
EAX - work register, EA storage
ESI, EDI - work registers
*/
#define HOST_REG_START 1
#define HOST_REG_END 4
static inline int find_host_reg()
{
int c;
for (c = 0; c < NR_HOST_REGS; c++)
for (c = HOST_REG_START; c < HOST_REG_END; c++)
{
if (host_reg_mapping[c] == -1)
break;
@ -100,6 +107,18 @@ static int LOAD_REG_L(int reg)
return host_reg;
}
static int LOAD_REG_IMM(uint32_t imm)
{
int host_reg = find_host_reg();
host_reg_mapping[host_reg] = reg;
addbyte(0xc7); /*MOVL host_reg, imm*/
addbyte(0xc0 | host_reg);
addlong(imm);
return host_reg;
}
static void STORE_REG_B_RELEASE(int host_reg)
{
addbyte(0x88); /*MOVB [reg],host_reg*/
@ -284,3 +303,615 @@ static void CALL_FUNC(void *dest)
addbyte(0xE8); /*CALL*/
addlong(((uint8_t *)dest - (uint8_t *)(&codeblock[block_current].data[block_pos + 4])));
}
static void CHECK_SEG_READ(x86seg *seg)
{
addbyte(0x83); /*CMP seg->base, -1*/
addbyte(0x05|0x38);
addlong((uint32_t)&seg->base);
addbyte(-1);
addbyte(0x0f);
addbyte(0x84); /*JE end*/
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
}
static void CHECK_SEG_WRITE(x86seg *seg)
{
addbyte(0x83); /*CMP seg->base, -1*/
addbyte(0x05|0x38);
addlong((uint32_t)&seg->base);
addbyte(-1);
addbyte(0x0f);
addbyte(0x84); /*JE end*/
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
}
static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
{
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
addbyte(0x05);
addlong((uint32_t)&seg->limit_low);
addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/
addbyte(0x82);
addlong(BLOCK_GPF_OFFSET - (block_pos + 4));
if (end_offset)
{
addbyte(0x83); /*ADD EAX, end_offset*/
addbyte(0xc0);
addbyte(end_offset);
addbyte(0x3b); /*CMP EAX, seg->limit_high*/
addbyte(0x05);
addlong((uint32_t)&seg->limit_high);
addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/
addbyte(0x87);
addlong(BLOCK_GPF_OFFSET - (block_pos + 4));
addbyte(0x83); /*SUB EAX, end_offset*/
addbyte(0xe8);
addbyte(end_offset);
}
}
static void MEM_LOAD_ADDR_EA_B(x86seg *seg)
{
addbyte(0x8b); /*MOVL EDX, seg->base*/
addbyte(0x05 | (REG_EDX << 3));
addlong((uint32_t)&seg->base);
addbyte(0x89); /*MOV ESI, EDX*/
addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2);
addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0xd7);
addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea);
addbyte(12);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14);
addbyte(0x95);
addlong((uint32_t)readlookup2);
addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
addbyte(3+2);
addbyte(0x8a); /*MOV AL, [EDX+EDI]*/
addbyte(0x04);
addbyte(0x3a);
addbyte(0xeb); /*JMP done*/
addbyte(4+3+5+7+6);
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addbyte(0x89); /*MOV [ESP], ESI*/
addbyte(0x34);
addbyte(0x24);
addbyte(0xe8); /*CALL readmemb386l*/
addlong((uint32_t)readmemb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
addbyte(0x83); /*CMP abrt, 0*/
addbyte(0x3d);
addlong((uint32_t)&abrt);
addbyte(0);
addbyte(0x0f); /*JNE end*/
addbyte(0x85);
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
/*done:*/
addbyte(0x0f); /*MOVZX EAX, AL*/
addbyte(0xb6);
addbyte(0xc0);
host_reg_mapping[0] = 8;
}
static void MEM_LOAD_ADDR_EA_W(x86seg *seg)
{
addbyte(0x8b); /*MOVL EDX, seg->base*/
addbyte(0x05 | (REG_EDX << 3));
addlong((uint32_t)&seg->base);
addbyte(0x89); /*MOV ESI, EDX*/
addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2);
addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0xd7);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea);
addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/
addbyte(0xc7);
addlong(0xfff);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14);
addbyte(0x95);
addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/
addbyte(3+3+2+4+2);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
addbyte(4+2);
addbyte(0x66); /*MOV AX, [EDX+EDI]*/
addbyte(0x8b);
addbyte(0x04);
addbyte(0x3a);
addbyte(0xeb); /*JMP done*/
addbyte(4+3+5+7+6);
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addbyte(0x89); /*MOV [ESP], ESI*/
addbyte(0x34);
addbyte(0x24);
addbyte(0xe8); /*CALL readmemwl*/
addlong((uint32_t)readmemwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
addbyte(0x83); /*CMP abrt, 0*/
addbyte(0x3d);
addlong((uint32_t)&abrt);
addbyte(0);
addbyte(0x0f);
addbyte(0x85); /*JNE end*/
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
/*done:*/
addbyte(0x0f); /*MOVZX EAX, AX*/
addbyte(0xb7);
addbyte(0xc0);
host_reg_mapping[0] = 8;
}
static void MEM_LOAD_ADDR_EA_L(x86seg *seg)
{
addbyte(0x8b); /*MOVL EDX, seg->base*/
addbyte(0x05 | (REG_EDX << 3));
addlong((uint32_t)&seg->base);
addbyte(0x89); /*MOV ESI, EDX*/
addbyte(0xd6);
addbyte(0x01); /*ADDL EDX, EAX*/
addbyte(0xc2);
addbyte(0x89); /*MOV EDI, EDX*/
addbyte(0xd7);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0xc1); /*SHR EDX, 12*/
addbyte(0xea);
addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/
addbyte(0xc7);
addlong(0xffc);
addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/
addbyte(0x14);
addbyte(0x95);
addlong((uint32_t)readlookup2);
addbyte(0x74); /*JE slowpath*/
addbyte(3+3+2+3+2);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0x83); /*CMP EDX, -1*/
addbyte(0xfa);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
addbyte(3+2);
addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/
addbyte(0x04);
addbyte(0x3a);
addbyte(0xeb); /*JMP done*/
addbyte(4+3+5+7+6);
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addbyte(0x89); /*MOV [ESP], ESI*/
addbyte(0x34);
addbyte(0x24);
addbyte(0xe8); /*CALL readmemll*/
addlong((uint32_t)readmemll - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
addbyte(0x83); /*CMP abrt, 0*/
addbyte(0x3d);
addlong((uint32_t)&abrt);
addbyte(0);
addbyte(0x0f);
addbyte(0x85); /*JNE end*/
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
/*done:*/
host_reg_mapping[0] = 8;
}
static void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr)
{
addbyte(0xb8); /*MOV EAX, addr*/
addlong(addr);
MEM_LOAD_ADDR_EA_B(seg);
}
static void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr)
{
addbyte(0xb8); /*MOV EAX, addr*/
addlong(addr);
MEM_LOAD_ADDR_EA_W(seg);
}
static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr)
{
addbyte(0xb8); /*MOV EAX, addr*/
addlong(addr);
MEM_LOAD_ADDR_EA_L(seg);
}
static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
{
addbyte(0x8b); /*MOVL ESI, seg->base*/
addbyte(0x05 | (REG_ESI << 3));
addlong((uint32_t)&seg->base);
addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0xc0 | (REG_ESI << 3) | REG_EDI);
addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI);
addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/
addbyte(0xc7);
addlong(0xfff);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2);
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
addbyte(3+2);
addbyte(0x88); /*MOV [EDI+ESI],host_reg*/
addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3));
addbyte(0xeb); /*JMP done*/
addbyte(4+5+4+3+5+7+6);
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addbyte(0xa1); /*MOV EAX, seg->base*/
addlong((uint32_t)&seg->base);
addbyte(0x89); /*MOV [ESP+8], host_reg*/
addbyte(0x44 | (host_reg << 3));
addbyte(0x24);
addbyte(0x08);
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xe8); /*CALL writememb386l*/
addlong((uint32_t)writememb386l - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
addbyte(0x83); /*CMP abrt, 0*/
addbyte(0x3d);
addlong((uint32_t)&abrt);
addbyte(0);
addbyte(0x0f); /*JNE end*/
addbyte(0x85);
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
/*done:*/
}
static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
{
addbyte(0x8b); /*MOVL ESI, seg->base*/
addbyte(0x05 | (REG_ESI << 3));
addlong((uint32_t)&seg->base);
addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0xc0 | (REG_ESI << 3) | REG_EDI);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI);
addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xfff*/
addbyte(0xc7);
addlong(0xfff);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/
addbyte(3+3+2+4+2);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
addbyte(4+2);
addbyte(0x66); /*MOV [EDI+ESI],host_reg*/
addbyte(0x89);
addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3));
addbyte(0xeb); /*JMP done*/
addbyte(4+5+4+3+5+7+6);
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addbyte(0xa1); /*MOV EAX, seg->base*/
addlong((uint32_t)&seg->base);
addbyte(0x89); /*MOV [ESP+8], host_reg*/
addbyte(0x44 | (host_reg << 3));
addbyte(0x24);
addbyte(0x08);
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xe8); /*CALL writememwl*/
addlong((uint32_t)writememwl - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
addbyte(0x83); /*CMP abrt, 0*/
addbyte(0x3d);
addlong((uint32_t)&abrt);
addbyte(0);
addbyte(0x0f); /*JNE end*/
addbyte(0x85);
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
/*done:*/
}
static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
{
addbyte(0x8b); /*MOVL ESI, seg->base*/
addbyte(0x05 | (REG_ESI << 3));
addlong((uint32_t)&seg->base);
addbyte(0x01); /*ADDL ESI, EAX*/
addbyte(0xc0 | (REG_EAX << 3) | REG_ESI);
addbyte(0x89); /*MOV EDI, ESI*/
addbyte(0xc0 | (REG_ESI << 3) | REG_EDI);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0xc1); /*SHR ESI, 12*/
addbyte(0xe8 | REG_ESI);
addbyte(12);
addbyte(0xf7); /*TEST EDI, 0xffc*/
addbyte(0xc7);
addlong(0xffc);
addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/
addbyte(0x04 | (REG_ESI << 3));
addbyte(0x85 | (REG_ESI << 3));
addlong((uint32_t)writelookup2);
addbyte(0x74); /*JE slowpath*/
addbyte(3+3+2+3+2);
addbyte(0x83); /*XOR EDI, -1*/
addbyte(0xf7);
addbyte(-1);
addbyte(0x83); /*CMP ESI, -1*/
addbyte(0xf8 | REG_ESI);
addbyte(-1);
addbyte(0x74); /*JE slowpath*/
addbyte(3+2);
addbyte(0x89); /*MOV [EDI+ESI],host_reg*/
addbyte(0x04 | (host_reg << 3));
addbyte(REG_EDI | (REG_ESI << 3));
addbyte(0xeb); /*JMP done*/
addbyte(4+5+4+3+5+7+6);
addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addbyte(0xa1); /*MOV EAX, seg->base*/
addlong((uint32_t)&seg->base);
addbyte(0x89); /*MOV [ESP+8], host_reg*/
addbyte(0x44 | (host_reg << 3));
addbyte(0x24);
addbyte(0x08);
addbyte(0x89); /*MOV [ESP], EAX*/
addbyte(0x04);
addbyte(0x24);
addbyte(0xe8); /*CALL writememll*/
addlong((uint32_t)writememll - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
addbyte(0x83); /*CMP abrt, 0*/
addbyte(0x3d);
addlong((uint32_t)&abrt);
addbyte(0);
addbyte(0x0f); /*JNE end*/
addbyte(0x85);
addlong(BLOCK_EXIT_OFFSET - (block_pos + 4));
/*done:*/
}
static void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg)
{
addbyte(0xb8); /*MOV EAX, addr*/
addlong(addr);
MEM_STORE_ADDR_EA_B(seg, host_reg);
}
static void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg)
{
addbyte(0xb8); /*MOV EAX, addr*/
addlong(addr);
MEM_STORE_ADDR_EA_L(seg, host_reg);
}
static void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg)
{
addbyte(0xb8); /*MOV EAX, addr*/
addlong(addr);
MEM_STORE_ADDR_EA_W(seg, host_reg);
}
static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
{
int mod = (fetchdat >> 6) & 3;
int reg = (fetchdat >> 3) & 7;
int rm = fetchdat & 7;
if (!mod && rm == 6)
{
addbyte(0xb8); /*MOVL EAX, imm16*/
addlong((fetchdat >> 8) & 0xffff);
(*op_pc) += 2;
}
else
{
switch (mod)
{
case 0:
addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/
addlong((uint32_t)mod1add[0][rm]);
addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/
addbyte(0x05);
addlong((uint32_t)mod1add[1][rm]);
break;
case 1:
addbyte(0xb8); /*MOVL EAX, imm8*/
addlong((uint32_t)(int8_t)(rmdat >> 8));// pc++;
addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/
addbyte(0x05);
addlong((uint32_t)mod1add[0][rm]);
addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/
addbyte(0x05);
addlong((uint32_t)mod1add[1][rm]);
(*op_pc)++;
break;
case 2:
addbyte(0xb8); /*MOVL EAX, imm16*/
addlong((fetchdat >> 8) & 0xffff);// pc++;
addbyte(0x03); /*EAX, ADDL *mod1add[0][rm]*/
addbyte(0x05);
addlong((uint32_t)mod1add[0][rm]);
addbyte(0x03); /*EAX, ADDL *mod1add[1][rm]*/
addbyte(0x05);
addlong((uint32_t)mod1add[1][rm]);
(*op_pc) += 2;
break;
}
addbyte(0x25); /*ANDL EAX, 0xffff*/
addlong(0xffff);
if (mod1seg[rm] == &ss && !op_ssegs)
op_ea_seg = &_ss;
}
return op_ea_seg;
}
static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset)
{
uint32_t new_eaaddr;
int mod = (fetchdat >> 6) & 3;
int reg = (fetchdat >> 3) & 7;
int rm = fetchdat & 7;
if (rm == 4)
{
uint8_t sib = fetchdat >> 8;
(*op_pc)++;
switch (mod)
{
case 0:
if ((sib & 7) == 5)
{
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0xb8); /*MOVL EAX, imm32*/
addlong(new_eaaddr);// pc++;
(*op_pc) += 4;
}
else
{
addbyte(0xa1); /*MOVL EAX, regs[sib&7].l*/
addlong((uint32_t)&regs[sib & 7].l);
}
break;
case 1:
new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff);
addbyte(0xb8); /*MOVL EAX, imm8*/
addlong(new_eaaddr);
addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/
addbyte(0x05);
addlong((uint32_t)&regs[sib & 7].l);
(*op_pc)++;
break;
case 2:
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0xb8); /*MOVL EAX, new_eaaddr*/
addlong(new_eaaddr);
addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/
addbyte(0x05);
addlong((uint32_t)&regs[sib & 7].l);
(*op_pc) += 4;
break;
}
if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/
{
addbyte(0x05); /*ADDL EAX, stack_offset*/
addlong(stack_offset);
}
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
op_ea_seg = &_ss;
if (((sib >> 3) & 7) != 4)
{
switch (sib >> 6)
{
case 0:
addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/
addbyte(0x05);
addlong((uint32_t)&regs[(sib >> 3) & 7].l);
break;
case 1:
addbyte(0x8B); addbyte(0x05 | (REG_EDI << 3)); addlong((uint32_t)&regs[(sib >> 3) & 7].l); /*MOVL EDI, reg*/
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
break;
case 2:
addbyte(0x8B); addbyte(0x05 | (REG_EDI << 3)); addlong((uint32_t)&regs[(sib >> 3) & 7].l); /*MOVL EDI, reg*/
addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(2); /*SHL EDI, 2*/
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
break;
case 3:
addbyte(0x8B); addbyte(0x05 | (REG_EDI << 3)); addlong((uint32_t)&regs[(sib >> 3) & 7].l); /*MOVL EDI reg*/
addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(3); /*SHL EDI, 3*/
addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/
break;
}
}
}
else
{
if (!mod && rm == 5)
{
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0xb8); /*MOVL EAX, imm32*/
addlong(new_eaaddr);
(*op_pc) += 4;
return op_ea_seg;
}
addbyte(0xa1); /*MOVL EAX, regs[rm].l*/
addlong((uint32_t)&regs[rm].l);
eaaddr = regs[rm].l;
if (mod)
{
if (rm == 5 && !op_ssegs)
op_ea_seg = &_ss;
if (mod == 1)
{
addbyte(0x05); /*ADD EAX, imm8*/
addlong((uint32_t)(int8_t)(fetchdat >> 8));
(*op_pc)++;
}
else
{
new_eaaddr = fastreadl(cs + (*op_pc) + 1);
addbyte(0x05); /*ADD EAX, imm32*/
addlong(new_eaaddr);
(*op_pc) += 4;
}
}
}
return op_ea_seg;
}
static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32)
{
if (op_32 & 0x200)
return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0);
return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc);
}

View file

@ -10,13 +10,15 @@
#include "x87.h"
#include "mem.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ops.h"
#include "codegen_ops_x86.h"
#include "386_common.h"
#define BLOCK_EXIT_OFFSET 0x7f0
x86seg *op_ea_seg;
int op_ssegs;
uint32_t op_old_pc;
uint32_t recomp_page = -1;
@ -38,6 +40,7 @@ static uint32_t codegen_endpc;
int codegen_block_cycles;
static int codegen_block_ins;
static int codegen_block_full_ins;
static uint32_t last_op32;
static x86seg *last_ea_seg;
@ -188,17 +191,28 @@ void codegen_block_init(uint32_t phys_addr)
block->use32 = use32;
block->next = block->prev = NULL;
block_pos = 0;
block_pos = BLOCK_GPF_OFFSET;
addbyte(0xc7); /*MOV [ESP],0*/
addbyte(0x04);
addbyte(0x24);
addlong(0);
addbyte(0xc7); /*MOV [ESP+4],0*/
addbyte(0x44);
addbyte(0x24);
addbyte(0x04);
addlong(0);
addbyte(0xe8); /*CALL x86gpf*/
addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4]));
block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/
addbyte(0x83); /*ADDL $8,%esp*/
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0xC4);
addbyte(0x08);
addbyte(0x10);
addbyte(0xC3); /*RET*/
cpu_block_end = 0;
block_pos = 0; /*Entry code*/
addbyte(0x83); /*SUBL $8,%esp*/
addbyte(0x83); /*SUBL $16,%esp*/
addbyte(0xEC);
addbyte(0x08);
addbyte(0x10);
// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num);
@ -210,6 +224,7 @@ void codegen_block_init(uint32_t phys_addr)
codegen_timing_block_start();
codegen_block_ins = 0;
codegen_block_full_ins = 0;
recomp_page = phys_addr & ~0xfff;
}
@ -342,11 +357,22 @@ void codegen_block_end()
addlong((uint32_t)&cpu_recomp_ins);
addlong(codegen_block_ins);
}
addbyte(0x83); /*ADDL $8,%esp*/
#if 0
if (codegen_block_full_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x05);
addlong((uint32_t)&cpu_recomp_full_ins);
addlong(codegen_block_full_ins);
}
#endif
addbyte(0x83); /*ADDL $16,%esp*/
addbyte(0xC4);
addbyte(0x08);
addbyte(0x10);
addbyte(0xC3); /*RET*/
if (block_pos > BLOCK_GPF_OFFSET)
fatal("Over limit!\n");
// pclog("End block %i\n", block_num);
recomp_page = -1;
@ -636,8 +662,6 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
uint32_t op_32 = use32;
uint32_t op_pc = new_pc;
OpFn *op_table = x86_dynarec_opcodes;
x86seg *op_ea_seg = &_ds;
int op_ssegs = 0;
int opcode_shift = 0;
int opcode_mask = 0x3ff;
int over = 0;
@ -645,6 +669,10 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
int test_modrm = 1;
int c;
op_ea_seg = &_ds;
op_ssegs = 0;
op_old_pc = old_pc;
for (c = 0; c < NR_HOST_REGS; c++)
host_reg_mapping[c] = -1;
@ -779,6 +807,7 @@ generate_call:
codegen_block_ins++;
block->ins++;
codegen_block_full_ins++;
codegen_endpc = (cs + pc) + 8;
return;
@ -899,6 +928,16 @@ generate_call:
addlong(codegen_block_ins);
codegen_block_ins = 0;
}
#if 0
if (codegen_block_full_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x05);
addlong((uint32_t)&cpu_recomp_full_ins);
addlong(codegen_block_full_ins);
codegen_block_full_ins = 0;
}
#endif
}
block->ins++;

View file

@ -7,6 +7,9 @@
#define HASH(l) ((l) & 0x1ffff)
#define BLOCK_EXIT_OFFSET 0x7f0
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
enum
{
OP_RET = 0xc3

View file

@ -372,6 +372,7 @@ void runpc()
#if DYNAREC
cpu_recomp_blocks_latched = cpu_recomp_blocks;
cpu_recomp_ins_latched = cpu_recomp_ins;
cpu_recomp_full_ins_latched = cpu_recomp_full_ins;
cpu_new_blocks_latched = cpu_new_blocks;
cpu_recomp_flushes_latched = cpu_recomp_flushes;
cpu_recomp_evicted_latched = cpu_recomp_evicted;
@ -382,6 +383,7 @@ void runpc()
cpu_recomp_blocks = 0;
cpu_recomp_ins = 0;
cpu_recomp_full_ins = 0;
cpu_new_blocks = 0;
cpu_recomp_flushes = 0;
cpu_recomp_evicted = 0;

View file

@ -48,7 +48,8 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
"CPU time : %f%% (%f%%)\n"
#ifdef DYNAREC
"New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n"
"Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS\nREP : %i\nnot REP : %i\n"
"Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS"
// "\nFully recompiled ins %% : %f%%"
#endif
,mips,
flops,
@ -67,8 +68,9 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
cpu_recomp_flushes_latched, cpu_recomp_evicted_latched,
cpu_recomp_reuse_latched, cpu_recomp_removed_latched,
((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq),
cpu_reps_latched, cpu_notreps_latched
((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq)
// ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0
// cpu_reps_latched, cpu_notreps_latched
#endif
);
main_time = 0;

View file

@ -101,3 +101,4 @@ extern int inscounts[256];
void x86illegal();
void x86seg_reset();
void x86gpf(char *s, uint16_t error);