1/* { dg-do run } */
2/* { dg-options "-O2 -mavx512f -std=c99" } */
3/* { dg-require-effective-target avx512f } */
4/* { dg-require-effective-target c99_runtime } */
5
6#define AVX512F
7
8#include "avx512f-helper.h"
9
10#define SIZE (AVX512F_LEN / 64)
11#include "avx512f-mask-type.h"
12#include <math.h>
13
14#ifndef GET_NORM_MANT
15#define GET_NORM_MANT
16
17union fp_int_t
18{
19  long long int int_val;
20  double fp_val;
21};
22
23double
24get_norm_mant (double source, int signctrl, int interv)
25{
26  long long src, sign, exp, fraction;
27  union fp_int_t bin_conv;
28
29  bin_conv.fp_val = source;
30  src = bin_conv.int_val;
31  sign = (signctrl & 0x1) ? 0 : (src >> 63);
32  exp = (src & 0x7ff0000000000000) >> 52;
33  fraction = (src & 0xfffffffffffff);
34
35  if (isnan (source))
36    return signbit (source) ? -NAN : NAN;
37  if (source == 0.0 || source == -0.0 || isinf (source))
38    return sign ? -1.0 : 1.0;
39  if (signbit (source) && (signctrl & 0x2))
40    return -NAN;
41  if (!isnormal (source))
42    {
43      src = (src & 0xfff7ffffffffffff);
44      exp = 0x3ff;
45      while (!(src & 0x8000000000000))
46	{
47	  src += fraction & 0x8000000000000;
48	  fraction = fraction << 1;
49	  exp--;
50	}
51    }
52
53  switch (interv)
54    {
55    case 0:
56      exp = 0x3ff;
57      break;
58    case 1:
59      exp = ((exp - 0x3ff) & 0x1) ? 0x3fe : 0x3ff;
60      break;
61    case 2:
62      exp = 0x3fe;
63      break;
64    case 3:
65      exp = (fraction & 0x8000000000000) ? 0x3fe : 0x3ff;
66      break;
67    default:
68      abort ();
69    }
70
71  bin_conv.int_val = (sign << 63) | (exp << 52) | fraction;
72  return bin_conv.fp_val;
73}
74#endif
75
76void static
77CALC (double *r, double *s, int interv, int signctrl)
78{
79  int i;
80  for (i = 0; i < SIZE; i++)
81    {
82      r[i] = get_norm_mant (s[i], signctrl, interv);
83    }
84}
85
86void
87TEST (void)
88{
89  int i, sign;
90  UNION_TYPE (AVX512F_LEN, d) res1, res2, res3, src;
91  MASK_TYPE mask = MASK_VALUE;
92  double res_ref[SIZE];
93  int interv = _MM_MANT_NORM_p5_1;
94  int signctrl = _MM_MANT_SIGN_src;
95
96  sign = -1;
97  for (i = 0; i < SIZE; i++)
98    {
99      src.a[i] = 34.67 * i * sign;
100      sign = sign * -1;
101    }
102  for (i = 0; i < SIZE; i++)
103    res2.a[i] = DEFAULT_VALUE;
104
105  res1.x = INTRINSIC (_getmant_pd) (src.x, interv, signctrl);
106  res2.x =
107    INTRINSIC (_mask_getmant_pd) (res2.x, mask, src.x, interv,
108				  signctrl);
109  res3.x =
110    INTRINSIC (_maskz_getmant_pd) (mask, src.x, interv, signctrl);
111
112  CALC (res_ref, src.a, interv, signctrl);
113
114  if (UNION_CHECK (AVX512F_LEN, d) (res1, res_ref))
115    abort ();
116
117  MASK_MERGE (d) (res_ref, mask, SIZE);
118  if (UNION_CHECK (AVX512F_LEN, d) (res2, res_ref))
119    abort ();
120
121  MASK_ZERO (d) (res_ref, mask, SIZE);
122  if (UNION_CHECK (AVX512F_LEN, d) (res3, res_ref))
123    abort ();
124}
125