1 /* Test vrnd_f64 works correctly. */
3 /* { dg-options "--save-temps" } */
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
)
21 /* Read current FPCR. */
22 asm volatile ("mrs %[r], fpcr" : [r
] "=r" (r
) : :);
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
)
40 void __attribute__ ((noinline
))
41 run_round_tests (float64x1_t
*tests
,
42 float64_t expectations
[][6])
46 for (i
= 0; i
< 6; i
++)
48 if (compare_f64 (vrnd_f64 (tests
[i
]), expectations
[0][i
]))
50 if (compare_f64 (vrndx_f64 (tests
[i
]), expectations
[1][i
]))
52 if (compare_f64 (vrndp_f64 (tests
[i
]), expectations
[2][i
]))
54 if (compare_f64 (vrndn_f64 (tests
[i
]), expectations
[3][i
]))
56 if (compare_f64 (vrndm_f64 (tests
[i
]), expectations
[4][i
]))
58 if (compare_f64 (vrndi_f64 (tests
[i
]), expectations
[5][i
]))
60 if (compare_f64 (vrnda_f64 (tests
[i
]), expectations
[6][i
]))
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 behavior. */
91 set_rounding_mode (FPROUNDING_ZERO
);
93 run_round_tests (tests
, expectations
);
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 } } */