Blame SOURCES/0021-MIPS64-Fix-register-allocation-in-assembly-of-HREF.patch

006bc1
From 99cdfbf6a1e8856f64908072ef10443a7eab14f2 Mon Sep 17 00:00:00 2001
006bc1
From: Mike Pall <mike>
006bc1
Date: Wed, 8 Nov 2017 12:54:03 +0100
006bc1
Subject: [PATCH 21/72] MIPS64: Fix register allocation in assembly of HREF.
006bc1
006bc1
Contributed by James Cowgill.
006bc1
---
006bc1
 src/lj_asm_mips.h | 42 +++++++++++++++++++++++++-----------------
006bc1
 1 file changed, 25 insertions(+), 17 deletions(-)
006bc1
006bc1
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
006bc1
index 1406a87..3a4679b 100644
006bc1
--- a/src/lj_asm_mips.h
006bc1
+++ b/src/lj_asm_mips.h
006bc1
@@ -859,6 +859,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
006bc1
   Reg dest = ra_dest(as, ir, allow);
006bc1
   Reg tab = ra_alloc1(as, ir->op1, rset_clear(allow, dest));
006bc1
   Reg key = RID_NONE, type = RID_NONE, tmpnum = RID_NONE, tmp1 = RID_TMP, tmp2;
006bc1
+#if LJ_64
006bc1
+  Reg cmp64 = RID_NONE;
006bc1
+#endif
006bc1
   IRRef refkey = ir->op2;
006bc1
   IRIns *irkey = IR(refkey);
006bc1
   int isk = irref_isk(refkey);
006bc1
@@ -901,6 +904,26 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
006bc1
 #endif
006bc1
   tmp2 = ra_scratch(as, allow);
006bc1
   rset_clear(allow, tmp2);
006bc1
+#if LJ_64
006bc1
+  if (LJ_SOFTFP || !irt_isnum(kt)) {
006bc1
+    /* Allocate cmp64 register used for 64-bit comparisons */
006bc1
+    if (LJ_SOFTFP && irt_isnum(kt)) {
006bc1
+      cmp64 = key;
006bc1
+    } else if (!isk && irt_isaddr(kt)) {
006bc1
+      cmp64 = tmp2;
006bc1
+    } else {
006bc1
+      int64_t k;
006bc1
+      if (isk && irt_isaddr(kt)) {
006bc1
+	k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
006bc1
+      } else {
006bc1
+	lua_assert(irt_ispri(kt) && !irt_isnil(kt));
006bc1
+	k = ~((int64_t)~irt_toitype(ir->t) << 47);
006bc1
+      }
006bc1
+      cmp64 = ra_allock(as, k, allow);
006bc1
+      rset_clear(allow, cmp64);
006bc1
+    }
006bc1
+  }
006bc1
+#endif
006bc1
 
006bc1
   /* Key not found in chain: jump to exit (if merged) or load niltv. */
006bc1
   l_end = emit_label(as);
006bc1
@@ -943,24 +966,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
006bc1
     emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15);
006bc1
     emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum);
006bc1
     emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
006bc1
-  } else if (LJ_SOFTFP && irt_isnum(kt)) {
006bc1
-    emit_branch(as, MIPSI_BEQ, tmp1, key, l_end);
006bc1
-    emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
006bc1
-  } else if (irt_isaddr(kt)) {
006bc1
-    Reg refk = tmp2;
006bc1
-    if (isk) {
006bc1
-      int64_t k = ((int64_t)irt_toitype(irkey->t) << 47) | irkey[1].tv.u64;
006bc1
-      refk = ra_allock(as, k, allow);
006bc1
-      rset_clear(allow, refk);
006bc1
-    }
006bc1
-    emit_branch(as, MIPSI_BEQ, tmp1, refk, l_end);
006bc1
-    emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));
006bc1
   } else {
006bc1
-    Reg pri = ra_allock(as, ~((int64_t)~irt_toitype(ir->t) << 47), allow);
006bc1
-    rset_clear(allow, pri);
006bc1
-    lua_assert(irt_ispri(kt) && !irt_isnil(kt));
006bc1
-    emit_branch(as, MIPSI_BEQ, tmp1, pri, l_end);
006bc1
-    emit_tsi(as, MIPSI_LD, tmp1, dest, offsetof(Node, key));
006bc1
+    emit_branch(as, MIPSI_BEQ, tmp1, cmp64, l_end);
006bc1
+    emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64));
006bc1
   }
006bc1
   *l_loop = MIPSI_BNE | MIPSF_S(tmp1) | ((as->mcp-l_loop-1) & 0xffffu);
006bc1
   if (!isk && irt_isaddr(kt)) {
006bc1
-- 
006bc1
2.20.1
006bc1