x86-64 recompiler now at parity with x86-32

This commit is contained in:
TomW 2015-08-04 18:36:27 +01:00
commit 0bf08d9e74
10 changed files with 4591 additions and 222 deletions

View file

@ -9,7 +9,12 @@
#include "cpu.h" #include "cpu.h"
#include "codegen.h" #include "codegen.h"
#include "codegen_ops.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" #include "codegen_ops_x86.h"
#endif
#include "codegen_ops_arith.h" #include "codegen_ops_arith.h"
#include "codegen_ops_fpu.h" #include "codegen_ops_fpu.h"

View file

@ -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); 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); ADD_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1); STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1);
AND_HOST_REG_IMM(host_reg, 0xffff); AND_HOST_REG_IMM(host_reg, 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_INC16); 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); STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1; 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); 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); SUB_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1); STORE_IMM_ADDR_L((uint32_t)&flags_op2, 1);
AND_HOST_REG_IMM(host_reg, 0xffff); AND_HOST_REG_IMM(host_reg, 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_DEC16); 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); STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1; 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); \ dst_reg = LOAD_REG_B(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 8); \ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ 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); \ op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, dst_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_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); \ dst_reg = LOAD_REG_W(fetchdat & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 16); \ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ 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); \ op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, dst_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_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); \ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ 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); \ 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); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(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); \ dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 8); \ 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); \ op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ STORE_HOST_REG_ADDR_BL((uint32_t)&flags_res, dst_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_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); \ dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 16); \ 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); \ op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); \ STORE_HOST_REG_ADDR_WL((uint32_t)&flags_res, dst_reg); \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_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); \ dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 32); \ STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ ## op ## 32); \
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); \ 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); \ 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); \ STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(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_RMW(SUB, SUB, 1)
ROP_ARITH_RM(ADD, ADD, 1) ROP_ARITH_RM(ADD, ADD, 1)
ROP_ARITH_RM(SUB, SUB, 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) 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); 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);
SUB_HOST_REG_B(dst_reg, src_reg); dst_reg = CMP_HOST_REG_B(dst_reg, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); STORE_HOST_REG_ADDR_BL((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);
RELEASE_REG(dst_reg); RELEASE_REG(dst_reg);
RELEASE_REG(src_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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); 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);
SUB_HOST_REG_W(dst_reg, src_reg); dst_reg = CMP_HOST_REG_W(dst_reg, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&flags_op2, src_reg); STORE_HOST_REG_ADDR_WL((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);
RELEASE_REG(dst_reg); RELEASE_REG(dst_reg);
RELEASE_REG(src_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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, dst_reg); 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_op2, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg); STORE_HOST_REG_ADDR((uint32_t)&flags_res, dst_reg);
RELEASE_REG(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); 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); 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_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8); 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); STORE_REG_B_RELEASE(host_reg);
codegen_flags_changed = 1; 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); 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); 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_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); 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); STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1; 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); 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); 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_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); 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); RELEASE_REG(host_reg);
codegen_flags_changed = 1; 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) 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); 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); 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_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); 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); RELEASE_REG(host_reg);
codegen_flags_changed = 1; 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); STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc); 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_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); 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); 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); 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_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); 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); STORE_REG_B_RELEASE(host_reg);
codegen_flags_changed = 1; 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); 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); 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_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); 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); STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1; 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) switch (fetchdat & 0x38)
{ {
case 0x00: /*ADD*/ 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); ADD_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD8); 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
break; break;
case 0x20: /*AND*/ 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
break; break;
case 0x28: /*SUB*/ 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); SUB_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8);
break; break;
case 0x38: /*CMP*/ case 0x38: /*CMP*/
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); 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_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB8);
break; 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) if ((fetchdat & 0x38) != 0x38)
STORE_REG_B_RELEASE(host_reg); STORE_REG_B_RELEASE(host_reg);
else else
@ -524,7 +608,7 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
switch (fetchdat & 0x38) switch (fetchdat & 0x38)
{ {
case 0x00: /*ADD*/ 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); ADD_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
break; break;
case 0x20: /*AND*/ 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
break; break;
case 0x28: /*SUB*/ 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); SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
break; break;
case 0x38: /*CMP*/ case 0x38: /*CMP*/
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); 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_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
break; 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) if ((fetchdat & 0x38) != 0x38)
STORE_REG_W_RELEASE(host_reg); STORE_REG_W_RELEASE(host_reg);
else else
@ -604,7 +688,7 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
break; break;
case 0x38: /*CMP*/ case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); 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_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
break; break;
@ -636,7 +720,7 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
switch (fetchdat & 0x38) switch (fetchdat & 0x38)
{ {
case 0x00: /*ADD*/ 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); ADD_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ADD16); 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
break; break;
case 0x20: /*AND*/ 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
break; break;
case 0x28: /*SUB*/ 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); SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm); STORE_IMM_ADDR_L((uint32_t)&flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); 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); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16);
break; break;
case 0x38: /*CMP*/ case 0x38: /*CMP*/
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); 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_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB16);
break; 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) if ((fetchdat & 0x38) != 0x38)
STORE_REG_W_RELEASE(host_reg); STORE_REG_W_RELEASE(host_reg);
else else
@ -717,7 +801,7 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
break; break;
case 0x38: /*CMP*/ case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&flags_op1, host_reg); 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_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32); STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_SUB32);
break; break;

View file

@ -7,10 +7,10 @@
return 0; \ return 0; \
\ \
dst_reg = LOAD_REG_B(fetchdat & 7); \ 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); \ src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
op ## _HOST_REG_B(dst_reg, src_reg); \ 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); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \ RELEASE_REG(src_reg); \
@ -25,10 +25,10 @@
return 0; \ return 0; \
\ \
dst_reg = LOAD_REG_W(fetchdat & 7); \ 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); \ src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
op ## _HOST_REG_W(dst_reg, src_reg); \ 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); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \ RELEASE_REG(src_reg); \
@ -43,10 +43,10 @@
return 0; \ return 0; \
\ \
dst_reg = LOAD_REG_L(fetchdat & 7); \ 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); \ src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
op ## _HOST_REG_L(dst_reg, src_reg); \ 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); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \ RELEASE_REG(src_reg); \
@ -70,9 +70,9 @@
} \ } \
\ \
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ 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); \ 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); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \ RELEASE_REG(src_reg); \
@ -96,9 +96,9 @@
} \ } \
\ \
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ 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); \ 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); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \ RELEASE_REG(src_reg); \
@ -122,9 +122,9 @@
} \ } \
\ \
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ 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); \ 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); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \ else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \ RELEASE_REG(src_reg); \
@ -134,16 +134,91 @@
ROP_LOGIC(AND, AND, 1) ROP_LOGIC(AND, AND, 1)
ROP_LOGIC(OR, OR, 1) ROP_LOGIC(OR, OR, 1)
ROP_LOGIC(TEST, AND, 0)
ROP_LOGIC(XOR, XOR, 1) 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) 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); int host_reg = LOAD_REG_B(REG_AL);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xff); AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg); STORE_REG_B_RELEASE(host_reg);
return op_pc + 1; 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); int host_reg = LOAD_REG_W(REG_AX);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xffff); AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg); STORE_REG_W_RELEASE(host_reg);
return op_pc + 2; 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); fetchdat = fastreadl(cs + op_pc);
AND_HOST_REG_IMM(host_reg, fetchdat); AND_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg); STORE_REG_L_RELEASE(host_reg);
return op_pc + 4; 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); int host_reg = LOAD_REG_B(REG_AL);
OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); OR_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg); STORE_REG_B_RELEASE(host_reg);
return op_pc + 1; 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); int host_reg = LOAD_REG_W(REG_AX);
OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg); STORE_REG_W_RELEASE(host_reg);
return op_pc + 2; 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); fetchdat = fastreadl(cs + op_pc);
OR_HOST_REG_IMM(host_reg, fetchdat); OR_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg); STORE_REG_L_RELEASE(host_reg);
return op_pc + 4; 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); int host_reg = LOAD_REG_B(REG_AL);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xff); host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
RELEASE_REG(host_reg); RELEASE_REG(host_reg);
return op_pc + 1; 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); int host_reg = LOAD_REG_W(REG_AX);
AND_HOST_REG_IMM(host_reg, fetchdat & 0xffff); host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
RELEASE_REG(host_reg); RELEASE_REG(host_reg);
return op_pc + 2; 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); int host_reg = LOAD_REG_L(REG_EAX);
fetchdat = fastreadl(cs + op_pc); fetchdat = fastreadl(cs + op_pc);
AND_HOST_REG_IMM(host_reg, fetchdat); host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
RELEASE_REG(host_reg); RELEASE_REG(host_reg);
return op_pc + 4; 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); int host_reg = LOAD_REG_B(REG_AL);
XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg); STORE_REG_B_RELEASE(host_reg);
return op_pc + 1; 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); int host_reg = LOAD_REG_W(REG_AX);
XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg); STORE_REG_W_RELEASE(host_reg);
return op_pc + 2; 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); fetchdat = fastreadl(cs + op_pc);
XOR_HOST_REG_IMM(host_reg, fetchdat); XOR_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg); STORE_REG_L_RELEASE(host_reg);
return op_pc + 4; 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); MEM_LOAD_ADDR_EA_B(target_seg);
host_reg = 0; host_reg = 0;
} }
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN8); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN8);
AND_HOST_REG_IMM(host_reg, imm); host_reg = TEST_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_BL((uintptr_t)&flags_res, host_reg);
RELEASE_REG(host_reg); RELEASE_REG(host_reg);
return op_pc + 2; 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) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
imm_reg = LOAD_REG_IMM(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); 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); 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_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; 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); MEM_LOAD_ADDR_EA_W(target_seg);
host_reg = 0; host_reg = 0;
} }
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN16); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN16);
AND_HOST_REG_IMM(host_reg, imm); host_reg = TEST_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR_WL((uintptr_t)&flags_res, host_reg);
RELEASE_REG(host_reg); RELEASE_REG(host_reg);
return op_pc + 3; 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) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
imm_reg = LOAD_REG_IMM(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); 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); 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_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; 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); MEM_LOAD_ADDR_EA_L(target_seg);
host_reg = 0; host_reg = 0;
} }
STORE_IMM_ADDR_L((uint32_t)&flags_op, FLAGS_ZN32); STORE_IMM_ADDR_L((uintptr_t)&flags_op, FLAGS_ZN32);
AND_HOST_REG_IMM(host_reg, imm); host_reg = TEST_HOST_REG_IMM(host_reg, imm);
STORE_HOST_REG_ADDR((uint32_t)&flags_res, host_reg); STORE_HOST_REG_ADDR((uintptr_t)&flags_res, host_reg);
RELEASE_REG(host_reg); RELEASE_REG(host_reg);
return op_pc + 5; 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) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
imm_reg = LOAD_REG_IMM(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); 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); 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_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; return op_pc + 1;
} }

View file

@ -370,7 +370,7 @@ static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
if ((fetchdat & 0xc0) == 0xc0) if ((fetchdat & 0xc0) == 0xc0)
{ {
int host_reg = LOAD_REG_B(fetchdat & 7); 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); STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
} }
else 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) if ((fetchdat & 0xc0) == 0xc0)
{ {
int host_reg = LOAD_REG_B(fetchdat & 7); 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); STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
} }
else 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) if ((fetchdat & 0xc0) == 0xc0)
{ {
int host_reg = LOAD_REG_W(fetchdat & 7); 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); STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
} }
else 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) if ((fetchdat & 0xc0) == 0xc0)
{ {
int host_reg = LOAD_REG_B(fetchdat & 7); 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); STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7);
} }
else 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) if ((fetchdat & 0xc0) == 0xc0)
{ {
int host_reg = LOAD_REG_B(fetchdat & 7); 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); STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
} }
else 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) if ((fetchdat & 0xc0) == 0xc0)
{ {
int host_reg = LOAD_REG_W(fetchdat & 7); 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); STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7);
} }
else else

View file

@ -1,7 +1,7 @@
#define SHIFT(size, size2, count) \ #define SHIFT(size, size2, count, res_store) \
STORE_IMM_ADDR_ ## size((uint32_t)&flags_op2, count); \ STORE_IMM_ADDR_L((uint32_t)&flags_op2, count); \
reg = LOAD_REG_ ## size(fetchdat & 7); \ 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) \ switch (fetchdat & 0x38) \
{ \ { \
@ -21,7 +21,7 @@
break; \ break; \
} \ } \
\ \
STORE_HOST_REG_ADDR((uint32_t)&flags_res, reg); \ res_store((uint32_t)&flags_res, reg); \
STORE_REG_ ## size ## _RELEASE(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) 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; count = (fetchdat >> 8) & 0x1f;
SHIFT(B, 8, count); SHIFT(B, 8, count, STORE_HOST_REG_ADDR_BL);
return op_pc + 2; 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; count = (fetchdat >> 8) & 0x1f;
SHIFT(W, 16, count); SHIFT(W, 16, count, STORE_HOST_REG_ADDR_WL);
return op_pc + 2; 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; count = (fetchdat >> 8) & 0x1f;
SHIFT(L, 32, count); SHIFT(L, 32, count, STORE_HOST_REG_ADDR);
return op_pc + 2; 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) if ((fetchdat & 0x38) < 0x20)
return 0; return 0;
SHIFT(B, 8, 1); SHIFT(B, 8, 1, STORE_HOST_REG_ADDR_BL);
return op_pc + 1; 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) if ((fetchdat & 0x38) < 0x20)
return 0; return 0;
SHIFT(W, 16, 1); SHIFT(W, 16, 1, STORE_HOST_REG_ADDR_WL);
return op_pc + 1; 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) if ((fetchdat & 0x38) < 0x20)
return 0; return 0;
SHIFT(L, 32, 1); SHIFT(L, 32, 1, STORE_HOST_REG_ADDR);
return op_pc + 1; return op_pc + 1;
} }

View file

@ -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); LOAD_EBP_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss); MEM_LOAD_ADDR_EA_W(&_ss);
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ 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); ADD_HOST_REG_IMM_W(host_reg, 2);
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/
return op_pc; 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); LOAD_EBP_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss); MEM_LOAD_ADDR_EA_L(&_ss);
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ 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); ADD_HOST_REG_IMM(host_reg, 4);
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/
return op_pc; return op_pc;
} }

4185
src/codegen_ops_x86-64.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -214,6 +214,8 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg)
addbyte(0x05 | (host_reg << 3)); addbyte(0x05 | (host_reg << 3));
addlong(addr); 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) 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); 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_B OR_HOST_REG_L
#define OR_HOST_REG_W 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_B XOR_HOST_REG_L
#define XOR_HOST_REG_W 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) 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); 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(0x0f); /*MOVZX regl, regb*/
addbyte(0xb6); addbyte(0xb6);
addbyte(0xc0 | reg | (reg << 3)); 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(0x0f); /*MOVZX regl, regb*/
addbyte(0xb6); addbyte(0xb6);
addbyte(0xc0 | reg | (reg << 3)); 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(0x0f); /*MOVZX regl, regw*/
addbyte(0xb7); addbyte(0xb7);
addbyte(0xc0 | reg | (reg << 3)); 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(0x0f); /*MOVSX regl, regb*/
addbyte(0xbe); addbyte(0xbe);
addbyte(0xc0 | reg | (reg << 3)); 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(0x0f); /*MOVSX regl, regb*/
addbyte(0xbe); addbyte(0xbe);
addbyte(0xc0 | reg | (reg << 3)); 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(0x0f); /*MOVSX regl, regw*/
addbyte(0xbf); addbyte(0xbf);
addbyte(0xc0 | reg | (reg << 3)); addbyte(0xc0 | reg | (reg << 3));
return reg;
}
static int COPY_REG(int src_reg)
{
return src_reg;
} }

View file

@ -1,12 +1,13 @@
#define OP_XCHG_AX_(reg) \ #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) \ 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); \ ax_reg = LOAD_REG_W(REG_AX); \
host_reg = LOAD_REG_W(REG_ ## reg); \ 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(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; \ return op_pc; \
} }
@ -22,12 +23,13 @@ OP_XCHG_AX_(BP)
#define OP_XCHG_EAX_(reg) \ #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) \ 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); \ eax_reg = LOAD_REG_L(REG_EAX); \
host_reg = LOAD_REG_L(REG_ ## reg); \ 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(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; \ 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) 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) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
dst_reg = LOAD_REG_B(fetchdat & 7); dst_reg = LOAD_REG_B(fetchdat & 7);
src_reg = LOAD_REG_B((fetchdat >> 3) & 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(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; 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) 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) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
dst_reg = LOAD_REG_W(fetchdat & 7); dst_reg = LOAD_REG_W(fetchdat & 7);
src_reg = LOAD_REG_W((fetchdat >> 3) & 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(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; 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) 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) if ((fetchdat & 0xc0) != 0xc0)
return 0; return 0;
dst_reg = LOAD_REG_L(fetchdat & 7); dst_reg = LOAD_REG_L(fetchdat & 7);
src_reg = LOAD_REG_L((fetchdat >> 3) & 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(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; return op_pc + 1;
} }

View file

@ -24,64 +24,6 @@
#include <windows.h> #include <windows.h>
#endif #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_flags_changed = 0;
int codegen_fpu_entered = 0; int codegen_fpu_entered = 0;
@ -1142,7 +1084,6 @@ generate_call:
} }
#endif #endif
} }
#if 0
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) 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); 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; return;
} }
} }
#endif
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output) // 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]); // 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]);