Added recompiled versions of MOVD and MOVQ.
This commit is contained in:
parent
f545d9d57f
commit
76115568f2
10 changed files with 320 additions and 15 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
106
src/codegen_ops_mmx_loadstore.c
Normal file
106
src/codegen_ops_mmx_loadstore.c
Normal 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;
|
||||
}
|
||||
5
src/codegen_ops_mmx_loadstore.h
Normal file
5
src/codegen_ops_mmx_loadstore.h
Normal 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);
|
||||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue