aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-02 18:24:31 +0100
committerMike Pall <mike>2011-01-02 18:24:31 +0100
commit0005b2c2b91d3d3c115b1e5d12b32715c0ea77a6 (patch)
tree8a745a631db9c6954fd22f248ddcf2c9b2022a3b /src
parentddfa7fc246569f2fb7a664efcca73ac0e047d876 (diff)
downloadluajit-0005b2c2b91d3d3c115b1e5d12b32715c0ea77a6.tar.gz
luajit-0005b2c2b91d3d3c115b1e5d12b32715c0ea77a6.tar.bz2
luajit-0005b2c2b91d3d3c115b1e5d12b32715c0ea77a6.zip
Add support for uint64_t <-> FP conversions to x64 backend.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c49
-rw-r--r--src/lj_obj.h3
2 files changed, 35 insertions, 17 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 8127b2eb..14d6d849 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1641,8 +1641,19 @@ static void asm_conv(ASMState *as, IRIns *ir)
1641 return; 1641 return;
1642#endif 1642#endif
1643 } else { /* Integer to FP conversion. */ 1643 } else { /* Integer to FP conversion. */
1644 Reg left = (LJ_64 && st == IRT_U32) ? ra_alloc1(as, lref, RSET_GPR) : 1644 Reg tmp = (LJ_64 && st == IRT_U64) ? ra_scratch(as, RSET_GPR) : RID_NONE;
1645 asm_fuseload(as, lref, RSET_GPR); 1645 Reg left = (LJ_64 && (st == IRT_U32 || st == IRT_U64)) ?
1646 ra_alloc1(as, lref, RSET_GPR) :
1647 asm_fuseload(as, lref, RSET_GPR);
1648 if (LJ_64 && st == IRT_U64) {
1649 Reg tmpn = ra_scratch(as, rset_exclude(RSET_FPR, dest));
1650 MCLabel l_end = emit_label(as);
1651 emit_rr(as, XO_ADDSD, dest, tmpn);
1652 emit_rr(as, XO_MOVD, tmpn|REX_64, tmp);
1653 emit_loadu64(as, tmp, U64x(43f00000,00000000));
1654 emit_sjcc(as, CC_NS, l_end);
1655 emit_rr(as, XO_TEST, left|REX_64, left);
1656 }
1646 emit_mrm(as, irt_isnum(ir->t) ? XO_CVTSI2SD : XO_CVTSI2SS, 1657 emit_mrm(as, irt_isnum(ir->t) ? XO_CVTSI2SD : XO_CVTSI2SS,
1647 dest|((LJ_64 && (st64 || st == IRT_U32)) ? REX_64 : 0), left); 1658 dest|((LJ_64 && (st64 || st == IRT_U32)) ? REX_64 : 0), left);
1648 } 1659 }
@@ -1657,24 +1668,32 @@ static void asm_conv(ASMState *as, IRIns *ir)
1657 /* NYI: number to 64 bit integer or uint32_t conversion. */ 1668 /* NYI: number to 64 bit integer or uint32_t conversion. */
1658 setintV(&as->J->errinfo, ir->o); 1669 setintV(&as->J->errinfo, ir->o);
1659 lj_trace_err_info(as->J, LJ_TRERR_NYIIR); 1670 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
1660#else
1661 } else if (irt_isu64(ir->t)) {
1662 /* NYI: number to uint64_t conversion. */
1663 setintV(&as->J->errinfo, ir->o);
1664 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
1665#endif 1671#endif
1666 } else { 1672 } else {
1667 Reg dest = ra_dest(as, ir, RSET_GPR); 1673 Reg dest = ra_dest(as, ir, RSET_GPR);
1668 Reg left = asm_fuseload(as, ir->op1, RSET_FPR);
1669 x86Op op = st == IRT_NUM ? 1674 x86Op op = st == IRT_NUM ?
1670 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSD2SI : XO_CVTSD2SI) : 1675 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSD2SI : XO_CVTSD2SI) :
1671 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSS2SI : XO_CVTSS2SI); 1676 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSS2SI : XO_CVTSS2SI);
1672 if (LJ_64 && irt_isu32(ir->t)) 1677 if (LJ_64 && irt_isu64(ir->t)) {
1673 emit_rr(as, XO_MOV, dest, dest); /* Zero upper 32 bits. */ 1678 Reg left = ra_alloc1(as, lref, RSET_FPR);
1674 emit_mrm(as, op, 1679 Reg tmpn = ra_scratch(as, rset_exclude(RSET_FPR, left));
1675 dest|((LJ_64 && 1680 MCLabel l_end = emit_label(as);
1676 (irt_is64(ir->t) || irt_isu32(ir->t))) ? REX_64 : 0), 1681 emit_rr(as, op, dest|REX_64, tmpn);
1677 left); 1682 emit_rr(as, XO_ADDSD, tmpn, left);
1683 emit_rr(as, XO_MOVD, tmpn|REX_64, dest);
1684 emit_loadu64(as, dest, U64x(c3f00000,00000000));
1685 emit_sjcc(as, CC_NS, l_end);
1686 emit_rr(as, XO_TEST, dest|REX_64, dest);
1687 emit_rr(as, op, dest|REX_64, left);
1688 } else {
1689 Reg left = asm_fuseload(as, lref, RSET_FPR);
1690 if (LJ_64 && irt_isu32(ir->t))
1691 emit_rr(as, XO_MOV, dest, dest); /* Zero upper 32 bits. */
1692 emit_mrm(as, op,
1693 dest|((LJ_64 &&
1694 (irt_is64(ir->t) || irt_isu32(ir->t))) ? REX_64 : 0),
1695 left);
1696 }
1678 } 1697 }
1679 } else if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */ 1698 } else if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
1680 Reg left, dest = ra_dest(as, ir, RSET_GPR); 1699 Reg left, dest = ra_dest(as, ir, RSET_GPR);
@@ -1690,7 +1709,7 @@ static void asm_conv(ASMState *as, IRIns *ir)
1690 } else { 1709 } else {
1691 op = XO_MOVZXw; 1710 op = XO_MOVZXw;
1692 } 1711 }
1693 left = asm_fuseload(as, ir->op1, allow); 1712 left = asm_fuseload(as, lref, allow);
1694 /* Add extra MOV if source is already in wrong register. */ 1713 /* Add extra MOV if source is already in wrong register. */
1695 if (!LJ_64 && left != RID_MRM && !rset_test(allow, left)) { 1714 if (!LJ_64 && left != RID_MRM && !rset_test(allow, left)) {
1696 Reg tmp = ra_scratch(as, allow); 1715 Reg tmp = ra_scratch(as, allow);
diff --git a/src/lj_obj.h b/src/lj_obj.h
index 456aef0b..342ebafb 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -767,8 +767,7 @@ static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)
767{ 767{
768#ifdef _MSC_VER 768#ifdef _MSC_VER
769 if (n >= 9223372036854775808.0) /* They think it's a feature. */ 769 if (n >= 9223372036854775808.0) /* They think it's a feature. */
770 return (uint64_t)(int64_t)(n - 9223372036854775808.0) + 770 return (uint64_t)(int64_t)(n - 18446744073709551616.0);
771 U64x(80000000,00000000);
772 else 771 else
773#endif 772#endif
774 return (uint64_t)n; 773 return (uint64_t)n;