aboutsummaryrefslogtreecommitdiff
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.h114
1 files changed, 99 insertions, 15 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
index 3a4679b8..3dbe836d 100644
--- a/src/lj_asm_mips.h
+++ b/src/lj_asm_mips.h
@@ -101,7 +101,12 @@ static void asm_guard(ASMState *as, MIPSIns mi, Reg rs, Reg rt)
101 as->invmcp = NULL; 101 as->invmcp = NULL;
102 as->loopinv = 1; 102 as->loopinv = 1;
103 as->mcp = p+1; 103 as->mcp = p+1;
104#if !LJ_TARGET_MIPSR6
104 mi = mi ^ ((mi>>28) == 1 ? 0x04000000u : 0x00010000u); /* Invert cond. */ 105 mi = mi ^ ((mi>>28) == 1 ? 0x04000000u : 0x00010000u); /* Invert cond. */
106#else
107 mi = mi ^ ((mi>>28) == 1 ? 0x04000000u :
108 (mi>>28) == 4 ? 0x00800000u : 0x00010000u); /* Invert cond. */
109#endif
105 target = p; /* Patch target later in asm_loop_fixup. */ 110 target = p; /* Patch target later in asm_loop_fixup. */
106 } 111 }
107 emit_ti(as, MIPSI_LI, RID_TMP, as->snapno); 112 emit_ti(as, MIPSI_LI, RID_TMP, as->snapno);
@@ -410,7 +415,11 @@ static void asm_callround(ASMState *as, IRIns *ir, IRCallID id)
410{ 415{
411 /* The modified regs must match with the *.dasc implementation. */ 416 /* The modified regs must match with the *.dasc implementation. */
412 RegSet drop = RID2RSET(RID_R1)|RID2RSET(RID_R12)|RID2RSET(RID_FPRET)| 417 RegSet drop = RID2RSET(RID_R1)|RID2RSET(RID_R12)|RID2RSET(RID_FPRET)|
413 RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(REGARG_FIRSTFPR); 418 RID2RSET(RID_F2)|RID2RSET(RID_F4)|RID2RSET(REGARG_FIRSTFPR)
419#if LJ_TARGET_MIPSR6
420 |RID2RSET(RID_F21)
421#endif
422 ;
414 if (ra_hasreg(ir->r)) rset_clear(drop, ir->r); 423 if (ra_hasreg(ir->r)) rset_clear(drop, ir->r);
415 ra_evictset(as, drop); 424 ra_evictset(as, drop);
416 ra_destreg(as, ir, RID_FPRET); 425 ra_destreg(as, ir, RID_FPRET);
@@ -444,8 +453,13 @@ static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
444{ 453{
445 Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left)); 454 Reg tmp = ra_scratch(as, rset_exclude(RSET_FPR, left));
446 Reg dest = ra_dest(as, ir, RSET_GPR); 455 Reg dest = ra_dest(as, ir, RSET_GPR);
456#if !LJ_TARGET_MIPSR6
447 asm_guard(as, MIPSI_BC1F, 0, 0); 457 asm_guard(as, MIPSI_BC1F, 0, 0);
448 emit_fgh(as, MIPSI_C_EQ_D, 0, tmp, left); 458 emit_fgh(as, MIPSI_C_EQ_D, 0, tmp, left);
459#else
460 asm_guard(as, MIPSI_BC1EQZ, 0, (tmp&31));
461 emit_fgh(as, MIPSI_CMP_EQ_D, tmp, tmp, left);
462#endif
449 emit_fg(as, MIPSI_CVT_D_W, tmp, tmp); 463 emit_fg(as, MIPSI_CVT_D_W, tmp, tmp);
450 emit_tg(as, MIPSI_MFC1, dest, tmp); 464 emit_tg(as, MIPSI_MFC1, dest, tmp);
451 emit_fg(as, MIPSI_CVT_W_D, tmp, left); 465 emit_fg(as, MIPSI_CVT_W_D, tmp, left);
@@ -599,8 +613,13 @@ static void asm_conv(ASMState *as, IRIns *ir)
599 (void *)&as->J->k64[LJ_K64_M2P64], 613 (void *)&as->J->k64[LJ_K64_M2P64],
600 rset_exclude(RSET_GPR, dest)); 614 rset_exclude(RSET_GPR, dest));
601 emit_fg(as, MIPSI_TRUNC_L_D, tmp, left); /* Delay slot. */ 615 emit_fg(as, MIPSI_TRUNC_L_D, tmp, left); /* Delay slot. */
602 emit_branch(as, MIPSI_BC1T, 0, 0, l_end); 616#if !LJ_TARGET_MIPSR6
603 emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp); 617 emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
618 emit_fgh(as, MIPSI_C_OLT_D, 0, left, tmp);
619#else
620 emit_branch(as, MIPSI_BC1NEZ, 0, (left&31), l_end);
621 emit_fgh(as, MIPSI_CMP_LT_D, left, left, tmp);
622#endif
604 emit_lsptr(as, MIPSI_LDC1, (tmp & 31), 623 emit_lsptr(as, MIPSI_LDC1, (tmp & 31),
605 (void *)&as->J->k64[LJ_K64_2P63], 624 (void *)&as->J->k64[LJ_K64_2P63],
606 rset_exclude(RSET_GPR, dest)); 625 rset_exclude(RSET_GPR, dest));
@@ -611,8 +630,13 @@ static void asm_conv(ASMState *as, IRIns *ir)
611 (void *)&as->J->k32[LJ_K32_M2P64], 630 (void *)&as->J->k32[LJ_K32_M2P64],
612 rset_exclude(RSET_GPR, dest)); 631 rset_exclude(RSET_GPR, dest));
613 emit_fg(as, MIPSI_TRUNC_L_S, tmp, left); /* Delay slot. */ 632 emit_fg(as, MIPSI_TRUNC_L_S, tmp, left); /* Delay slot. */
614 emit_branch(as, MIPSI_BC1T, 0, 0, l_end); 633#if !LJ_TARGET_MIPSR6
615 emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp); 634 emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
635 emit_fgh(as, MIPSI_C_OLT_S, 0, left, tmp);
636#else
637 emit_branch(as, MIPSI_BC1NEZ, 0, (left&31), l_end);
638 emit_fgh(as, MIPSI_CMP_LT_S, left, left, tmp);
639#endif
616 emit_lsptr(as, MIPSI_LWC1, (tmp & 31), 640 emit_lsptr(as, MIPSI_LWC1, (tmp & 31),
617 (void *)&as->J->k32[LJ_K32_2P63], 641 (void *)&as->J->k32[LJ_K32_2P63],
618 rset_exclude(RSET_GPR, dest)); 642 rset_exclude(RSET_GPR, dest));
@@ -840,8 +864,12 @@ static void asm_aref(ASMState *as, IRIns *ir)
840 } 864 }
841 base = ra_alloc1(as, ir->op1, RSET_GPR); 865 base = ra_alloc1(as, ir->op1, RSET_GPR);
842 idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base)); 866 idx = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, base));
867#if !LJ_TARGET_MIPSR6
843 emit_dst(as, MIPSI_AADDU, dest, RID_TMP, base); 868 emit_dst(as, MIPSI_AADDU, dest, RID_TMP, base);
844 emit_dta(as, MIPSI_SLL, RID_TMP, idx, 3); 869 emit_dta(as, MIPSI_SLL, RID_TMP, idx, 3);
870#else
871 emit_dst(as, MIPSI_ALSA | MIPSF_A(3-1), dest, idx, base);
872#endif
845} 873}
846 874
847/* Inlined hash lookup. Specialized for key type and for const keys. 875/* Inlined hash lookup. Specialized for key type and for const keys.
@@ -944,8 +972,13 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
944 l_end = asm_exitstub_addr(as); 972 l_end = asm_exitstub_addr(as);
945 } 973 }
946 if (!LJ_SOFTFP && irt_isnum(kt)) { 974 if (!LJ_SOFTFP && irt_isnum(kt)) {
975#if !LJ_TARGET_MIPSR6
947 emit_branch(as, MIPSI_BC1T, 0, 0, l_end); 976 emit_branch(as, MIPSI_BC1T, 0, 0, l_end);
948 emit_fgh(as, MIPSI_C_EQ_D, 0, tmpnum, key); 977 emit_fgh(as, MIPSI_C_EQ_D, 0, tmpnum, key);
978#else
979 emit_branch(as, MIPSI_BC1NEZ, 0, (tmpnum&31), l_end);
980 emit_fgh(as, MIPSI_CMP_EQ_D, tmpnum, tmpnum, key);
981#endif
949 *--as->mcp = MIPSI_NOP; /* Avoid NaN comparison overhead. */ 982 *--as->mcp = MIPSI_NOP; /* Avoid NaN comparison overhead. */
950 emit_branch(as, MIPSI_BEQ, tmp1, RID_ZERO, l_next); 983 emit_branch(as, MIPSI_BEQ, tmp1, RID_ZERO, l_next);
951 emit_tsi(as, MIPSI_SLTIU, tmp1, tmp1, (int32_t)LJ_TISNUM); 984 emit_tsi(as, MIPSI_SLTIU, tmp1, tmp1, (int32_t)LJ_TISNUM);
@@ -1196,7 +1229,9 @@ static MIPSIns asm_fxloadins(IRIns *ir)
1196 case IRT_I16: return MIPSI_LH; 1229 case IRT_I16: return MIPSI_LH;
1197 case IRT_U16: return MIPSI_LHU; 1230 case IRT_U16: return MIPSI_LHU;
1198 case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_LDC1; 1231 case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_LDC1;
1232 /* fallthrough */
1199 case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1; 1233 case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1;
1234 /* fallthrough */
1200 default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW; 1235 default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW;
1201 } 1236 }
1202} 1237}
@@ -1207,7 +1242,9 @@ static MIPSIns asm_fxstoreins(IRIns *ir)
1207 case IRT_I8: case IRT_U8: return MIPSI_SB; 1242 case IRT_I8: case IRT_U8: return MIPSI_SB;
1208 case IRT_I16: case IRT_U16: return MIPSI_SH; 1243 case IRT_I16: case IRT_U16: return MIPSI_SH;
1209 case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_SDC1; 1244 case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_SDC1;
1245 /* fallthrough */
1210 case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1; 1246 case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1;
1247 /* fallthrough */
1211 default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW; 1248 default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW;
1212 } 1249 }
1213} 1250}
@@ -1253,7 +1290,7 @@ static void asm_xload(ASMState *as, IRIns *ir)
1253{ 1290{
1254 Reg dest = ra_dest(as, ir, 1291 Reg dest = ra_dest(as, ir,
1255 (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR); 1292 (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
1256 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED)); 1293 lua_assert(LJ_TARGET_UNALIGNED || !(ir->op2 & IRXLOAD_UNALIGNED));
1257 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0); 1294 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
1258} 1295}
1259 1296
@@ -1544,7 +1581,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
1544 ofs -= 4; if (LJ_BE) ir++; else ir--; 1581 ofs -= 4; if (LJ_BE) ir++; else ir--;
1545 } 1582 }
1546#else 1583#else
1547 emit_tsi(as, MIPSI_SD, ra_alloc1(as, ir->op2, allow), 1584 emit_tsi(as, sz == 8 ? MIPSI_SD : MIPSI_SW, ra_alloc1(as, ir->op2, allow),
1548 RID_RET, sizeof(GCcdata)); 1585 RID_RET, sizeof(GCcdata));
1549#endif 1586#endif
1550 lua_assert(sz == 4 || sz == 8); 1587 lua_assert(sz == 4 || sz == 8);
@@ -1672,6 +1709,7 @@ static void asm_add(ASMState *as, IRIns *ir)
1672 } else 1709 } else
1673#endif 1710#endif
1674 { 1711 {
1712 /* TODO MIPSR6: Fuse ADD(BSHL(a,1-4),b) or ADD(ADD(a,a),b) to MIPSI_ALSA. */
1675 Reg dest = ra_dest(as, ir, RSET_GPR); 1713 Reg dest = ra_dest(as, ir, RSET_GPR);
1676 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); 1714 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1677 if (irref_isk(ir->op2)) { 1715 if (irref_isk(ir->op2)) {
@@ -1716,8 +1754,12 @@ static void asm_mul(ASMState *as, IRIns *ir)
1716 Reg right, left = ra_alloc2(as, ir, RSET_GPR); 1754 Reg right, left = ra_alloc2(as, ir, RSET_GPR);
1717 right = (left >> 8); left &= 255; 1755 right = (left >> 8); left &= 255;
1718 if (LJ_64 && irt_is64(ir->t)) { 1756 if (LJ_64 && irt_is64(ir->t)) {
1757#if !LJ_TARGET_MIPSR6
1719 emit_dst(as, MIPSI_MFLO, dest, 0, 0); 1758 emit_dst(as, MIPSI_MFLO, dest, 0, 0);
1720 emit_dst(as, MIPSI_DMULT, 0, left, right); 1759 emit_dst(as, MIPSI_DMULT, 0, left, right);
1760#else
1761 emit_dst(as, MIPSI_DMUL, dest, left, right);
1762#endif
1721 } else { 1763 } else {
1722 emit_dst(as, MIPSI_MUL, dest, left, right); 1764 emit_dst(as, MIPSI_MUL, dest, left, right);
1723 } 1765 }
@@ -1801,6 +1843,7 @@ static void asm_abs(ASMState *as, IRIns *ir)
1801 1843
1802static void asm_arithov(ASMState *as, IRIns *ir) 1844static void asm_arithov(ASMState *as, IRIns *ir)
1803{ 1845{
1846 /* TODO MIPSR6: bovc/bnvc. Caveat: no delay slot to load RID_TMP. */
1804 Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR); 1847 Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR);
1805 lua_assert(!irt_is64(ir->t)); 1848 lua_assert(!irt_is64(ir->t));
1806 if (irref_isk(ir->op2)) { 1849 if (irref_isk(ir->op2)) {
@@ -1845,9 +1888,14 @@ static void asm_mulov(ASMState *as, IRIns *ir)
1845 right), dest)); 1888 right), dest));
1846 asm_guard(as, MIPSI_BNE, RID_TMP, tmp); 1889 asm_guard(as, MIPSI_BNE, RID_TMP, tmp);
1847 emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31); 1890 emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31);
1891#if !LJ_TARGET_MIPSR6
1848 emit_dst(as, MIPSI_MFHI, tmp, 0, 0); 1892 emit_dst(as, MIPSI_MFHI, tmp, 0, 0);
1849 emit_dst(as, MIPSI_MFLO, dest, 0, 0); 1893 emit_dst(as, MIPSI_MFLO, dest, 0, 0);
1850 emit_dst(as, MIPSI_MULT, 0, left, right); 1894 emit_dst(as, MIPSI_MULT, 0, left, right);
1895#else
1896 emit_dst(as, MIPSI_MUL, dest, left, right);
1897 emit_dst(as, MIPSI_MUH, tmp, left, right);
1898#endif
1851} 1899}
1852 1900
1853#if LJ_32 && LJ_HASFFI 1901#if LJ_32 && LJ_HASFFI
@@ -2071,6 +2119,7 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
2071 Reg dest = ra_dest(as, ir, RSET_FPR); 2119 Reg dest = ra_dest(as, ir, RSET_FPR);
2072 Reg right, left = ra_alloc2(as, ir, RSET_FPR); 2120 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
2073 right = (left >> 8); left &= 255; 2121 right = (left >> 8); left &= 255;
2122#if !LJ_TARGET_MIPSR6
2074 if (dest == left) { 2123 if (dest == left) {
2075 emit_fg(as, MIPSI_MOVT_D, dest, right); 2124 emit_fg(as, MIPSI_MOVT_D, dest, right);
2076 } else { 2125 } else {
@@ -2078,19 +2127,37 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
2078 if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right); 2127 if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
2079 } 2128 }
2080 emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left); 2129 emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left);
2130#else
2131 emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right);
2132#endif
2081#endif 2133#endif
2082 } else { 2134 } else {
2083 Reg dest = ra_dest(as, ir, RSET_GPR); 2135 Reg dest = ra_dest(as, ir, RSET_GPR);
2084 Reg right, left = ra_alloc2(as, ir, RSET_GPR); 2136 Reg right, left = ra_alloc2(as, ir, RSET_GPR);
2085 right = (left >> 8); left &= 255; 2137 right = (left >> 8); left &= 255;
2086 if (dest == left) { 2138 if (left == right) {
2087 emit_dst(as, MIPSI_MOVN, dest, right, RID_TMP); 2139 if (dest != left) emit_move(as, dest, left);
2088 } else { 2140 } else {
2089 emit_dst(as, MIPSI_MOVZ, dest, left, RID_TMP); 2141#if !LJ_TARGET_MIPSR6
2090 if (dest != right) emit_move(as, dest, right); 2142 if (dest == left) {
2143 emit_dst(as, MIPSI_MOVN, dest, right, RID_TMP);
2144 } else {
2145 emit_dst(as, MIPSI_MOVZ, dest, left, RID_TMP);
2146 if (dest != right) emit_move(as, dest, right);
2147 }
2148#else
2149 emit_dst(as, MIPSI_OR, dest, dest, RID_TMP);
2150 if (dest != right) {
2151 emit_dst(as, MIPSI_SELNEZ, RID_TMP, right, RID_TMP);
2152 emit_dst(as, MIPSI_SELEQZ, dest, left, RID_TMP);
2153 } else {
2154 emit_dst(as, MIPSI_SELEQZ, RID_TMP, left, RID_TMP);
2155 emit_dst(as, MIPSI_SELNEZ, dest, right, RID_TMP);
2156 }
2157#endif
2158 emit_dst(as, MIPSI_SLT, RID_TMP,
2159 ismax ? left : right, ismax ? right : left);
2091 } 2160 }
2092 emit_dst(as, MIPSI_SLT, RID_TMP,
2093 ismax ? left : right, ismax ? right : left);
2094 } 2161 }
2095} 2162}
2096 2163
@@ -2174,10 +2241,18 @@ static void asm_comp(ASMState *as, IRIns *ir)
2174#if LJ_SOFTFP 2241#if LJ_SOFTFP
2175 asm_sfpcomp(as, ir); 2242 asm_sfpcomp(as, ir);
2176#else 2243#else
2244#if !LJ_TARGET_MIPSR6
2177 Reg right, left = ra_alloc2(as, ir, RSET_FPR); 2245 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
2178 right = (left >> 8); left &= 255; 2246 right = (left >> 8); left &= 255;
2179 asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); 2247 asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
2180 emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right); 2248 emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right);
2249#else
2250 Reg tmp, right, left = ra_alloc2(as, ir, RSET_FPR);
2251 right = (left >> 8); left &= 255;
2252 tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_FPR, left), right));
2253 asm_guard(as, (op&1) ? MIPSI_BC1NEZ : MIPSI_BC1EQZ, 0, (tmp&31));
2254 emit_fgh(as, MIPSI_CMP_LT_D + ((op&3) ^ ((op>>2)&1)), tmp, left, right);
2255#endif
2181#endif 2256#endif
2182 } else { 2257 } else {
2183 Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR); 2258 Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR);
@@ -2213,9 +2288,13 @@ static void asm_equal(ASMState *as, IRIns *ir)
2213 if (!LJ_SOFTFP32 && irt_isnum(ir->t)) { 2288 if (!LJ_SOFTFP32 && irt_isnum(ir->t)) {
2214#if LJ_SOFTFP 2289#if LJ_SOFTFP
2215 asm_sfpcomp(as, ir); 2290 asm_sfpcomp(as, ir);
2216#else 2291#elif !LJ_TARGET_MIPSR6
2217 asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); 2292 asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0);
2218 emit_fgh(as, MIPSI_C_EQ_D, 0, left, right); 2293 emit_fgh(as, MIPSI_C_EQ_D, 0, left, right);
2294#else
2295 Reg tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_FPR, left), right));
2296 asm_guard(as, (ir->o & 1) ? MIPSI_BC1NEZ : MIPSI_BC1EQZ, 0, (tmp&31));
2297 emit_fgh(as, MIPSI_CMP_EQ_D, tmp, left, right);
2219#endif 2298#endif
2220 } else { 2299 } else {
2221 asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right); 2300 asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right);
@@ -2618,7 +2697,12 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
2618 if (((p[-1] ^ (px-p)) & 0xffffu) == 0 && 2697 if (((p[-1] ^ (px-p)) & 0xffffu) == 0 &&
2619 ((p[-1] & 0xf0000000u) == MIPSI_BEQ || 2698 ((p[-1] & 0xf0000000u) == MIPSI_BEQ ||
2620 (p[-1] & 0xfc1e0000u) == MIPSI_BLTZ || 2699 (p[-1] & 0xfc1e0000u) == MIPSI_BLTZ ||
2621 (p[-1] & 0xffe00000u) == MIPSI_BC1F)) { 2700#if !LJ_TARGET_MIPSR6
2701 (p[-1] & 0xffe00000u) == MIPSI_BC1F
2702#else
2703 (p[-1] & 0xff600000u) == MIPSI_BC1EQZ
2704#endif
2705 )) {
2622 ptrdiff_t delta = target - p; 2706 ptrdiff_t delta = target - p;
2623 if (((delta + 0x8000) >> 16) == 0) { /* Patch in-range branch. */ 2707 if (((delta + 0x8000) >> 16) == 0) { /* Patch in-range branch. */
2624 patchbranch: 2708 patchbranch: