summaryrefslogtreecommitdiff
path: root/src/lj_asm_mips.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_mips.h')
-rw-r--r--src/lj_asm_mips.h38
1 files changed, 24 insertions, 14 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
index 9bae4778..a3a4da6c 100644
--- a/src/lj_asm_mips.h
+++ b/src/lj_asm_mips.h
@@ -183,20 +183,20 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow)
183 183
184/* Fuse XLOAD/XSTORE reference into load/store operand. */ 184/* Fuse XLOAD/XSTORE reference into load/store operand. */
185static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref, 185static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref,
186 RegSet allow) 186 RegSet allow, int32_t ofs)
187{ 187{
188 IRIns *ir = IR(ref); 188 IRIns *ir = IR(ref);
189 int32_t ofs = 0;
190 Reg base; 189 Reg base;
191 if (ra_noreg(ir->r) && mayfuse(as, ref)) { 190 if (ra_noreg(ir->r) && mayfuse(as, ref)) {
192 if (ir->o == IR_ADD) { 191 if (ir->o == IR_ADD) {
193 int32_t ofs2; 192 int32_t ofs2;
194 if (irref_isk(ir->op2) && (ofs2 = IR(ir->op2)->i, checki16(ofs2))) { 193 if (irref_isk(ir->op2) && (ofs2 = ofs + IR(ir->op2)->i, checki16(ofs2))) {
195 ref = ir->op1; 194 ref = ir->op1;
196 ofs = ofs2; 195 ofs = ofs2;
197 } 196 }
198 } else if (ir->o == IR_STRREF) { 197 } else if (ir->o == IR_STRREF) {
199 int32_t ofs2 = 65536; 198 int32_t ofs2 = 65536;
199 lua_assert(ofs == 0);
200 ofs = (int32_t)sizeof(GCstr); 200 ofs = (int32_t)sizeof(GCstr);
201 if (irref_isk(ir->op2)) { 201 if (irref_isk(ir->op2)) {
202 ofs2 = ofs + IR(ir->op2)->i; 202 ofs2 = ofs + IR(ir->op2)->i;
@@ -889,27 +889,32 @@ static void asm_fload(ASMState *as, IRIns *ir)
889 889
890static void asm_fstore(ASMState *as, IRIns *ir) 890static void asm_fstore(ASMState *as, IRIns *ir)
891{ 891{
892 Reg src = ra_alloc1z(as, ir->op2, RSET_GPR); 892 if (ir->r == RID_SINK) { /* Sink store. */
893 IRIns *irf = IR(ir->op1); 893 asm_snap_prep(as);
894 Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src)); 894 return;
895 int32_t ofs = field_ofs[irf->op2]; 895 } else {
896 MIPSIns mi = asm_fxstoreins(ir); 896 Reg src = ra_alloc1z(as, ir->op2, RSET_GPR);
897 lua_assert(!irt_isfp(ir->t)); 897 IRIns *irf = IR(ir->op1);
898 emit_tsi(as, mi, src, idx, ofs); 898 Reg idx = ra_alloc1(as, irf->op1, rset_exclude(RSET_GPR, src));
899 int32_t ofs = field_ofs[irf->op2];
900 MIPSIns mi = asm_fxstoreins(ir);
901 lua_assert(!irt_isfp(ir->t));
902 emit_tsi(as, mi, src, idx, ofs);
903 }
899} 904}
900 905
901static void asm_xload(ASMState *as, IRIns *ir) 906static void asm_xload(ASMState *as, IRIns *ir)
902{ 907{
903 Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); 908 Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
904 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED)); 909 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
905 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR); 910 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
906} 911}
907 912
908static void asm_xstore(ASMState *as, IRIns *ir) 913static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs)
909{ 914{
910 Reg src = ra_alloc1z(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); 915 Reg src = ra_alloc1z(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
911 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1, 916 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
912 rset_exclude(RSET_GPR, src)); 917 rset_exclude(RSET_GPR, src), ofs);
913} 918}
914 919
915static void asm_ahuvload(ASMState *as, IRIns *ir) 920static void asm_ahuvload(ASMState *as, IRIns *ir)
@@ -1554,6 +1559,11 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1554 as->curins--; /* Always skip the loword comparison. */ 1559 as->curins--; /* Always skip the loword comparison. */
1555 asm_comp64eq(as, ir); 1560 asm_comp64eq(as, ir);
1556 return; 1561 return;
1562 } else if ((ir-1)->o == IR_XSTORE) {
1563 as->curins--; /* Handle both stores here. */
1564 asm_xstore(as, ir, LJ_LE ? 4 : 0);
1565 asm_xstore(as, ir-1, LJ_LE ? 0 : 4);
1566 return;
1557 } 1567 }
1558 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */ 1568 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
1559 switch ((ir-1)->o) { 1569 switch ((ir-1)->o) {
@@ -1832,7 +1842,7 @@ static void asm_ir(ASMState *as, IRIns *ir)
1832 1842
1833 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break; 1843 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
1834 case IR_FSTORE: asm_fstore(as, ir); break; 1844 case IR_FSTORE: asm_fstore(as, ir); break;
1835 case IR_XSTORE: asm_xstore(as, ir); break; 1845 case IR_XSTORE: asm_xstore(as, ir, 0); break;
1836 1846
1837 /* Allocations. */ 1847 /* Allocations. */
1838 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break; 1848 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;