aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 5f3c5fab..d395010d 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2059,7 +2059,7 @@ static void asm_href(ASMState *as, IRIns *ir)
2059 } else { 2059 } else {
2060 emit_sjcc(as, CC_P, l_next); 2060 emit_sjcc(as, CC_P, l_next);
2061 emit_rmro(as, XO_UCOMISD, key, dest, offsetof(Node, key.n)); 2061 emit_rmro(as, XO_UCOMISD, key, dest, offsetof(Node, key.n));
2062 emit_sjcc(as, CC_A, l_next); 2062 emit_sjcc(as, CC_AE, l_next);
2063 /* The type check avoids NaN penalties and complaints from Valgrind. */ 2063 /* The type check avoids NaN penalties and complaints from Valgrind. */
2064#if LJ_64 2064#if LJ_64
2065 emit_u32(as, LJ_TISNUM); 2065 emit_u32(as, LJ_TISNUM);
@@ -2388,7 +2388,8 @@ static Reg asm_load_lightud64(ASMState *as, IRIns *ir, int typecheck)
2388 2388
2389static void asm_ahuvload(ASMState *as, IRIns *ir) 2389static void asm_ahuvload(ASMState *as, IRIns *ir)
2390{ 2390{
2391 lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t)); 2391 lua_assert(irt_isnum(ir->t) || irt_ispri(ir->t) || irt_isaddr(ir->t) ||
2392 (LJ_DUALNUM && irt_isint(ir->t)));
2392#if LJ_64 2393#if LJ_64
2393 if (irt_islightud(ir->t)) { 2394 if (irt_islightud(ir->t)) {
2394 Reg dest = asm_load_lightud64(as, ir, 1); 2395 Reg dest = asm_load_lightud64(as, ir, 1);
@@ -2409,8 +2410,9 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
2409 } 2410 }
2410 /* Always do the type check, even if the load result is unused. */ 2411 /* Always do the type check, even if the load result is unused. */
2411 as->mrm.ofs += 4; 2412 as->mrm.ofs += 4;
2412 asm_guardcc(as, irt_isnum(ir->t) ? CC_A : CC_NE); 2413 asm_guardcc(as, irt_isnum(ir->t) ? CC_AE : CC_NE);
2413 if (LJ_64 && irt_isnum(ir->t)) { 2414 if (LJ_64 && irt_type(ir->t) >= IRT_NUM) {
2415 lua_assert(irt_isinteger(ir->t) || irt_isnum(ir->t));
2414 emit_u32(as, LJ_TISNUM); 2416 emit_u32(as, LJ_TISNUM);
2415 emit_mrm(as, XO_ARITHi, XOg_CMP, RID_MRM); 2417 emit_mrm(as, XO_ARITHi, XOg_CMP, RID_MRM);
2416 } else { 2418 } else {
@@ -2443,7 +2445,7 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
2443 if (ra_hasreg(src)) { 2445 if (ra_hasreg(src)) {
2444 emit_mrm(as, XO_MOVto, src, RID_MRM); 2446 emit_mrm(as, XO_MOVto, src, RID_MRM);
2445 } else if (!irt_ispri(irr->t)) { 2447 } else if (!irt_ispri(irr->t)) {
2446 lua_assert(irt_isaddr(ir->t)); 2448 lua_assert(irt_isaddr(ir->t) || (LJ_DUALNUM && irt_isinteger(ir->t)));
2447 emit_i32(as, irr->i); 2449 emit_i32(as, irr->i);
2448 emit_mrm(as, XO_MOVmi, 0, RID_MRM); 2450 emit_mrm(as, XO_MOVmi, 0, RID_MRM);
2449 } 2451 }
@@ -2460,8 +2462,9 @@ static void asm_sload(ASMState *as, IRIns *ir)
2460 Reg base; 2462 Reg base;
2461 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ 2463 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
2462 lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK)); 2464 lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK));
2463 lua_assert(!irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME))); 2465 lua_assert(LJ_DUALNUM ||
2464 if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t)) { 2466 !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
2467 if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
2465 Reg left = ra_scratch(as, RSET_FPR); 2468 Reg left = ra_scratch(as, RSET_FPR);
2466 asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */ 2469 asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */
2467 base = ra_alloc1(as, REF_BASE, RSET_GPR); 2470 base = ra_alloc1(as, REF_BASE, RSET_GPR);
@@ -2481,12 +2484,14 @@ static void asm_sload(ASMState *as, IRIns *ir)
2481 Reg dest = ra_dest(as, ir, allow); 2484 Reg dest = ra_dest(as, ir, allow);
2482 base = ra_alloc1(as, REF_BASE, RSET_GPR); 2485 base = ra_alloc1(as, REF_BASE, RSET_GPR);
2483 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t)); 2486 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
2484 if ((ir->op2 & IRSLOAD_CONVERT)) 2487 if ((ir->op2 & IRSLOAD_CONVERT)) {
2485 emit_rmro(as, XO_CVTSD2SI, dest, base, ofs); 2488 t.irt = irt_isint(t) ? IRT_NUM : IRT_INT; /* Check for original type. */
2486 else if (irt_isnum(t)) 2489 emit_rmro(as, irt_isint(t) ? XO_CVTSI2SD : XO_CVTSD2SI, dest, base, ofs);
2490 } else if (irt_isnum(t)) {
2487 emit_rmro(as, XMM_MOVRM(as), dest, base, ofs); 2491 emit_rmro(as, XMM_MOVRM(as), dest, base, ofs);
2488 else 2492 } else {
2489 emit_rmro(as, XO_MOV, dest, base, ofs); 2493 emit_rmro(as, XO_MOV, dest, base, ofs);
2494 }
2490 } else { 2495 } else {
2491 if (!(ir->op2 & IRSLOAD_TYPECHECK)) 2496 if (!(ir->op2 & IRSLOAD_TYPECHECK))
2492 return; /* No type check: avoid base alloc. */ 2497 return; /* No type check: avoid base alloc. */
@@ -2494,8 +2499,9 @@ static void asm_sload(ASMState *as, IRIns *ir)
2494 } 2499 }
2495 if ((ir->op2 & IRSLOAD_TYPECHECK)) { 2500 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
2496 /* Need type check, even if the load result is unused. */ 2501 /* Need type check, even if the load result is unused. */
2497 asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE); 2502 asm_guardcc(as, irt_isnum(t) ? CC_AE : CC_NE);
2498 if (LJ_64 && irt_isnum(t)) { 2503 if (LJ_64 && irt_type(t) >= IRT_NUM) {
2504 lua_assert(irt_isinteger(t) || irt_isnum(t));
2499 emit_u32(as, LJ_TISNUM); 2505 emit_u32(as, LJ_TISNUM);
2500 emit_rmro(as, XO_ARITHi, XOg_CMP, base, ofs+4); 2506 emit_rmro(as, XO_ARITHi, XOg_CMP, base, ofs+4);
2501 } else { 2507 } else {
@@ -3408,7 +3414,8 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
3408 Reg src = ra_alloc1(as, ref, RSET_FPR); 3414 Reg src = ra_alloc1(as, ref, RSET_FPR);
3409 emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs); 3415 emit_rmro(as, XO_MOVSDto, src, RID_BASE, ofs);
3410 } else { 3416 } else {
3411 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t)); 3417 lua_assert(irt_ispri(ir->t) || irt_isaddr(ir->t) ||
3418 (LJ_DUALNUM && irt_isinteger(ir->t)));
3412 if (!irref_isk(ref)) { 3419 if (!irref_isk(ref)) {
3413 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE)); 3420 Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE));
3414 emit_movtomro(as, REX_64IR(ir, src), RID_BASE, ofs); 3421 emit_movtomro(as, REX_64IR(ir, src), RID_BASE, ofs);