diff options
Diffstat (limited to 'gcc/config/rs6000/predicates.md')
| -rw-r--r-- | gcc/config/rs6000/predicates.md | 102 |
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") |
