(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
i386/
sse4_1-roundsd-4.c
       1  /* { dg-do run } */
       2  /* { dg-require-effective-target sse4 } */
       3  /* { dg-options "-O2 -msse4.1" } */
       4  
       5  #include "sse4_1-check.h"
       6  
       7  #include <smmintrin.h>
       8  #include "math_m_pi.h"
       9  #include <string.h>
      10  
      11  #define NUM 64
      12  
      13  static void
      14  init_round (double *src)
      15  {
      16    int i, sign = 1;
      17    double d = rand ();
      18  
      19    for (i = 0; i < NUM; i++)
      20      {
      21        src[i] = (i + 1)* d * M_PI * sign;
      22        if (i < (NUM / 2))
      23  	{
      24            if ((i % 6) == 0)
      25  	    d = d * src[i];
      26          }
      27        else if (i == (NUM / 2))
      28  	d = rand ();
      29        else if ((i % 6) == 0)
      30  	d = 1 / (d * (i + 1) * src[i] * M_PI *sign);
      31        sign = -sign;
      32      }
      33  }
      34  
      35  static double
      36  do_round (double f, int type)
      37  {
      38    unsigned short saved_cw, new_cw, clr_mask;
      39    double ret;
      40  
      41    if ((type & 4))
      42      {
      43        type = 0;
      44        clr_mask = 0xFFFF;
      45      }
      46    else
      47      {
      48        type = 0x003F | ((type & 3) << 10);
      49        clr_mask = ~0x0C3F;
      50      }
      51  
      52    __asm__ ("fnstcw %0" : "=m" (saved_cw));
      53  
      54    new_cw = saved_cw & clr_mask;
      55    new_cw |= type;
      56  
      57    __asm__ ("fldcw %2\n\t"
      58  	   "frndint\n\t"
      59  	   "fldcw %3" : "=t" (ret)
      60  		      : "0" (f), "m" (new_cw), "m" (saved_cw));
      61    return ret;
      62  }
      63  
      64  static void
      65  sse4_1_test (void)
      66  {
      67    int i;
      68    double f;
      69    union
      70      {
      71        __m128d x[NUM / 2];
      72        double d[NUM];
      73      } dst, src;
      74  
      75    init_round (src.d);
      76    memset (&dst, 0, NUM * sizeof(double));
      77  
      78    for (i = 0; i < NUM / 2 ; i++)
      79      dst.x[i] =  _mm_round_sd (dst.x[i], src.x[i], _MM_FROUND_TRUNC);
      80  
      81    for (i = 0; i < NUM; i += 2)
      82      {
      83        if (dst.d[i + 1] != 0.0)
      84  	abort ();
      85  
      86        f = do_round (src.d[i], 0x03);
      87        if (f != dst.d[i])
      88  	abort ();
      89      }
      90  }