(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
aarch64/
vrnd_f64_1.c
       1  /* Test vrnd_f64 works correctly.  */
       2  /* { dg-do run } */
       3  /* { dg-options "--save-temps" } */
       4  
       5  #include "arm_neon.h"
       6  
       7  extern void abort (void);
       8  
       9  /* Bit offset to round mode field in FPCR.  */
      10  #define RMODE_START 22
      11  
      12  #define FPROUNDING_ZERO 3
      13  
      14  /* Set RMODE field of FPCR control register
      15     to rounding mode passed.  */
      16  void __inline __attribute__ ((__always_inline__))
      17  set_rounding_mode (uint32_t mode)
      18  {
      19    uint32_t r;
      20  
      21    /* Read current FPCR.  */
      22    asm volatile ("mrs %[r], fpcr" : [r] "=r" (r) : :);
      23  
      24    /* Clear rmode.  */
      25    r &= ~(3 << RMODE_START);
      26    /* Calculate desired FPCR.  */
      27    r |= mode << RMODE_START;
      28  
      29    /* Write desired FPCR back.  */
      30    asm volatile ("msr fpcr, %[r]" : : [r] "r" (r) :);
      31  }
      32  
      33  float64_t __attribute__ ((noinline))
      34  compare_f64 (float64x1_t passed, float64_t expected)
      35  {
      36    return (__builtin_fabs (vget_lane_f64 (passed, 0) - expected)
      37  	  > __DBL_EPSILON__);
      38  }
      39  
      40  void __attribute__ ((noinline))
      41  run_round_tests (float64x1_t *tests,
      42  		 float64_t expectations[][6])
      43  {
      44    int i;
      45  
      46    for (i = 0; i < 6; i++)
      47      {
      48        if (compare_f64 (vrnd_f64 (tests[i]), expectations[0][i]))
      49  	abort ();
      50        if (compare_f64 (vrndx_f64 (tests[i]), expectations[1][i]))
      51  	abort ();
      52        if (compare_f64 (vrndp_f64 (tests[i]), expectations[2][i]))
      53  	abort ();
      54        if (compare_f64 (vrndn_f64 (tests[i]), expectations[3][i]))
      55  	abort ();
      56        if (compare_f64 (vrndm_f64 (tests[i]), expectations[4][i]))
      57  	abort ();
      58        if (compare_f64 (vrndi_f64 (tests[i]), expectations[5][i]))
      59  	abort ();
      60        if (compare_f64 (vrnda_f64 (tests[i]), expectations[6][i]))
      61  	abort ();
      62      }
      63  }
      64  
      65  int
      66  main (int argc, char **argv)
      67  {
      68    float64x1_t tests[6] =
      69      {
      70        vcreate_f64 (0x3FE0000000000000), /* Hex for: 0.5.  */
      71        vcreate_f64 (0x3FD999999999999A), /* Hex for: 0.4.  */
      72        vcreate_f64 (0x3FE3333333333333), /* Hex for: 0.6.  */
      73        vcreate_f64 (0xBFE0000000000000), /* Hex for: -0.5.  */
      74        vcreate_f64 (0xBFD999999999999A), /* Hex for: -0.4.  */
      75        vcreate_f64 (0xBFE3333333333333), /* Hex for: -0.6.  */
      76      };
      77  
      78    float64_t expectations[7][6] =
      79    {
      80      { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },    /* vrnd - round towards zero.  */
      81      { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },    /* vrndx - round using FPCR mode.  */
      82      { 1.0, 1.0, 1.0, 0.0, 0.0, 0.0 },    /* vrndp - round to plus infinity.  */
      83      { 0.0, 0.0, 1.0, 0.0, 0.0, -1.0 },   /* vrndn - round ties to even.  */
      84      { 0.0, 0.0, 0.0, -1.0, -1.0, -1.0 }, /* vrndm - round to minus infinity.  */
      85      { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 },    /* vrndi - round using FPCR mode.  */
      86      { 1.0, 0.0, 1.0, -1.0, 0.0, -1.0 },  /* vrnda - round ties away from 0.  */
      87    };
      88  
      89    /* Set floating point control register
      90       to have predictable vrndx and vrndi behavior.  */
      91    set_rounding_mode (FPROUNDING_ZERO);
      92  
      93    run_round_tests (tests, expectations);
      94  
      95    return 0;
      96  }
      97  
      98  /* { dg-final { scan-assembler-times "frintz\\td\[0-9\]+, d\[0-9\]+" 1 } } */
      99  /* { dg-final { scan-assembler-times "frintx\\td\[0-9\]+, d\[0-9\]+" 1 } } */
     100  /* { dg-final { scan-assembler-times "frintp\\td\[0-9\]+, d\[0-9\]+" 1 } } */
     101  /* { dg-final { scan-assembler-times "frintn\\td\[0-9\]+, d\[0-9\]+" 1 } } */
     102  /* { dg-final { scan-assembler-times "frintm\\td\[0-9\]+, d\[0-9\]+" 1 } } */
     103  /* { dg-final { scan-assembler-times "frinti\\td\[0-9\]+, d\[0-9\]+" 1 } } */
     104  /* { dg-final { scan-assembler-times "frinta\\td\[0-9\]+, d\[0-9\]+" 1 } } */