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
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=rintl 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
232 _DIAGASSERT((round & ~_ROUND_MASK) == 0);
233 if (round & ~_ROUND_MASK)
234 return -1;
235
236 __stxfsr(&r);
237 r &= ~(_ROUND_MASK << _ROUND_SHIFT);
238 r |= round << _ROUND_SHIFT;
239 __ldxfsr(r);
240
241 /* Success */
242 return 0;
243 }
https://nxr.netbsd.org/xref/src/lib/libm/arch/sparc64/fenv.c?r=1.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
32 __asm("st %%fsr,%0" : "=m" (*&old));
33
34 #ifdef SOFTFLOATSPARC64_FOR_GCC
=> 35 _softfloat_float_rounding_mode = rnd_dir;
36 #endif
37
38 new = old;
39 new &= ~(0x03U << 30);
40 new |= ((rnd_dir & 0x03U) << 30);
41
42 __asm("ld %0,%%fsr" : : "m" (*&new));
43
44 return ((uint32_t)old >> 30) & 0x03;
45 }
https://nxr.netbsd.org/xref/src/lib/libc/arch/sparc64/gen/fpsetround.c?r=1.9#35
Home |
Main Index |
Thread Index |
Old Index