Added recompiled versions of MOVD and MOVQ.

This commit is contained in:
SarahW 2018-11-21 17:02:20 +00:00
commit 76115568f2
10 changed files with 320 additions and 15 deletions

View file

@ -699,6 +699,32 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
{
uint32_t *branch_ptr;
if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state))
fatal("codegen_MMX_ENTER - out of range\n");
host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state);
host_arm64_TST_IMM(block, REG_TEMP, 0xc);
branch_ptr = host_arm64_BEQ_(block);
host_arm64_mov_imm(block, REG_TEMP, uop->imm_data);
host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state);
host_arm64_mov_imm(block, REG_ARG0, 7);
host_arm64_call(block, x86_int);
host_arm64_B(block, &block->data[BLOCK_EXIT_OFFSET]);
host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]);
host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state);
host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state);
host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state);
host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state);
return 0;
}
static int codegen_JMP(codeblock_t *block, uop_t *uop)
{
@ -1162,7 +1188,15 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_B(src_size))
if (REG_IS_Q(dest_size) && REG_IS_L(src_size))
{
host_arm64_FMOV_D_Q(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_Q(src_size))
{
host_arm64_FMOV_W_S(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_B(src_size))
{
host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff);
}
@ -1836,6 +1870,7 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST,
[UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER,
[UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER,
[UOP_FADD & UOP_MASK] = codegen_FADD,
[UOP_FCOM & UOP_MASK] = codegen_FCOM,

View file

@ -772,6 +772,33 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
{
uint32_t *branch_ptr;
if (!in_range(&cr0, &cpu_state))
fatal("codegen_MMX_ENTER - out of range\n");
host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state);
host_arm_TST_IMM(block, REG_TEMP, 0xc);
branch_ptr = host_arm_BEQ_(block);
host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data);
host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state);
host_arm_MOV_IMM(block, REG_ARG0, 7);
host_arm_call(block, x86_int);
host_arm_B(block, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
*branch_ptr |= ((((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2;
host_arm_MOV_IMM(block, REG_TEMP, 0);
host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state);
host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state);
host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state);
host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state);
return 0;
}
static int codegen_JMP(codeblock_t *block, uop_t *uop)
{
@ -1238,7 +1265,16 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_B(src_size))
if (REG_IS_Q(dest_size) && REG_IS_L(src_size))
{
host_arm_MOV_IMM(block, REG_TEMP, 0);
host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP);
}
else if (REG_IS_L(dest_size) && REG_IS_Q(src_size))
{
host_arm_VMOV_32_S(block, dest_reg, src_reg, REG_TEMP);
}
else if (REG_IS_L(dest_size) && REG_IS_B(src_size))
{
host_arm_UXTB(block, dest_reg, src_reg, 0);
}
@ -1955,6 +1991,7 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST,
[UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER,
[UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER,
[UOP_FADD & UOP_MASK] = codegen_FADD,
[UOP_FCOM & UOP_MASK] = codegen_FCOM,

View file

@ -641,6 +641,29 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
{
uint8_t *branch_offset;
host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0);
host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc);
branch_offset = host_x86_JZ_short(block);
host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data);
#if WIN64
host_x86_MOV32_REG_IMM(block, REG_ECX, 7);
#else
host_x86_MOV32_REG_IMM(block, REG_EDI, 7);
#endif
host_x86_CALL(block, x86_int);
host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]);
*branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1;
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0);
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0);
host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0);
host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1);
return 0;
}
static int codegen_JMP(codeblock_t *block, uop_t *uop)
{
@ -1076,7 +1099,15 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_W(src_size))
if (REG_IS_Q(dest_size) && REG_IS_L(src_size))
{
host_x86_MOVD_XREG_REG(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_Q(src_size))
{
host_x86_MOVD_REG_XREG(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_W(src_size))
{
host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg);
}
@ -1640,6 +1671,7 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST,
[UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER,
[UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER,
[UOP_FADD & UOP_MASK] = codegen_FADD,
[UOP_FCOM & UOP_MASK] = codegen_FCOM,
@ -1757,6 +1789,10 @@ void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_of
{
host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset);
}
void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset)
{
host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset);
}
void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset)
{
host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset);
@ -1766,6 +1802,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos
{
host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg);
}
void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg)
{
host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg);
}
void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg)
{
host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg);

View file

@ -649,6 +649,26 @@ static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop)
{
uint8_t *branch_offset;
host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0);
host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc);
branch_offset = host_x86_JZ_short(block);
host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data);
host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7);
host_x86_CALL(block, x86_int);
host_x86_JMP(block, &block->data[BLOCK_EXIT_OFFSET]);
*branch_offset = (uint8_t)((uintptr_t)&block->data[block_pos] - (uintptr_t)branch_offset) - 1;
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0);
host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0);
host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0);
host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1);
return 0;
}
static int codegen_JMP(codeblock_t *block, uop_t *uop)
{
host_x86_JMP(block, uop->p);
@ -1073,7 +1093,15 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_L(dest_size) && REG_IS_W(src_size))
if (REG_IS_Q(dest_size) && REG_IS_L(src_size))
{
host_x86_MOVD_XREG_REG(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_Q(src_size))
{
host_x86_MOVD_REG_XREG(block, dest_reg, src_reg);
}
else if (REG_IS_L(dest_size) && REG_IS_W(src_size))
{
host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg);
}
@ -1642,7 +1670,8 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST,
[UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST,
[UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER,
[UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER,
[UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER,
[UOP_FADD & UOP_MASK] = codegen_FADD,
[UOP_FDIV & UOP_MASK] = codegen_FDIV,

View file

@ -167,7 +167,7 @@
/*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/
#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP)
/*UOP_FP_ENTER - */
/*UOP_FP_ENTER - must be called before any FPU register accessed*/
#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER)
/*UOP_FADD - (floating point) dest_reg = src_reg_a + src_reg_b*/
#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81)
@ -180,7 +180,10 @@
/*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/
#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85)
#define UOP_MAX 0x86
/*UOP_MMX_ENTER - must be called before any MMX registers accessed*/
#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER)
#define UOP_MAX 0x91
#define UOP_MASK 0xffff
@ -488,7 +491,8 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; } while (0)
#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0)
#define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0)
#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p)
#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir)
@ -549,6 +553,7 @@ void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_of
void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset);
void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg);
void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg);
void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg);
void codegen_set_jump_dest(codeblock_t *block, void *p);

View file

@ -11,6 +11,7 @@
#include "codegen_ops_jump.h"
#include "codegen_ops_logic.h"
#include "codegen_ops_misc.h"
#include "codegen_ops_mmx_loadstore.h"
#include "codegen_ops_mov.h"
#include "codegen_ops_shift.h"
#include "codegen_ops_stack.h"
@ -74,8 +75,8 @@ RecompOpFn recomp_opcodes_0f[512] =
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r,
/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@ -96,8 +97,8 @@ RecompOpFn recomp_opcodes_0f[512] =
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q,
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r,
/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32,
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,

View file

@ -0,0 +1,106 @@
#include "ibm.h"
#include "x86.h"
#include "x86_flags.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_accumulate.h"
#include "codegen_ir.h"
#include "codegen_ops.h"
#include "codegen_ops_mmx_loadstore.h"
#include "codegen_ops_helpers.h"
uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int dest_reg = (fetchdat >> 3) & 7;
uop_MMX_ENTER(ir);
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr);
uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0);
}
return op_pc + 1;
}
uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7;
uop_MMX_ENTER(ir);
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
codegen_check_seg_write(block, ir, target_seg);
uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg));
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0);
}
return op_pc + 1;
}
uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int dest_reg = (fetchdat >> 3) & 7;
uop_MMX_ENTER(ir);
if ((fetchdat & 0xc0) == 0xc0)
{
int src_reg = fetchdat & 7;
uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
codegen_check_seg_read(block, ir, target_seg);
uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr);
}
return op_pc + 1;
}
uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
int src_reg = (fetchdat >> 3) & 7;
uop_MMX_ENTER(ir);
if ((fetchdat & 0xc0) == 0xc0)
{
int dest_reg = fetchdat & 7;
uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg));
}
else
{
x86seg *target_seg;
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0);
codegen_check_seg_write(block, ir, target_seg);
uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg));
}
return op_pc + 1;
}

View file

@ -0,0 +1,5 @@
uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);

View file

@ -123,6 +123,15 @@ struct
[IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP},
[IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP},
[IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP},
[IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP},
[IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP},
[IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP},
[IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP},
[IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER},
[IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER},
@ -204,6 +213,15 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
else
codegen_direct_read_32(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break;
case REG_QWORD:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_QWORD !REG_FP\n");
if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256)
codegen_direct_read_64_stack(block, reg_set->reg_list[c], (int)ireg_data[IREG_GET_REG(ir_reg.reg)].p);
else
codegen_direct_read_64(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break;
case REG_DOUBLE:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
@ -282,6 +300,15 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
codegen_direct_write_32(block, p, reg_set->reg_list[c]);
break;
case REG_QWORD:
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n");
if ((uintptr_t)p < 256)
codegen_direct_write_64_stack(block, (int)p, reg_set->reg_list[c]);
else
codegen_direct_write_64(block, p, reg_set->reg_list[c]);
break;
case REG_POINTER:
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n");

View file

@ -104,10 +104,19 @@ enum
IREG_ST6_i64 = 62,
IREG_ST7_i64 = 63,
IREG_NPXCx = 64,
IREG_NPXSx = 65,
IREG_MM0x = 64,
IREG_MM1x = 65,
IREG_MM2x = 66,
IREG_MM3x = 67,
IREG_MM4x = 68,
IREG_MM5x = 69,
IREG_MM6x = 70,
IREG_MM7x = 71,
IREG_NPXCx = 72,
IREG_NPXSx = 73,
IREG_COUNT = 66,
IREG_COUNT = 74,
IREG_INVALID = 255,
@ -160,6 +169,15 @@ enum
IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W,
IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W,
IREG_MM0 = IREG_MM0x + IREG_SIZE_Q,
IREG_MM1 = IREG_MM1x + IREG_SIZE_Q,
IREG_MM2 = IREG_MM2x + IREG_SIZE_Q,
IREG_MM3 = IREG_MM3x + IREG_SIZE_Q,
IREG_MM4 = IREG_MM4x + IREG_SIZE_Q,
IREG_MM5 = IREG_MM5x + IREG_SIZE_Q,
IREG_MM6 = IREG_MM6x + IREG_SIZE_Q,
IREG_MM7 = IREG_MM7x + IREG_SIZE_Q,
IREG_NPXC = IREG_NPXCx + IREG_SIZE_W,
IREG_NPXS = IREG_NPXSx + IREG_SIZE_W
};
@ -173,6 +191,8 @@ enum
#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7))
#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B)
#define IREG_MM(reg) ((reg) + IREG_MM0)
#define IREG_TOP_diff_stack_offset 32
static inline int ireg_seg_base(x86seg *seg)