diff mbox

rs6000: Add eqsi/nesi storing to a 64-bit reg (PR36557)

Message ID c15f8798a3088d610c982deb725499dfa4e5cf1c.1420680045.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Jan. 8, 2015, 1:28 a.m. UTC
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(+)

Comments

David Edelsohn Jan. 8, 2015, 2:11 a.m. UTC | #1
On Wed, Jan 7, 2015 at 8:28 PM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> 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.

Okay.

Thanks, David
diff mbox

Patch

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