Added recompiled version of FILDq.

This commit is contained in:
SarahW 2018-10-22 21:23:09 +01:00
commit 589f50e479
21 changed files with 150 additions and 24 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

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