1/* Test vrnd_f64 works correctly. */ 2/* { dg-do run } */ 3/* { dg-options "--save-temps" } */ 4 5#include "arm_neon.h" 6 7extern 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. */ 16void __inline __attribute__ ((__always_inline__)) 17set_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 33float64_t __attribute__ ((noinline)) 34compare_f64 (float64x1_t passed, float64_t expected) 35{ 36 return (__builtin_fabs (vget_lane_f64 (passed, 0) - expected) 37 > __DBL_EPSILON__); 38} 39 40void __attribute__ ((noinline)) 41run_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 65int 66main (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 behaviour. */ 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 } } */ 105/* { dg-final { cleanup-saved-temps } } */ 106