This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/2] rs6000: Implement cstore for signed Pmode register compares


This implements cstore for the last case we do not yet handle, using
the superopt algo from the venerable CWG.  The only integer cases we
do still not handle after this are for -m32 -mpowerpc64.  Those case
now generate a branch sequence, which is better than what we had
before.

Tested on powerpc64-linux; okay for mainline?


Segher


2015-12-04  Segher Boessenkool  <segher&kernel.crashing.org>

	* (cstore<mode>4_signed): New expander.
	(cstore<mode>4): Call it.  FAIL instead of calling rs6000_emit_sCOND.

---
 gcc/config/rs6000/rs6000.md | 50 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 48 insertions(+), 2 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 26b0962..98abdb2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10525,6 +10525,47 @@ (define_expand "cbranch<mode>4"
   DONE;
 }")
 
+(define_expand "cstore<mode>4_signed"
+  [(use (match_operator 1 "signed_comparison_operator"
+         [(match_operand:P 2 "gpc_reg_operand")
+          (match_operand:P 3 "gpc_reg_operand")]))
+   (clobber (match_operand:P 0 "gpc_reg_operand"))]
+  ""
+{
+  enum rtx_code cond_code = GET_CODE (operands[1]);
+
+  rtx op0 = operands[0];
+  rtx op1 = operands[2];
+  rtx op2 = operands[3];
+
+  if (cond_code == GE || cond_code == LT)
+    {
+      cond_code = swap_condition (cond_code);
+      std::swap (op1, op2);
+    }
+
+  rtx tmp1 = gen_reg_rtx (<MODE>mode);
+  rtx tmp2 = gen_reg_rtx (<MODE>mode);
+  rtx tmp3 = gen_reg_rtx (<MODE>mode);
+
+  int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
+  emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
+  emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
+
+  emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
+
+  if (cond_code == LE)
+    emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
+  else
+    {
+      rtx tmp4 = gen_reg_rtx (<MODE>mode);
+      emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
+      emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
+    }
+
+  DONE;
+})
+
 (define_expand "cstore<mode>4_unsigned"
   [(use (match_operator 1 "unsigned_comparison_operator"
          [(match_operand:P 2 "gpc_reg_operand" "")
@@ -10751,9 +10792,14 @@ (define_expand "cstore<mode>4"
     emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
 					       operands[2], operands[3]));
 
-  /* Everything else, use the mfcr brute force.  */
+  /* We also do not want to use mfcr for signed comparisons.  */
+  else if (<MODE>mode == Pmode
+	   && signed_comparison_operator (operands[1], VOIDmode))
+    emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
+					 operands[2], operands[3]));
+
   else
-    rs6000_emit_sCOND (<MODE>mode, operands);
+    FAIL;
 
   DONE;
 })
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]