aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/testsuite/gcc.target/aarch64/vneg_f.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/testsuite/gcc.target/aarch64/vneg_f.c')
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.target/aarch64/vneg_f.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/testsuite/gcc.target/aarch64/vneg_f.c b/gcc-4.9/gcc/testsuite/gcc.target/aarch64/vneg_f.c
new file mode 100644
index 000000000..015030285
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.target/aarch64/vneg_f.c
@@ -0,0 +1,270 @@
+/* Test vneg works correctly. */
+/* { dg-do run } */
+/* { dg-options "--save-temps" } */
+
+#include <arm_neon.h>
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define FLT_MAX __FLT_MAX__
+#define FLT_MIN __FLT_MIN__
+#define DBL_MAX __DBL_MAX__
+#define DBL_MIN __DBL_MIN__
+
+#define TEST0 0
+/* 6 digits of pi. */
+#define TEST1 3.14159
+/* 6 digits of -e. */
+#define TEST2 -2.71828
+/* 2^25, float has 24 significand bits
+ according to Single-precision floating-point format. */
+#define TEST3_FLT 33554432
+/* 2^54, double has 53 significand bits
+ according to Double-precision floating-point format. */
+#define TEST3_DBL 18014398509481984
+
+extern void abort (void);
+
+#define FLT_INFINITY (__builtin_inff ())
+#define DBL_INFINITY (__builtin_inf ())
+
+#ifndef NAN
+#define NAN (0.0 / 0.0)
+#endif
+
+#define CONCAT(a, b) a##b
+#define CONCAT1(a, b) CONCAT (a, b)
+#define REG_INFEX64 _
+#define REG_INFEX128 q_
+#define REG_INFEX(reg_len) REG_INFEX##reg_len
+#define POSTFIX(reg_len, data_len) \
+ CONCAT1 (REG_INFEX (reg_len), f##data_len)
+
+#define DATA_TYPE_32 float
+#define DATA_TYPE_64 double
+#define DATA_TYPE(data_len) DATA_TYPE_##data_len
+
+#define STORE_INST(reg_len, data_len) \
+ CONCAT1 (vst1, POSTFIX (reg_len, data_len))
+#define LOAD_INST(reg_len, data_len) \
+ CONCAT1 (vld1, POSTFIX (reg_len, data_len))
+#define NEG_INST(reg_len, data_len) \
+ CONCAT1 (vneg, POSTFIX (reg_len, data_len))
+
+#define INHIB_OPTIMIZATION asm volatile ("" : : : "memory")
+#define RUN_TEST(test_set, reg_len, data_len, n, a, b, c) \
+ { \
+ int i; \
+ (a) = LOAD_INST (reg_len, data_len) (test_set); \
+ (b) = NEG_INST (reg_len, data_len) (a); \
+ STORE_INST (reg_len, data_len) (c, b); \
+ for (i = 0; i < n; i++) \
+ { \
+ DATA_TYPE (data_len) diff; \
+ INHIB_OPTIMIZATION; \
+ diff = test_set[i] + c[i]; \
+ if (diff > EPSILON) \
+ return 1; \
+ } \
+ }
+
+#define TEST3 TEST3_FLT
+#define EPSILON FLT_EPSILON
+#define VAR_MIN FLT_MIN
+#define VAR_MAX FLT_MAX
+#define INFINITY FLT_INFINITY
+
+int
+test_vneg_f32 ()
+{
+ float32x2_t a;
+ float32x2_t b;
+ float32_t c[2];
+
+ float32_t test_set0[2] = { TEST0, TEST1 };
+ float32_t test_set1[2] = { TEST2, TEST3 };
+ float32_t test_set2[2] = { VAR_MAX, VAR_MIN };
+ float32_t test_set3[2] = { INFINITY, NAN };
+
+ RUN_TEST (test_set0, 64, 32, 2, a, b, c);
+ RUN_TEST (test_set1, 64, 32, 2, a, b, c);
+ RUN_TEST (test_set2, 64, 32, 2, a, b, c);
+ RUN_TEST (test_set3, 64, 32, 0, a, b, c);
+
+ /* Since last test cannot be checked in a uniform way by adding
+ negation result to original value, the number of lanes to be
+ checked in RUN_TEST is 0 (last argument). Instead, result
+ will be checked manually. */
+
+ if (c[0] != -INFINITY)
+ return 1;
+
+ if (!__builtin_isnan (c[1]))
+ return 1;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.2s, v\[0-9\]+\.2s" 4 } } */
+
+#undef TEST3
+#undef EPSILON
+#undef VAR_MIN
+#undef VAR_MAX
+#undef INFINITY
+
+#define TEST3 TEST3_DBL
+#define EPSILON DBL_EPSILON
+#define VAR_MIN DBL_MIN
+#define VAR_MAX DBL_MAX
+#define INFINITY DBL_INFINITY
+
+int
+test_vneg_f64 ()
+{
+ float64x1_t a;
+ float64x1_t b;
+ float64_t c[1];
+
+ float64_t test_set0[1] = { TEST0 };
+ float64_t test_set1[1] = { TEST1 };
+ float64_t test_set2[1] = { TEST2 };
+ float64_t test_set3[1] = { TEST3 };
+ float64_t test_set4[1] = { VAR_MAX };
+ float64_t test_set5[1] = { VAR_MIN };
+ float64_t test_set6[1] = { INFINITY };
+ float64_t test_set7[1] = { NAN };
+
+ RUN_TEST (test_set0, 64, 64, 1, a, b, c);
+ RUN_TEST (test_set1, 64, 64, 1, a, b, c);
+ RUN_TEST (test_set2, 64, 64, 1, a, b, c);
+ RUN_TEST (test_set3, 64, 64, 1, a, b, c);
+ RUN_TEST (test_set4, 64, 64, 1, a, b, c);
+ RUN_TEST (test_set5, 64, 64, 1, a, b, c);
+ RUN_TEST (test_set6, 64, 64, 0, a, b, c);
+
+ /* Since last test cannot be checked in a uniform way by adding
+ negation result to original value, the number of lanes to be
+ checked in RUN_TEST is 0 (last argument). Instead, result
+ will be checked manually. */
+
+ if (c[0] != -INFINITY)
+ return 1;
+
+ /* Same as above. */
+
+ RUN_TEST (test_set7, 64, 64, 0, a, b, c);
+
+ if (!__builtin_isnan (c[0]))
+ return 1;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "fneg\\td\[0-9\]+, d\[0-9\]+" 8 } } */
+
+#undef TEST3
+#undef EPSILON
+#undef VAR_MIN
+#undef VAR_MAX
+#undef INFINITY
+
+#define TEST3 TEST3_FLT
+#define EPSILON FLT_EPSILON
+#define VAR_MIN FLT_MIN
+#define VAR_MAX FLT_MAX
+#define INFINITY FLT_INFINITY
+
+int
+test_vnegq_f32 ()
+{
+ float32x4_t a;
+ float32x4_t b;
+ float32_t c[4];
+
+ float32_t test_set0[4] = { TEST0, TEST1, TEST2, TEST3 };
+ float32_t test_set1[4] = { FLT_MAX, FLT_MIN, INFINITY, NAN };
+
+ RUN_TEST (test_set0, 128, 32, 4, a, b, c);
+ RUN_TEST (test_set1, 128, 32, 2, a, b, c);
+
+ /* Since last test cannot be fully checked in a uniform way by
+ adding negation result to original value, the number of lanes
+ to be checked in RUN_TEST is 0 (last argument). Instead, result
+ will be checked manually. */
+
+ if (c[2] != -INFINITY)
+ return 1;
+
+ if (!__builtin_isnan (c[3]))
+ return 1;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.4s, v\[0-9\]+\.4s" 2 } } */
+
+#undef TEST3
+#undef EPSILON
+#undef VAR_MIN
+#undef VAR_MAX
+#undef INFINITY
+
+#define TEST3 TEST3_DBL
+#define EPSILON DBL_EPSILON
+#define VAR_MIN DBL_MIN
+#define VAR_MAX DBL_MAX
+#define INFINITY DBL_INFINITY
+
+int
+test_vnegq_f64 ()
+{
+ float64x2_t a;
+ float64x2_t b;
+ float64_t c[2];
+
+ float64_t test_set0[2] = { TEST0, TEST1 };
+ float64_t test_set1[2] = { TEST2, TEST3 };
+ float64_t test_set2[2] = { FLT_MAX, FLT_MIN };
+ float64_t test_set3[2] = { INFINITY, NAN };
+
+ RUN_TEST (test_set0, 128, 64, 2, a, b, c);
+ RUN_TEST (test_set1, 128, 64, 2, a, b, c);
+ RUN_TEST (test_set2, 128, 64, 2, a, b, c);
+ RUN_TEST (test_set3, 128, 64, 0, a, b, c);
+
+ /* Since last test cannot be checked in a uniform way by adding
+ negation result to original value, the number of lanes to be
+ checked in RUN_TEST is 0 (last argument). Instead, result
+ will be checked manually. */
+
+ if (c[0] != -INFINITY)
+ return 1;
+
+ if (!__builtin_isnan (c[1]))
+ return 1;
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "fneg\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d" 4 } } */
+
+int
+main (int argc, char **argv)
+{
+ if (test_vneg_f32 ())
+ abort ();
+
+ if (test_vneg_f64 ())
+ abort ();
+
+ if (test_vnegq_f32 ())
+ abort ();
+
+ if (test_vnegq_f64 ())
+ abort ();
+
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */