mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Add support for uint64_t <-> FP conversions to x64 backend.
This commit is contained in:
parent
ddfa7fc246
commit
0005b2c2b9
35
src/lj_asm.c
35
src/lj_asm.c
@ -1641,8 +1641,19 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
return;
|
||||
#endif
|
||||
} else { /* Integer to FP conversion. */
|
||||
Reg left = (LJ_64 && st == IRT_U32) ? ra_alloc1(as, lref, RSET_GPR) :
|
||||
Reg tmp = (LJ_64 && st == IRT_U64) ? ra_scratch(as, RSET_GPR) : RID_NONE;
|
||||
Reg left = (LJ_64 && (st == IRT_U32 || st == IRT_U64)) ?
|
||||
ra_alloc1(as, lref, RSET_GPR) :
|
||||
asm_fuseload(as, lref, RSET_GPR);
|
||||
if (LJ_64 && st == IRT_U64) {
|
||||
Reg tmpn = ra_scratch(as, rset_exclude(RSET_FPR, dest));
|
||||
MCLabel l_end = emit_label(as);
|
||||
emit_rr(as, XO_ADDSD, dest, tmpn);
|
||||
emit_rr(as, XO_MOVD, tmpn|REX_64, tmp);
|
||||
emit_loadu64(as, tmp, U64x(43f00000,00000000));
|
||||
emit_sjcc(as, CC_NS, l_end);
|
||||
emit_rr(as, XO_TEST, left|REX_64, left);
|
||||
}
|
||||
emit_mrm(as, irt_isnum(ir->t) ? XO_CVTSI2SD : XO_CVTSI2SS,
|
||||
dest|((LJ_64 && (st64 || st == IRT_U32)) ? REX_64 : 0), left);
|
||||
}
|
||||
@ -1657,18 +1668,25 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
/* NYI: number to 64 bit integer or uint32_t conversion. */
|
||||
setintV(&as->J->errinfo, ir->o);
|
||||
lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
|
||||
#else
|
||||
} else if (irt_isu64(ir->t)) {
|
||||
/* NYI: number to uint64_t conversion. */
|
||||
setintV(&as->J->errinfo, ir->o);
|
||||
lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
|
||||
#endif
|
||||
} else {
|
||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||
Reg left = asm_fuseload(as, ir->op1, RSET_FPR);
|
||||
x86Op op = st == IRT_NUM ?
|
||||
((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSD2SI : XO_CVTSD2SI) :
|
||||
((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSS2SI : XO_CVTSS2SI);
|
||||
if (LJ_64 && irt_isu64(ir->t)) {
|
||||
Reg left = ra_alloc1(as, lref, RSET_FPR);
|
||||
Reg tmpn = ra_scratch(as, rset_exclude(RSET_FPR, left));
|
||||
MCLabel l_end = emit_label(as);
|
||||
emit_rr(as, op, dest|REX_64, tmpn);
|
||||
emit_rr(as, XO_ADDSD, tmpn, left);
|
||||
emit_rr(as, XO_MOVD, tmpn|REX_64, dest);
|
||||
emit_loadu64(as, dest, U64x(c3f00000,00000000));
|
||||
emit_sjcc(as, CC_NS, l_end);
|
||||
emit_rr(as, XO_TEST, dest|REX_64, dest);
|
||||
emit_rr(as, op, dest|REX_64, left);
|
||||
} else {
|
||||
Reg left = asm_fuseload(as, lref, RSET_FPR);
|
||||
if (LJ_64 && irt_isu32(ir->t))
|
||||
emit_rr(as, XO_MOV, dest, dest); /* Zero upper 32 bits. */
|
||||
emit_mrm(as, op,
|
||||
@ -1676,6 +1694,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
(irt_is64(ir->t) || irt_isu32(ir->t))) ? REX_64 : 0),
|
||||
left);
|
||||
}
|
||||
}
|
||||
} else if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
|
||||
Reg left, dest = ra_dest(as, ir, RSET_GPR);
|
||||
RegSet allow = RSET_GPR;
|
||||
@ -1690,7 +1709,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
|
||||
} else {
|
||||
op = XO_MOVZXw;
|
||||
}
|
||||
left = asm_fuseload(as, ir->op1, allow);
|
||||
left = asm_fuseload(as, lref, allow);
|
||||
/* Add extra MOV if source is already in wrong register. */
|
||||
if (!LJ_64 && left != RID_MRM && !rset_test(allow, left)) {
|
||||
Reg tmp = ra_scratch(as, allow);
|
||||
|
@ -767,8 +767,7 @@ static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
if (n >= 9223372036854775808.0) /* They think it's a feature. */
|
||||
return (uint64_t)(int64_t)(n - 9223372036854775808.0) +
|
||||
U64x(80000000,00000000);
|
||||
return (uint64_t)(int64_t)(n - 18446744073709551616.0);
|
||||
else
|
||||
#endif
|
||||
return (uint64_t)n;
|
||||
|
Loading…
Reference in New Issue
Block a user