From 6cb877be49d68f2d626681f033e9dc7af3628f96 Mon Sep 17 00:00:00 2001 From: "Paul A. Clarke" Date: Tue, 9 Oct 2018 20:31:52 +0000 Subject: [PATCH] This is part 2/2 for contributing PPC64LE support for X86 SSE3 instrisics. This is part 2/2 for contributing PPC64LE support for X86 SSE3 instrisics. This patch includes testsuite/gcc.target tests for the intrinsics defined in pmmintrin.h. Tested on POWER8 ppc64le and ppc64 (-m64 and -m32, the latter only reporting 10 new unsupported tests.) [gcc/testsuite] 2018-10-09 Paul A. Clarke * gcc.target/powerpc/sse3-check.h: New file. * gcc.target/powerpc/sse3-addsubps.c: New file. * gcc.target/powerpc/sse3-addsubpd.c: New file. * gcc.target/powerpc/sse3-haddps.c: New file. * gcc.target/powerpc/sse3-hsubps.c: New file. * gcc.target/powerpc/sse3-haddpd.c: New file. * gcc.target/powerpc/sse3-hsubpd.c: New file. * gcc.target/powerpc/sse3-lddqu.c: New file. * gcc.target/powerpc/sse3-movsldup.c: New file. * gcc.target/powerpc/sse3-movshdup.c: New file. * gcc.target/powerpc/sse3-movddup.c: New file. * gcc.target/powerpc/pr37191.c: New file. From-SVN: r264992 --- gcc/testsuite/ChangeLog | 15 + gcc/testsuite/gcc.target/powerpc/pr37191.c | 102 +++++++ .../gcc.target/powerpc/sse3-addsubpd.c | 203 +++++++++++++ .../gcc.target/powerpc/sse3-addsubps.c | 215 ++++++++++++++ gcc/testsuite/gcc.target/powerpc/sse3-check.h | 86 ++++++ .../gcc.target/powerpc/sse3-haddpd.c | 200 +++++++++++++ .../gcc.target/powerpc/sse3-haddps.c | 215 ++++++++++++++ .../gcc.target/powerpc/sse3-hsubpd.c | 202 +++++++++++++ .../gcc.target/powerpc/sse3-hsubps.c | 215 ++++++++++++++ gcc/testsuite/gcc.target/powerpc/sse3-lddqu.c | 159 +++++++++++ .../gcc.target/powerpc/sse3-movddup.c | 269 ++++++++++++++++++ .../gcc.target/powerpc/sse3-movshdup.c | 195 +++++++++++++ .../gcc.target/powerpc/sse3-movsldup.c | 195 +++++++++++++ 13 files changed, 2271 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr37191.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-addsubpd.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-check.h create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-haddpd.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-haddps.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-hsubpd.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-hsubps.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-lddqu.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-movddup.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-movshdup.c create mode 100644 gcc/testsuite/gcc.target/powerpc/sse3-movsldup.c diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3389faa17e5..1256e0faaa3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,18 @@ +2018-10-09 Paul A. Clarke + + * gcc.target/powerpc/sse3-check.h: New file. + * gcc.target/powerpc/sse3-addsubps.c: New file. + * gcc.target/powerpc/sse3-addsubpd.c: New file. + * gcc.target/powerpc/sse3-haddps.c: New file. + * gcc.target/powerpc/sse3-hsubps.c: New file. + * gcc.target/powerpc/sse3-haddpd.c: New file. + * gcc.target/powerpc/sse3-hsubpd.c: New file. + * gcc.target/powerpc/sse3-lddqu.c: New file. + * gcc.target/powerpc/sse3-movsldup.c: New file. + * gcc.target/powerpc/sse3-movshdup.c: New file. + * gcc.target/powerpc/sse3-movddup.c: New file. + * gcc.target/powerpc/pr37191.c: New file. + 2018-10-09 Tobias Burnus PR fortran/83522 diff --git a/gcc/testsuite/gcc.target/powerpc/pr37191.c b/gcc/testsuite/gcc.target/powerpc/pr37191.c new file mode 100644 index 00000000000..72c26fe359d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr37191.c @@ -0,0 +1,102 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O3 -mpower8-vector" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#define NO_WARN_X86_INTRINSICS 1 + +#include +#include +#include + +#if 0 +extern const uint64_t ff_bone; +#endif + +static inline void transpose4x4(uint8_t *dst, uint8_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride) { + __m64 row0 = _mm_cvtsi32_si64(*(unsigned*)(src + (0 * src_stride))); + __m64 row1 = _mm_cvtsi32_si64(*(unsigned*)(src + (1 * src_stride))); + __m64 row2 = _mm_cvtsi32_si64(*(unsigned*)(src + (2 * src_stride))); + __m64 row3 = _mm_cvtsi32_si64(*(unsigned*)(src + (3 * src_stride))); + __m64 tmp0 = _mm_unpacklo_pi8(row0, row1); + __m64 tmp1 = _mm_unpacklo_pi8(row2, row3); + __m64 row01 = _mm_unpacklo_pi16(tmp0, tmp1); + __m64 row23 = _mm_unpackhi_pi16(tmp0, tmp1); + *((unsigned*)(dst + (0 * dst_stride))) = _mm_cvtsi64_si32(row01); + *((unsigned*)(dst + (1 * dst_stride))) = _mm_cvtsi64_si32(_mm_unpackhi_pi32(row01, row01)); + *((unsigned*)(dst + (2 * dst_stride))) = _mm_cvtsi64_si32(row23); + *((unsigned*)(dst + (3 * dst_stride))) = _mm_cvtsi64_si32(_mm_unpackhi_pi32(row23, row23)); +} + +#if 0 +static inline void h264_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha1, int beta1) +{ + asm volatile( + "" + :: "r"(pix-2*stride), "r"(pix), "r"((long)stride), + "m"(alpha1), "m"(beta1), "m"(ff_bone) + ); +} +#endif + +void h264_h_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha, int beta) +{ + uint8_t trans[8*4] __attribute__ ((aligned (8))); + transpose4x4(trans, pix-2, 8, stride); + transpose4x4(trans+4, pix-2+4*stride, 8, stride); +// h264_loop_filter_chroma_intra_mmx2(trans+2*8, 8, alpha-1, beta-1); + transpose4x4(pix-2, trans, stride, 8); + transpose4x4(pix-2+4*stride, trans+4, stride, 8); +} +/* { dg-do compile } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O3 -mpower8-vector" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#define NO_WARN_X86_INTRINSICS 1 + +#include +#include +#include + +#if 0 +extern const uint64_t ff_bone; +#endif + +static inline void transpose4x4(uint8_t *dst, uint8_t *src, ptrdiff_t dst_stride, ptrdiff_t src_stride) { + __m64 row0 = _mm_cvtsi32_si64(*(unsigned*)(src + (0 * src_stride))); + __m64 row1 = _mm_cvtsi32_si64(*(unsigned*)(src + (1 * src_stride))); + __m64 row2 = _mm_cvtsi32_si64(*(unsigned*)(src + (2 * src_stride))); + __m64 row3 = _mm_cvtsi32_si64(*(unsigned*)(src + (3 * src_stride))); + __m64 tmp0 = _mm_unpacklo_pi8(row0, row1); + __m64 tmp1 = _mm_unpacklo_pi8(row2, row3); + __m64 row01 = _mm_unpacklo_pi16(tmp0, tmp1); + __m64 row23 = _mm_unpackhi_pi16(tmp0, tmp1); + *((unsigned*)(dst + (0 * dst_stride))) = _mm_cvtsi64_si32(row01); + *((unsigned*)(dst + (1 * dst_stride))) = _mm_cvtsi64_si32(_mm_unpackhi_pi32(row01, row01)); + *((unsigned*)(dst + (2 * dst_stride))) = _mm_cvtsi64_si32(row23); + *((unsigned*)(dst + (3 * dst_stride))) = _mm_cvtsi64_si32(_mm_unpackhi_pi32(row23, row23)); +} + +#if 0 +static inline void h264_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha1, int beta1) +{ + asm volatile( + "" + :: "r"(pix-2*stride), "r"(pix), "r"((long)stride), + "m"(alpha1), "m"(beta1), "m"(ff_bone) + ); +} +#endif + +void h264_h_loop_filter_chroma_intra_mmx2(uint8_t *pix, int stride, int alpha, int beta) +{ + uint8_t trans[8*4] __attribute__ ((aligned (8))); + transpose4x4(trans, pix-2, 8, stride); + transpose4x4(trans+4, pix-2+4*stride, 8, stride); +// h264_loop_filter_chroma_intra_mmx2(trans+2*8, 8, alpha-1, beta-1); + transpose4x4(pix-2, trans, stride, 8); + transpose4x4(pix-2+4*stride, trans+4, stride, 8); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-addsubpd.c b/gcc/testsuite/gcc.target/powerpc/sse3-addsubpd.c new file mode 100644 index 00000000000..1308d6ad2a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-addsubpd.c @@ -0,0 +1,203 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_addsubpd_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_addsubpd (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (i2); + + t1 = _mm_addsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static void +sse3_test_addsubpd_subsume (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_load_pd (i2); + + t1 = _mm_addsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2] __attribute__ ((aligned(16))); +static double p3[2]; +static double ck[2]; + +double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static +void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 4) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + + p2[0] = vals[i+2]; + p2[1] = vals[i+3]; + + ck[0] = p1[0] - p2[0]; + ck[1] = p1[1] + p2[1]; + + sse3_test_addsubpd (p1, p2, p3); + + fail += chk_pd (ck, p3); + + sse3_test_addsubpd_subsume (p1, p2, p3); + + fail += chk_pd (ck, p3); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_addsubpd_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_addsubpd (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (i2); + + t1 = _mm_addsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static void +sse3_test_addsubpd_subsume (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_load_pd (i2); + + t1 = _mm_addsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2] __attribute__ ((aligned(16))); +static double p3[2]; +static double ck[2]; + +double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 4) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + + p2[0] = vals[i+2]; + p2[1] = vals[i+3]; + + ck[0] = p1[0] - p2[0]; + ck[1] = p1[1] + p2[1]; + + sse3_test_addsubpd (p1, p2, p3); + + fail += chk_pd (ck, p3); + + sse3_test_addsubpd_subsume (p1, p2, p3); + + fail += chk_pd (ck, p3); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c b/gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c new file mode 100644 index 00000000000..546728a6d51 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-addsubps.c @@ -0,0 +1,215 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#define NO_WARN_X86_INTRINSICS 1 +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_addsubps_1 +#endif + +#include + +static void +sse3_test_addsubps (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_loadu_ps (i2); + + t1 = _mm_addsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static void +sse3_test_addsubps_subsume (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_load_ps (i2); + + t1 = _mm_addsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static int +chk_ps (float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4] __attribute__ ((aligned(16))); +static float p3[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals); i += 8) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + p1[2] = vals[i+2]; + p1[3] = vals[i+3]; + + p2[0] = vals[i+4]; + p2[1] = vals[i+5]; + p2[2] = vals[i+6]; + p2[3] = vals[i+7]; + + ck[0] = p1[0] - p2[0]; + ck[1] = p1[1] + p2[1]; + ck[2] = p1[2] - p2[2]; + ck[3] = p1[3] + p2[3]; + + sse3_test_addsubps (p1, p2, p3); + + fail += chk_ps (ck, p3); + + sse3_test_addsubps_subsume (p1, p2, p3); + + fail += chk_ps (ck, p3); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#define NO_WARN_X86_INTRINSICS 1 +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_addsubps_1 +#endif + +#include + +static void +sse3_test_addsubps (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_loadu_ps (i2); + + t1 = _mm_addsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static void +sse3_test_addsubps_subsume (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_load_ps (i2); + + t1 = _mm_addsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static int +chk_ps (float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4] __attribute__ ((aligned(16))); +static float p3[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals); i += 8) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + p1[2] = vals[i+2]; + p1[3] = vals[i+3]; + + p2[0] = vals[i+4]; + p2[1] = vals[i+5]; + p2[2] = vals[i+6]; + p2[3] = vals[i+7]; + + ck[0] = p1[0] - p2[0]; + ck[1] = p1[1] + p2[1]; + ck[2] = p1[2] - p2[2]; + ck[3] = p1[3] + p2[3]; + + sse3_test_addsubps (p1, p2, p3); + + fail += chk_ps (ck, p3); + + sse3_test_addsubps_subsume (p1, p2, p3); + + fail += chk_ps (ck, p3); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-check.h b/gcc/testsuite/gcc.target/powerpc/sse3-check.h new file mode 100644 index 00000000000..80c90d706e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-check.h @@ -0,0 +1,86 @@ +#include +#include + +#include "m128-check.h" + +/* define DEBUG replace abort with printf on error. */ +//#define DEBUG 1 + +#define TEST sse3_test + +static void sse3_test (void); + +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse3_test (); +} + +int +main () +{ +#ifdef __BUILTIN_CPU_SUPPORTS__ + /* Most SSE intrinsic operations can be implemented via VMX + instructions, but some operations may be faster / simpler + using the POWER8 VSX instructions. This is especially true + when we are transferring / converting to / from __m64 types. + The direct register transfer instructions from POWER8 are + especially important. So we test for arch_2_07. */ + if (__builtin_cpu_supports ("arch_2_07")) + { + do_test (); +#ifdef DEBUG + printf ("PASSED\n"); +#endif + } +#ifdef DEBUG + else + printf ("SKIPPED\n"); +#endif +#endif /* __BUILTIN_CPU_SUPPORTS__ */ + return 0; +} +#include +#include + +#include "m128-check.h" + +/* define DEBUG replace abort with printf on error. */ +//#define DEBUG 1 + +#define TEST sse3_test + +static void sse3_test (void); + +static void +__attribute__ ((noinline)) +do_test (void) +{ + sse3_test (); +} + +int +main () +{ +#ifdef __BUILTIN_CPU_SUPPORTS__ + /* Most SSE intrinsic operations can be implemented via VMX + instructions, but some operations may be faster / simpler + using the POWER8 VSX instructions. This is especially true + when we are transferring / converting to / from __m64 types. + The direct register transfer instructions from POWER8 are + especially important. So we test for arch_2_07. */ + if (__builtin_cpu_supports ("arch_2_07")) + { + do_test (); +#ifdef DEBUG + printf ("PASSED\n"); +#endif + } +#ifdef DEBUG + else + printf ("SKIPPED\n"); +#endif +#endif /* __BUILTIN_CPU_SUPPORTS__ */ + return 0; +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-haddpd.c b/gcc/testsuite/gcc.target/powerpc/sse3-haddpd.c new file mode 100644 index 00000000000..4a1e25f11e4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-haddpd.c @@ -0,0 +1,200 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#define NO_WARN_X86_INTRINSICS 1 +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_haddpd_1 +#endif +#include + +static void +sse3_test_haddpd (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (i2); + + t1 = _mm_hadd_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static void +sse3_test_haddpd_subsume (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_load_pd (i2); + + t1 = _mm_hadd_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2] __attribute__ ((aligned(16))); +static double p3[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 4) + { + p1[0] = vals[i + 0]; + p1[1] = vals[i + 1]; + + p2[0] = vals[i + 2]; + p2[1] = vals[i + 3]; + + ck[0] = p1[0] + p1[1]; + ck[1] = p2[0] + p2[1]; + + sse3_test_haddpd (p1, p2, p3); + + fail += chk_pd (ck, p3); + + sse3_test_haddpd_subsume (p1, p2, p3); + + fail += chk_pd (ck, p3); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#define NO_WARN_X86_INTRINSICS 1 +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_haddpd_1 +#endif +#include + +static void +sse3_test_haddpd (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (i2); + + t1 = _mm_hadd_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static void +sse3_test_haddpd_subsume (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_load_pd (i2); + + t1 = _mm_hadd_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2] __attribute__ ((aligned(16))); +static double p3[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 4) + { + p1[0] = vals[i + 0]; + p1[1] = vals[i + 1]; + + p2[0] = vals[i + 2]; + p2[1] = vals[i + 3]; + + ck[0] = p1[0] + p1[1]; + ck[1] = p2[0] + p2[1]; + + sse3_test_haddpd (p1, p2, p3); + + fail += chk_pd (ck, p3); + + sse3_test_haddpd_subsume (p1, p2, p3); + + fail += chk_pd (ck, p3); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-haddps.c b/gcc/testsuite/gcc.target/powerpc/sse3-haddps.c new file mode 100644 index 00000000000..b4bfaf1db2f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-haddps.c @@ -0,0 +1,215 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_haddps_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_haddps (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_loadu_ps (i2); + + t1 = _mm_hadd_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static void +sse3_test_haddps_subsume (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_load_ps (i2); + + t1 = _mm_hadd_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static int +chk_ps(float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4] __attribute__ ((aligned(16))); +static float p3[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST () +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 8) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + p1[2] = vals[i+2]; + p1[3] = vals[i+3]; + + p2[0] = vals[i+4]; + p2[1] = vals[i+5]; + p2[2] = vals[i+6]; + p2[3] = vals[i+7]; + + ck[0] = p1[0] + p1[1]; + ck[1] = p1[2] + p1[3]; + ck[2] = p2[0] + p2[1]; + ck[3] = p2[2] + p2[3]; + + sse3_test_haddps (p1, p2, p3); + + fail += chk_ps (ck, p3); + + sse3_test_haddps_subsume (p1, p2, p3); + + fail += chk_ps (ck, p3); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_haddps_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_haddps (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_loadu_ps (i2); + + t1 = _mm_hadd_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static void +sse3_test_haddps_subsume (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_load_ps (i2); + + t1 = _mm_hadd_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static int +chk_ps(float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4] __attribute__ ((aligned(16))); +static float p3[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST () +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 8) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + p1[2] = vals[i+2]; + p1[3] = vals[i+3]; + + p2[0] = vals[i+4]; + p2[1] = vals[i+5]; + p2[2] = vals[i+6]; + p2[3] = vals[i+7]; + + ck[0] = p1[0] + p1[1]; + ck[1] = p1[2] + p1[3]; + ck[2] = p2[0] + p2[1]; + ck[3] = p2[2] + p2[3]; + + sse3_test_haddps (p1, p2, p3); + + fail += chk_ps (ck, p3); + + sse3_test_haddps_subsume (p1, p2, p3); + + fail += chk_ps (ck, p3); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-hsubpd.c b/gcc/testsuite/gcc.target/powerpc/sse3-hsubpd.c new file mode 100644 index 00000000000..6c71fc79c0b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-hsubpd.c @@ -0,0 +1,202 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_hsubpd_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_hsubpd (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (i2); + + t1 = _mm_hsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static void +sse3_test_hsubpd_subsume (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_load_pd (i2); + + t1 = _mm_hsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2] __attribute__ ((aligned(16))); +static double p3[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 4) + { + p1[0] = vals[i + 0]; + p1[1] = vals[i + 1]; + + p2[0] = vals[i + 2]; + p2[1] = vals[i + 3]; + + ck[0] = p1[0] - p1[1]; + ck[1] = p2[0] - p2[1]; + + sse3_test_hsubpd (p1, p2, p3); + + fail += chk_pd (ck, p3); + + sse3_test_hsubpd_subsume (p1, p2, p3); + + fail += chk_pd (ck, p3); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_hsubpd_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_hsubpd (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (i2); + + t1 = _mm_hsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static void +sse3_test_hsubpd_subsume (double *i1, double *i2, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_load_pd (i2); + + t1 = _mm_hsub_pd (t1, t2); + + _mm_storeu_pd (r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2] __attribute__ ((aligned(16))); +static double p3[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 4) + { + p1[0] = vals[i + 0]; + p1[1] = vals[i + 1]; + + p2[0] = vals[i + 2]; + p2[1] = vals[i + 3]; + + ck[0] = p1[0] - p1[1]; + ck[1] = p2[0] - p2[1]; + + sse3_test_hsubpd (p1, p2, p3); + + fail += chk_pd (ck, p3); + + sse3_test_hsubpd_subsume (p1, p2, p3); + + fail += chk_pd (ck, p3); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-hsubps.c b/gcc/testsuite/gcc.target/powerpc/sse3-hsubps.c new file mode 100644 index 00000000000..39d9665f187 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-hsubps.c @@ -0,0 +1,215 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_hsubps_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_hsubps (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_loadu_ps (i2); + + t1 = _mm_hsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static void +sse3_test_hsubps_subsume (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_load_ps (i2); + + t1 = _mm_hsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static int +chk_ps(float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4] __attribute__ ((aligned(16))); +static float p3[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST () +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 8) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + p1[2] = vals[i+2]; + p1[3] = vals[i+3]; + + p2[0] = vals[i+4]; + p2[1] = vals[i+5]; + p2[2] = vals[i+6]; + p2[3] = vals[i+7]; + + ck[0] = p1[0] - p1[1]; + ck[1] = p1[2] - p1[3]; + ck[2] = p2[0] - p2[1]; + ck[3] = p2[2] - p2[3]; + + sse3_test_hsubps (p1, p2, p3); + + fail += chk_ps (ck, p3); + + sse3_test_hsubps_subsume (p1, p2, p3); + + fail += chk_ps (ck, p3); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_hsubps_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_hsubps (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_loadu_ps (i2); + + t1 = _mm_hsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static void +sse3_test_hsubps_subsume (float *i1, float *i2, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_load_ps (i2); + + t1 = _mm_hsub_ps (t1, t2); + + _mm_storeu_ps (r, t1); +} + +static int +chk_ps(float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4] __attribute__ ((aligned(16))); +static float p3[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST () +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 8) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + p1[2] = vals[i+2]; + p1[3] = vals[i+3]; + + p2[0] = vals[i+4]; + p2[1] = vals[i+5]; + p2[2] = vals[i+6]; + p2[3] = vals[i+7]; + + ck[0] = p1[0] - p1[1]; + ck[1] = p1[2] - p1[3]; + ck[2] = p2[0] - p2[1]; + ck[3] = p2[2] - p2[3]; + + sse3_test_hsubps (p1, p2, p3); + + fail += chk_ps (ck, p3); + + sse3_test_hsubps_subsume (p1, p2, p3); + + fail += chk_ps (ck, p3); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-lddqu.c b/gcc/testsuite/gcc.target/powerpc/sse3-lddqu.c new file mode 100644 index 00000000000..dd32f6494a0 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-lddqu.c @@ -0,0 +1,159 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_lddqu_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_lddqu (double *i1, double *r) +{ + __m128i t1 = _mm_lddqu_si128 ((__m128i *) i1); + + _mm_storeu_si128 ((__m128i *) r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2]; +static double p2[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 2) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + + sse3_test_lddqu (p1, p2); + + ck[0] = p1[0]; + ck[1] = p1[1]; + + fail += chk_pd (ck, p2); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_lddqu_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_lddqu (double *i1, double *r) +{ + __m128i t1 = _mm_lddqu_si128 ((__m128i *) i1); + + _mm_storeu_si128 ((__m128i *) r, t1); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2]; +static double p2[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 2) + { + p1[0] = vals[i+0]; + p1[1] = vals[i+1]; + + sse3_test_lddqu (p1, p2); + + ck[0] = p1[0]; + ck[1] = p1[1]; + + fail += chk_pd (ck, p2); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-movddup.c b/gcc/testsuite/gcc.target/powerpc/sse3-movddup.c new file mode 100644 index 00000000000..f463f64220b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-movddup.c @@ -0,0 +1,269 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_movddup_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_movddup_mem (double *i1, double *r) +{ + __m128d t1 = _mm_loaddup_pd (i1); + + _mm_storeu_pd (r, t1); +} + +static double cnst1 [2] = {1.0, 1.0}; + +static void +sse3_test_movddup_reg (double *i1, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (&cnst1[0]); + + t1 = _mm_mul_pd (t1, t2); + t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static void +sse3_test_movddup_reg_subsume_unaligned (double *i1, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static void +sse3_test_movddup_reg_subsume_ldsd (double *i1, double *r) +{ + __m128d t1 = _mm_load_sd (i1); + __m128d t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static void +sse3_test_movddup_reg_subsume (double *i1, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 1) + { + p1[0] = vals[i+0]; + + ck[0] = p1[0]; + ck[1] = p1[0]; + + sse3_test_movddup_mem (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg_subsume (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg_subsume_unaligned (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg_subsume_ldsd (p1, p2); + + fail += chk_pd (ck, p2); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_movddup_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_movddup_mem (double *i1, double *r) +{ + __m128d t1 = _mm_loaddup_pd (i1); + + _mm_storeu_pd (r, t1); +} + +static double cnst1 [2] = {1.0, 1.0}; + +static void +sse3_test_movddup_reg (double *i1, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_loadu_pd (&cnst1[0]); + + t1 = _mm_mul_pd (t1, t2); + t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static void +sse3_test_movddup_reg_subsume_unaligned (double *i1, double *r) +{ + __m128d t1 = _mm_loadu_pd (i1); + __m128d t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static void +sse3_test_movddup_reg_subsume_ldsd (double *i1, double *r) +{ + __m128d t1 = _mm_load_sd (i1); + __m128d t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static void +sse3_test_movddup_reg_subsume (double *i1, double *r) +{ + __m128d t1 = _mm_load_pd (i1); + __m128d t2 = _mm_movedup_pd (t1); + + _mm_storeu_pd (r, t2); +} + +static int +chk_pd (double *v1, double *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 2; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static double p1[2] __attribute__ ((aligned(16))); +static double p2[2]; +static double ck[2]; + +static double vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 1) + { + p1[0] = vals[i+0]; + + ck[0] = p1[0]; + ck[1] = p1[0]; + + sse3_test_movddup_mem (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg_subsume (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg_subsume_unaligned (p1, p2); + + fail += chk_pd (ck, p2); + + sse3_test_movddup_reg_subsume_ldsd (p1, p2); + + fail += chk_pd (ck, p2); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-movshdup.c b/gcc/testsuite/gcc.target/powerpc/sse3-movshdup.c new file mode 100644 index 00000000000..a49f89a69b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-movshdup.c @@ -0,0 +1,195 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_movshdup_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_movshdup_reg (float *i1, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_movehdup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static void +sse3_test_movshdup_reg_subsume (float *i1, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_movehdup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static int +chk_ps (float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 2) + { + p1[0] = 0.0; + p1[1] = vals[i+0]; + p1[2] = 1.0; + p1[3] = vals[i+1]; + + ck[0] = p1[1]; + ck[1] = p1[1]; + ck[2] = p1[3]; + ck[3] = p1[3]; + + sse3_test_movshdup_reg (p1, p2); + + fail += chk_ps (ck, p2); + + sse3_test_movshdup_reg_subsume (p1, p2); + + fail += chk_ps (ck, p2); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_movshdup_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_movshdup_reg (float *i1, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_movehdup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static void +sse3_test_movshdup_reg_subsume (float *i1, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_movehdup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static int +chk_ps (float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 2) + { + p1[0] = 0.0; + p1[1] = vals[i+0]; + p1[2] = 1.0; + p1[3] = vals[i+1]; + + ck[0] = p1[1]; + ck[1] = p1[1]; + ck[2] = p1[3]; + ck[3] = p1[3]; + + sse3_test_movshdup_reg (p1, p2); + + fail += chk_ps (ck, p2); + + sse3_test_movshdup_reg_subsume (p1, p2); + + fail += chk_ps (ck, p2); + } + + if (fail != 0) + abort (); +} diff --git a/gcc/testsuite/gcc.target/powerpc/sse3-movsldup.c b/gcc/testsuite/gcc.target/powerpc/sse3-movsldup.c new file mode 100644 index 00000000000..2933be20e45 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/sse3-movsldup.c @@ -0,0 +1,195 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_movsldup_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_movsldup_reg (float *i1, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_moveldup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static void +sse3_test_movsldup_reg_subsume (float *i1, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_moveldup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static int +chk_ps (float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +//static +void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 2) + { + p1[0] = vals[i+0]; + p1[1] = 0.0; + p1[2] = vals[i+1]; + p1[3] = 1.0; + + ck[0] = p1[0]; + ck[1] = p1[0]; + ck[2] = p1[2]; + ck[3] = p1[2]; + + sse3_test_movsldup_reg (p1, p2); + + fail += chk_ps (ck, p2); + + sse3_test_movsldup_reg_subsume (p1, p2); + + fail += chk_ps (ck, p2); + } + + if (fail != 0) + abort (); +} +/* { dg-do run } */ +/* { dg-options "-O3 -mpower8-vector -Wno-psabi" } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p8vector_hw } */ + +#ifndef CHECK_H +#define CHECK_H "sse3-check.h" +#endif + +#include CHECK_H + +#ifndef TEST +#define TEST sse3_test_movsldup_1 +#endif + +#define NO_WARN_X86_INTRINSICS 1 +#include + +static void +sse3_test_movsldup_reg (float *i1, float *r) +{ + __m128 t1 = _mm_loadu_ps (i1); + __m128 t2 = _mm_moveldup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static void +sse3_test_movsldup_reg_subsume (float *i1, float *r) +{ + __m128 t1 = _mm_load_ps (i1); + __m128 t2 = _mm_moveldup_ps (t1); + + _mm_storeu_ps (r, t2); +} + +static int +chk_ps (float *v1, float *v2) +{ + int i; + int n_fails = 0; + + for (i = 0; i < 4; i++) + if (v1[i] != v2[i]) + n_fails += 1; + + return n_fails; +} + +static float p1[4] __attribute__ ((aligned(16))); +static float p2[4]; +static float ck[4]; + +static float vals[] = + { + 100.0, 200.0, 300.0, 400.0, 5.0, -1.0, .345, -21.5, + 1100.0, 0.235, 321.3, 53.40, 0.3, 10.0, 42.0, 32.52, + 32.6, 123.3, 1.234, 2.156, 0.1, 3.25, 4.75, 32.44, + 12.16, 52.34, 64.12, 71.13, -.1, 2.30, 5.12, 3.785, + 541.3, 321.4, 231.4, 531.4, 71., 321., 231., -531., + 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, 23.45, + 23.45, -1.43, -6.74, 6.345, -20.1, -20.1, -40.1, -40.1, + 1.234, 2.345, 3.456, 4.567, 5.678, 6.789, 7.891, 8.912, + -9.32, -8.41, -7.50, -6.59, -5.68, -4.77, -3.86, -2.95, + 9.32, 8.41, 7.50, 6.59, -5.68, -4.77, -3.86, -2.95 + }; + +static void +TEST (void) +{ + int i; + int fail = 0; + + for (i = 0; i < sizeof (vals) / sizeof (vals[0]); i += 2) + { + p1[0] = vals[i+0]; + p1[1] = 0.0; + p1[2] = vals[i+1]; + p1[3] = 1.0; + + ck[0] = p1[0]; + ck[1] = p1[0]; + ck[2] = p1[2]; + ck[3] = p1[2]; + + sse3_test_movsldup_reg (p1, p2); + + fail += chk_ps (ck, p2); + + sse3_test_movsldup_reg_subsume (p1, p2); + + fail += chk_ps (ck, p2); + } + + if (fail != 0) + abort (); +} -- 2.30.2