diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 35 |
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 | ||
2389 | static void asm_ahuvload(ASMState *as, IRIns *ir) | 2389 | static 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); |