diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm_arm.h | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index c93c99c9..208c3203 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
@@ -185,6 +185,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow, | |||
185 | *ofsp = (ofs & 255); /* Mask out less bits to allow LDRD. */ | 185 | *ofsp = (ofs & 255); /* Mask out less bits to allow LDRD. */ |
186 | return ra_allock(as, (ofs & ~255), allow); | 186 | return ra_allock(as, (ofs & ~255), allow); |
187 | } | 187 | } |
188 | } else if (ir->o == IR_TMPREF) { | ||
189 | *ofsp = 0; | ||
190 | return RID_SP; | ||
188 | } | 191 | } |
189 | } | 192 | } |
190 | *ofsp = 0; | 193 | *ofsp = 0; |
@@ -666,35 +669,55 @@ static void asm_strto(ASMState *as, IRIns *ir) | |||
666 | /* -- Memory references --------------------------------------------------- */ | 669 | /* -- Memory references --------------------------------------------------- */ |
667 | 670 | ||
668 | /* Get pointer to TValue. */ | 671 | /* Get pointer to TValue. */ |
669 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 672 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
670 | { | 673 | { |
671 | IRIns *ir = IR(ref); | 674 | if ((mode & IRTMPREF_IN1)) { |
672 | if (irt_isnum(ir->t)) { | 675 | IRIns *ir = IR(ref); |
673 | if (irref_isk(ref)) { | 676 | if (irt_isnum(ir->t)) { |
674 | /* Use the number constant itself as a TValue. */ | 677 | if ((mode & IRTMPREF_OUT1)) { |
675 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | 678 | #if LJ_SOFTFP |
676 | } else { | 679 | lj_assertA(irref_isk(ref), "unsplit FP op"); |
680 | emit_dm(as, ARMI_MOV, dest, RID_SP); | ||
681 | emit_lso(as, ARMI_STR, | ||
682 | ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR), | ||
683 | RID_SP, 0); | ||
684 | emit_lso(as, ARMI_STR, | ||
685 | ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR), | ||
686 | RID_SP, 4); | ||
687 | #else | ||
688 | Reg src = ra_alloc1(as, ref, RSET_FPR); | ||
689 | emit_dm(as, ARMI_MOV, dest, RID_SP); | ||
690 | emit_vlso(as, ARMI_VSTR_D, src, RID_SP, 0); | ||
691 | #endif | ||
692 | } else if (irref_isk(ref)) { | ||
693 | /* Use the number constant itself as a TValue. */ | ||
694 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | ||
695 | } else { | ||
677 | #if LJ_SOFTFP | 696 | #if LJ_SOFTFP |
678 | lj_assertA(0, "unsplit FP op"); | 697 | lj_assertA(0, "unsplit FP op"); |
679 | #else | 698 | #else |
680 | /* Otherwise force a spill and use the spill slot. */ | 699 | /* Otherwise force a spill and use the spill slot. */ |
681 | emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR); | 700 | emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR); |
682 | #endif | 701 | #endif |
702 | } | ||
703 | } else { | ||
704 | /* Otherwise use [sp] and [sp+4] to hold the TValue. | ||
705 | ** This assumes the following call has max. 4 args. | ||
706 | */ | ||
707 | Reg type; | ||
708 | emit_dm(as, ARMI_MOV, dest, RID_SP); | ||
709 | if (!irt_ispri(ir->t)) { | ||
710 | Reg src = ra_alloc1(as, ref, RSET_GPR); | ||
711 | emit_lso(as, ARMI_STR, src, RID_SP, 0); | ||
712 | } | ||
713 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)) | ||
714 | type = ra_alloc1(as, ref+1, RSET_GPR); | ||
715 | else | ||
716 | type = ra_allock(as, irt_toitype(ir->t), RSET_GPR); | ||
717 | emit_lso(as, ARMI_STR, type, RID_SP, 4); | ||
683 | } | 718 | } |
684 | } else { | 719 | } else { |
685 | /* Otherwise use [sp] and [sp+4] to hold the TValue. */ | ||
686 | RegSet allow = rset_exclude(RSET_GPR, dest); | ||
687 | Reg type; | ||
688 | emit_dm(as, ARMI_MOV, dest, RID_SP); | 720 | emit_dm(as, ARMI_MOV, dest, RID_SP); |
689 | if (!irt_ispri(ir->t)) { | ||
690 | Reg src = ra_alloc1(as, ref, allow); | ||
691 | emit_lso(as, ARMI_STR, src, RID_SP, 0); | ||
692 | } | ||
693 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) | ||
694 | type = ra_alloc1(as, ref+1, allow); | ||
695 | else | ||
696 | type = ra_allock(as, irt_toitype(ir->t), allow); | ||
697 | emit_lso(as, ARMI_STR, type, RID_SP, 4); | ||
698 | } | 721 | } |
699 | } | 722 | } |
700 | 723 | ||
@@ -1909,7 +1932,7 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
1909 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ | 1932 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ |
1910 | break; | 1933 | break; |
1911 | #if LJ_SOFTFP | 1934 | #if LJ_SOFTFP |
1912 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: | 1935 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF: |
1913 | #endif | 1936 | #endif |
1914 | case IR_CNEWI: | 1937 | case IR_CNEWI: |
1915 | /* Nothing to do here. Handled by lo op itself. */ | 1938 | /* Nothing to do here. Handled by lo op itself. */ |