Added recompiled version of FILDq.
This commit is contained in:
parent
bce9ad4f3d
commit
589f50e479
21 changed files with 150 additions and 24 deletions
|
|
@ -20,6 +20,7 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_quad;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
|
|
@ -93,7 +94,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1);
|
||||
host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)
|
||||
{
|
||||
host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1);
|
||||
host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0);
|
||||
|
|
@ -117,7 +118,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
fatal("build_load_routine - unknown size %i\n", size);
|
||||
if (size == 4 && is_float)
|
||||
host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0);
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)
|
||||
host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1);
|
||||
host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt);
|
||||
host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4);
|
||||
|
|
@ -206,6 +207,8 @@ static void build_loadstore_routines(codeblock_t *block)
|
|||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_quad = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_quad;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
|
|
@ -96,7 +97,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0);
|
||||
else if (size == 4 && is_float)
|
||||
host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0);
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)
|
||||
host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0);
|
||||
host_arm64_MOVZ_IMM(block, REG_W1, 0);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
|
@ -118,7 +119,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
codegen_direct_read_8(block, REG_W1, &cpu_state.abrt);
|
||||
if (size == 4 && is_float)
|
||||
host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0);
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)
|
||||
host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0);
|
||||
host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_SP, 16);
|
||||
host_arm64_RET(block, REG_X30);
|
||||
|
|
@ -205,6 +206,8 @@ static void build_loadstore_routines(codeblock_t *block)
|
|||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_quad = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@
|
|||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_quad;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
|
|||
#define OPCODE_LSR (0x1ac02400)
|
||||
#define OPCODE_NOP (0xd503201f)
|
||||
#define OPCODE_RET (0xd65f0000)
|
||||
#define OPCODE_SCVTF_D_Q (0x9e620000)
|
||||
#define OPCODE_SCVTF_D_W (0x1e620000)
|
||||
#define OPCODE_STR_REG (0xb8206800)
|
||||
#define OPCODE_STRB_REG (0x38206800)
|
||||
|
|
@ -754,6 +755,10 @@ void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int
|
|||
codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31));
|
||||
}
|
||||
|
||||
void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg));
|
||||
}
|
||||
void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg));
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ void host_arm64_RET(codeblock_t *block, int reg);
|
|||
|
||||
void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width);
|
||||
|
||||
void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset);
|
||||
|
|
|
|||
|
|
@ -817,8 +817,12 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_arm64_call(block, codegen_mem_load_long);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_arm64_call(block, codegen_mem_load_quad);
|
||||
}
|
||||
else
|
||||
fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real);
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm64_CBNZ(block, REG_X1, (uintptr_t)&block->data[BLOCK_EXIT_OFFSET]);
|
||||
if (REG_IS_B(dest_size))
|
||||
{
|
||||
|
|
@ -836,6 +840,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_arm64_MOV_REG(block, dest_reg, REG_X0, 0);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1169,6 +1177,11 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
|||
host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16);
|
||||
host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg);
|
||||
host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@
|
|||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_quad;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
|
|
|
|||
|
|
@ -888,6 +888,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_load_long);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_arm_BL(block, (uintptr_t)codegen_mem_load_quad);
|
||||
}
|
||||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_arm_TST_REG(block, REG_R1, REG_R1);
|
||||
|
|
@ -908,6 +912,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_arm_MOV_REG(block, dest_reg, REG_R0);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1237,6 +1245,10 @@ static int codegen_MOVZX(codeblock_t *block, uop_t *uop)
|
|||
|
||||
return 0;
|
||||
}
|
||||
static double int64_to_double(int64_t a)
|
||||
{
|
||||
return (double)a;
|
||||
}
|
||||
static int codegen_MOV_DOUBLE_INT(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);
|
||||
|
|
@ -1253,6 +1265,14 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
|||
host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP);
|
||||
host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
/*ARMv7 has no instructions to convert a 64-bit integer to a double.
|
||||
For simplicity, call a C function and let the compiler do it.*/
|
||||
host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg);
|
||||
host_arm_BL(block, (uintptr_t)int64_to_double); /*Input - R0/R1, Output - D0*/
|
||||
host_arm_VMOV_D_D(block, dest_reg, REG_D0);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_quad;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
|
|
@ -92,7 +93,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX);
|
||||
else if (size == 4 && is_float)
|
||||
host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX);
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)
|
||||
host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX);
|
||||
else
|
||||
fatal("build_load_routine: size=%i\n", size);
|
||||
|
|
@ -131,7 +132,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX);
|
||||
host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)
|
||||
{
|
||||
host_x86_CALL(block, (void *)readmemql);
|
||||
host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX);
|
||||
|
|
@ -242,6 +243,8 @@ static void build_loadstore_routines(codeblock_t *block)
|
|||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_quad = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_quad;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
|
|
|
|||
|
|
@ -348,7 +348,12 @@ void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
|||
|
||||
void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3));
|
||||
codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/
|
||||
}
|
||||
void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg)
|
||||
{
|
||||
codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/
|
||||
codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3));
|
||||
}
|
||||
|
||||
void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b);
|
|||
|
||||
void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
|
|
@ -75,6 +76,8 @@ void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg,
|
|||
void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
|
||||
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg);
|
||||
|
||||
void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
|
|
@ -105,18 +108,17 @@ void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
|||
void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
|
||||
void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift);
|
||||
void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg);
|
||||
void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg);
|
||||
void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg);
|
||||
void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p);
|
||||
void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift);
|
||||
void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
|
||||
void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
|
||||
void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
||||
void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
|
@ -125,8 +127,6 @@ void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg);
|
|||
void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
|
||||
|
||||
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg);
|
||||
|
||||
void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg);
|
||||
void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg);
|
||||
|
|
|
|||
|
|
@ -765,6 +765,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_x86_CALL(block, codegen_mem_load_long);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_x86_CALL(block, codegen_mem_load_quad);
|
||||
}
|
||||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
|
|
@ -781,6 +785,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1069,6 +1077,11 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg);
|
||||
host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg);
|
||||
host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
void *codegen_mem_load_byte;
|
||||
void *codegen_mem_load_word;
|
||||
void *codegen_mem_load_long;
|
||||
void *codegen_mem_load_quad;
|
||||
void *codegen_mem_load_single;
|
||||
void *codegen_mem_load_double;
|
||||
|
||||
|
|
@ -90,7 +91,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX);
|
||||
else if (size == 4 && is_float)
|
||||
host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX);
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8/* && is_float*/)
|
||||
host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX);
|
||||
else
|
||||
fatal("build_load_routine: size=%i\n", size);
|
||||
|
|
@ -123,7 +124,7 @@ static void build_load_routine(codeblock_t *block, int size, int is_float)
|
|||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX);
|
||||
host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
|
||||
}
|
||||
else if (size == 8 && is_float)
|
||||
else if (size == 8)// && is_float)
|
||||
{
|
||||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX);
|
||||
host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX);
|
||||
|
|
@ -228,6 +229,8 @@ static void build_loadstore_routines(codeblock_t *block)
|
|||
build_load_routine(block, 2, 0);
|
||||
codegen_mem_load_long = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 0);
|
||||
codegen_mem_load_quad = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 8, 0);
|
||||
codegen_mem_load_single = &codeblock[block_current].data[block_pos];
|
||||
build_load_routine(block, 4, 1);
|
||||
codegen_mem_load_double = &codeblock[block_current].data[block_pos];
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
extern void *codegen_mem_load_byte;
|
||||
extern void *codegen_mem_load_word;
|
||||
extern void *codegen_mem_load_long;
|
||||
extern void *codegen_mem_load_quad;
|
||||
extern void *codegen_mem_load_single;
|
||||
extern void *codegen_mem_load_double;
|
||||
|
||||
|
|
|
|||
|
|
@ -1316,4 +1316,20 @@ void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32
|
|||
}
|
||||
}
|
||||
|
||||
void host_x87_FILDq_BASE(codeblock_t *block, int base_reg)
|
||||
{
|
||||
if (base_reg == REG_ESP)
|
||||
codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/
|
||||
else
|
||||
codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/
|
||||
}
|
||||
|
||||
void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg)
|
||||
{
|
||||
if (base_reg == REG_ESP)
|
||||
codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/
|
||||
else
|
||||
codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -199,3 +199,6 @@ void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int
|
|||
void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
|
||||
void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data);
|
||||
void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data);
|
||||
|
||||
void host_x87_FILDq_BASE(codeblock_t *block, int base_reg);
|
||||
void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg);
|
||||
|
|
|
|||
|
|
@ -755,6 +755,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_x86_CALL(block, codegen_mem_load_long);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_x86_CALL(block, codegen_mem_load_quad);
|
||||
}
|
||||
else
|
||||
fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real);
|
||||
host_x86_TEST32_REG(block, REG_ESI, REG_ESI);
|
||||
|
|
@ -771,6 +775,10 @@ static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX);
|
||||
}
|
||||
else if (REG_IS_Q(dest_size))
|
||||
{
|
||||
host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1060,6 +1068,15 @@ static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop)
|
|||
host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg);
|
||||
host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX);
|
||||
}
|
||||
else if (REG_IS_D(dest_size) && REG_IS_Q(src_size))
|
||||
{
|
||||
/*There is no SSE instruction to convert a 64-bit integer to a floating point value.
|
||||
Instead we have to bounce the integer through memory via x87.*/
|
||||
host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg);
|
||||
host_x87_FILDq_BASE(block, REG_ESP);
|
||||
host_x87_FSTPd_BASE(block, REG_ESP);
|
||||
host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0);
|
||||
}
|
||||
else
|
||||
fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
|
||||
|
||||
|
|
|
|||
|
|
@ -444,17 +444,17 @@ RecompOpFn recomp_opcodes_df[512] =
|
|||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, 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,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
@ -466,17 +466,17 @@ RecompOpFn recomp_opcodes_df[512] =
|
|||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, 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,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
|
|
|||
|
|
@ -132,3 +132,19 @@ uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
|
||||
return op_pc+1;
|
||||
}
|
||||
uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
|
||||
{
|
||||
x86seg *target_seg;
|
||||
|
||||
uop_FP_ENTER(ir);
|
||||
uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc);
|
||||
op_pc--;
|
||||
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(-1), ireg_seg_base(target_seg), IREG_eaaddr);
|
||||
uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_MM(-1));
|
||||
uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64);
|
||||
fpu_PUSH(ir);
|
||||
|
||||
return op_pc+1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,3 +8,4 @@ uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe
|
|||
|
||||
uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
|
||||
|
|
|
|||
Loading…
Reference in a new issue