summaryrefslogtreecommitdiff
path: root/src/lj_asm_arm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_arm.h')
-rw-r--r--src/lj_asm_arm.h44
1 files changed, 27 insertions, 17 deletions
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h
index 5ec3d59f..c08b6196 100644
--- a/src/lj_asm_arm.h
+++ b/src/lj_asm_arm.h
@@ -206,17 +206,19 @@ static IRRef asm_fuselsl2(ASMState *as, IRRef ref)
206 206
207/* Fuse XLOAD/XSTORE reference into load/store operand. */ 207/* Fuse XLOAD/XSTORE reference into load/store operand. */
208static void asm_fusexref(ASMState *as, ARMIns ai, Reg rd, IRRef ref, 208static void asm_fusexref(ASMState *as, ARMIns ai, Reg rd, IRRef ref,
209 RegSet allow) 209 RegSet allow, int32_t ofs)
210{ 210{
211 IRIns *ir = IR(ref); 211 IRIns *ir = IR(ref);
212 int32_t ofs = 0;
213 Reg base; 212 Reg base;
214 if (ra_noreg(ir->r) && mayfuse(as, ref)) { 213 if (ra_noreg(ir->r) && mayfuse(as, ref)) {
215 int32_t lim = (ai & 0x04000000) ? 4096 : 256; 214 int32_t lim = (ai & 0x04000000) ? 4096 : 256;
216 if (ir->o == IR_ADD) { 215 if (ir->o == IR_ADD) {
217 if (irref_isk(ir->op2) && (ofs = IR(ir->op2)->i) > -lim && ofs < lim) { 216 int32_t ofs2;
217 if (irref_isk(ir->op2) &&
218 (ofs2 = ofs + IR(ir->op2)->i) > -lim && ofs2 < lim) {
219 ofs = ofs2;
218 ref = ir->op1; 220 ref = ir->op1;
219 } else { 221 } else if (ofs == 0) {
220 IRRef lref = ir->op1, rref = ir->op2; 222 IRRef lref = ir->op1, rref = ir->op2;
221 Reg rn, rm; 223 Reg rn, rm;
222 if ((ai & 0x04000000)) { 224 if ((ai & 0x04000000)) {
@@ -237,6 +239,7 @@ static void asm_fusexref(ASMState *as, ARMIns ai, Reg rd, IRRef ref,
237 return; 239 return;
238 } 240 }
239 } else if (ir->o == IR_STRREF) { 241 } else if (ir->o == IR_STRREF) {
242 lua_assert(ofs == 0);
240 ofs = (int32_t)sizeof(GCstr); 243 ofs = (int32_t)sizeof(GCstr);
241 if (irref_isk(ir->op2)) { 244 if (irref_isk(ir->op2)) {
242 ofs += IR(ir->op2)->i; 245 ofs += IR(ir->op2)->i;
@@ -809,29 +812,33 @@ static void asm_fload(ASMState *as, IRIns *ir)
809 812
810static void asm_fstore(ASMState *as, IRIns *ir) 813static void asm_fstore(ASMState *as, IRIns *ir)
811{ 814{
812 Reg src = ra_alloc1(as, ir->op2, RSET_GPR); 815 if (ir->r == RID_SINK) { /* Sink store. */
813 IRIns *irf = IR(ir->op1); 816 asm_snap_prep(as);
814 Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src)); 817 } else {
815 int32_t ofs = field_ofs[irf->op2]; 818 Reg src = ra_alloc1(as, ir->op2, RSET_GPR);
816 ARMIns ai = asm_fxstoreins(ir); 819 IRIns *irf = IR(ir->op1);
817 if ((ai & 0x04000000)) 820 Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
818 emit_lso(as, ai, src, idx, ofs); 821 int32_t ofs = field_ofs[irf->op2];
819 else 822 ARMIns ai = asm_fxstoreins(ir);
820 emit_lsox(as, ai, src, idx, ofs); 823 if ((ai & 0x04000000))
824 emit_lso(as, ai, src, idx, ofs);
825 else
826 emit_lsox(as, ai, src, idx, ofs);
827 }
821} 828}
822 829
823static void asm_xload(ASMState *as, IRIns *ir) 830static void asm_xload(ASMState *as, IRIns *ir)
824{ 831{
825 Reg dest = ra_dest(as, ir, RSET_GPR); 832 Reg dest = ra_dest(as, ir, RSET_GPR);
826 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED)); 833 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
827 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR); 834 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
828} 835}
829 836
830static void asm_xstore(ASMState *as, IRIns *ir) 837static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs)
831{ 838{
832 Reg src = ra_alloc1(as, ir->op2, RSET_GPR); 839 Reg src = ra_alloc1(as, ir->op2, RSET_GPR);
833 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1, 840 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
834 rset_exclude(RSET_GPR, src)); 841 rset_exclude(RSET_GPR, src), ofs);
835} 842}
836 843
837static void asm_ahuvload(ASMState *as, IRIns *ir) 844static void asm_ahuvload(ASMState *as, IRIns *ir)
@@ -1374,6 +1381,9 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1374 if (uselo || usehi) 1381 if (uselo || usehi)
1375 asm_fpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO); 1382 asm_fpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO);
1376 return; 1383 return;
1384 } else if ((ir-1)->o == IR_XSTORE) {
1385 asm_xstore(as, ir, 4);
1386 return;
1377 } 1387 }
1378 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */ 1388 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
1379 switch ((ir-1)->o) { 1389 switch ((ir-1)->o) {
@@ -1702,7 +1712,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
1702 1712
1703 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break; 1713 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
1704 case IR_FSTORE: asm_fstore(as, ir); break; 1714 case IR_FSTORE: asm_fstore(as, ir); break;
1705 case IR_XSTORE: asm_xstore(as, ir); break; 1715 case IR_XSTORE: asm_xstore(as, ir, 0); break;
1706 1716
1707 /* Allocations. */ 1717 /* Allocations. */
1708 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break; 1718 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;