diff options
Diffstat (limited to 'src/lj_asm_mips.h')
-rw-r--r-- | src/lj_asm_mips.h | 38 |
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. */ |
185 | static void asm_fusexref(ASMState *as, MIPSIns mi, Reg rt, IRRef ref, | 185 | static 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 | ||
890 | static void asm_fstore(ASMState *as, IRIns *ir) | 890 | static 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 | ||
901 | static void asm_xload(ASMState *as, IRIns *ir) | 906 | static 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 | ||
908 | static void asm_xstore(ASMState *as, IRIns *ir) | 913 | static 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 | ||
915 | static void asm_ahuvload(ASMState *as, IRIns *ir) | 920 | static 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; |