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] rs6000: Add eqsi/nesi storing to a 64-bit reg (PR36557)


The compiler cannot assume that the eqsi etc. patterns write a properly
extended result to a DI reg.  The current way to tell it is to add an
extra pattern with an extend.  This patch does that.  A less cumbersome
method of specifying this would be nice -- maybe one where we say in
the SI pattern that the result is already extended correctly as DI (both
sign- and zero-extended, in this case).

This partially fixes PR36557 (and is the best we can do for the test
case there, we cannot assume function args are correctly extended for
their type).

Tested as usual; okay for mainline?


Segher


2015-01-07  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	PR target/36557
	* config/rs6000/rs6000.md (*eqsi3_ext<mode>, *nesi3_ext<mode>): New.

---
 gcc/config/rs6000/rs6000.md | 60 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 3da529c..6da1a6a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -12588,6 +12588,66 @@ (define_insn_and_split "*minus_ne_<mode>"
 	(if_then_else (match_test "operands[2] == const0_rtx")
 		      (const_string "8")
 		      (const_string "12")))])
+
+(define_insn_and_split "*eqsi3_ext<mode>"
+  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
+	(eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
+		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
+   (clobber (match_scratch:SI 3 "=r"))
+   (clobber (match_scratch:SI 4 "=r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 4)
+	(clz:SI (match_dup 3)))
+   (set (match_dup 0)
+	(zero_extend:EXTSI
+	  (lshiftrt:SI (match_dup 4)
+		       (const_int 5))))]
+{
+  operands[3] = rs6000_emit_eqne (SImode,
+				  operands[1], operands[2], operands[3]);
+
+  if (GET_CODE (operands[4]) == SCRATCH)
+    operands[4] = gen_reg_rtx (SImode);
+}
+  [(set (attr "length")
+	(if_then_else (match_test "operands[2] == const0_rtx")
+		      (const_string "8")
+		      (const_string "12")))])
+
+(define_insn_and_split "*nesi3_ext<mode>"
+  [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
+	(ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
+		  (match_operand:SI 2 "scc_eq_operand" "rKLI")))
+   (clobber (match_scratch:SI 3 "=r"))
+   (clobber (match_scratch:SI 4 "=r"))
+   (clobber (match_scratch:EXTSI 5 "=r"))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 4)
+	(clz:SI (match_dup 3)))
+   (set (match_dup 5)
+	(zero_extend:EXTSI
+	  (lshiftrt:SI (match_dup 4)
+		       (const_int 5))))
+   (set (match_dup 0)
+	(xor:EXTSI (match_dup 5)
+		   (const_int 1)))]
+{
+  operands[3] = rs6000_emit_eqne (SImode,
+				  operands[1], operands[2], operands[3]);
+
+  if (GET_CODE (operands[4]) == SCRATCH)
+    operands[4] = gen_reg_rtx (SImode);
+  if (GET_CODE (operands[5]) == SCRATCH)
+    operands[5] = gen_reg_rtx (<MODE>mode);
+}
+  [(set (attr "length")
+	(if_then_else (match_test "operands[2] == const0_rtx")
+		      (const_string "12")
+		      (const_string "16")))])
 
 ;; Define both directions of branch and return.  If we need a reload
 ;; register, we'd rather use CR0 since it is much easier to copy a
-- 
1.8.1.4


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