V1DF V2DF
(V1TF "TARGET_VXE") (TF "TARGET_VXE")])
-(define_mode_iterator VF [(V2SF "TARGET_VXE") (V4SF "TARGET_VXE") V2DF])
+(define_mode_iterator VF [V2SF V4SF V2DF])
; All modes present in V_HW1 and VFT.
(define_mode_iterator V_HW1_FT [V16QI V8HI V4SI V2DI V1TI V1DF
(define_mode_iterator VEC_SET_NONFLOAT
[V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V2SF V4SF])
; Iterator for single element float vectors
-(define_mode_iterator VEC_SET_SINGLEFLOAT [(V1SF "TARGET_VXE") V1DF (V1TF "TARGET_VXE")])
+(define_mode_iterator VEC_SET_SINGLEFLOAT [V1SF V1DF (V1TF "TARGET_VXE")])
; FIXME: Support also vector mode operands for 1
; FIXME: A target memory operand seems to be useful otherwise we end
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=arch11 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+typedef double V2DF __attribute__((vector_size(16)));
+typedef float V4SF __attribute__((vector_size(16)));
+typedef float V2SF __attribute__((vector_size(8)));
+typedef double V1DF __attribute__((vector_size(8)));
+typedef float V1SF __attribute__((vector_size(4)));
+typedef long double V1TF __attribute__((vector_size(16)));
+
+/*
+** extractfirstdouble:
+** vsteg %v24,0\(%r2\),0
+** br %r14
+*/
+void
+extractfirstdouble (double *res, V2DF x)
+{
+ *res = x[0];
+}
+
+/*
+** extractseconddouble:
+** vsteg %v24,0\(%r2\),1
+** br %r14
+*/
+void
+extractseconddouble (double *res, V2DF x)
+{
+ *res = x[1];
+}
+
+/*
+** extractnthdouble:
+** vlgvg (%r.),%v24,0\(%r3\)
+** stg \1,0\(%r2\)
+** br %r14
+*/
+void
+extractnthdouble (double *res, V2DF x, int n)
+{
+ *res = x[n];
+}
+
+/*
+** extractfirstfloat:
+** vstef %v24,0\(%r2\),0
+** br %r14
+*/
+void
+extractfirstfloat (float *res, V4SF x)
+{
+ *res = x[0];
+}
+
+/*
+** extractsecondfloat:
+** vstef %v24,0\(%r2\),1
+** br %r14
+*/
+void
+extractsecondfloat (float *res, V4SF x)
+{
+ *res = x[1];
+}
+
+/*
+** extractthirdfloat:
+** vstef %v24,0\(%r2\),2
+** br %r14
+*/
+void
+extractthirdfloat (float *res, V4SF x)
+{
+ *res = x[2];
+}
+
+/*
+** extractfourthfloat:
+** vstef %v24,0\(%r2\),3
+** br %r14
+*/
+void
+extractfourthfloat (float *res, V4SF x)
+{
+ *res = x[3];
+}
+
+/*
+** extractnthfloat:
+** vlgvf (%r.),%v24,0\(%r3\)
+** st \1,0\(%r2\)
+** br %r14
+*/
+void
+extractnthfloat (float *res, V4SF x, int n)
+{
+ *res = x[n];
+}
+
+/*
+** extractfirst2:
+** vstef %v24,0\(%r2\),0
+** br %r14
+*/
+void
+extractfirst2 (float *res, V2SF x)
+{
+ *res = x[0];
+}
+
+/*
+** extractsecond2:
+** vstef %v24,0\(%r2\),1
+** br %r14
+*/
+void
+extractsecond2 (float *res, V2SF x)
+{
+ *res = x[1];
+}
+
+/*
+** extractnth2:
+** vlgvf (%r.),%v24,0\(%r3\)
+** st \1,0\(%r2\)
+** br %r14
+*/
+void
+extractnth2 (float *res, V2SF x, int n)
+{
+ *res = x[n];
+}
+
+/*
+** extractsinglef:
+** vlr %v(.),%v24
+** ste %f\1,0\(%r2\)
+** br %r14
+*/
+void
+extractsinglef (float *res, V1SF x)
+{
+ *res = x[0];
+}
+
+/*
+** extractsingled:
+** vsteg %v24,0\(%r2\),0
+** br %r14
+*/
+void
+extractsingled (double *res, V1DF x)
+{
+ *res = x[0];
+}
+
+/*
+** extractsingleld:
+** vst %v24,0\(%r2\),3
+** br %r14
+*/
+void
+extractsingleld (long double *res, V1TF x)
+{
+ *res = x[0];
+}
/* { dg-do compile } */
-/* { dg-options "-O2 -march=z14 -mzarch" } */
+/* { dg-options "-O2 -march=arch11 -mzarch" } */
/* { dg-final { check-function-bodies "**" "" } } */
typedef double V2DF __attribute__((vector_size(16)));
/*
** setsf0:
-** lgdr (%r.),%f0
+** vlgvf (%r.),%v0,0
** vlvgf %v24,\1,0
** br %r14
*/
/*
** setsf1:
-** lgdr (%r.),%f0
+** vlgvf (%r.),%v0,0
** vlvgf %v24,\1,1
** br %r14
*/
}
/*
-** setsf0:
-** lgdr (%r.),%f0
+** setsf2:
+** vlgvf (%r.),%v0,0
** vlvgf %v24,\1,2
** br %r14
*/
}
/*
-** setsf1:
-** lgdr (%r.),%f0
+** setsf3:
+** vlgvf (%r.),%v0,0
** vlvgf %v24,\1,3
** br %r14
*/
/*
** setsfn:
-** lgdr (%r.),%f0
+** vlgvf (%r.),%v0,0
** vlvgf %v24,\1,0\(%r2\)
** br %r14
*/
setsfn (V4SF x, float y, int n)
{
x[n] = y;
+ /* Make sure to read all FPRs such that the "save GPRs in FPRs" optimization
+ cannot be used. That optimization has a memory clobber on SP restore
+ causing DSE to fail to eliminate dead stores in leaf functions using this
+ optimization. */
+ asm volatile ("" : : "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), "f" (y),
+ "f" (y), "f" (y), "f" (y), "f" (y), "f" (y), "f" (y),
+ "f" (y), "f" (y), "f" (y), "f" (y));
return x;
}