]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AArch64] Implement vadd_f64 and vsub_f64 ADVSimd intrinsics.
authorAlex Velenko <Alex.Velenko@arm.com>
Wed, 9 Oct 2013 11:59:38 +0000 (11:59 +0000)
committerMarcus Shawcroft <mshawcroft@gcc.gnu.org>
Wed, 9 Oct 2013 11:59:38 +0000 (11:59 +0000)
From-SVN: r203313

gcc/ChangeLog
gcc/config/aarch64/arm_neon.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/vadd_f64.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/vsub_f64.c [new file with mode: 0644]

index cc3c3c1feafd08a3e7bcf058edf5776c53dceb20..4248751cdbfc5ec3e9b7c14fcb5c0e60fbbc1e7a 100644 (file)
@@ -1,3 +1,7 @@
+2013-10-09  Alex Velenko  <Alex.Velenko@arm.com>
+
+       * config/aarch64/arm_neon.h (vadd_f64, vsub_f64): Implementation added.
+
 2013-10-09  Alex Velenko  <Alex.Velenko@arm.com>
 
        * config/aarch64/arm_neon.h (vdiv_f64): Added.
index f296c2f202486b3dbbbbfafeb44f659471ff684d..db9bf28227e87072b48f5dca8835be8007c6b93d 100644 (file)
@@ -634,6 +634,12 @@ vadd_f32 (float32x2_t __a, float32x2_t __b)
   return __a + __b;
 }
 
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vadd_f64 (float64x1_t __a, float64x1_t __b)
+{
+  return __a + __b;
+}
+
 __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
 vadd_u8 (uint8x8_t __a, uint8x8_t __b)
 {
@@ -1830,6 +1836,12 @@ vsub_f32 (float32x2_t __a, float32x2_t __b)
   return __a - __b;
 }
 
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vsub_f64 (float64x1_t __a, float64x1_t __b)
+{
+  return __a - __b;
+}
+
 __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
 vsub_u8 (uint8x8_t __a, uint8x8_t __b)
 {
index 0fd94f6226ffa058a6026df806bd3d77c0057645..f15911bd280df0fc0d0089180a84516e6c245c95 100644 (file)
@@ -1,3 +1,8 @@
+2013-10-09  Alex Velenko  <Alex.Velenko@arm.com>
+
+       * gcc.target/aarch64/vadd_f64.c: New testcase.
+       * gcc.target/aarch64/vsub_f64.c: New testcase.
+
 2013-10-09  Alex Velenko  <Alex.Velenko@arm.com>
 
        * gcc.target/aarch64/vdiv_f.c: New testcase.
diff --git a/gcc/testsuite/gcc.target/aarch64/vadd_f64.c b/gcc/testsuite/gcc.target/aarch64/vadd_f64.c
new file mode 100644 (file)
index 0000000..c3bf734
--- /dev/null
@@ -0,0 +1,114 @@
+/* Test vadd works correctly.  */
+/* { dg-do run } */
+/* { dg-options "--save-temps" } */
+
+#include <arm_neon.h>
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+
+#define TESTA0 0.33333
+#define TESTA1 -1.7777
+#define TESTA2 0
+#define TESTA3 1.23456
+/* 2^54, double has 53 significand bits
+   according to Double-precision floating-point format.  */
+#define TESTA4 18014398509481984
+#define TESTA5 (1.0 / TESTA4)
+
+#define TESTB0 0.66667
+#define TESTB1 2
+#define TESTB2 0
+#define TESTB3 -2
+#define TESTB4 1.0
+#define TESTB5 2.0
+
+#define ANSW0 1
+#define ANSW1 0.2223
+#define ANSW2 0
+#define ANSW3 -0.76544
+#define ANSW4 TESTA4
+#define ANSW5 2.0
+
+extern void abort (void);
+
+#define EPSILON __DBL_EPSILON__
+#define ABS(a) __builtin_fabs (a)
+#define ISNAN(a) __builtin_isnan (a)
+#define FP_equals(a, b, epsilon)                       \
+  (                                                    \
+   ((a) == (b))                                                \
+    || (ISNAN (a) && ISNAN (b))                                \
+    || (ABS (a - b) < epsilon)                         \
+   )
+
+int
+test_vadd_f64 ()
+{
+  float64x1_t a;
+  float64x1_t b;
+  float64x1_t c;
+
+  a = TESTA0;
+  b = TESTB0;
+  c = ANSW0;
+
+  a = vadd_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA1;
+  b = TESTB1;
+  c = ANSW1;
+
+  a = vadd_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA2;
+  b = TESTB2;
+  c = ANSW2;
+
+  a = vadd_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA3;
+  b = TESTB3;
+  c = ANSW3;
+
+  a = vadd_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA4;
+  b = TESTB4;
+  c = ANSW4;
+
+  a = vadd_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA5;
+  b = TESTB5;
+  c = ANSW5;
+
+  a = vadd_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "fadd\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 6 } } */
+
+int
+main (int argc, char **argv)
+{
+  if (test_vadd_f64 ())
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vsub_f64.c b/gcc/testsuite/gcc.target/aarch64/vsub_f64.c
new file mode 100644 (file)
index 0000000..abf4fc4
--- /dev/null
@@ -0,0 +1,116 @@
+/* Test vsub works correctly.  */
+/* { dg-do run } */
+/* { dg-options "--save-temps" } */
+
+#include <arm_neon.h>
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+
+#define TESTA0 1
+#define TESTA1 0.2223
+#define TESTA2 0
+#define TESTA3 -0.76544
+/* 2^54, double has 53 significand bits
+   according to Double-precision floating-point format.  */
+#define TESTA4 18014398509481984
+#define TESTA5 2.0
+
+#define TESTB0 0.66667
+#define TESTB1 2
+#define TESTB2 0
+#define TESTB3 -2
+#define TESTB4 1.0
+#define TESTB5 (1.0 / TESTA4)
+
+#define ANSW0 0.33333
+#define ANSW1 -1.7777
+#define ANSW2 0
+#define ANSW3 1.23456
+#define ANSW4 TESTA4
+#define ANSW5 2.0
+
+extern void abort (void);
+
+#define EPSILON __DBL_EPSILON__
+#define ISNAN(a) __builtin_isnan (a)
+/* FP_equals is implemented like this to execute subtraction
+   exectly once during a single test run.  */
+#define FP_equals(a, b, epsilon)               \
+(                                              \
+ ((a) == (b))                                  \
+ || (ISNAN (a) && ISNAN (b))                   \
+ || (((a > b) && (a < (b + epsilon)))          \
+     || ((b > a) && (b < (a + epsilon))))      \
+)
+
+int
+test_vsub_f64 ()
+{
+  float64x1_t a;
+  float64x1_t b;
+  float64x1_t c;
+
+  a = TESTA0;
+  b = TESTB0;
+  c = ANSW0;
+
+  a = vsub_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA1;
+  b = TESTB1;
+  c = ANSW1;
+
+  a = vsub_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA2;
+  b = TESTB2;
+  c = ANSW2;
+
+  a = vsub_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA3;
+  b = TESTB3;
+  c = ANSW3;
+
+  a = vsub_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA4;
+  b = TESTB4;
+  c = ANSW4;
+
+  a = vsub_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  a = TESTA5;
+  b = TESTB5;
+  c = ANSW5;
+
+  a = vsub_f64 (a, b);
+  if (!FP_equals (a, c, EPSILON))
+    return 1;
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-times "fsub\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 6 } } */
+
+int
+main (int argc, char **argv)
+{
+  if (test_vsub_f64 ())
+    abort ();
+
+  return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */