aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/predicates.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/predicates.md')
-rw-r--r--gcc/config/rs6000/predicates.md102
1 files changed, 35 insertions, 67 deletions
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 936f932..cba7337 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -143,30 +143,25 @@
(TARGET_32BIT ? 'L' : 'J'))")
(match_operand 0 "gpc_reg_operand")))
-;; Return 1 if op is a 32-bit signed constant integer valid for arithmetic
+;; Return 1 if op is a constant integer valid for addition
;; or non-special register.
-(define_predicate "reg_or_arith_cint_operand"
+(define_predicate "reg_or_add_cint_operand"
(if_then_else (match_code "const_int")
- (match_test "HOST_BITS_PER_WIDE_INT == 32
- || ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
- < (unsigned HOST_WIDE_INT) 0x100000000ll)")
- (match_operand 0 "gpc_reg_operand")))
-
-;; Return 1 if op is a 32-bit signed constant integer valid for 64-bit addition
-;; or non-special register.
-(define_predicate "reg_or_add_cint64_operand"
- (if_then_else (match_code "const_int")
- (match_test "(HOST_BITS_PER_WIDE_INT == 32 && INTVAL (op) < 0x7fff8000)
+ (match_test "(HOST_BITS_PER_WIDE_INT == 32
+ && (mode == SImode || INTVAL (op) < 0x7fff8000))
|| ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
< (unsigned HOST_WIDE_INT) 0x100000000ll)")
(match_operand 0 "gpc_reg_operand")))
-;; Return 1 if op is a 32-bit constant integer valid for 64-bit subtraction
+;; Return 1 if op is a constant integer valid for subtraction
;; or non-special register.
-(define_predicate "reg_or_sub_cint64_operand"
+(define_predicate "reg_or_sub_cint_operand"
(if_then_else (match_code "const_int")
- (match_test "(HOST_BITS_PER_WIDE_INT == 32 && INTVAL (op) < 0x7fff8000)
- || ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
+ (match_test "(HOST_BITS_PER_WIDE_INT == 32
+ && (mode == SImode || - INTVAL (op) < 0x7fff8000))
+ || ((unsigned HOST_WIDE_INT) (- INTVAL (op)
+ + (mode == SImode
+ ? 0x80000000 : 0x80008000))
< (unsigned HOST_WIDE_INT) 0x100000000ll)")
(match_operand 0 "gpc_reg_operand")))
@@ -439,10 +434,14 @@
(and (not (match_operand 0 "logical_operand"))
(match_operand 0 "reg_or_logical_cint_operand"))))
-;; Return 1 if op is a constant that can be encoded in a 32-bit mask (no
-;; more than two 1->0 or 0->1 transitions). Reject all ones and all
-;; zeros, since these should have been optimized away and confuse the
-;; making of MB and ME.
+;; For SImode, return 1 if op is a constant that can be encoded in a
+;; 32-bit mask (no more than two 1->0 or 0->1 transitions). Reject
+;; all ones and all zeros, since these should have been optimized away
+;; and confuse the making of MB and ME.
+;; For DImode, return 1 if the operand is a constant that is a
+;; PowerPC64 mask (no more than one 1->0 or 0->1 transitions). Reject
+;; all zeros, since zero should have been optimized away and confuses
+;; the making of MB and ME.
(define_predicate "mask_operand"
(match_code "const_int")
{
@@ -452,7 +451,11 @@
/* Fail in 64-bit mode if the mask wraps around because the upper
32-bits of the mask will all be 1s, contrary to GCC's internal view. */
- if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
+ if (mode == SImode && TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
+ return 0;
+
+ /* Reject all zeros or all ones in 32-bit mode. */
+ if (c == 0 || (mode == SImode && c == -1))
return 0;
/* We don't change the number of transitions by inverting,
@@ -460,21 +463,20 @@
if (c & 1)
c = ~c;
- /* Reject all zeros or all ones. */
- if (c == 0)
- return 0;
-
/* Find the first transition. */
lsb = c & -c;
- /* Invert to look for a second transition. */
- c = ~c;
+ if (mode == SImode)
+ {
+ /* Invert to look for a second transition. */
+ c = ~c;
- /* Erase first transition. */
- c &= -lsb;
+ /* Erase first transition. */
+ c &= -lsb;
- /* Find the second transition (if any). */
- lsb = c & -c;
+ /* Find the second transition (if any). */
+ lsb = c & -c;
+ }
/* Match if all the bits above are 1's (or c is zero). */
return c == -lsb;
@@ -502,33 +504,7 @@
return c == -lsb;
})
-;; Return 1 if the operand is a constant that is a PowerPC64 mask (no more
-;; than one 1->0 or 0->1 transitions). Reject all zeros, since zero
-;; should have been optimized away and confuses the making of MB and ME.
-(define_predicate "mask64_operand"
- (match_code "const_int")
-{
- HOST_WIDE_INT c, lsb;
-
- c = INTVAL (op);
-
- /* Reject all zeros. */
- if (c == 0)
- return 0;
-
- /* We don't change the number of transitions by inverting,
- so make sure we start with the LS bit zero. */
- if (c & 1)
- c = ~c;
-
- /* Find the transition, and check that all bits above are 1's. */
- lsb = c & -c;
-
- /* Match if all the bits above are 1's (or c is zero). */
- return c == -lsb;
-})
-
-;; Like mask64_operand, but allow up to three transitions. This
+;; Like mask_operand, but allow up to three transitions. This
;; predicate is used by insn patterns that generate two rldicl or
;; rldicr machine insns.
(define_predicate "mask64_2_operand"
@@ -537,15 +513,7 @@
return mask64_1or2_operand (op, mode, false);
})
-;; Return 1 if the operand is either a non-special register or a constant
-;; that can be used as the operand of a PowerPC64 logical AND insn.
-(define_predicate "and64_operand"
- (ior (match_operand 0 "mask64_operand")
- (if_then_else (match_test "fixed_regs[CR0_REGNO]")
- (match_operand 0 "gpc_reg_operand")
- (match_operand 0 "logical_operand"))))
-
-;; Like and64_operand, but also match constants that can be implemented
+;; Like and_operand, but also match constants that can be implemented
;; with two rldicl or rldicr insns.
(define_predicate "and64_2_operand"
(ior (and (match_code "const_int")