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 "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"

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);
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;

View file

@ -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;
}

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)
{
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

View file

@ -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;
}

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);
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

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));
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;
}

View file

@ -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;
}

View file

@ -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]);