This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] rs6000: Add eqsi/nesi storing to a 64-bit reg (PR36557)
- From: Segher Boessenkool <segher at kernel dot crashing dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dje dot gcc at gmail dot com, Segher Boessenkool <segher at kernel dot crashing dot org>
- Date: Wed, 7 Jan 2015 17:28:55 -0800
- Subject: [PATCH] rs6000: Add eqsi/nesi storing to a 64-bit reg (PR36557)
- Authentication-results: sourceware.org; auth=none
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