Added recompiled versions of FFREE, FLD, FST, FSTP and FXCH.
This commit is contained in:
parent
6d8af5df4a
commit
bce9ad4f3d
12 changed files with 364 additions and 27 deletions
|
|
@ -18,6 +18,7 @@
|
|||
#define REG_IS_B(size) (size == IREG_SIZE_B)
|
||||
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
|
||||
#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)
|
||||
{
|
||||
|
|
@ -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_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
|
||||
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
|
||||
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)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
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_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_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");
|
||||
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_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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ void host_arm_nop(codeblock_t *block)
|
|||
#define REG_IS_B(size) (size == IREG_SIZE_B)
|
||||
#define REG_IS_BH(size) (size == IREG_SIZE_BH)
|
||||
#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)
|
||||
{
|
||||
|
|
@ -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_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
|
||||
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
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
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)
|
||||
{
|
||||
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_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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8))
|
||||
|
|
|
|||
|
|
@ -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_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_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_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#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_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)
|
||||
{
|
||||
|
|
@ -971,6 +972,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
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
|
||||
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
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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_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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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*/
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/
|
||||
|
|
|
|||
|
|
@ -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_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_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_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_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#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_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)
|
||||
{
|
||||
|
|
@ -962,6 +963,14 @@ static int codegen_MOV(codeblock_t *block, uop_t *uop)
|
|||
{
|
||||
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
|
||||
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
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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_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)
|
||||
{
|
||||
|
|
@ -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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg);
|
||||
|
|
|
|||
|
|
@ -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_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_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_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_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_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_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_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_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_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_write_32_stack(codeblock_t *block, int stack_offset, int host_reg);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "codegen_ops_branch.h"
|
||||
#include "codegen_ops_fpu_arith.h"
|
||||
#include "codegen_ops_fpu_loadstore.h"
|
||||
#include "codegen_ops_fpu_misc.h"
|
||||
#include "codegen_ops_jump.h"
|
||||
#include "codegen_ops_logic.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,
|
||||
/*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,
|
||||
/*d0*/ 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, 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,
|
||||
/*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,
|
||||
/*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,
|
||||
/*d0*/ 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, 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,
|
||||
/*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,
|
||||
/*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,
|
||||
/*d0*/ 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*/ 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,
|
||||
/*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,
|
||||
/*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,
|
||||
/*d0*/ 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*/ 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,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ enum
|
|||
REG_POINTER,
|
||||
REG_DOUBLE,
|
||||
REG_FPU_ST_BYTE,
|
||||
REG_FPU_ST_DOUBLE
|
||||
REG_FPU_ST_DOUBLE,
|
||||
REG_FPU_ST_QWORD
|
||||
};
|
||||
|
||||
enum
|
||||
|
|
@ -113,6 +114,15 @@ struct
|
|||
[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_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
|
||||
be preserved across uOPs. They will not be written back if they will
|
||||
not be read again.*/
|
||||
|
|
@ -121,7 +131,8 @@ struct
|
|||
[IREG_temp2] = {REG_DWORD, (void *)24, 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()
|
||||
|
|
@ -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);
|
||||
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:
|
||||
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)
|
||||
codegen_direct_read_double(block, reg_set->reg_list[c], &cpu_state.ST[ir_reg.reg & 7]);
|
||||
else
|
||||
|
|
@ -266,13 +297,26 @@ static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, i
|
|||
break;
|
||||
|
||||
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)
|
||||
codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c]);
|
||||
else
|
||||
codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c]);
|
||||
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:
|
||||
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)
|
||||
codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c]);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT)
|
||||
#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT)
|
||||
#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT)
|
||||
#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT)
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -67,7 +68,8 @@ enum
|
|||
|
||||
IREG_FPU_TOP = 37,
|
||||
|
||||
IREG_temp0d = 39,
|
||||
IREG_temp0d = 38,
|
||||
IREG_temp1d = 39,
|
||||
|
||||
/*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag()
|
||||
to access.
|
||||
|
|
@ -93,9 +95,18 @@ enum
|
|||
IREG_tag6 = 54,
|
||||
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_CX = IREG_ECX + IREG_SIZE_W,
|
||||
|
|
@ -132,6 +143,10 @@ enum
|
|||
IREG_temp1_B = IREG_temp1 + IREG_SIZE_B,
|
||||
|
||||
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,
|
||||
|
||||
|
|
@ -148,6 +163,7 @@ enum
|
|||
#define IREG_32(reg) ((reg) + IREG_EAX)
|
||||
|
||||
#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_TOP_diff_stack_offset 32
|
||||
|
|
|
|||
Loading…
Reference in a new issue