Added recompiled versions of FFREE, FLD, FST, FSTP and FXCH.

This commit is contained in:
SarahW 2018-10-21 16:22:20 +01:00
commit bce9ad4f3d
12 changed files with 364 additions and 27 deletions

View file

@ -18,6 +18,7 @@
#define REG_IS_B(size) (size == IREG_SIZE_B) #define REG_IS_B(size) (size == IREG_SIZE_B)
#define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH)
#define REG_IS_D(size) (size == IREG_SIZE_D) #define REG_IS_D(size) (size == IREG_SIZE_D)
#define REG_IS_Q(size) (size == IREG_SIZE_Q)
static int codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD(codeblock_t *block, uop_t *uop)
{ {
@ -1040,6 +1041,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop)
host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8);
host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8);
} }
else if (REG_IS_D(dest_size) && REG_IS_D(src_size))
{
host_arm64_FMOV_D_D(block, dest_reg, src_reg);
}
else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
{
host_arm64_FMOV_D_D(block, dest_reg, src_reg);
}
else else
fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
@ -1767,6 +1776,13 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
else else
fatal("codegen_direct_read_32 - not in range\n"); fatal("codegen_direct_read_32 - not in range\n");
} }
void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p)
{
if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state))
host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
else
fatal("codegen_direct_read_double - not in range\n");
}
void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p)
{ {
if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state))
@ -1774,6 +1790,22 @@ void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p)
else else
fatal("codegen_direct_read_double - not in range\n"); fatal("codegen_direct_read_double - not in range\n");
} }
void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset);
host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx);
host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state);
host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP);
}
void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset);
host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx);
host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state);
host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP);
}
void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx)
{ {
host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset);
@ -1804,6 +1836,20 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
else else
fatal("codegen_direct_write_32 - not in range\n"); fatal("codegen_direct_write_32 - not in range\n");
} }
void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg)
{
if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state))
host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
else
fatal("codegen_direct_write_double - not in range\n");
}
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg)
{
if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state))
host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
else
fatal("codegen_direct_write_double - not in range\n");
}
void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset); host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset);
@ -1812,12 +1858,13 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int
host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP);
} }
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) host_arm64_LDR_IMM_W(block, REG_TEMP, REG_SP, IREG_TOP_diff_stack_offset);
host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx);
else host_arm64_ADD_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state);
fatal("codegen_direct_write_double - not in range\n"); host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP);
} }
void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {

View file

@ -76,6 +76,7 @@ void host_arm_nop(codeblock_t *block)
#define REG_IS_B(size) (size == IREG_SIZE_B) #define REG_IS_B(size) (size == IREG_SIZE_B)
#define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH)
#define REG_IS_D(size) (size == IREG_SIZE_D) #define REG_IS_D(size) (size == IREG_SIZE_D)
#define REG_IS_Q(size) (size == IREG_SIZE_Q)
static int codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD(codeblock_t *block, uop_t *uop)
{ {
@ -1116,6 +1117,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop)
host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8);
host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8);
} }
else if (REG_IS_D(dest_size) && REG_IS_D(src_size))
{
host_arm_VMOV_D_D(block, dest_reg, src_reg);
}
else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
{
host_arm_VMOV_D_D(block, dest_reg, src_reg);
}
else else
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
@ -1830,6 +1839,13 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FSUB & UOP_MASK] = codegen_FSUB [UOP_FSUB & UOP_MASK] = codegen_FSUB
}; };
void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p)
{
if (in_range_h(p, &cpu_state))
host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
else
fatal("codegen_direct_read_8 - not in range\n");
}
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
{ {
if (in_range_h(p, &cpu_state)) if (in_range_h(p, &cpu_state))
@ -1847,10 +1863,30 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
else else
fatal("codegen_direct_read_32 - not in range\n"); fatal("codegen_direct_read_32 - not in range\n");
} }
void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p)
{
host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
}
void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p)
{ {
host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
} }
void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset);
host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx);
host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3);
host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state);
}
void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset);
host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx);
host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3);
host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state);
}
void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx)
{ {
host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset);
@ -1884,6 +1920,14 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
else else
fatal("codegen_direct_write_32 - not in range\n"); fatal("codegen_direct_write_32 - not in range\n");
} }
void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg)
{
host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
}
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg)
{
host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state);
}
void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset);
@ -1892,9 +1936,13 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int
host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3);
host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state);
} }
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset);
host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx);
host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7);
host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3);
host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state);
} }
void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {

View file

@ -663,6 +663,27 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_r
codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/
} }
void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p)
{
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
if (dst_reg & 8)
fatal("host_x86_MOV8_REG_ABS reg & 8\n");
if (offset >= -128 && offset < 127)
{
codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/
}
else if (offset < (1ull << 32))
{
codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/
codegen_addlong(block, offset);
}
else
{
fatal("host_x86_MOV8_REG_ABS - out of range\n");
}
}
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p)
{ {
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
@ -709,6 +730,21 @@ void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p)
} }
} }
void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift)
{
if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8))
fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n");
if (addr < 0x80 || addr >= 0xffffff80)
{
codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/
}
else
{
codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/
codegen_addlong(block, addr);
}
}
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg)
{ {
if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8))

View file

@ -75,9 +75,12 @@ 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_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_INDEX_REG(codeblock_t *block, int dst_reg, int base_reg, int index_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_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); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift);
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg); void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg);
void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale); void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale);

View file

@ -21,6 +21,7 @@
#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) #define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH)
#define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH)
#define REG_IS_D(size) (size == IREG_SIZE_D) #define REG_IS_D(size) (size == IREG_SIZE_D)
#define REG_IS_Q(size) (size == IREG_SIZE_Q)
static int codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD(codeblock_t *block, uop_t *uop)
{ {
@ -971,6 +972,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop)
{ {
host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
} }
else if (REG_IS_D(dest_size) && REG_IS_D(src_size))
{
host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg);
}
else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
{
host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg);
}
else else
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
@ -1544,6 +1553,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FSUB & UOP_MASK] = codegen_FSUB [UOP_FSUB & UOP_MASK] = codegen_FSUB
}; };
void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p)
{
host_x86_MOV8_REG_ABS(block, host_reg, p);
}
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOV16_REG_ABS(block, host_reg, p); host_x86_MOV16_REG_ABS(block, host_reg, p);
@ -1552,10 +1565,32 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOV32_REG_ABS(block, host_reg, p); host_x86_MOV32_REG_ABS(block, host_reg, p);
} }
void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p)
{
host_x86_MOVQ_XREG_ABS(block, host_reg, p);
}
void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOVQ_XREG_ABS(block, host_reg, p); host_x86_MOVQ_XREG_ABS(block, host_reg, p);
} }
void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset);
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0);
}
void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset);
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3);
}
void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx)
{ {
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
@ -1578,6 +1613,14 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
{ {
host_x86_MOV32_ABS_REG(block, p, host_reg); host_x86_MOV32_ABS_REG(block, p, host_reg);
} }
void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg)
{
host_x86_MOVQ_ABS_XREG(block, p, host_reg);
}
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg)
{
host_x86_MOVQ_ABS_XREG(block, p, host_reg);
}
void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
@ -1587,9 +1630,14 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg);
} }
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
host_x86_MOVQ_ABS_XREG(block, p, host_reg); int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset);
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg);
} }
void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {

View file

@ -571,6 +571,21 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg
codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/
} }
void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p)
{
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
if (offset >= -128 && offset < 127)
{
codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/
}
else
{
codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/
codegen_addbyte(block, 0x05 | (dst_reg << 3));
codegen_addlong(block, (uint32_t)p);
}
}
void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p)
{ {
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
@ -607,6 +622,19 @@ void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p
codegen_addlong(block, (uint32_t)p); codegen_addlong(block, (uint32_t)p);
} }
void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift)
{
if (addr < 0x80 || addr >= 0xffffff80)
{
codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/
}
else
{
codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/
codegen_addlong(block, addr);
}
}
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg)
{ {
codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/

View file

@ -79,11 +79,14 @@ void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg
void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg);
void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_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_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); void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p);
void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift); void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift);
void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_addr, uint32_t addr, int base_reg, int idx_reg, int shift);
void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg);
void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);

View file

@ -31,6 +31,7 @@
#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) #define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH)
#define REG_IS_BH(size) (size == IREG_SIZE_BH) #define REG_IS_BH(size) (size == IREG_SIZE_BH)
#define REG_IS_D(size) (size == IREG_SIZE_D) #define REG_IS_D(size) (size == IREG_SIZE_D)
#define REG_IS_Q(size) (size == IREG_SIZE_Q)
static int codegen_ADD(codeblock_t *block, uop_t *uop) static int codegen_ADD(codeblock_t *block, uop_t *uop)
{ {
@ -962,6 +963,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop)
{ {
host_x86_MOV8_REG_REG(block, dest_reg, src_reg); host_x86_MOV8_REG_REG(block, dest_reg, src_reg);
} }
else if (REG_IS_D(dest_size) && REG_IS_D(src_size))
{
host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg);
}
else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size))
{
host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg);
}
else else
fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
@ -1531,6 +1540,10 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FSUB & UOP_MASK] = codegen_FSUB [UOP_FSUB & UOP_MASK] = codegen_FSUB
}; };
void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p)
{
host_x86_MOV8_REG_ABS(block, host_reg, p);
}
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOV16_REG_ABS(block, host_reg, p); host_x86_MOV16_REG_ABS(block, host_reg, p);
@ -1539,10 +1552,32 @@ void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOV32_REG_ABS(block, host_reg, p); host_x86_MOV32_REG_ABS(block, host_reg, p);
} }
void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p)
{
host_x86_MOVQ_XREG_ABS(block, host_reg, p);
}
void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p)
{ {
host_x86_MOVQ_XREG_ABS(block, host_reg, p); host_x86_MOVQ_XREG_ABS(block, host_reg, p);
} }
void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset);
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0);
}
void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx)
{
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset);
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3);
}
void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx)
{ {
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
@ -1565,6 +1600,14 @@ void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg)
{ {
host_x86_MOV32_ABS_REG(block, p, host_reg); host_x86_MOV32_ABS_REG(block, p, host_reg);
} }
void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg)
{
host_x86_MOVQ_ABS_XREG(block, p, host_reg);
}
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg)
{
host_x86_MOVQ_ABS_XREG(block, p, host_reg);
}
void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
@ -1574,9 +1617,14 @@ void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7); host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg);
} }
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
host_x86_MOVQ_ABS_XREG(block, p, host_reg); int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128);
host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset);
host_x86_ADD32_REG_IMM(block, REG_ECX, REG_ECX, reg_idx);
host_x86_AND32_REG_IMM(block, REG_ECX, REG_ECX, 7);
host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg);
} }
void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg)
{ {
@ -1601,6 +1649,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_ESP, stack_offset); host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, 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_ESP, stack_offset);
}
void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int 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_ESP, stack_offset); host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset);
@ -1610,6 +1662,10 @@ void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int hos
{ {
host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, 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_ESP, stack_offset, host_reg);
}
void codegen_direct_write_double_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)
{ {
host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg);

View file

@ -501,21 +501,28 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) #define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg)
#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) #define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg)
void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p);
void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p);
void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p);
void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p);
void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p);
void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx);
void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx);
void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx); void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx);
void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg);
void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg); void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg);
void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg);
void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg);
void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg); void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg);
void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset);
void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset); void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset);
void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset);
void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset); 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_32_stack(codeblock_t *block, int stack_offset, int host_reg);

View file

@ -6,6 +6,7 @@
#include "codegen_ops_branch.h" #include "codegen_ops_branch.h"
#include "codegen_ops_fpu_arith.h" #include "codegen_ops_fpu_arith.h"
#include "codegen_ops_fpu_loadstore.h" #include "codegen_ops_fpu_loadstore.h"
#include "codegen_ops_fpu_misc.h"
#include "codegen_ops_jump.h" #include "codegen_ops_jump.h"
#include "codegen_ops_logic.h" #include "codegen_ops_logic.h"
#include "codegen_ops_misc.h" #include "codegen_ops_misc.h"
@ -174,8 +175,8 @@ RecompOpFn recomp_opcodes_d9[512] =
/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*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, /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@ -196,8 +197,8 @@ RecompOpFn recomp_opcodes_d9[512] =
/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*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, /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
}; };
@ -362,8 +363,8 @@ RecompOpFn recomp_opcodes_dd[512] =
/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*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, /*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@ -384,8 +385,8 @@ RecompOpFn recomp_opcodes_dd[512] =
/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*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, /*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP,
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
}; };

View file

@ -35,7 +35,8 @@ enum
REG_POINTER, REG_POINTER,
REG_DOUBLE, REG_DOUBLE,
REG_FPU_ST_BYTE, REG_FPU_ST_BYTE,
REG_FPU_ST_DOUBLE REG_FPU_ST_DOUBLE,
REG_FPU_ST_QWORD
}; };
enum enum
@ -113,6 +114,15 @@ struct
[IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER},
[IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER}, [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER},
[IREG_MM0] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM1] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM2] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM3] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM4] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM5] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM6] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
[IREG_MM7] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP},
/*Temporary registers are stored on the stack, and are not guaranteed to /*Temporary registers are stored on the stack, and are not guaranteed to
be preserved across uOPs. They will not be written back if they will be preserved across uOPs. They will not be written back if they will
not be read again.*/ not be read again.*/
@ -121,7 +131,8 @@ struct
[IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER}, [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER},
[IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER}, [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER},
[IREG_temp0d] = {REG_DOUBLE, (void *)48, REG_FP} [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP},
[IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP},
}; };
void codegen_reg_reset() void codegen_reg_reset()
@ -200,7 +211,27 @@ static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c,
codegen_direct_read_double(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p); codegen_direct_read_double(block, reg_set->reg_list[c], ireg_data[IREG_GET_REG(ir_reg.reg)].p);
break; break;
case REG_FPU_ST_BYTE:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER)
fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n");
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_8(block, reg_set->reg_list[c], &cpu_state.tag[ir_reg.reg & 7]);
else
codegen_direct_read_st_8(block, reg_set->reg_list[c], &cpu_state.tag[0], ir_reg.reg & 7);
break;
case REG_FPU_ST_QWORD:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_64(block, reg_set->reg_list[c], &cpu_state.MM[ir_reg.reg & 7]);
else
codegen_direct_read_st_64(block, reg_set->reg_list[c], &cpu_state.MM[0], ir_reg.reg & 7);
break;
case REG_FPU_ST_DOUBLE: case REG_FPU_ST_DOUBLE:
if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP)
fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP) if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]); codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]);
else else
@ -266,13 +297,26 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
break; break;
case REG_FPU_ST_BYTE: case REG_FPU_ST_BYTE:
if (ireg_data[ir_reg].type != REG_INTEGER)
fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n");
if (block->flags & CODEBLOCK_STATIC_TOP) if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]);
else else
codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]); codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]);
break; break;
case REG_FPU_ST_QWORD:
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c]);
else
codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]);
break;
case REG_FPU_ST_DOUBLE: case REG_FPU_ST_DOUBLE:
if (ireg_data[ir_reg].type != REG_FP)
fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n");
if (block->flags & CODEBLOCK_STATIC_TOP) if (block->flags & CODEBLOCK_STATIC_TOP)
codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c]); codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c]);
else else

View file

@ -13,6 +13,7 @@
#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) #define IREG_SIZE_B (2 << IREG_SIZE_SHIFT)
#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) #define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT)
#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) #define IREG_SIZE_D (4 << IREG_SIZE_SHIFT)
#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT)
enum enum
{ {
@ -67,7 +68,8 @@ enum
IREG_FPU_TOP = 37, IREG_FPU_TOP = 37,
IREG_temp0d = 39, IREG_temp0d = 38,
IREG_temp1d = 39,
/*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag()
to access. to access.
@ -93,9 +95,18 @@ enum
IREG_tag6 = 54, IREG_tag6 = 54,
IREG_tag7 = 55, IREG_tag7 = 55,
IREG_COUNT = 56, IREG_MM0 = 56,
IREG_MM1 = 57,
IREG_MM2 = 58,
IREG_MM3 = 59,
IREG_MM4 = 60,
IREG_MM5 = 61,
IREG_MM6 = 62,
IREG_MM7 = 63,
IREG_INVALID = 63, IREG_COUNT = 64,
IREG_INVALID = 255,
IREG_AX = IREG_EAX + IREG_SIZE_W, IREG_AX = IREG_EAX + IREG_SIZE_W,
IREG_CX = IREG_ECX + IREG_SIZE_W, IREG_CX = IREG_ECX + IREG_SIZE_W,
@ -132,6 +143,10 @@ enum
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, IREG_temp1_B = IREG_temp1 + IREG_SIZE_B,
IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, IREG_temp0_D = IREG_temp0d + IREG_SIZE_D,
IREG_temp1_D = IREG_temp1d + IREG_SIZE_D,
IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q,
IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q,
IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W,
@ -148,6 +163,7 @@ enum
#define IREG_32(reg) ((reg) + IREG_EAX) #define IREG_32(reg) ((reg) + IREG_EAX)
#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) #define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D)
#define IREG_MM(r) (IREG_MM0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q)
#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) #define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7))
#define IREG_TOP_diff_stack_offset 32 #define IREG_TOP_diff_stack_offset 32