diff options
author | Alex Velenko <Alex.Velenko@arm.com> | 2013-10-09 11:59:38 +0000 |
---|---|---|
committer | Marcus Shawcroft <mshawcroft@gcc.gnu.org> | 2013-10-09 11:59:38 +0000 |
commit | bed9bae4f00a0a385e68fd81405320d1f3ad0a92 (patch) | |
tree | 38f41419f8689bfc3c4a1a277dbef1ef638a381b /gcc | |
parent | 7f3d8b194850ce14d96d9d1a68fdb41e1a19ef70 (diff) | |
download | gcc-bed9bae4f00a0a385e68fd81405320d1f3ad0a92.zip gcc-bed9bae4f00a0a385e68fd81405320d1f3ad0a92.tar.gz gcc-bed9bae4f00a0a385e68fd81405320d1f3ad0a92.tar.bz2 |
[AArch64] Implement vadd_f64 and vsub_f64 ADVSimd intrinsics.
From-SVN: r203313
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/config/aarch64/arm_neon.h | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vadd_f64.c | 114 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/vsub_f64.c | 116 |
5 files changed, 251 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc3c3c1..4248751 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 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. 2013-10-09 Alex Velenko <Alex.Velenko@arm.com> diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h index f296c2f..db9bf28 100644 --- a/gcc/config/aarch64/arm_neon.h +++ b/gcc/config/aarch64/arm_neon.h @@ -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) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0fd94f6..f15911b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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. 2013-10-09 Alex Velenko <Alex.Velenko@arm.com> diff --git a/gcc/testsuite/gcc.target/aarch64/vadd_f64.c b/gcc/testsuite/gcc.target/aarch64/vadd_f64.c new file mode 100644 index 0000000..c3bf734 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vadd_f64.c @@ -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 index 0000000..abf4fc4 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/vsub_f64.c @@ -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 } } */ |