diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-27 07:51:59 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-07-27 07:51:59 +0000 |
commit | cb56012690ae1b8f203a61decdcb5d281db2431c (patch) | |
tree | 58bc341cb04d6000b923fc1d7edb78289d9f2938 /gcc/config/rs6000/predicates.md | |
parent | 84836637fcb8e7c3aea3b25f4cbf17a59cfca553 (diff) | |
download | gcc-cb56012690ae1b8f203a61decdcb5d281db2431c.tar.gz |
2009-07-27 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 150103
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@150104 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000/predicates.md')
-rw-r--r-- | gcc/config/rs6000/predicates.md | 62 |
1 files changed, 60 insertions, 2 deletions
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index b6b443bf3f8..3e5c1a1a8df 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -38,6 +38,37 @@ || ALTIVEC_REGNO_P (REGNO (op)) || REGNO (op) > LAST_VIRTUAL_REGISTER"))) +;; 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"))) + +;; 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"))) + +;; 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"))) + +;; 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"))) + ;; Return 1 if op is XER register. (define_predicate "xer_operand" (and (match_code "reg") @@ -234,6 +265,10 @@ && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1); case DFmode: + /* The constant 0.f is easy under VSX. */ + if (op == CONST0_RTX (DFmode) && VECTOR_UNIT_VSX_P (DFmode)) + return 1; + /* Force constants to memory before reload to utilize compress_float_constant. Avoid this when flag_unsafe_math_optimizations is enabled @@ -292,6 +327,9 @@ if (TARGET_PAIRED_FLOAT) return false; + if ((VSX_VECTOR_MODE (mode) || mode == TImode) && zero_constant (op, mode)) + return true; + if (ALTIVEC_VECTOR_MODE (mode)) { if (zero_constant (op, mode)) @@ -394,16 +432,36 @@ (match_code "mem") { op = XEXP (op, 0); - if (TARGET_ALTIVEC - && ALTIVEC_VECTOR_MODE (mode) + if (VECTOR_MEM_ALTIVEC_P (mode) && GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT && INTVAL (XEXP (op, 1)) == -16) op = XEXP (op, 0); + else if (VECTOR_MEM_VSX_P (mode) + && GET_CODE (op) == PRE_MODIFY) + op = XEXP (op, 1); + return indexed_or_indirect_address (op, mode); }) +;; Return 1 if the operand is an indexed or indirect memory operand with an +;; AND -16 in it, used to recognize when we need to switch to Altivec loads +;; to realign loops instead of VSX (altivec silently ignores the bottom bits, +;; while VSX uses the full address and traps) +(define_predicate "altivec_indexed_or_indirect_operand" + (match_code "mem") +{ + op = XEXP (op, 0); + if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode) + && GET_CODE (op) == AND + && GET_CODE (XEXP (op, 1)) == CONST_INT + && INTVAL (XEXP (op, 1)) == -16) + return indexed_or_indirect_address (XEXP (op, 0), mode); + + return 0; +}) + ;; Return 1 if the operand is an indexed or indirect address. (define_special_predicate "indexed_or_indirect_address" (and (match_test "REG_P (op) |