diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 204d332e..b12b7466 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -678,6 +678,76 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref) | |||
678 | } | 678 | } |
679 | } | 679 | } |
680 | } | 680 | } |
681 | #else | ||
682 | /* Similar to ra_left, except we override any hints. */ | ||
683 | static void ra_leftov(ASMState *as, Reg dest, IRRef lref) | ||
684 | { | ||
685 | IRIns *ir = IR(lref); | ||
686 | Reg left = ir->r; | ||
687 | if (ra_noreg(left)) { | ||
688 | ra_sethint(ir->r, dest); /* Propagate register hint. */ | ||
689 | left = ra_allocref(as, lref, | ||
690 | (LJ_SOFTFP || dest < RID_MAX_GPR) ? RSET_GPR : RSET_FPR); | ||
691 | } | ||
692 | ra_noweak(as, left); | ||
693 | if (dest != left) { | ||
694 | /* Use register renaming if dest is the PHI reg. */ | ||
695 | if (irt_isphi(ir->t) && as->phireg[dest] == lref) { | ||
696 | ra_modified(as, left); | ||
697 | ra_rename(as, left, dest); | ||
698 | } else { | ||
699 | emit_movrr(as, ir, dest, left); | ||
700 | } | ||
701 | } | ||
702 | } | ||
703 | #endif | ||
704 | |||
705 | #if !LJ_TARGET_X86ORX64 | ||
706 | /* Force a RID_RET/RID_RETHI destination register pair (marked as free). */ | ||
707 | static void ra_destpair(ASMState *as, IRIns *ir) | ||
708 | { | ||
709 | Reg destlo = ir->r, desthi = (ir+1)->r; | ||
710 | /* First spill unrelated refs blocking the destination registers. */ | ||
711 | if (!rset_test(as->freeset, RID_RET) && | ||
712 | destlo != RID_RET && desthi != RID_RET) | ||
713 | ra_restore(as, regcost_ref(as->cost[RID_RET])); | ||
714 | if (!rset_test(as->freeset, RID_RETHI) && | ||
715 | destlo != RID_RETHI && desthi != RID_RETHI) | ||
716 | ra_restore(as, regcost_ref(as->cost[RID_RETHI])); | ||
717 | /* Next free the destination registers (if any). */ | ||
718 | if (ra_hasreg(destlo)) { | ||
719 | ra_free(as, destlo); | ||
720 | ra_modified(as, destlo); | ||
721 | } else { | ||
722 | destlo = RID_RET; | ||
723 | } | ||
724 | if (ra_hasreg(desthi)) { | ||
725 | ra_free(as, desthi); | ||
726 | ra_modified(as, desthi); | ||
727 | } else { | ||
728 | desthi = RID_RETHI; | ||
729 | } | ||
730 | /* Check for conflicts and shuffle the registers as needed. */ | ||
731 | if (destlo == RID_RETHI) { | ||
732 | if (desthi == RID_RET) { | ||
733 | emit_movrr(as, ir, RID_RETHI, RID_TMP); | ||
734 | emit_movrr(as, ir, RID_RET, RID_RETHI); | ||
735 | emit_movrr(as, ir, RID_TMP, RID_RET); | ||
736 | } else { | ||
737 | emit_movrr(as, ir, RID_RETHI, RID_RET); | ||
738 | if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI); | ||
739 | } | ||
740 | } else if (desthi == RID_RET) { | ||
741 | emit_movrr(as, ir, RID_RET, RID_RETHI); | ||
742 | if (destlo != RID_RET) emit_movrr(as, ir, destlo, RID_RET); | ||
743 | } else { | ||
744 | if (desthi != RID_RETHI) emit_movrr(as, ir, desthi, RID_RETHI); | ||
745 | if (destlo != RID_RET) emit_movrr(as, ir, destlo, RID_RET); | ||
746 | } | ||
747 | /* Restore spill slots (if any). */ | ||
748 | if (ra_hasspill((ir+1)->s)) ra_save(as, ir+1, RID_RETHI); | ||
749 | if (ra_hasspill(ir->s)) ra_save(as, ir, RID_RET); | ||
750 | } | ||
681 | #endif | 751 | #endif |
682 | 752 | ||
683 | /* -- Snapshot handling --------- ----------------------------------------- */ | 753 | /* -- Snapshot handling --------- ----------------------------------------- */ |