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