NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-sparc64/59310: t_fe_round:fe_nearbyint_rint tests are failing
The following reply was made to PR port-sparc64/59310; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Cc:
Subject: Re: port-sparc64/59310: t_fe_round:fe_nearbyint_rint tests are failing
Date: Thu, 17 Apr 2025 13:58:25 +0000
All the test cases that are failing are in long double functions with
non-default rounding modes.
On sparc64, long double is implemented via softfloat ABI, from what I
understand -- `objdump --disassemble=3Drintl libm.so' shows various
_Qp_* function calls:
00000000000776e0 <rintl>:
...
77760: 40 04 54 c8 call 18ca80 <_Qp_stoq@plt>
...
77790: 40 04 57 b4 call 18d660 <_Qp_add@plt>
...
777b8: 40 04 55 32 call 18cc80 <_Qp_sub@plt>
...
777f4: 40 04 55 a3 call 18ce80 <_Qp_feq@plt>
...
77824: 40 04 54 97 call 18ca80 <_Qp_stoq@plt>
...
77850: 40 04 57 84 call 18d660 <_Qp_add@plt>
I bet the reason these are failing is that the C99 fesetround() in
libm doesn't update _softfloat_float_rounding_mode, so the _Qp_*
functions are all working in round-to-nearest:
227 int
228 fesetround(int round)
229 {
230 fenv_t r;
231=20
232 _DIAGASSERT((round & ~_ROUND_MASK) =3D=3D 0);
233 if (round & ~_ROUND_MASK)
234 return -1;
235=20
236 __stxfsr(&r);
237 r &=3D ~(_ROUND_MASK << _ROUND_SHIFT);
238 r |=3D round << _ROUND_SHIFT;
239 __ldxfsr(r);
240=20
241 /* Success */
242 return 0;
243 }
https://nxr.netbsd.org/xref/src/lib/libm/arch/sparc64/fenv.c?r=3D1.4#227
In contrast, the legacy BSD fpsetround() in libc does set
_softfloat_float_rounding_mode:
26 fp_rnd
27 fpsetround(fp_rnd rnd_dir)
28 {
29 fp_rnd old;
30 fp_rnd new;
31=20
32 __asm("st %%fsr,%0" : "=3Dm" (*&old));
33=20
34 #ifdef SOFTFLOATSPARC64_FOR_GCC
=3D> 35 _softfloat_float_rounding_mode =3D rnd_dir;
36 #endif
37=20
38 new =3D old;
39 new &=3D ~(0x03U << 30);
40 new |=3D ((rnd_dir & 0x03U) << 30);
41=20
42 __asm("ld %0,%%fsr" : : "m" (*&new));
43=20
44 return ((uint32_t)old >> 30) & 0x03;
45 }
https://nxr.netbsd.org/xref/src/lib/libc/arch/sparc64/gen/fpsetround.c?r=3D=
1.9#35
Home |
Main Index |
Thread Index |
Old Index