1/* { dg-do run } */
2/* { dg-require-effective-target sse4 } */
3/* { dg-options "-O2 -msse4.1" } */
4
5#ifndef CHECK_H
6#define CHECK_H "sse4_1-check.h"
7#endif
8
9#ifndef TEST
10#define TEST sse4_1_test
11#endif
12
13#include CHECK_H
14
15#include <smmintrin.h>
16
17#define lmskN  0x00
18#define lmsk0  0x01
19#define lmsk1  0x02
20#define lmsk01 0x03
21
22#define hmskA  0x30
23#define hmsk0  0x10
24#define hmsk1  0x20
25#define hmsk01 0x30
26#define hmskN  0x00
27
28#ifndef HIMASK
29#define HIMASK hmskA
30#endif
31
32static void
33TEST (void)
34{
35  union
36    {
37      __m128d x;
38      double d[2];
39    } val1, val2, res[4];
40  int masks[4];
41  int i, j;
42
43  val1.d[0] = 2.;
44  val1.d[1] = 3.;
45
46  val2.d[0] = 10.;
47  val2.d[1] = 100.;
48
49  res[0].x = _mm_dp_pd (val1.x, val2.x, HIMASK | lmskN);
50  res[1].x = _mm_dp_pd (val1.x, val2.x, HIMASK | lmsk0);
51  res[2].x = _mm_dp_pd (val1.x, val2.x, HIMASK | lmsk1);
52  res[3].x = _mm_dp_pd (val1.x, val2.x, HIMASK | lmsk01);
53
54  masks[0] = HIMASK | lmskN;
55  masks[1] = HIMASK | lmsk0;
56  masks[2] = HIMASK | lmsk1;
57  masks[3] = HIMASK | lmsk01;
58
59  for (i = 0; i < 4; i++)
60    {
61      double tmp = 0.;
62
63      for (j = 0; j < 2; j++)
64	if (HIMASK & (0x10 << j))
65	  tmp = tmp + (val1.d[j] * val2.d[j]);
66
67      for (j = 0; j < 2; j++)
68	if ((masks[i] & (1 << j)) && res[i].d[j] != tmp)
69	  abort ();
70   }
71}
72