x86-64 recompiler now at parity with x86-32
This commit is contained in:
parent
396306bc39
commit
0bf08d9e74
10 changed files with 4591 additions and 222 deletions
|
|
@ -9,7 +9,12 @@
|
|||
#include "cpu.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
|
||||
#ifdef __amd64__
|
||||
#include "codegen_ops_x86-64.h"
|
||||
#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32
|
||||
#include "codegen_ops_x86.h"
|
||||
#endif
|
||||
|
||||
#include "codegen_ops_arith.h"
|
||||
#include "codegen_ops_fpu.h"
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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_INC16);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -45,12 +45,12 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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_DEC16);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -88,10 +88,10 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
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); \
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op1, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op2, src_reg); \
|
||||
op ## _HOST_REG_B(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -109,10 +109,10 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
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); \
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op1, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op2, src_reg); \
|
||||
op ## _HOST_REG_W(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -131,8 +131,8 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
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); \
|
||||
op ## _HOST_REG_L(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
|
|
@ -161,10 +161,10 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
\
|
||||
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 8); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op1, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op2, src_reg); \
|
||||
op ## _HOST_REG_B(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -190,10 +190,10 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
\
|
||||
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 16); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op1, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op2, src_reg); \
|
||||
op ## _HOST_REG_W(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -220,8 +220,8 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
|||
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 32); \
|
||||
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); \
|
||||
op ## _HOST_REG_L(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
|
|
@ -235,7 +235,91 @@ ROP_ARITH_RMW(ADD, ADD, 1)
|
|||
ROP_ARITH_RMW(SUB, SUB, 1)
|
||||
ROP_ARITH_RM(ADD, ADD, 1)
|
||||
ROP_ARITH_RM(SUB, SUB, 1)
|
||||
ROP_ARITH_RM(CMP, SUB, 0)
|
||||
|
||||
static uint32_t ropCMP_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)
|
||||
{
|
||||
src_reg = LOAD_REG_B(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);
|
||||
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_SUB8);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op1, dst_reg);
|
||||
dst_reg = CMP_HOST_REG_B(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropCMP_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)
|
||||
{
|
||||
src_reg = LOAD_REG_W(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);
|
||||
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_SUB16);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op1, dst_reg);
|
||||
dst_reg = CMP_HOST_REG_W(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropCMP_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)
|
||||
{
|
||||
src_reg = LOAD_REG_L(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);
|
||||
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_SUB32);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg);
|
||||
dst_reg = CMP_HOST_REG_L(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
|
|
@ -255,10 +339,10 @@ static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg);
|
||||
SUB_HOST_REG_B(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op1, dst_reg);
|
||||
dst_reg = CMP_HOST_REG_B(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
|
|
@ -283,10 +367,10 @@ static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg);
|
||||
SUB_HOST_REG_W(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op1, dst_reg);
|
||||
dst_reg = CMP_HOST_REG_W(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
|
|
@ -312,7 +396,7 @@ static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg);
|
||||
SUB_HOST_REG_L(dst_reg, src_reg);
|
||||
dst_reg = CMP_HOST_REG_L(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
|
|
@ -327,11 +411,11 @@ static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
{
|
||||
int host_reg = LOAD_REG_B(REG_AL);
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -341,11 +425,11 @@ static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
{
|
||||
int host_reg = LOAD_REG_W(REG_AX);
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -371,11 +455,11 @@ static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
{
|
||||
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_HOST_REG_ADDR_BL((uint32_t)&flags_op1, host_reg);
|
||||
host_reg = CMP_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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -384,12 +468,12 @@ static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
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_HOST_REG_ADDR_WL((uint32_t)&flags_op1, host_reg);
|
||||
host_reg = CMP_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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -401,7 +485,7 @@ static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
SUB_HOST_REG_IMM(host_reg, fetchdat);
|
||||
host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op2, fetchdat);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
|
|
@ -415,11 +499,11 @@ static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
{
|
||||
int host_reg = LOAD_REG_B(REG_AL);
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -429,11 +513,11 @@ static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
{
|
||||
int host_reg = LOAD_REG_W(REG_AX);
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
codegen_flags_changed = 1;
|
||||
|
|
@ -469,7 +553,7 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ADD*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((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);
|
||||
|
|
@ -479,11 +563,11 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
|
||||
break;
|
||||
case 0x20: /*AND*/
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
AND_HOST_REG_IMM(host_reg, imm | 0xffffff00);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
|
||||
break;
|
||||
case 0x28: /*SUB*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((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);
|
||||
|
|
@ -493,14 +577,14 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
|
||||
break;
|
||||
case 0x38: /*CMP*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_B(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_op1, host_reg);
|
||||
host_reg = CMP_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);
|
||||
break;
|
||||
}
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, host_reg);
|
||||
if ((fetchdat & 0x38) != 0x38)
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
else
|
||||
|
|
@ -524,7 +608,7 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ADD*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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);
|
||||
|
|
@ -534,11 +618,11 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
break;
|
||||
case 0x20: /*AND*/
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
AND_HOST_REG_IMM(host_reg, imm | 0xffff0000);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
break;
|
||||
case 0x28: /*SUB*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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);
|
||||
|
|
@ -548,14 +632,14 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
break;
|
||||
case 0x38: /*CMP*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_W(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op1, host_reg);
|
||||
host_reg = CMP_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);
|
||||
break;
|
||||
}
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
if ((fetchdat & 0x38) != 0x38)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else
|
||||
|
|
@ -604,7 +688,7 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
break;
|
||||
case 0x38: /*CMP*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM(host_reg, imm);
|
||||
host_reg = CMP_HOST_REG_IMM_L(host_reg, imm);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
|
||||
break;
|
||||
|
|
@ -636,7 +720,7 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ADD*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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);
|
||||
|
|
@ -646,11 +730,11 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
break;
|
||||
case 0x20: /*AND*/
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
AND_HOST_REG_IMM(host_reg, imm | 0xffff0000);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
break;
|
||||
case 0x28: /*SUB*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((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);
|
||||
|
|
@ -660,14 +744,14 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
break;
|
||||
case 0x38: /*CMP*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM_W(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_op1, host_reg);
|
||||
host_reg = CMP_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);
|
||||
break;
|
||||
}
|
||||
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, host_reg);
|
||||
if ((fetchdat & 0x38) != 0x38)
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
else
|
||||
|
|
@ -717,7 +801,7 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
break;
|
||||
case 0x38: /*CMP*/
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
|
||||
SUB_HOST_REG_IMM(host_reg, imm);
|
||||
host_reg = CMP_HOST_REG_IMM_L(host_reg, imm);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
return 0; \
|
||||
\
|
||||
dst_reg = LOAD_REG_B(fetchdat & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8); \
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
|
||||
op ## _HOST_REG_B(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -25,10 +25,10 @@
|
|||
return 0; \
|
||||
\
|
||||
dst_reg = LOAD_REG_W(fetchdat & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16); \
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
|
||||
op ## _HOST_REG_W(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -43,10 +43,10 @@
|
|||
return 0; \
|
||||
\
|
||||
dst_reg = LOAD_REG_L(fetchdat & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32); \
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
|
||||
op ## _HOST_REG_L(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -70,9 +70,9 @@
|
|||
} \
|
||||
\
|
||||
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8); \
|
||||
op ## _HOST_REG_B(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -96,9 +96,9 @@
|
|||
} \
|
||||
\
|
||||
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16); \
|
||||
op ## _HOST_REG_W(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -122,9 +122,9 @@
|
|||
} \
|
||||
\
|
||||
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32); \
|
||||
op ## _HOST_REG_L(dst_reg, src_reg); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, dst_reg); \
|
||||
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
|
||||
else RELEASE_REG(dst_reg); \
|
||||
RELEASE_REG(src_reg); \
|
||||
|
|
@ -134,16 +134,91 @@
|
|||
|
||||
ROP_LOGIC(AND, AND, 1)
|
||||
ROP_LOGIC(OR, OR, 1)
|
||||
ROP_LOGIC(TEST, AND, 0)
|
||||
ROP_LOGIC(XOR, XOR, 1)
|
||||
|
||||
static uint32_t ropTEST_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)
|
||||
{
|
||||
src_reg = LOAD_REG_B(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);
|
||||
MEM_LOAD_ADDR_EA_B(target_seg);
|
||||
src_reg = 0;
|
||||
}
|
||||
|
||||
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
|
||||
dst_reg = TEST_HOST_REG_B(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropTEST_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)
|
||||
{
|
||||
src_reg = LOAD_REG_W(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);
|
||||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
src_reg = 0;
|
||||
}
|
||||
|
||||
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
|
||||
dst_reg = TEST_HOST_REG_W(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
static uint32_t ropTEST_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)
|
||||
{
|
||||
src_reg = LOAD_REG_L(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);
|
||||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
src_reg = 0;
|
||||
}
|
||||
|
||||
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
|
||||
dst_reg = TEST_HOST_REG_L(dst_reg, src_reg);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, dst_reg);
|
||||
RELEASE_REG(dst_reg);
|
||||
RELEASE_REG(src_reg);
|
||||
|
||||
return op_pc + 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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
|
|
@ -152,9 +227,9 @@ static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
{
|
||||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 2;
|
||||
|
|
@ -165,8 +240,8 @@ static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
AND_HOST_REG_IMM(host_reg, fetchdat);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 4;
|
||||
|
|
@ -177,8 +252,8 @@ static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
|
|
@ -188,8 +263,8 @@ static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 2;
|
||||
|
|
@ -200,8 +275,8 @@ static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
OR_HOST_REG_IMM(host_reg, fetchdat);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 4;
|
||||
|
|
@ -211,9 +286,9 @@ static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
{
|
||||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
|
|
@ -222,9 +297,9 @@ static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
{
|
||||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
return op_pc + 2;
|
||||
|
|
@ -234,9 +309,9 @@ static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_3
|
|||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
|
||||
return op_pc + 4;
|
||||
|
|
@ -247,8 +322,8 @@ static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_B_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 1;
|
||||
|
|
@ -258,8 +333,8 @@ static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
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);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_W_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 2;
|
||||
|
|
@ -270,8 +345,8 @@ static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
|||
|
||||
fetchdat = fastreadl(cs + op_pc);
|
||||
XOR_HOST_REG_IMM(host_reg, fetchdat);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
STORE_REG_L_RELEASE(host_reg);
|
||||
|
||||
return op_pc + 4;
|
||||
|
|
@ -299,9 +374,9 @@ static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
MEM_LOAD_ADDR_EA_B(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
|
||||
host_reg = TEST_HOST_REG_IMM(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
return op_pc + 2;
|
||||
|
||||
|
|
@ -317,13 +392,13 @@ static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
imm_reg = LOAD_REG_IMM(0);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB8);
|
||||
host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, imm_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_op1, imm_reg);
|
||||
SUB_HOST_REG_B(imm_reg, host_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, host_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_op2, host_reg);
|
||||
STORE_REG_TARGET_B_RELEASE(imm_reg, fetchdat & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, imm_reg);
|
||||
STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, imm_reg);
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
|
@ -351,9 +426,9 @@ static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
MEM_LOAD_ADDR_EA_W(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
|
||||
host_reg = TEST_HOST_REG_IMM(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
return op_pc + 3;
|
||||
|
||||
|
|
@ -369,13 +444,13 @@ static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
imm_reg = LOAD_REG_IMM(0);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB16);
|
||||
host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, imm_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_op1, imm_reg);
|
||||
SUB_HOST_REG_W(imm_reg, host_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, host_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_op2, host_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(imm_reg, fetchdat & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, imm_reg);
|
||||
STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, imm_reg);
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
|
@ -403,9 +478,9 @@ static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
MEM_LOAD_ADDR_EA_L(target_seg);
|
||||
host_reg = 0;
|
||||
}
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32);
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
|
||||
host_reg = TEST_HOST_REG_IMM(host_reg, imm);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
|
||||
RELEASE_REG(host_reg);
|
||||
return op_pc + 5;
|
||||
|
||||
|
|
@ -421,13 +496,13 @@ static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
imm_reg = LOAD_REG_IMM(0);
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_SUB32);
|
||||
host_reg = LOAD_REG_L(fetchdat & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, imm_reg);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_op1, imm_reg);
|
||||
SUB_HOST_REG_L(imm_reg, host_reg);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, host_reg);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_op2, host_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(imm_reg, fetchdat & 7);
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, imm_reg);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&flags_res, imm_reg);
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
ZERO_EXTEND_W_B(host_reg);
|
||||
host_reg = ZERO_EXTEND_W_B(host_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
|
||||
}
|
||||
else
|
||||
|
|
@ -393,7 +393,7 @@ static uint32_t ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
ZERO_EXTEND_L_B(host_reg);
|
||||
host_reg = ZERO_EXTEND_L_B(host_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
|
||||
}
|
||||
else
|
||||
|
|
@ -416,7 +416,7 @@ static uint32_t ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
ZERO_EXTEND_L_W(host_reg);
|
||||
host_reg = ZERO_EXTEND_L_W(host_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
|
||||
}
|
||||
else
|
||||
|
|
@ -440,7 +440,7 @@ static uint32_t ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
SIGN_EXTEND_W_B(host_reg);
|
||||
host_reg = SIGN_EXTEND_W_B(host_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
|
||||
}
|
||||
else
|
||||
|
|
@ -463,7 +463,7 @@ static uint32_t ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_B(fetchdat & 7);
|
||||
SIGN_EXTEND_L_B(host_reg);
|
||||
host_reg = SIGN_EXTEND_L_B(host_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
|
||||
}
|
||||
else
|
||||
|
|
@ -486,7 +486,7 @@ static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
|||
if ((fetchdat & 0xc0) == 0xc0)
|
||||
{
|
||||
int host_reg = LOAD_REG_W(fetchdat & 7);
|
||||
SIGN_EXTEND_L_W(host_reg);
|
||||
host_reg = SIGN_EXTEND_L_W(host_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#define SHIFT(size, size2, count) \
|
||||
STORE_IMM_ADDR_ ## size((uint32_t)&flags_op2, count); \
|
||||
#define SHIFT(size, size2, count, res_store) \
|
||||
STORE_IMM_ADDR_L((uint32_t)&flags_op2, count); \
|
||||
reg = LOAD_REG_ ## size(fetchdat & 7); \
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, reg); \
|
||||
res_store((uint32_t)&flags_op1, reg); \
|
||||
\
|
||||
switch (fetchdat & 0x38) \
|
||||
{ \
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
break; \
|
||||
} \
|
||||
\
|
||||
STORE_HOST_REG_ADDR((uint32_t)&flags_res, reg); \
|
||||
res_store((uint32_t)&flags_res, reg); \
|
||||
STORE_REG_ ## size ## _RELEASE(reg);
|
||||
|
||||
static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
|
|
@ -36,7 +36,7 @@ static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
|
||||
count = (fetchdat >> 8) & 0x1f;
|
||||
|
||||
SHIFT(B, 8, count);
|
||||
SHIFT(B, 8, count, STORE_HOST_REG_ADDR_BL);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
|
||||
count = (fetchdat >> 8) & 0x1f;
|
||||
|
||||
SHIFT(W, 16, count);
|
||||
SHIFT(W, 16, count, STORE_HOST_REG_ADDR_WL);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
|
||||
count = (fetchdat >> 8) & 0x1f;
|
||||
|
||||
SHIFT(L, 32, count);
|
||||
SHIFT(L, 32, count, STORE_HOST_REG_ADDR);
|
||||
|
||||
return op_pc + 2;
|
||||
}
|
||||
|
|
@ -82,7 +82,7 @@ static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
|
|||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(B, 8, 1);
|
||||
SHIFT(B, 8, 1, STORE_HOST_REG_ADDR_BL);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
|
@ -95,7 +95,7 @@ static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(W, 16, 1);
|
||||
SHIFT(W, 16, 1, STORE_HOST_REG_ADDR_WL);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
|
|||
if ((fetchdat & 0x38) < 0x20)
|
||||
return 0;
|
||||
|
||||
SHIFT(L, 32, 1);
|
||||
SHIFT(L, 32, 1, STORE_HOST_REG_ADDR);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -197,9 +197,9 @@ static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
|||
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);
|
||||
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
|
@ -211,9 +211,9 @@ static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
|||
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);
|
||||
|
||||
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
|
||||
|
||||
return op_pc;
|
||||
}
|
||||
|
|
|
|||
4185
src/codegen_ops_x86-64.h
Normal file
4185
src/codegen_ops_x86-64.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -214,6 +214,8 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg)
|
|||
addbyte(0x05 | (host_reg << 3));
|
||||
addlong(addr);
|
||||
}
|
||||
#define STORE_HOST_REG_ADDR_BL STORE_HOST_REG_ADDR
|
||||
#define STORE_HOST_REG_ADDR_WL STORE_HOST_REG_ADDR
|
||||
|
||||
static void ADD_HOST_REG_B(int dst_reg, int src_reg)
|
||||
{
|
||||
|
|
@ -292,6 +294,30 @@ static void AND_HOST_REG_IMM(int host_reg, uint32_t imm)
|
|||
addlong(imm);
|
||||
}
|
||||
}
|
||||
static int TEST_HOST_REG_B(int dst_reg, int src_reg)
|
||||
{
|
||||
AND_HOST_REG_B(dst_reg, src_reg);
|
||||
|
||||
return dst_reg;
|
||||
}
|
||||
static int TEST_HOST_REG_W(int dst_reg, int src_reg)
|
||||
{
|
||||
AND_HOST_REG_W(dst_reg, src_reg);
|
||||
|
||||
return dst_reg;
|
||||
}
|
||||
static int TEST_HOST_REG_L(int dst_reg, int src_reg)
|
||||
{
|
||||
AND_HOST_REG_L(dst_reg, src_reg);
|
||||
|
||||
return dst_reg;
|
||||
}
|
||||
static int TEST_HOST_REG_IMM(int host_reg, uint32_t imm)
|
||||
{
|
||||
AND_HOST_REG_IMM(host_reg, imm);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
|
||||
#define OR_HOST_REG_B OR_HOST_REG_L
|
||||
#define OR_HOST_REG_W OR_HOST_REG_L
|
||||
|
|
@ -372,6 +398,43 @@ static void SUB_HOST_REG_IMM(int host_reg, uint32_t imm)
|
|||
}
|
||||
}
|
||||
|
||||
static int CMP_HOST_REG_B(int dst_reg, int src_reg)
|
||||
{
|
||||
SUB_HOST_REG_B(dst_reg, src_reg);
|
||||
|
||||
return dst_reg;
|
||||
}
|
||||
static int CMP_HOST_REG_W(int dst_reg, int src_reg)
|
||||
{
|
||||
SUB_HOST_REG_W(dst_reg, src_reg);
|
||||
|
||||
return dst_reg;
|
||||
}
|
||||
static int CMP_HOST_REG_L(int dst_reg, int src_reg)
|
||||
{
|
||||
SUB_HOST_REG_L(dst_reg, src_reg);
|
||||
|
||||
return dst_reg;
|
||||
}
|
||||
static int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm)
|
||||
{
|
||||
SUB_HOST_REG_IMM_B(host_reg, imm);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
static int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm)
|
||||
{
|
||||
SUB_HOST_REG_IMM_W(host_reg, imm);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
static int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm)
|
||||
{
|
||||
SUB_HOST_REG_IMM(host_reg, imm);
|
||||
|
||||
return host_reg;
|
||||
}
|
||||
|
||||
#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)
|
||||
|
|
@ -2647,40 +2710,51 @@ static void FP_COMPARE_REG(int dst, int src)
|
|||
addlong(((uintptr_t)&npxs) + 1);
|
||||
}
|
||||
|
||||
static void ZERO_EXTEND_W_B(int reg)
|
||||
static int ZERO_EXTEND_W_B(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX regl, regb*/
|
||||
addbyte(0xb6);
|
||||
addbyte(0xc0 | reg | (reg << 3));
|
||||
return reg;
|
||||
}
|
||||
static void ZERO_EXTEND_L_B(int reg)
|
||||
static int ZERO_EXTEND_L_B(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX regl, regb*/
|
||||
addbyte(0xb6);
|
||||
addbyte(0xc0 | reg | (reg << 3));
|
||||
return reg;
|
||||
}
|
||||
static void ZERO_EXTEND_L_W(int reg)
|
||||
static int ZERO_EXTEND_L_W(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVZX regl, regw*/
|
||||
addbyte(0xb7);
|
||||
addbyte(0xc0 | reg | (reg << 3));
|
||||
return reg;
|
||||
}
|
||||
|
||||
static void SIGN_EXTEND_W_B(int reg)
|
||||
static int SIGN_EXTEND_W_B(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVSX regl, regb*/
|
||||
addbyte(0xbe);
|
||||
addbyte(0xc0 | reg | (reg << 3));
|
||||
return reg;
|
||||
}
|
||||
static void SIGN_EXTEND_L_B(int reg)
|
||||
static int SIGN_EXTEND_L_B(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVSX regl, regb*/
|
||||
addbyte(0xbe);
|
||||
addbyte(0xc0 | reg | (reg << 3));
|
||||
return reg;
|
||||
}
|
||||
static void SIGN_EXTEND_L_W(int reg)
|
||||
static int SIGN_EXTEND_L_W(int reg)
|
||||
{
|
||||
addbyte(0x0f); /*MOVSX regl, regw*/
|
||||
addbyte(0xbf);
|
||||
addbyte(0xc0 | reg | (reg << 3));
|
||||
return reg;
|
||||
}
|
||||
|
||||
static int COPY_REG(int src_reg)
|
||||
{
|
||||
return src_reg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
#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; \
|
||||
int ax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
ax_reg = LOAD_REG_W(REG_AX); \
|
||||
host_reg = LOAD_REG_W(REG_ ## reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); \
|
||||
STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
|
@ -22,12 +23,13 @@ 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; \
|
||||
int eax_reg, host_reg, temp_reg; \
|
||||
\
|
||||
eax_reg = LOAD_REG_L(REG_EAX); \
|
||||
host_reg = LOAD_REG_L(REG_ ## reg); \
|
||||
temp_reg = COPY_REG(host_reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_EAX); \
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
|
@ -42,43 +44,46 @@ 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;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_B(fetchdat & 7);
|
||||
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_B_RELEASE(src_reg, fetchdat & 7);
|
||||
STORE_REG_TARGET_B_RELEASE(temp_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;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_W(fetchdat & 7);
|
||||
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_W_RELEASE(src_reg, fetchdat & 7);
|
||||
STORE_REG_TARGET_W_RELEASE(temp_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;
|
||||
int src_reg, dst_reg, temp_reg;
|
||||
|
||||
if ((fetchdat & 0xc0) != 0xc0)
|
||||
return 0;
|
||||
|
||||
dst_reg = LOAD_REG_L(fetchdat & 7);
|
||||
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
|
||||
temp_reg = COPY_REG(src_reg);
|
||||
STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7);
|
||||
STORE_REG_TARGET_L_RELEASE(src_reg, fetchdat & 7);
|
||||
STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7);
|
||||
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,64 +24,6 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static void load_param_1_32(codeblock_t *block, uint32_t param)
|
||||
{
|
||||
#if WIN64
|
||||
addbyte(0xb9); /*MOVL $fetchdat,%ecx*/
|
||||
#else
|
||||
addbyte(0xbf); /*MOVL $fetchdat,%edi*/
|
||||
#endif
|
||||
addlong(param);
|
||||
}
|
||||
static void load_param_1_64(codeblock_t *block, uint64_t param)
|
||||
{
|
||||
addbyte(0x48);
|
||||
#if WIN64
|
||||
addbyte(0xb9); /*MOVL $fetchdat,%ecx*/
|
||||
#else
|
||||
addbyte(0xbf); /*MOVL $fetchdat,%edi*/
|
||||
#endif
|
||||
addquad(param);
|
||||
}
|
||||
|
||||
static void load_param_2_32(codeblock_t *block, uint32_t param)
|
||||
{
|
||||
#if WIN64
|
||||
addbyte(0xba); /*MOVL $fetchdat,%edx*/
|
||||
#else
|
||||
addbyte(0xbe); /*MOVL $fetchdat,%esi*/
|
||||
#endif
|
||||
addlong(param);
|
||||
}
|
||||
static void load_param_2_64(codeblock_t *block, uint64_t param)
|
||||
{
|
||||
addbyte(0x48);
|
||||
#if WIN64
|
||||
addbyte(0xba); /*MOVL $fetchdat,%edx*/
|
||||
#else
|
||||
addbyte(0xbe); /*MOVL $fetchdat,%esi*/
|
||||
#endif
|
||||
addquad(param);
|
||||
}
|
||||
|
||||
static void call(codeblock_t *block, uintptr_t func)
|
||||
{
|
||||
uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5];
|
||||
|
||||
if (diff >= -0x80000000 && diff < 0x7fffffff)
|
||||
{
|
||||
addbyte(0xE8); /*CALL*/
|
||||
addlong((uint32_t)diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
addbyte(0x48); /*MOV RAX, func*/
|
||||
addbyte(0xb8);
|
||||
addquad(func);
|
||||
addbyte(0xff); /*CALL RAX*/
|
||||
addbyte(0xd0);
|
||||
}
|
||||
}
|
||||
|
||||
int codegen_flags_changed = 0;
|
||||
int codegen_fpu_entered = 0;
|
||||
|
|
@ -1142,7 +1084,6 @@ generate_call:
|
|||
}
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff])
|
||||
{
|
||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
|
|
@ -1159,7 +1100,7 @@ generate_call:
|
|||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
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]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue