]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
predicates.md (equality_operator): New.
authorPaolo Bonzini <bonzini@gnu.org>
Tue, 23 Aug 2005 17:39:59 +0000 (17:39 +0000)
committerPaolo Bonzini <bonzini@gcc.gnu.org>
Tue, 23 Aug 2005 17:39:59 +0000 (17:39 +0000)
2005-08-23  Paolo Bonzini  <bonzini@gnu.org>

* config/rs6000/predicates.md (equality_operator): New.
* config/rs6000/rs6000.md: Rewrite as a peephole2 the split for
comparison with a large constant.

From-SVN: r103405

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.md

index e88c8eb509e5ef658e75338c90e7da53f052580a..4c1dd35148953d6321cdd511484b7133a94f166f 100644 (file)
@@ -1,3 +1,9 @@
+2005-08-23  Paolo Bonzini  <bonzini@gnu.org>
+
+       * config/rs6000/predicates.md (equality_operator): New.
+       * config/rs6000/rs6000.md: Rewrite as a peephole2 the split for
+       comparison with a large constant.
+
 2005-08-23  Mark Mitchell  <mark@codesourcery.com>
 
        * hwint.h (HOST_WIDE_INT_PRINT): Use HOST_LONG_LONG_FORMAT.
index 122ec45e8569399f652193eb2f58b7cab7f1cfe6..3b5ef34a41b2f85c771d409946b6b3d5599babe1 100644 (file)
 (define_predicate "boolean_or_operator"
   (match_code "ior,xor"))
 
+;; Return true if operand is an equality operator.
+(define_special_predicate "equality_operator"
+  (match_code "eq,ne"))
+
 ;; Return true if operand is MIN or MAX operator.
 (define_predicate "min_max_operator"
   (match_code "smin,smax,umin,umax"))
index 84db59fd14a634e1607b53f0c54fba371a01ec59..d1f810919ba550917af2d6bfd8957b5c28fc1a15 100644 (file)
   [(set_attr "type" "cmp")])
 
 ;; If we are comparing a register for equality with a large constant,
-;; we can do this with an XOR followed by a compare.  But we need a scratch
-;; register for the result of the XOR.
+;; we can do this with an XOR followed by a compare.  But this is profitable
+;; only if the large constant is only used for the comparison (and in this
+;; case we already have a register to reuse as scratch).
 
-(define_split
-  [(set (match_operand:CC 0 "cc_reg_operand" "")
-       (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
-                   (match_operand:SI 2 "non_short_cint_operand" "")))
-   (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
-  "find_single_use (operands[0], insn, 0)
-   && (GET_CODE (*find_single_use (operands[0], insn, 0)) == EQ
-       || GET_CODE (*find_single_use (operands[0], insn, 0)) == NE)"
-  [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 4)))
-   (set (match_dup 0) (compare:CC (match_dup 3) (match_dup 5)))]
-  "
-{
-  /* Get the constant we are comparing against, C,  and see what it looks like
-     sign-extended to 16 bits.  Then see what constant could be XOR'ed
-     with C to get the sign-extended value.  */
-
-  HOST_WIDE_INT c = INTVAL (operands[2]);
+(define_peephole2
+  [(set (match_operand:GPR 0 "register_operand")
+        (match_operand:GPR 1 "logical_operand" ""))
+   (set (match_dup 0) (match_operator:GPR 3 "boolean_or_operator"
+                      [(match_dup 0)
+                       (match_operand:GPR 2 "logical_operand" "")]))
+   (set (match_operand:CC 4 "cc_reg_operand" "")
+        (compare:CC (match_operand:GPR 5 "gpc_reg_operand" "")
+                    (match_dup 0)))
+   (set (pc)
+        (if_then_else (match_operator 6 "equality_operator"
+                       [(match_dup 4) (const_int 0)])
+                      (match_operand 7 "" "")
+                      (match_operand 8 "" "")))]
+  "peep2_reg_dead_p (3, operands[0])"
+ [(set (match_dup 0) (xor:GPR (match_dup 5) (match_dup 9)))
+  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
+  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
+{
+  /* Get the constant we are comparing against, and see what it looks like
+     when sign-extended from 16 to 32 bits.  Then see what constant we could
+     XOR with SEXTC to get the sign-extended value.  */
+  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
+                                             GET_MODE (operands[3]),
+                                             operands[1], operands[2]);
+  HOST_WIDE_INT c = INTVAL (cnst);
   HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
   HOST_WIDE_INT xorv = c ^ sextc;
 
-  operands[4] = GEN_INT (xorv);
-  operands[5] = GEN_INT (sextc);
-}")
+  operands[9] = GEN_INT (xorv);
+  operands[10] = GEN_INT (sextc);
+})
 
 (define_insn "*cmpsi_internal2"
   [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")