diff options
Diffstat (limited to 'gcc/config/rs6000/predicates.md')
-rw-r--r-- | gcc/config/rs6000/predicates.md | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 71fac765e2..41694a51f1 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -572,6 +572,38 @@ } }) +;; Return 1 if the operand is a CONST_VECTOR or VEC_DUPLICATE of a constant +;; that can loaded with a XXSPLTIB instruction and then a VUPKHSB, VECSB2W or +;; VECSB2D instruction. + +(define_predicate "xxspltib_constant_split" + (match_code "const_vector,vec_duplicate,const_int") +{ + int value = 256; + int num_insns = -1; + + if (!xxspltib_constant_p (op, mode, &num_insns, &value)) + return false; + + return num_insns > 1; +}) + + +;; Return 1 if the operand is a CONST_VECTOR that can loaded directly with a +;; XXSPLTIB instruction. + +(define_predicate "xxspltib_constant_nosplit" + (match_code "const_vector,vec_duplicate,const_int") +{ + int value = 256; + int num_insns = -1; + + if (!xxspltib_constant_p (op, mode, &num_insns, &value)) + return false; + + return num_insns == 1; +}) + ;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a ;; vector register without using memory. (define_predicate "easy_vector_constant" @@ -590,7 +622,14 @@ if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) { - if (zero_constant (op, mode)) + int value = 256; + int num_insns = -1; + + if (zero_constant (op, mode) || all_ones_constant (op, mode)) + return true; + + if (TARGET_P9_VECTOR + && xxspltib_constant_p (op, mode, &num_insns, &value)) return true; return easy_altivec_constant (op, mode); @@ -669,6 +708,11 @@ (and (match_code "const_int,const_double,const_wide_int,const_vector") (match_test "op == CONST0_RTX (mode)"))) +;; Return 1 if operand is constant -1 (scalars and vectors). +(define_predicate "all_ones_constant" + (and (match_code "const_int,const_double,const_wide_int,const_vector") + (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)"))) + ;; Return 1 if operand is 0.0. (define_predicate "zero_fp_constant" (and (match_code "const_double") @@ -698,48 +742,25 @@ (define_predicate "quad_memory_operand" (match_code "mem") { - rtx addr, op0, op1; - int ret; - if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI) - ret = 0; - - else if (!memory_operand (op, mode)) - ret = 0; - - else if (GET_MODE_SIZE (GET_MODE (op)) != 16) - ret = 0; - - else if (MEM_ALIGN (op) < 128) - ret = 0; - - else - { - addr = XEXP (op, 0); - if (int_reg_operand (addr, Pmode)) - ret = 1; + return false; - else if (GET_CODE (addr) != PLUS) - ret = 0; + if (GET_MODE_SIZE (mode) != 16 || !MEM_P (op) || MEM_ALIGN (op) < 128) + return false; - else - { - op0 = XEXP (addr, 0); - op1 = XEXP (addr, 1); - ret = (int_reg_operand (op0, Pmode) - && GET_CODE (op1) == CONST_INT - && IN_RANGE (INTVAL (op1), -32768, 32767) - && (INTVAL (op1) & 15) == 0); - } - } + return quad_address_p (XEXP (op, 0), mode, false); +}) - if (TARGET_DEBUG_ADDR) - { - fprintf (stderr, "\nquad_memory_operand, ret = %s\n", ret ? "true" : "false"); - debug_rtx (op); - } +;; Return 1 if the operand is suitable for load/store to vector registers with +;; d-form addressing (register+offset), which was added in ISA 3.0. +;; Unlike quad_memory_operand, we do not have to check for alignment. +(define_predicate "vsx_quad_dform_memory_operand" + (match_code "mem") +{ + if (!TARGET_P9_DFORM_VECTOR || !MEM_P (op) || GET_MODE_SIZE (mode) != 16) + return false; - return ret; + return quad_address_p (XEXP (op, 0), mode, false); }) ;; Return 1 if the operand is an indexed or indirect memory operand. @@ -1054,6 +1075,10 @@ mode = V2DFmode; else if (mode == DImode) mode = V2DImode; + else if (mode == SImode && TARGET_P9_VECTOR) + mode = V4SImode; + else if (mode == SFmode && TARGET_P9_VECTOR) + mode = V4SFmode; else gcc_unreachable (); return memory_address_addr_space_p (mode, XEXP (op, 0), @@ -1091,10 +1116,6 @@ (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")) - ;; Return 1 if OP is a comparison operation that is valid for a branch ;; instruction. We check the opcode against the mode of the CC value. ;; validate_condition_mode is an assertion. @@ -1137,6 +1158,11 @@ (and (match_operand 0 "branch_comparison_operator") (match_code "ne,le,ge,leu,geu,ordered"))) +;; Return 1 if OP is a comparison operator suitable for vector/scalar +;; comparisons that generate a -1/0 mask. +(define_predicate "fpmask_comparison_operator" + (match_code "eq,gt,ge")) + ;; Return 1 if OP is a comparison operation that is valid for a branch ;; insn, which is true if the corresponding bit in the CC register is set. (define_predicate "branch_positive_comparison_operator" |