Added recompiled versions of FABS, FCHS, FSQRT and FTST.

This commit is contained in:
SarahW 2018-11-26 17:00:00 +00:00
commit 07035c97c8
16 changed files with 424 additions and 4 deletions

View file

@ -120,6 +120,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_CMGT_V4H (0x0e603400)
#define OPCODE_CMGT_V2S (0x0ea03400)
#define OPCODE_EOR_V (0x2e201c00)
#define OPCODE_FABS_D (0x1e60c000)
#define OPCODE_FADD_D (0x1e602800)
#define OPCODE_FCMP_D (0x1e602000)
#define OPCODE_FCVT_D_S (0x1e22c000)
@ -139,7 +140,9 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_FMOV_S_W (0x1e270000)
#define OPCODE_FMOV_W_S (0x1e260000)
#define OPCODE_FMUL_D (0x1e600800)
#define OPCODE_FNEG_D (0x1e614000)
#define OPCODE_FRINTX_D (0x1e674000)
#define OPCODE_FSQRT_D (0x1e61c000)
#define OPCODE_FSUB_D (0x1e603800)
#define OPCODE_LDR_REG (0xb8606800)
#define OPCODE_LDRX_REG (0xf8606800)
@ -680,6 +683,11 @@ void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int sr
codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
}
void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg)
{
codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg));
@ -768,11 +776,21 @@ void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg)
codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg));
}
void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset)
{
if (!in_range7_x(offset))

View file

@ -75,6 +75,8 @@ void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t
void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift);
void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg);
void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg);
void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg);
@ -101,6 +103,8 @@ void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg);
void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg);
void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg);
void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset);
void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset);

View file

@ -619,6 +619,71 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_FABS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_arm64_FABS_D(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FCHS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_arm64_FNEG_D(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FSQRT(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_arm64_FSQRT_D(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FTST(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_W(dest_size) && REG_IS_D(src_size_a))
{
host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP);
host_arm64_MOVZ_IMM(block, dest_reg, 0);
host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP);
host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3);
host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0);
host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg);
host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3);
host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg);
host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg);
}
else
fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_FADD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2540,6 +2605,11 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FMUL & UOP_MASK] = codegen_FMUL,
[UOP_FSUB & UOP_MASK] = codegen_FSUB,
[UOP_FABS & UOP_MASK] = codegen_FABS,
[UOP_FCHS & UOP_MASK] = codegen_FCHS,
[UOP_FSQRT & UOP_MASK] = codegen_FSQRT,
[UOP_FTST & UOP_MASK] = codegen_FTST,
[UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB,
[UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW,
[UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB,

View file

@ -86,6 +86,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_USUB16 0xe6500f70
#define OPCODE_UXTB 0xe6ef0070
#define OPCODE_UXTH 0xe6ff0070
#define OPCODE_VABS_D 0xeeb00bc0
#define OPCODE_VADD 0xee300b00
#define OPCODE_VADD_I8 0xf2000800
#define OPCODE_VADD_I16 0xf2100800
@ -120,6 +121,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_VMUL 0xee200b00
#define OPCODE_VMUL_S16 0xf2100910
#define OPCODE_VMULL_S16 0xf2900c00
#define OPCODE_VNEG_D 0xeeb10b40
#define OPCODE_VORR_D 0xf2200110
#define OPCODE_VPADDL_S16 0xf3b40200
#define OPCODE_VPADDL_S32 0xf3b80200
@ -145,6 +147,7 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val)
#define OPCODE_VSHR_D_U32 0xf3a00010
#define OPCODE_VSHR_D_U64 0xf3800090
#define OPCODE_VSHRN 0xf2800810
#define OPCODE_VSQRT_D 0xeeb10bc0
#define OPCODE_VSTR_D 0xed800b00
#define OPCODE_VSTR_S 0xed800a00
#define OPCODE_VSUB 0xee300b40
@ -796,6 +799,11 @@ void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate)
codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate));
}
void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg)
{
codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg));
}
void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
@ -940,6 +948,11 @@ void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_
codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
}
void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg)
{
codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg));
}
void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m)
{
codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m));
@ -1065,6 +1078,11 @@ void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift)
codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift));
}
void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg)
{
codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg));
}
void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset)
{
if ((offset > 1020) || (offset & 3))

View file

@ -139,6 +139,8 @@ void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg
void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate);
void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate);
void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
@ -154,6 +156,8 @@ void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_re
void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VCHS_D(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg);
@ -179,6 +183,8 @@ void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg
void host_arm_VMUL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m);
void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m);
void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg);
void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m);
void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg);

View file

@ -693,6 +693,69 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_FABS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_arm_VABS_D(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FCHS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_arm_VNEG_D(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FSQRT(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_arm_VSQRT_D(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FTST(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_W(dest_size) && REG_IS_D(src_size_a))
{
host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP);
host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP);
host_arm_MOV_IMM(block, dest_reg, 0);
host_arm_VMRS_APSR(block);
host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3);
host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0);
host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3);
}
else
fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_FADD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2688,6 +2751,11 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FMUL & UOP_MASK] = codegen_FMUL,
[UOP_FSUB & UOP_MASK] = codegen_FSUB,
[UOP_FABS & UOP_MASK] = codegen_FABS,
[UOP_FCHS & UOP_MASK] = codegen_FCHS,
[UOP_FSQRT & UOP_MASK] = codegen_FSQRT,
[UOP_FTST & UOP_MASK] = codegen_FTST,
[UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB,
[UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW,
[UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB,

View file

@ -548,6 +548,11 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a,
(shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7));
}
void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/
}
void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
@ -1571,6 +1576,11 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift)
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/
}
void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg || (dst_reg & 8) || (src_reg & 8))

View file

@ -71,6 +71,8 @@ void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t
void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift);
void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
@ -236,6 +238,8 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data);
void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data);

View file

@ -548,6 +548,78 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_FABS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a)
{
host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg);
host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
}
else
fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FCHS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a);
host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg);
host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
}
else
fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FSQRT(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FTST(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_W(dest_size) && REG_IS_D(src_size_a))
{
host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
if (dest_reg != REG_EAX)
host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX);
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP);
host_x86_LAHF(block);
host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3);
if (dest_reg != REG_EAX)
{
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
}
}
else
fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_FADD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2288,6 +2360,11 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FMUL & UOP_MASK] = codegen_FMUL,
[UOP_FSUB & UOP_MASK] = codegen_FSUB,
[UOP_FABS & UOP_MASK] = codegen_FABS,
[UOP_FCHS & UOP_MASK] = codegen_FCHS,
[UOP_FSQRT & UOP_MASK] = codegen_FSQRT,
[UOP_FTST & UOP_MASK] = codegen_FTST,
[UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB,
[UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW,
[UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB,

View file

@ -513,6 +513,11 @@ void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a,
codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/
}
void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/
}
void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data)
{
int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128);
@ -1397,6 +1402,11 @@ void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift)
codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/
}
void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg)
{
codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/
}
void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data)
{
if (dst_reg != src_reg)

View file

@ -75,6 +75,8 @@ void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32
void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b);
void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift);
void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data);
@ -239,6 +241,8 @@ void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift);
void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg);
void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t imm_data);
void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint16_t imm_data);
void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm_data);

View file

@ -559,6 +559,78 @@ static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop)
return 0;
}
static int codegen_FABS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a)
{
host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg);
host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
}
else
fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FCHS(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a);
host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg);
host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP);
}
else
fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FSQRT(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_D(dest_size) && REG_IS_D(src_size_a))
{
host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a);
}
else
fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real);
return 0;
}
static int codegen_FTST(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real);
int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real);
if (REG_IS_W(dest_size) && REG_IS_D(src_size_a))
{
host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP);
if (dest_reg != REG_EAX)
host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX);
host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX, REG_EAX);
host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP);
host_x86_LAHF(block);
host_x86_AND16_REG_IMM(block, REG_EAX, REG_EAX, C0|C2|C3);
if (dest_reg != REG_EAX)
{
host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX);
host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX);
}
}
else
fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real);
return 0;
}
static int codegen_FADD(codeblock_t *block, uop_t *uop)
{
int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real);
@ -2297,6 +2369,11 @@ const uOpFn uop_handlers[UOP_MAX] =
[UOP_FMUL & UOP_MASK] = codegen_FMUL,
[UOP_FSUB & UOP_MASK] = codegen_FSUB,
[UOP_FCOM & UOP_MASK] = codegen_FCOM,
[UOP_FABS & UOP_MASK] = codegen_FABS,
[UOP_FCHS & UOP_MASK] = codegen_FCHS,
[UOP_FSQRT & UOP_MASK] = codegen_FSQRT,
[UOP_FTST & UOP_MASK] = codegen_FTST,
[UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB,
[UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW,

View file

@ -187,6 +187,14 @@
#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84)
/*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/
#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85)
/*UOP_FABS - dest_reg = fabs(src_reg_a)*/
#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86)
/*UOP_FCHS - dest_reg = fabs(src_reg_a)*/
#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87)
/*UOP_FTST - dest_reg = flags from compare(src_reg_a, 0)*/
#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88)
/*UOP_FSQRT - dest_reg = fsqrt(src_reg_a)*/
#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89)
/*UOP_MMX_ENTER - must be called before any MMX registers accessed*/
#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER)
@ -582,6 +590,11 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir,
#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b)
#define uop_FABS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FABS, ir, dst_reg, src_reg)
#define uop_FCHS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FCHS, ir, dst_reg, src_reg)
#define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg)
#define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg)
#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0)
#define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0)

View file

@ -184,8 +184,8 @@ RecompOpFn recomp_opcodes_d9[512] =
/*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, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL,
/*32-bit data*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@ -206,8 +206,8 @@ RecompOpFn recomp_opcodes_d9[512] =
/*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, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
/*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL,
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL,
};
RecompOpFn recomp_opcodes_da[512] =

View file

@ -534,3 +534,39 @@ uint32_t ropFISUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, ui
ropFI_arith_mem(l, IREG_temp0)
ropFI_arith_mem(w, IREG_temp0_W)
uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
uop_FP_ENTER(ir);
uop_FABS(ir, IREG_ST(0), IREG_ST(0));
uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID);
return op_pc;
}
uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
uop_FP_ENTER(ir);
uop_FCHS(ir, IREG_ST(0), IREG_ST(0));
uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID);
return op_pc;
}
uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
uop_FP_ENTER(ir);
uop_FSQRT(ir, IREG_ST(0), IREG_ST(0));
uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID);
return op_pc;
}
uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)
{
uop_FP_ENTER(ir);
uop_FTST(ir, IREG_temp0_W, IREG_ST(0));
uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3));
uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W);
return op_pc;
}

View file

@ -56,3 +56,8 @@ uint32_t ropFISUBl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t f
uint32_t ropFISUBw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFISUBRl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFISUBRw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);
uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc);