1/* { dg-do run } */
2/* { dg-options "-mavx512f -O2 -std=c99" } */
3/* { dg-require-effective-target avx512f } */
4/* { dg-require-effective-target c99_runtime } */
5
6#include "avx512f-check.h"
7#include <math.h>
8
9union fp_int_t
10{
11  int int_val;
12  float fp_val;
13};
14
15float
16get_norm_mant (float source, int signctrl, int interv)
17{
18  int src, sign, exp, fraction;
19  union fp_int_t bin_conv;
20
21  bin_conv.fp_val = source;
22  src = bin_conv.int_val;
23  sign = (signctrl & 0x1) ? 0 : (src >> 31);
24  exp = (src & 0x7f800000) >> 23;
25  fraction = (src & 0x7fffff);
26
27  if (isnan (source))
28    return signbit (source) ? -NAN : NAN;
29  if (source == 0.0 || source == -0.0 || isinf (source))
30    return sign ? -1.0 : 1.0;
31  if (signbit (source) && (signctrl & 0x2))
32    return -NAN;
33  if (!isnormal (source))
34    {
35      src = (src & 0xffbfffff);
36      exp = 0x7f;
37      while (!(src & 0x400000))
38	{
39	  src += fraction & 0x400000;
40	  fraction = fraction << 1;
41	  exp--;
42	}
43    }
44
45  switch (interv)
46    {
47    case 0:
48      exp = 0x7f;
49      break;
50    case 1:
51      exp = ((exp - 0x7f) & 0x1) ? 0x7e : 0x7f;
52      break;
53    case 2:
54      exp = 0x7e;
55      break;
56    case 3:
57      exp = (fraction & 0x400000) ? 0x7e : 0x7f;
58      break;
59    default:
60      abort ();
61    }
62
63  bin_conv.int_val = (sign << 31) | (exp << 23) | fraction;
64
65  return bin_conv.fp_val;
66
67}
68
69static void
70compute_vgetmantss (float *r, float *s1, float *s2, int interv,
71		    int signctrl)
72{
73  int i;
74  r[0] = get_norm_mant (s2[0], signctrl, interv);
75  for (i = 1; i < 4; i++)
76    {
77      r[i] = s1[i];
78    }
79}
80
81static void
82avx512f_test (void)
83{
84  union128 res1, src1, src2;
85  float res_ref[4];
86  int interv = _MM_MANT_NORM_p5_1;
87  int signctrl = _MM_MANT_SIGN_src;
88
89  src1.x = _mm_set_ps (-24.043, 68.346, -43.35, 546.46);
90  src2.x = _mm_set_ps (222.222, 333.333, 444.444, -2.0);
91
92  res1.x = _mm_getmant_ss (src1.x, src2.x, interv, signctrl);
93
94  compute_vgetmantss (res_ref, src1.a, src2.a, interv, signctrl);
95
96  if (check_union128 (res1, res_ref))
97    abort ();
98}
99