aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-10-19 00:18:36 +0200
committerMike Pall <mike>2011-10-19 00:18:36 +0200
commit45df079c01efbd237b7f2ae4ee3569c83769cf44 (patch)
tree387d4f49ec992a02577f131a0ec9420e0b203995 /src
parent2fcd56258284501c6ac874d26a61ea65a05480af (diff)
downloadluajit-45df079c01efbd237b7f2ae4ee3569c83769cf44.tar.gz
luajit-45df079c01efbd237b7f2ae4ee3569c83769cf44.tar.bz2
luajit-45df079c01efbd237b7f2ae4ee3569c83769cf44.zip
FFI/x86: Fix CONV.u32.num rounding.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm_x86.h30
1 files changed, 10 insertions, 20 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index f4ac0c10..21ab7c25 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -620,33 +620,23 @@ static void asm_conv(ASMState *as, IRIns *ir)
620 x86Op op = st == IRT_NUM ? 620 x86Op op = st == IRT_NUM ?
621 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSD2SI : XO_CVTSD2SI) : 621 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSD2SI : XO_CVTSD2SI) :
622 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSS2SI : XO_CVTSS2SI); 622 ((ir->op2 & IRCONV_TRUNC) ? XO_CVTTSS2SI : XO_CVTSS2SI);
623 if (LJ_32 && irt_isu32(ir->t)) { /* FP to U32 conversion on x86. */ 623 if (LJ_64 ? irt_isu64(ir->t) : irt_isu32(ir->t)) {
624 /* u32 = (int32_t)(number - 2^31) + 2^31 */ 624 /* LJ_64: For inputs >= 2^63 add -2^64, convert again. */
625 Reg tmp = ra_noreg(IR(lref)->r) ? ra_alloc1(as, lref, RSET_FPR) : 625 /* LJ_32: For inputs >= 2^31 add -2^31, convert again and add 2^31. */
626 ra_scratch(as, RSET_FPR);
627 emit_gri(as, XG_ARITHi(XOg_ADD), dest, (int32_t)0x80000000);
628 emit_rr(as, op, dest, tmp);
629 if (st == IRT_NUM)
630 emit_rma(as, XO_ADDSD, tmp,
631 lj_ir_k64_find(as->J, U64x(c1e00000,00000000)));
632 else
633 emit_rma(as, XO_ADDSS, tmp,
634 lj_ir_k64_find(as->J, U64x(00000000,cf000000)));
635 ra_left(as, tmp, lref);
636 } else if (LJ_64 && irt_isu64(ir->t)) {
637 /* For inputs in [2^63,2^64-1] add -2^64 and convert again. */
638 Reg tmp = ra_noreg(IR(lref)->r) ? ra_alloc1(as, lref, RSET_FPR) : 626 Reg tmp = ra_noreg(IR(lref)->r) ? ra_alloc1(as, lref, RSET_FPR) :
639 ra_scratch(as, RSET_FPR); 627 ra_scratch(as, RSET_FPR);
640 MCLabel l_end = emit_label(as); 628 MCLabel l_end = emit_label(as);
629 if (LJ_32)
630 emit_gri(as, XG_ARITHi(XOg_ADD), dest, (int32_t)0x80000000);
641 emit_rr(as, op, dest|REX_64, tmp); 631 emit_rr(as, op, dest|REX_64, tmp);
642 if (st == IRT_NUM) 632 if (st == IRT_NUM)
643 emit_rma(as, XO_ADDSD, tmp, 633 emit_rma(as, XO_ADDSD, tmp, lj_ir_k64_find(as->J,
644 lj_ir_k64_find(as->J, U64x(c3f00000,00000000))); 634 LJ_64 ? U64x(c3f00000,00000000) : U64x(c1e00000,00000000)));
645 else 635 else
646 emit_rma(as, XO_ADDSS, tmp, 636 emit_rma(as, XO_ADDSS, tmp, lj_ir_k64_find(as->J,
647 lj_ir_k64_find(as->J, U64x(00000000,df800000))); 637 LJ_64 ? U64x(00000000,df800000) : U64x(00000000,cf000000)));
648 emit_sjcc(as, CC_NS, l_end); 638 emit_sjcc(as, CC_NS, l_end);
649 emit_rr(as, XO_TEST, dest|REX_64, dest); /* Check if dest < 2^63. */ 639 emit_rr(as, XO_TEST, dest|REX_64, dest); /* Check if dest negative. */
650 emit_rr(as, op, dest|REX_64, tmp); 640 emit_rr(as, op, dest|REX_64, tmp);
651 ra_left(as, tmp, lref); 641 ra_left(as, tmp, lref);
652 } else { 642 } else {