Added code generation for register and immediate PUSH/POP, RET, relative CALL and JMP instructions.
This commit is contained in:
parent
42155b4c6a
commit
a97e89e857
8 changed files with 371 additions and 17 deletions
|
|
@ -1191,7 +1191,7 @@ void exec386(int cycs)
|
|||
|
||||
cycdiff=0;
|
||||
oldcyc=cycles;
|
||||
// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x %i\n", CS, pc, SS,ESP, codeblock_page_dirty[0x1de]);
|
||||
// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP);
|
||||
if (!CACHE_ON()) /*Interpret block*/
|
||||
{
|
||||
cpu_block_end = 0;
|
||||
|
|
@ -1265,7 +1265,7 @@ void exec386(int cycs)
|
|||
and physical address. The physical address check will
|
||||
also catch any page faults at this stage*/
|
||||
valid_block = (block->pc == cs + pc) && (block->_cs == cs) &&
|
||||
(block->use32 == use32) && (block->phys == phys_addr);
|
||||
(block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32);
|
||||
|
||||
if (valid_block && (block->page_mask & page->dirty_mask))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ typedef struct codeblock_t
|
|||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t use32;
|
||||
int stack32;
|
||||
int pnt;
|
||||
int ins;
|
||||
uint64_t page_mask, page_mask2;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@
|
|||
#include "codegen_ops_x86.h"
|
||||
|
||||
#include "codegen_ops_arith.h"
|
||||
#include "codegen_ops_jump.h"
|
||||
#include "codegen_ops_logic.h"
|
||||
#include "codegen_ops_mov.h"
|
||||
#include "codegen_ops_stack.h"
|
||||
#include "codegen_ops_xchg.h"
|
||||
|
||||
RecompOpFn recomp_opcodes[512] =
|
||||
|
|
@ -24,8 +26,8 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*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,
|
||||
/*50*/ ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPUSH_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16, ropPOP_16,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_b16,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,
|
||||
|
|
@ -33,9 +35,9 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*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,
|
||||
/*c0*/ NULL, NULL, ropRET_imm_16, ropRET_16, NULL, NULL, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
|
|
@ -46,8 +48,8 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*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,
|
||||
/*50*/ ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPUSH_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32, ropPOP_32,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_b32,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,
|
||||
|
|
@ -55,9 +57,9 @@ RecompOpFn recomp_opcodes[512] =
|
|||
/*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,
|
||||
/*c0*/ NULL, NULL, ropRET_imm_32, ropRET_32, NULL, NULL, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
29
src/codegen_ops_jump.h
Normal file
29
src/codegen_ops_jump.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fetchdat & 0xff;
|
||||
|
||||
if (offset & 0x80)
|
||||
offset |= 0xffffff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&pc, op_pc+1+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&pc, (op_pc+2+offset) & 0xffff);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&pc, op_pc+4+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
219
src/codegen_ops_stack.h
Normal file
219
src/codegen_ops_stack.h
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_L(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t imm = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+2;
|
||||
}
|
||||
static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t imm = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+4;
|
||||
}
|
||||
|
||||
static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
|
||||
if (imm & 0x80)
|
||||
imm |= 0xff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t imm = fetchdat & 0xff;
|
||||
int host_reg;
|
||||
|
||||
if (imm & 0x80)
|
||||
imm |= 0xffffff00;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
|
||||
static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
SP_MODIFY(2);
|
||||
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
SP_MODIFY(4);
|
||||
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
STORE_HOST_REG_ADDR(&pc, 0);
|
||||
SP_MODIFY(2);
|
||||
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
STORE_HOST_REG_ADDR(&pc, 0);
|
||||
SP_MODIFY(4);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
STORE_HOST_REG_ADDR(&pc, 0);
|
||||
SP_MODIFY(2+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
STORE_HOST_REG_ADDR(&pc, 0);
|
||||
SP_MODIFY(4+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint16_t offset = fetchdat & 0xffff;
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc+2);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L(&pc, (op_pc+2+offset) & 0xffff);
|
||||
|
||||
return -1;
|
||||
}
|
||||
static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
uint32_t offset = fastreadl(cs + op_pc);
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc+4);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L(&pc, op_pc+4+offset);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
|
||||
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
|
||||
ADD_HOST_REG_IMM_W(host_reg, 2);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
int host_reg;
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
|
||||
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
|
||||
ADD_HOST_REG_IMM(host_reg, 4);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
|
@ -915,3 +915,102 @@ static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
static void LOAD_STACK_TO_EA(int off)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EAX,[ESP]*/
|
||||
addbyte(0x05 | (REG_EAX << 3));
|
||||
addlong((uint32_t)&ESP);
|
||||
if (off)
|
||||
{
|
||||
addbyte(0x83); /*ADD EAX, off*/
|
||||
addbyte(0xc0 | (0 << 3) | REG_EAX);
|
||||
addbyte(off);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX EAX,W[ESP]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0x05 | (REG_EAX << 3));
|
||||
addlong((uint32_t)&ESP);
|
||||
if (off)
|
||||
{
|
||||
addbyte(0x66); /*ADD AX, off*/
|
||||
addbyte(0x05);
|
||||
addword(off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LOAD_EBP_TO_EA(int off)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
addbyte(0x8b); /*MOVL EAX,[EBP]*/
|
||||
addbyte(0x05 | (REG_EAX << 3));
|
||||
addlong((uint32_t)&EBP);
|
||||
if (off)
|
||||
{
|
||||
addbyte(0x83); /*ADD EAX, off*/
|
||||
addbyte(0xc0 | (0 << 3) | REG_EAX);
|
||||
addbyte(off);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX EAX,W[EBP]*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0x05 | (REG_EAX << 3));
|
||||
addlong((uint32_t)&EBP);
|
||||
if (off)
|
||||
{
|
||||
addbyte(0x66); /*ADD AX, off*/
|
||||
addbyte(0x05);
|
||||
addword(off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void SP_MODIFY(int off)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
if (off < 0x80)
|
||||
{
|
||||
addbyte(0x83); /*ADD [ESP], off*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&ESP);
|
||||
addbyte(off);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x81); /*ADD [ESP], off*/
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&ESP);
|
||||
addlong(off);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (off < 0x80)
|
||||
{
|
||||
addbyte(0x66); /*ADD [SP], off*/
|
||||
addbyte(0x83);
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&SP);
|
||||
addbyte(off);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x66); /*ADD [SP], off*/
|
||||
addbyte(0x81);
|
||||
addbyte(0x05);
|
||||
addlong((uint32_t)&SP);
|
||||
addword(off);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ void codegen_block_init(uint32_t phys_addr)
|
|||
block->pnt = block_current;
|
||||
block->phys = phys_addr;
|
||||
block->use32 = use32;
|
||||
block->stack32 = stack32;
|
||||
block->next = block->prev = NULL;
|
||||
|
||||
block_pos = BLOCK_GPF_OFFSET;
|
||||
|
|
@ -803,7 +804,8 @@ generate_call:
|
|||
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);
|
||||
if (new_pc != -1)
|
||||
STORE_IMM_ADDR_L((uintptr_t)&pc, new_pc);
|
||||
|
||||
codegen_block_ins++;
|
||||
block->ins++;
|
||||
|
|
|
|||
|
|
@ -154,7 +154,8 @@ static int opMOV_seg_w_a16(uint32_t fetchdat)
|
|||
fetchdat = fastreadl(cs + pc);
|
||||
pc++;
|
||||
if (abrt) return 1;
|
||||
return x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8);
|
||||
x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &_fs);
|
||||
break;
|
||||
|
|
@ -192,7 +193,8 @@ static int opMOV_seg_w_a32(uint32_t fetchdat)
|
|||
fetchdat = fastreadl(cs + pc);
|
||||
pc++;
|
||||
if (abrt) return 1;
|
||||
return x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8);
|
||||
x86_opcodes[(fetchdat & 0xff) | op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &_fs);
|
||||
break;
|
||||
|
|
@ -277,7 +279,7 @@ static int opLSS_w_a16(uint32_t fetchdat)
|
|||
regs[reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static int opLSS_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
|
|
@ -291,7 +293,7 @@ static int opLSS_w_a32(uint32_t fetchdat)
|
|||
regs[reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static int opLSS_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
|
|
@ -306,7 +308,7 @@ static int opLSS_l_a16(uint32_t fetchdat)
|
|||
regs[reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static int opLSS_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
|
|
@ -321,7 +323,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
|||
regs[reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define opLsel(name, sel) \
|
||||
|
|
|
|||
Loading…
Reference in a new issue