Rebase.
[official-gcc.git] / gcc / testsuite / gcc.target / aarch64 / vrnd_f64_1.c
blob31efc4f2752b6e32808d7ba382c9f378e9e73299
1 /* Test vrnd_f64 works correctly. */
2 /* { dg-do run } */
3 /* { dg-options "--save-temps" } */
5 #include "arm_neon.h"
7 extern void abort (void);
9 /* Bit offset to round mode field in FPCR. */
10 #define RMODE_START 22
12 #define FPROUNDING_ZERO 3
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)
19 uint32_t r;
21 /* Read current FPCR. */
22 asm volatile ("mrs %[r], fpcr" : [r] "=r" (r) : :);
24 /* Clear rmode. */
25 r &= ~(3 << RMODE_START);
26 /* Calculate desired FPCR. */
27 r |= mode << RMODE_START;
29 /* Write desired FPCR back. */
30 asm volatile ("msr fpcr, %[r]" : : [r] "r" (r) :);
33 float64_t __attribute__ ((noinline))
34 compare_f64 (float64x1_t passed, float64_t expected)
36 return (__builtin_fabs (vget_lane_f64 (passed, 0) - expected)
37 > __DBL_EPSILON__);
40 void __attribute__ ((noinline))
41 run_round_tests (float64x1_t *tests,
42 float64_t expectations[][6])
44 int i;
46 for (i = 0; i < 6; i++)
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 ();
65 int
66 main (int argc, char **argv)
68 float64x1_t tests[6] =
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. */
78 float64_t expectations[7][6] =
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. */
89 /* Set floating point control register
90 to have predictable vrndx and vrndi behaviour. */
91 set_rounding_mode (FPROUNDING_ZERO);
93 run_round_tests (tests, expectations);
95 return 0;
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 } } */