Commit 452a7d36 by Hartmut Penner Committed by Hartmut Penner

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
parent 708d2456
2004-03-30 Hartmut Penner <hpenner@de.ibm.com> 2004-03-30 Hartmut Penner <hpenner@de.ibm.com>
* 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 <hpenner@de.ibm.com>
PR 11591 PR 11591
* config/rs6000/rs6000.c (rs6000_legitimate_address): * config/rs6000/rs6000.c (rs6000_legitimate_address):
Allow any offset to argument pointer in no-strict case. Allow any offset to argument pointer in no-strict case.
......
...@@ -124,13 +124,14 @@ ...@@ -124,13 +124,14 @@
[(set (match_operand:V4SI 0 "altivec_register_operand" "") [(set (match_operand:V4SI 0 "altivec_register_operand" "")
(match_operand:V4SI 1 "easy_vector_constant_add_self" ""))] (match_operand:V4SI 1 "easy_vector_constant_add_self" ""))]
"TARGET_ALTIVEC && reload_completed" "TARGET_ALTIVEC && reload_completed"
[(set (match_dup 0) [(set (match_dup 0) (match_dup 3))
(unspec:V4SI [(match_dup 3)] UNSPEC_VSPLTISW))
(set (match_dup 0) (set (match_dup 0)
(plus:V4SI (match_dup 0) (plus:V4SI (match_dup 0)
(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" (define_expand "movv8hi"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "") [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
...@@ -172,13 +173,14 @@ ...@@ -172,13 +173,14 @@
[(set (match_operand:V8HI 0 "altivec_register_operand" "") [(set (match_operand:V8HI 0 "altivec_register_operand" "")
(match_operand:V8HI 1 "easy_vector_constant_add_self" ""))] (match_operand:V8HI 1 "easy_vector_constant_add_self" ""))]
"TARGET_ALTIVEC && reload_completed" "TARGET_ALTIVEC && reload_completed"
[(set (match_dup 0) [(set (match_dup 0) (match_dup 3))
(unspec:V8HI [(match_dup 3)] UNSPEC_VSPLTISH))
(set (match_dup 0) (set (match_dup 0)
(plus:V8HI (match_dup 0) (plus:V8HI (match_dup 0)
(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" (define_expand "movv16qi"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "") [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
...@@ -220,13 +222,14 @@ ...@@ -220,13 +222,14 @@
[(set (match_operand:V16QI 0 "altivec_register_operand" "") [(set (match_operand:V16QI 0 "altivec_register_operand" "")
(match_operand:V16QI 1 "easy_vector_constant_add_self" ""))] (match_operand:V16QI 1 "easy_vector_constant_add_self" ""))]
"TARGET_ALTIVEC && reload_completed" "TARGET_ALTIVEC && reload_completed"
[(set (match_dup 0) [(set (match_dup 0) (match_dup 3))
(unspec:V16QI [(match_dup 3)] UNSPEC_VSPLTISB))
(set (match_dup 0) (set (match_dup 0)
(plus:V16QI (match_dup 0) (plus:V16QI (match_dup 0)
(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" (define_expand "movv4sf"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "") [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
......
...@@ -57,6 +57,7 @@ extern int got_no_const_operand (rtx, enum machine_mode); ...@@ -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 num_insns_constant (rtx, enum machine_mode);
extern int easy_fp_constant (rtx, enum machine_mode); extern int easy_fp_constant (rtx, enum machine_mode);
extern int easy_vector_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 const char *output_vec_const_move (rtx *);
extern int zero_fp_constant (rtx, enum machine_mode); extern int zero_fp_constant (rtx, enum machine_mode);
extern int zero_constant (rtx, enum machine_mode); extern int zero_constant (rtx, enum machine_mode);
......
...@@ -60,12 +60,9 @@ ...@@ -60,12 +60,9 @@
#define TARGET_NO_PROTOTYPE 0 #define TARGET_NO_PROTOTYPE 0
#endif #endif
#define EASY_VECTOR_15(n, x, y) ((n) >= -16 && (n) <= 15 \ #define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
&& easy_vector_same (x, y)) #define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e \
&& !((n) & 1))
#define EASY_VECTOR_15_ADD_SELF(n, x, y) ((n) >= 0x10 && (n) <= 0x1e \
&& !((n) & 1) \
&& easy_vector_same (x, y))
#define min(A,B) ((A) < (B) ? (A) : (B)) #define min(A,B) ((A) < (B) ? (A) : (B))
#define max(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 *); ...@@ -411,6 +408,7 @@ static void is_altivec_return_reg (rtx, void *);
static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int); static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
int easy_vector_constant (rtx, enum machine_mode); int easy_vector_constant (rtx, enum machine_mode);
static int easy_vector_same (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 bool is_ev64_opaque_type (tree);
static rtx rs6000_dwarf_register_span (rtx); static rtx rs6000_dwarf_register_span (rtx);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model); static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
...@@ -1677,6 +1675,38 @@ easy_fp_constant (rtx op, enum machine_mode mode) ...@@ -1677,6 +1675,38 @@ easy_fp_constant (rtx op, enum machine_mode mode)
abort (); 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. */ /* Return nonzero if all elements of a vector have the same value. */
static int static int
...@@ -1690,7 +1720,7 @@ easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) ...@@ -1690,7 +1720,7 @@ easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
for (i = 1; i < units; ++i) for (i = 1; i < units; ++i)
if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst) if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
break; break;
if (i == units) if (i == units && easy_vector_splat_const (cst, mode))
return 1; return 1;
return 0; return 0;
} }
...@@ -1736,31 +1766,14 @@ easy_vector_constant (rtx op, enum machine_mode mode) ...@@ -1736,31 +1766,14 @@ easy_vector_constant (rtx op, enum machine_mode mode)
&& cst2 >= -0x7fff && cst2 <= 0x7fff) && cst2 >= -0x7fff && cst2 <= 0x7fff)
return 1; return 1;
if (TARGET_ALTIVEC) if (TARGET_ALTIVEC
switch (mode) && easy_vector_same (op, mode))
{ {
case V4SImode: cst = easy_vector_splat_const (cst, mode);
if (EASY_VECTOR_15 (cst, op, mode)) if (EASY_VECTOR_15_ADD_SELF (cst)
return 1; || EASY_VECTOR_15 (cst))
if ((cst & 0xffff) != ((cst >> 16) & 0xffff)) return 1;
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;
return 0; return 0;
} }
...@@ -1770,13 +1783,31 @@ int ...@@ -1770,13 +1783,31 @@ int
easy_vector_constant_add_self (rtx op, enum machine_mode mode) easy_vector_constant_add_self (rtx op, enum machine_mode mode)
{ {
int cst; 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)) /* Generate easy_vector_constant out of a easy_vector_constant_add_self. */
return 0;
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 * const char *
...@@ -1797,33 +1828,37 @@ output_vec_const_move (rtx *operands) ...@@ -1797,33 +1828,37 @@ output_vec_const_move (rtx *operands)
{ {
if (zero_constant (vec, mode)) if (zero_constant (vec, mode))
return "vxor %0,%0,%0"; return "vxor %0,%0,%0";
else if (EASY_VECTOR_15_ADD_SELF (cst, vec, mode))
return "#";
else if (easy_vector_constant (vec, mode)) else if (easy_vector_constant (vec, mode))
{ {
operands[1] = GEN_INT (cst); operands[1] = GEN_INT (cst);
switch (mode) switch (mode)
{ {
case V4SImode: case V4SImode:
if (EASY_VECTOR_15 (cst, vec, mode)) if (EASY_VECTOR_15 (cst))
{ {
operands[1] = GEN_INT (cst); operands[1] = GEN_INT (cst);
return "vspltisw %0,%1"; return "vspltisw %0,%1";
} }
else if (EASY_VECTOR_15_ADD_SELF (cst))
return "#";
cst = cst >> 16; cst = cst >> 16;
case V8HImode: case V8HImode:
if (EASY_VECTOR_15 (cst, vec, mode)) if (EASY_VECTOR_15 (cst))
{ {
operands[1] = GEN_INT (cst); operands[1] = GEN_INT (cst);
return "vspltish %0,%1"; return "vspltish %0,%1";
} }
else if (EASY_VECTOR_15_ADD_SELF (cst))
return "#";
cst = cst >> 8; cst = cst >> 8;
case V16QImode: case V16QImode:
if (EASY_VECTOR_15 (cst, vec, mode)) if (EASY_VECTOR_15 (cst))
{ {
operands[1] = GEN_INT (cst); operands[1] = GEN_INT (cst);
return "vspltisb %0,%1"; return "vspltisb %0,%1";
} }
else if (EASY_VECTOR_15_ADD_SELF (cst))
return "#";
default: default:
abort (); abort ();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment