From: Hartmut Penner Date: Tue, 30 Mar 2004 08:25:30 +0000 (+0000) Subject: rs6000.c (output_vec_const_move): Find all cases of EASY_VECTOR_15_ADD_SELF. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=452a7d365084a8dc318c005e2a312217ab43c719;p=gcc.git rs6000.c (output_vec_const_move): Find all cases of EASY_VECTOR_15_ADD_SELF. * config/rs6000/rs6000.c (output_vec_const_move): Find all cases of EASY_VECTOR_15_ADD_SELF. (easy_vector_constant_add_self): Accept all vector constant loadable by vsplt* and vadd*. (easy_vector_same): Use easy_vector_splat_const. (easy_vector_const): Use easy_vector_splat_const. (easy_vector_splat_const): New function. (gen_easy_vector_constant_add_self): New function. * config/rs6000/rs6000-protos.c (gen_easy_vector_constant_add_self): New prototype. * config/rs6000/altivec.md (movv4si splitter): Change to emit move insn with halfed vector constant. (*movv8hi splitter): Likewise. (*movv16qi splitter): Likewise. From-SVN: r80077 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e0b5a3526c8..5b197fc1a44 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2004-03-30 Hartmut Penner + + * config/rs6000/rs6000.c (output_vec_const_move): + Find all cases of EASY_VECTOR_15_ADD_SELF. + (easy_vector_constant_add_self): Accept + all vector constant loadable by vsplt* and vadd*. + (easy_vector_same): Use easy_vector_splat_const. + (easy_vector_const): Use easy_vector_splat_const. + (easy_vector_splat_const): New function. + (gen_easy_vector_constant_add_self): New function. + + * config/rs6000/rs6000-protos.c (gen_easy_vector_constant_add_self): + New prototype. + + * config/rs6000/altivec.md (movv4si splitter): Change to + emit move insn with halfed vector constant. + (*movv8hi splitter): Likewise. + (*movv16qi splitter): Likewise. + 2004-03-30 Hartmut Penner PR 11591 diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 684a5d4c4b9..3e27a1b86c2 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -124,13 +124,14 @@ [(set (match_operand:V4SI 0 "altivec_register_operand" "") (match_operand:V4SI 1 "easy_vector_constant_add_self" ""))] "TARGET_ALTIVEC && reload_completed" - [(set (match_dup 0) - (unspec:V4SI [(match_dup 3)] UNSPEC_VSPLTISW)) + [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (plus:V4SI (match_dup 0) (match_dup 0)))] " -{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }") +{ + operands[3] = gen_easy_vector_constant_add_self (operands[1]); +}") (define_expand "movv8hi" [(set (match_operand:V8HI 0 "nonimmediate_operand" "") @@ -172,13 +173,14 @@ [(set (match_operand:V8HI 0 "altivec_register_operand" "") (match_operand:V8HI 1 "easy_vector_constant_add_self" ""))] "TARGET_ALTIVEC && reload_completed" - [(set (match_dup 0) - (unspec:V8HI [(match_dup 3)] UNSPEC_VSPLTISH)) + [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (plus:V8HI (match_dup 0) (match_dup 0)))] " -{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }") +{ + operands[3] = gen_easy_vector_constant_add_self (operands[1]); +}") (define_expand "movv16qi" [(set (match_operand:V16QI 0 "nonimmediate_operand" "") @@ -220,13 +222,14 @@ [(set (match_operand:V16QI 0 "altivec_register_operand" "") (match_operand:V16QI 1 "easy_vector_constant_add_self" ""))] "TARGET_ALTIVEC && reload_completed" - [(set (match_dup 0) - (unspec:V16QI [(match_dup 3)] UNSPEC_VSPLTISB)) + [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (plus:V16QI (match_dup 0) (match_dup 0)))] " -{ operands[3] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)) >> 1); }") +{ + operands[3] = gen_easy_vector_constant_add_self (operands[1]); +}") (define_expand "movv4sf" [(set (match_operand:V4SF 0 "nonimmediate_operand" "") diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 5c778e15f05..95a506b4fcc 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -57,6 +57,7 @@ extern int got_no_const_operand (rtx, enum machine_mode); extern int num_insns_constant (rtx, enum machine_mode); extern int easy_fp_constant (rtx, enum machine_mode); extern int easy_vector_constant (rtx, enum machine_mode); +extern rtx gen_easy_vector_constant_add_self (rtx); extern const char *output_vec_const_move (rtx *); extern int zero_fp_constant (rtx, enum machine_mode); extern int zero_constant (rtx, enum machine_mode); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index c8854b09328..bd649fa5695 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -60,12 +60,9 @@ #define TARGET_NO_PROTOTYPE 0 #endif -#define EASY_VECTOR_15(n, x, y) ((n) >= -16 && (n) <= 15 \ - && easy_vector_same (x, y)) - -#define EASY_VECTOR_15_ADD_SELF(n, x, y) ((n) >= 0x10 && (n) <= 0x1e \ - && !((n) & 1) \ - && easy_vector_same (x, y)) +#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15) +#define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e \ + && !((n) & 1)) #define min(A,B) ((A) < (B) ? (A) : (B)) #define max(A,B) ((A) > (B) ? (A) : (B)) @@ -411,6 +408,7 @@ static void is_altivec_return_reg (rtx, void *); static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int); int easy_vector_constant (rtx, enum machine_mode); static int easy_vector_same (rtx, enum machine_mode); +static int easy_vector_splat_const (int, enum machine_mode); static bool is_ev64_opaque_type (tree); static rtx rs6000_dwarf_register_span (rtx); static rtx rs6000_legitimize_tls_address (rtx, enum tls_model); @@ -1677,6 +1675,38 @@ easy_fp_constant (rtx op, enum machine_mode mode) abort (); } +/* Returns the constant for the splat instrunction, if exists. */ + +static int +easy_vector_splat_const (int cst, enum machine_mode mode) +{ + switch (mode) + { + case V4SImode: + if (EASY_VECTOR_15 (cst) + || EASY_VECTOR_15_ADD_SELF (cst)) + return cst; + if ((cst & 0xffff) != ((cst >> 16) & 0xffff)) + break; + cst = cst >> 16; + case V8HImode: + if (EASY_VECTOR_15 (cst) + || EASY_VECTOR_15_ADD_SELF (cst)) + return cst; + if ((cst & 0xff) != ((cst >> 8) & 0xff)) + break; + cst = cst >> 8; + case V16QImode: + if (EASY_VECTOR_15 (cst) + || EASY_VECTOR_15_ADD_SELF (cst)) + return cst; + default: + break; + } + return 0; +} + + /* Return nonzero if all elements of a vector have the same value. */ static int @@ -1690,7 +1720,7 @@ easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) for (i = 1; i < units; ++i) if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst) break; - if (i == units) + if (i == units && easy_vector_splat_const (cst, mode)) return 1; return 0; } @@ -1736,31 +1766,14 @@ easy_vector_constant (rtx op, enum machine_mode mode) && cst2 >= -0x7fff && cst2 <= 0x7fff) return 1; - if (TARGET_ALTIVEC) - switch (mode) - { - case V4SImode: - if (EASY_VECTOR_15 (cst, op, mode)) - return 1; - if ((cst & 0xffff) != ((cst >> 16) & 0xffff)) - break; - cst = cst >> 16; - case V8HImode: - if (EASY_VECTOR_15 (cst, op, mode)) - return 1; - if ((cst & 0xff) != ((cst >> 8) & 0xff)) - break; - cst = cst >> 8; - case V16QImode: - if (EASY_VECTOR_15 (cst, op, mode)) - return 1; - default: - break; - } - - if (TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode)) - return 1; - + if (TARGET_ALTIVEC + && easy_vector_same (op, mode)) + { + cst = easy_vector_splat_const (cst, mode); + if (EASY_VECTOR_15_ADD_SELF (cst) + || EASY_VECTOR_15 (cst)) + return 1; + } return 0; } @@ -1770,13 +1783,31 @@ int easy_vector_constant_add_self (rtx op, enum machine_mode mode) { int cst; + if (TARGET_ALTIVEC + && GET_CODE (op) == CONST_VECTOR + && easy_vector_same (op, mode)) + { + cst = easy_vector_splat_const (INTVAL (CONST_VECTOR_ELT (op, 0)), mode); + if (EASY_VECTOR_15_ADD_SELF (cst)) + return 1; + } + return 0; +} - if (!easy_vector_constant (op, mode)) - return 0; +/* Generate easy_vector_constant out of a easy_vector_constant_add_self. */ - cst = INTVAL (CONST_VECTOR_ELT (op, 0)); +rtx +gen_easy_vector_constant_add_self (rtx op) +{ + int i, units; + rtvec v; + units = GET_MODE_NUNITS (GET_MODE (op)); + v = rtvec_alloc (units); - return TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode); + for (i = 0; i < units; i++) + RTVEC_ELT (v, i) = + GEN_INT (INTVAL (CONST_VECTOR_ELT (op, i)) >> 1); + return gen_rtx_raw_CONST_VECTOR (GET_MODE (op), v); } const char * @@ -1797,33 +1828,37 @@ output_vec_const_move (rtx *operands) { if (zero_constant (vec, mode)) return "vxor %0,%0,%0"; - else if (EASY_VECTOR_15_ADD_SELF (cst, vec, mode)) - return "#"; else if (easy_vector_constant (vec, mode)) { operands[1] = GEN_INT (cst); switch (mode) { case V4SImode: - if (EASY_VECTOR_15 (cst, vec, mode)) + if (EASY_VECTOR_15 (cst)) { operands[1] = GEN_INT (cst); return "vspltisw %0,%1"; } + else if (EASY_VECTOR_15_ADD_SELF (cst)) + return "#"; cst = cst >> 16; case V8HImode: - if (EASY_VECTOR_15 (cst, vec, mode)) + if (EASY_VECTOR_15 (cst)) { operands[1] = GEN_INT (cst); return "vspltish %0,%1"; } + else if (EASY_VECTOR_15_ADD_SELF (cst)) + return "#"; cst = cst >> 8; case V16QImode: - if (EASY_VECTOR_15 (cst, vec, mode)) + if (EASY_VECTOR_15 (cst)) { operands[1] = GEN_INT (cst); return "vspltisb %0,%1"; } + else if (EASY_VECTOR_15_ADD_SELF (cst)) + return "#"; default: abort (); }