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 long long int int_val; 12 double fp_val; 13}; 14 15double 16get_norm_mant (double source, int signctrl, int interv) 17{ 18 long long src, sign, exp, fraction; 19 20 union fp_int_t bin_conv; 21 22 bin_conv.fp_val = source; 23 src = bin_conv.int_val; 24 sign = (signctrl & 0x1) ? 0 : (src >> 63); 25 exp = (src & 0x7ff0000000000000) >> 52; 26 fraction = (src & 0xfffffffffffff); 27 28 if (isnan (source)) 29 return signbit (source) ? -NAN : NAN; 30 if (source == 0.0 || source == -0.0 || isinf (source)) 31 return sign ? -1.0 : 1.0; 32 if (signbit (source) && (signctrl & 0x2)) 33 return -NAN; 34 if (!isnormal (source)) 35 { 36 src = (src & 0xfff7ffffffffffff); 37 exp = 0x3ff; 38 while (!(src & 0x8000000000000)) 39 { 40 src += fraction & 0x8000000000000; 41 fraction = fraction << 1; 42 exp--; 43 } 44 } 45 46 switch (interv) 47 { 48 case 0: 49 exp = 0x3ff; 50 break; 51 case 1: 52 exp = ((exp - 0x3ff) & 0x1) ? 0x3fe : 0x3ff; 53 break; 54 case 2: 55 exp = 0x3fe; 56 break; 57 case 3: 58 exp = (fraction & 0x8000000000000) ? 0x3fe : 0x3ff; 59 break; 60 default: 61 abort (); 62 } 63 64 bin_conv.int_val = (sign << 63) | (exp << 52) | fraction; 65 return bin_conv.fp_val; 66} 67 68static void 69compute_vgetmantsd (double *r, double *s1, double *s2, int interv, 70 int signctrl) 71{ 72 r[0] = get_norm_mant (s2[0], signctrl, interv); 73 r[1] = s1[1]; 74} 75 76static void 77avx512f_test (void) 78{ 79 union128d res1, src1, src2; 80 double res_ref[2]; 81 int interv = _MM_MANT_NORM_p5_1; 82 int signctrl = _MM_MANT_SIGN_src; 83 84 src1.x = _mm_set_pd (-3.0, 111.111); 85 src2.x = _mm_set_pd (222.222, -2.0); 86 87 res1.x = _mm_getmant_sd (src1.x, src2.x, interv, signctrl); 88 89 compute_vgetmantsd (res_ref, src1.a, src2.a, interv, signctrl); 90 91 if (check_union128d (res1, res_ref)) 92 abort (); 93} 94