Blame SOURCES/arm-Fix-up-condition-codes-for-conditional-arithmeti.patch

006bc1
From 24429cc95657332e3953a21581d3220884da3d75 Mon Sep 17 00:00:00 2001
006bc1
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
006bc1
Date: Wed, 8 May 2019 22:14:00 +0530
006bc1
Subject: [PATCH] arm: Fix up condition codes for conditional arithmetic insn
006bc1
006bc1
When an arithmetic instruction such as add or sub are combined with a
006bc1
subsequent compare with zero, its following conditional branch code
006bc1
needs fixing up.  This is necessary because one could generate an add
006bc1
with a subtract of the negative but such a substitution, while correct
006bc1
on its own, will change the effect on condition flags since while
006bc1
addition of two positive numbers may signal an overflow, addition of a
006bc1
positive and a negative number may not.  So if earlier the condition
006bc1
code was GE, it needs to be fixed up to PL to remain correct.
006bc1
006bc1
We did that for bit operations but not for arithmetic, so do that now.
006bc1
---
006bc1
 src/lj_asm_arm.h | 38 ++++++++++++++++++++------------------
006bc1
 1 file changed, 20 insertions(+), 18 deletions(-)
006bc1
006bc1
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h
006bc1
index 37bfa40f..e585b4c2 100644
006bc1
--- a/src/lj_asm_arm.h
006bc1
+++ b/src/lj_asm_arm.h
006bc1
@@ -1412,13 +1412,28 @@ static void asm_intop(ASMState *as, IRIns *ir, ARMIns ai)
006bc1
   emit_dn(as, ai^m, dest, left);
006bc1
 }
006bc1
 
006bc1
-static void asm_intop_s(ASMState *as, IRIns *ir, ARMIns ai)
006bc1
+static ARMIns maybe_drop_zero_cmp(ASMState *as, ARMIns ai)
006bc1
 {
006bc1
-  if (as->flagmcp == as->mcp) {  /* Drop cmp r, #0. */
006bc1
+  if (as->flagmcp == as->mcp) {  /* Try to drop cmp r, #0. */
006bc1
+    uint32_t cc = (as->mcp[1] >> 28);
006bc1
     as->flagmcp = NULL;
006bc1
-    as->mcp++;
006bc1
-    ai |= ARMI_S;
006bc1
+    if (cc <= CC_NE) {
006bc1
+      as->mcp++;
006bc1
+      ai |= ARMI_S;
006bc1
+    } else if (cc == CC_GE) {
006bc1
+      *++as->mcp ^= ((CC_GE^CC_PL) << 28);
006bc1
+      ai |= ARMI_S;
006bc1
+    } else if (cc == CC_LT) {
006bc1
+      *++as->mcp ^= ((CC_LT^CC_MI) << 28);
006bc1
+      ai |= ARMI_S;
006bc1
+    }  /* else: other conds don't work with bit ops. */
006bc1
   }
006bc1
+  return ai;
006bc1
+}
006bc1
+
006bc1
+static void asm_intop_s(ASMState *as, IRIns *ir, ARMIns ai)
006bc1
+{
006bc1
+  ai = maybe_drop_zero_cmp(as, ai);
006bc1
   asm_intop(as, ir, ai);
006bc1
 }
006bc1
 
006bc1
@@ -1514,20 +1529,7 @@ static void asm_neg(ASMState *as, IRIns *ir)
006bc1
 
006bc1
 static void asm_bitop(ASMState *as, IRIns *ir, ARMIns ai)
006bc1
 {
006bc1
-  if (as->flagmcp == as->mcp) {  /* Try to drop cmp r, #0. */
006bc1
-    uint32_t cc = (as->mcp[1] >> 28);
006bc1
-    as->flagmcp = NULL;
006bc1
-    if (cc <= CC_NE) {
006bc1
-      as->mcp++;
006bc1
-      ai |= ARMI_S;
006bc1
-    } else if (cc == CC_GE) {
006bc1
-      *++as->mcp ^= ((CC_GE^CC_PL) << 28);
006bc1
-      ai |= ARMI_S;
006bc1
-    } else if (cc == CC_LT) {
006bc1
-      *++as->mcp ^= ((CC_LT^CC_MI) << 28);
006bc1
-      ai |= ARMI_S;
006bc1
-    }  /* else: other conds don't work with bit ops. */
006bc1
-  }
006bc1
+  ai = maybe_drop_zero_cmp(as, ai);
006bc1
   if (ir->op2 == 0) {
006bc1
     Reg dest = ra_dest(as, ir, RSET_GPR);
006bc1
     uint32_t m = asm_fuseopm(as, ai, ir->op1, RSET_GPR);
006bc1
-- 
006bc1
2.21.0
006bc1