summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-02 09:22:17 +0000
committerrevitale <revitale@138bc75d-0d04-0410-961f-82ee72b054a4>2007-10-02 09:22:17 +0000
commitdd9e4c8842392aed12a9a00dd872c5fe3acede54 (patch)
treeb6943adaff05cd744724e4661c974a2378355cf2 /gcc/config/rs6000
parent894ad0f31f144323951b45f86a675718bf019826 (diff)
downloadgcc-dd9e4c8842392aed12a9a00dd872c5fe3acede54.tar.gz
Add vec_init support for 750CL paired vectors and fix movv2sf_paired
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128952 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r--gcc/config/rs6000/paired.md21
-rw-r--r--gcc/config/rs6000/predicates.md5
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c53
4 files changed, 78 insertions, 2 deletions
diff --git a/gcc/config/rs6000/paired.md b/gcc/config/rs6000/paired.md
index ad3001d884c..67eee233c5e 100644
--- a/gcc/config/rs6000/paired.md
+++ b/gcc/config/rs6000/paired.md
@@ -188,7 +188,7 @@
[(set_attr "type" "fp")])
(define_insn "*movv2sf_paired"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,o,r,r,v")
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,o,r,r,f")
(match_operand:V2SF 1 "input_operand" "f,Z,f,r,o,r,W"))]
"TARGET_PAIRED_FLOAT
&& (register_operand (operands[0], V2SFmode)
@@ -202,7 +202,7 @@
case 3: return "#";
case 4: return "#";
case 5: return "#";
- case 6: return output_vec_const_move (operands);
+ case 6: return "#";
default: gcc_unreachable ();
}
}
@@ -352,4 +352,21 @@
"ps_muls1 %0, %1, %2"
[(set_attr "type" "fp")])
+(define_expand "vec_initv2sf"
+ [(match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (match_operand 1 "" "")]
+ "TARGET_PAIRED_FLOAT"
+{
+ paired_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "*vconcatsf"
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f")
+ (vec_concat:V2SF
+ (match_operand:SF 1 "gpc_reg_operand" "f")
+ (match_operand:SF 2 "gpc_reg_operand" "f")))]
+ "TARGET_PAIRED_FLOAT"
+ "ps_merge00 %0, %1, %2"
+ [(set_attr "type" "fp")])
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index f56c176b37c..3dd4bf560d7 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -275,6 +275,11 @@
(define_predicate "easy_vector_constant"
(match_code "const_vector")
{
+ /* As the paired vectors are actually FPRs it seems that there is
+ no easy way to load a CONST_VECTOR without using memory. */
+ if (TARGET_PAIRED_FLOAT)
+ return false;
+
if (ALTIVEC_VECTOR_MODE (mode))
{
if (zero_constant (op, mode))
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 799a15ac0a4..8c9eb0696c1 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -48,6 +48,7 @@ extern rtx find_addr_reg (rtx);
extern rtx gen_easy_altivec_constant (rtx);
extern const char *output_vec_const_move (rtx *);
extern void rs6000_expand_vector_init (rtx, rtx);
+extern void paired_expand_vector_init (rtx, rtx);
extern void rs6000_expand_vector_set (rtx, rtx, int);
extern void rs6000_expand_vector_extract (rtx, rtx, int);
extern void build_mask64_2_operands (rtx, rtx *);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8a840ef568a..0f2617fd82b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -2716,6 +2716,59 @@ output_vec_const_move (rtx *operands)
return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
}
+/* Initialize TARGET of vector PAIRED to VALS. */
+
+void
+paired_expand_vector_init (rtx target, rtx vals)
+{
+ enum machine_mode mode = GET_MODE (target);
+ int n_elts = GET_MODE_NUNITS (mode);
+ int n_var = 0;
+ rtx x, new, tmp, constant_op, op1, op2;
+ int i;
+
+ for (i = 0; i < n_elts; ++i)
+ {
+ x = XVECEXP (vals, 0, i);
+ if (!CONSTANT_P (x))
+ ++n_var;
+ }
+ if (n_var == 0)
+ {
+ /* Load from constant pool. */
+ emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
+ return;
+ }
+
+ if (n_var == 2)
+ {
+ /* The vector is initialized only with non-constants. */
+ new = gen_rtx_VEC_CONCAT (V2SFmode, XVECEXP (vals, 0, 0),
+ XVECEXP (vals, 0, 1));
+
+ emit_move_insn (target, new);
+ return;
+ }
+
+ /* One field is non-constant and the other one is a constant. Load the
+ constant from the constant pool and use ps_merge instruction to
+ construct the whole vector. */
+ op1 = XVECEXP (vals, 0, 0);
+ op2 = XVECEXP (vals, 0, 1);
+
+ constant_op = (CONSTANT_P (op1)) ? op1 : op2;
+
+ tmp = gen_reg_rtx (GET_MODE (constant_op));
+ emit_move_insn (tmp, constant_op);
+
+ if (CONSTANT_P (op1))
+ new = gen_rtx_VEC_CONCAT (V2SFmode, tmp, op2);
+ else
+ new = gen_rtx_VEC_CONCAT (V2SFmode, op1, tmp);
+
+ emit_move_insn (target, new);
+}
+
/* Initialize vector TARGET to VALS. */
void