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 #include "avx512f-helper.h"
9 
10 #define SIZE (128/32)
11 #include "avx512f-mask-type.h"
12 
13 union fp_int_t
14 {
15   int int_val;
16   float fp_val;
17 };
18 
19 float
get_norm_mant(float source,int signctrl,int interv)20 get_norm_mant (float source, int signctrl, int interv)
21 {
22   int src, sign, exp, fraction;
23   union fp_int_t bin_conv;
24 
25   bin_conv.fp_val = source;
26   src = bin_conv.int_val;
27   sign = (signctrl & 0x1) ? 0 : (src >> 31);
28   exp = (src & 0x7f800000) >> 23;
29   fraction = (src & 0x7fffff);
30 
31   if (isnan (source))
32     return signbit (source) ? -NAN : NAN;
33   if (source == 0.0 || source == -0.0 || isinf (source))
34     return sign ? -1.0 : 1.0;
35   if (signbit (source) && (signctrl & 0x2))
36     return -NAN;
37   if (!isnormal (source))
38     {
39       src = (src & 0xffbfffff);
40       exp = 0x7f;
41       while (!(src & 0x400000))
42 	{
43 	  src += fraction & 0x400000;
44 	  fraction = fraction << 1;
45 	  exp--;
46 	}
47     }
48 
49   switch (interv)
50     {
51     case 0:
52       exp = 0x7f;
53       break;
54     case 1:
55       exp = ((exp - 0x7f) & 0x1) ? 0x7e : 0x7f;
56       break;
57     case 2:
58       exp = 0x7e;
59       break;
60     case 3:
61       exp = (fraction & 0x400000) ? 0x7e : 0x7f;
62       break;
63     default:
64       abort ();
65     }
66 
67   bin_conv.int_val = (sign << 31) | (exp << 23) | fraction;
68 
69   return bin_conv.fp_val;
70 
71 }
72 
73 static void
compute_vgetmantss(float * r,float * s1,float * s2,int interv,int signctrl)74 compute_vgetmantss (float *r, float *s1, float *s2, int interv,
75 		    int signctrl)
76 {
77   int i;
78   r[0] = get_norm_mant (s2[0], signctrl, interv);
79   for (i = 1; i < SIZE; i++)
80     {
81       r[i] = s1[i];
82     }
83 }
84 
85 static void
avx512f_test(void)86 avx512f_test (void)
87 {
88   union128 res1, res2, res3, res4, res5, res6, src1, src2;
89   float res_ref[4];
90   MASK_TYPE mask = MASK_VALUE;
91 
92   src1.x = _mm_set_ps (-24.043, 68.346, -43.35, 546.46);
93   src2.x = _mm_set_ps (222.222, 333.333, 444.444, -2.0);
94 
95   int i;
96   for (i = 0; i < SIZE; i++)
97     {
98       res2.a[i] = DEFAULT_VALUE;
99       res5.a[i] = DEFAULT_VALUE;
100     }
101 
102   res1.x = _mm_getmant_ss (src1.x, src2.x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
103   res2.x = _mm_mask_getmant_ss (res2.x, mask, src1.x, src2.x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
104   res3.x = _mm_maskz_getmant_ss (mask, src1.x, src2.x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
105   res4.x = _mm_getmant_round_ss (src1.x, src2.x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src, _MM_FROUND_NO_EXC);
106   res5.x = _mm_mask_getmant_round_ss (res5.x, mask, src1.x, src2.x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src, _MM_FROUND_NO_EXC);
107   res6.x = _mm_maskz_getmant_round_ss (mask, src1.x, src2.x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src, _MM_FROUND_NO_EXC);
108 
109   compute_vgetmantss (res_ref, src1.a, src2.a, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
110 
111   if (check_union128 (res1, res_ref))
112     abort ();
113 
114   MASK_MERGE () (res_ref, mask, 1);
115   if (check_union128 (res2, res_ref))
116     abort ();
117 
118   MASK_ZERO () (res_ref, mask, 1);
119   if (check_union128 (res3, res_ref))
120     abort ();
121 
122   compute_vgetmantss (res_ref, src1.a, src2.a, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
123 
124   if (check_union128 (res4, res_ref))
125     abort ();
126 
127   MASK_MERGE () (res_ref, mask, 1);
128   if (check_union128 (res5, res_ref))
129     abort ();
130 
131   MASK_ZERO () (res_ref, mask, 1);
132   if (check_union128 (res6, res_ref))
133     abort ();
134 }
135