aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2012-09-23 01:02:06 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2012-09-23 01:02:06 +0200
commita2027aad1b81c6b56d198a26b56e9f179a82cd6b (patch)
treef2a23ab1341f2eaac8258e8b64131bec579e1d5f
parent699bae64e5f2db1e1d67259a7ab1d54765d6475e (diff)
downloadgcc-a2027aad1b81c6b56d198a26b56e9f179a82cd6b.zip
gcc-a2027aad1b81c6b56d198a26b56e9f179a82cd6b.tar.gz
gcc-a2027aad1b81c6b56d198a26b56e9f179a82cd6b.tar.bz2
predicates.md (altivec_register_operand, [...]): If op is a SUBREG, consider its SUBREG_REG instead.
gcc/ * config/rs6000/predicates.md (altivec_register_operand, vsx_register_operand, vfloat_operand, vint_operand, vlogical_operand, gpc_reg_operand, cc_reg_operand, cc_reg_not_cr0_operand, cc_reg_not_micro_cr0_operand): If op is a SUBREG, consider its SUBREG_REG instead. From-SVN: r191645
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/predicates.md166
2 files changed, 132 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4e29d4d..e650f90 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2012-09-22 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/predicates.md (altivec_register_operand,
+ vsx_register_operand, vfloat_operand, vint_operand,
+ vlogical_operand, gpc_reg_operand, cc_reg_operand,
+ cc_reg_not_cr0_operand, cc_reg_not_micro_cr0_operand):
+ If op is a SUBREG, consider its SUBREG_REG instead.
+
2012-09-22 Uros Bizjak <ubizjak@gmail.com>
* optabs.c (prepare_cmp_insn): Expand comparison of the result
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index e2c3e70..12b7527 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -30,44 +30,89 @@
(and (match_code "reg")
(match_test "REGNO (op) == CTR_REGNO
|| REGNO (op) > LAST_VIRTUAL_REGISTER")))
-
+
;; Return 1 if op is an Altivec register.
(define_predicate "altivec_register_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || ALTIVEC_REGNO_P (REGNO (op))
- || REGNO (op) > LAST_VIRTUAL_REGISTER")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return ALTIVEC_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a VSX register.
(define_predicate "vsx_register_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || VSX_REGNO_P (REGNO (op))
- || REGNO (op) > LAST_VIRTUAL_REGISTER")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return VSX_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a vector register that operates on floating point vectors
;; (either altivec or VSX).
(define_predicate "vfloat_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || VFLOAT_REGNO_P (REGNO (op))
- || REGNO (op) > LAST_VIRTUAL_REGISTER")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return VFLOAT_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a vector register that operates on integer vectors
;; (only altivec, VSX doesn't support integer vectors)
(define_predicate "vint_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || VINT_REGNO_P (REGNO (op))
- || REGNO (op) > LAST_VIRTUAL_REGISTER")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return VINT_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a vector register to do logical operations on (and, or,
;; xor, etc.)
(define_predicate "vlogical_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || VLOGICAL_REGNO_P (REGNO (op))
- || REGNO (op) > LAST_VIRTUAL_REGISTER")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return VLOGICAL_REGNO_P (REGNO (op));
+})
;; Return 1 if op is the carry register.
(define_predicate "ca_operand"
@@ -123,36 +168,73 @@
;; Return 1 if op is a register that is not special.
(define_predicate "gpc_reg_operand"
- (and (match_operand 0 "register_operand")
- (match_test "(GET_CODE (op) != REG
- || (REGNO (op) >= ARG_POINTER_REGNUM
- && !CA_REGNO_P (REGNO (op)))
- || INT_REGNO_P (REGNO (op))
- || FP_REGNO_P (REGNO (op)))
- && !((TARGET_E500_DOUBLE || TARGET_SPE)
- && invalid_e500_subreg (op, mode))")))
+ (match_operand 0 "register_operand")
+{
+ if ((TARGET_E500_DOUBLE || TARGET_SPE) && invalid_e500_subreg (op, mode))
+ return 0;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) >= ARG_POINTER_REGNUM && !CA_REGNO_P (REGNO (op)))
+ return 1;
+
+ return INT_REGNO_P (REGNO (op)) || FP_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a register that is a condition register field.
(define_predicate "cc_reg_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || REGNO (op) > LAST_VIRTUAL_REGISTER
- || CR_REGNO_P (REGNO (op))")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return CR_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a register that is a condition register field not cr0.
(define_predicate "cc_reg_not_cr0_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || REGNO (op) > LAST_VIRTUAL_REGISTER
- || CR_REGNO_NOT_CR0_P (REGNO (op))")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ return CR_REGNO_NOT_CR0_P (REGNO (op));
+})
;; Return 1 if op is a register that is a condition register field and if generating microcode, not cr0.
(define_predicate "cc_reg_not_micro_cr0_operand"
- (and (match_operand 0 "register_operand")
- (match_test "GET_CODE (op) != REG
- || REGNO (op) > LAST_VIRTUAL_REGISTER
- || (rs6000_gen_cell_microcode && CR_REGNO_NOT_CR0_P (REGNO (op)))
- || (!rs6000_gen_cell_microcode && CR_REGNO_P (REGNO (op)))")))
+ (match_operand 0 "register_operand")
+{
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (!REG_P (op))
+ return 0;
+
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER)
+ return 1;
+
+ if (rs6000_gen_cell_microcode)
+ return CR_REGNO_NOT_CR0_P (REGNO (op));
+ else
+ return CR_REGNO_P (REGNO (op));
+})
;; Return 1 if op is a constant integer valid for D field
;; or non-special register register.