diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm_arm64.h | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index f51c6f76..3cedd021 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h | |||
@@ -460,8 +460,11 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
460 | static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) | 460 | static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) |
461 | { | 461 | { |
462 | RegSet drop = RSET_SCRATCH; | 462 | RegSet drop = RSET_SCRATCH; |
463 | int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); | ||
463 | if (ra_hasreg(ir->r)) | 464 | if (ra_hasreg(ir->r)) |
464 | rset_clear(drop, ir->r); /* Dest reg handled below. */ | 465 | rset_clear(drop, ir->r); /* Dest reg handled below. */ |
466 | if (hiop && ra_hasreg((ir+1)->r)) | ||
467 | rset_clear(drop, (ir+1)->r); /* Dest reg handled below. */ | ||
465 | ra_evictset(as, drop); /* Evictions must be performed first. */ | 468 | ra_evictset(as, drop); /* Evictions must be performed first. */ |
466 | if (ra_used(ir)) { | 469 | if (ra_used(ir)) { |
467 | lj_assertA(!irt_ispri(ir->t), "PRI dest"); | 470 | lj_assertA(!irt_ispri(ir->t), "PRI dest"); |
@@ -473,6 +476,8 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci) | |||
473 | } else { | 476 | } else { |
474 | ra_destreg(as, ir, RID_FPRET); | 477 | ra_destreg(as, ir, RID_FPRET); |
475 | } | 478 | } |
479 | } else if (hiop) { | ||
480 | ra_destpair(as, ir); | ||
476 | } else { | 481 | } else { |
477 | ra_destreg(as, ir, RID_RET); | 482 | ra_destreg(as, ir, RID_RET); |
478 | } | 483 | } |
@@ -1720,13 +1725,25 @@ static void asm_comp(ASMState *as, IRIns *ir) | |||
1720 | 1725 | ||
1721 | #define asm_equal(as, ir) asm_comp(as, ir) | 1726 | #define asm_equal(as, ir) asm_comp(as, ir) |
1722 | 1727 | ||
1723 | /* -- Support for 64 bit ops in 32 bit mode ------------------------------- */ | 1728 | /* -- Split register ops -------------------------------------------------- */ |
1724 | 1729 | ||
1725 | /* Hiword op of a split 64 bit op. Previous op must be the loword op. */ | 1730 | /* Hiword op of a split 64/64 bit op. Previous op is the loword op. */ |
1726 | static void asm_hiop(ASMState *as, IRIns *ir) | 1731 | static void asm_hiop(ASMState *as, IRIns *ir) |
1727 | { | 1732 | { |
1728 | UNUSED(as); UNUSED(ir); | 1733 | /* HIOP is marked as a store because it needs its own DCE logic. */ |
1729 | lj_assertA(0, "unexpected HIOP"); /* Unused on 64 bit. */ | 1734 | int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */ |
1735 | if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1; | ||
1736 | if (!usehi) return; /* Skip unused hiword op for all remaining ops. */ | ||
1737 | switch ((ir-1)->o) { | ||
1738 | case IR_CALLN: | ||
1739 | case IR_CALLL: | ||
1740 | case IR_CALLS: | ||
1741 | case IR_CALLXS: | ||
1742 | if (!uselo) | ||
1743 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ | ||
1744 | break; | ||
1745 | default: lj_assertA(0, "bad HIOP for op %d", (ir-1)->o); break; | ||
1746 | } | ||
1730 | } | 1747 | } |
1731 | 1748 | ||
1732 | /* -- Profiling ----------------------------------------------------------- */ | 1749 | /* -- Profiling ----------------------------------------------------------- */ |