sparc64/55773: Conversion from long to long double is broken

Mark Kettenis kettenis at
Wed Aug 20 02:42:18 PDT 2003

>Number:         55773
>Category:       sparc64
>Synopsis:       Conversion from long to long double is broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-sparc64
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 20 02:41:50 PDT 2003
>Originator:     Mark Kettenis
>Release:        FreeBSD 5.1-CURRENT sparc64
System: FreeBSD 5.1-CURRENT FreeBSD 5.1-CURRENT #166: Fri Aug 15 11:44:38 PDT 2003     root at  sparc64


Conversion of `long' and `unsigned long' to `long double' are broken
on FreeBSD/sparc64.  GCC generates the right code AFAICT, but the
implementation of _Qp_xtoq() and _Qp_uxtoq() in
/src/lib/libc/sparc64/fpu/fpu_qp.c seem to be broken.  Every value
that has bit 32 set will be negative when converted to a `long


The following test program exhibits the behaviour:

#include <stdio.h>

unsigned long mant_long = 0x80000000;

main (void)
  long double mant = mant_long;
  printf ("%lu\n", mant_long);
  printf ("%Lf\n", mant);
  return 0;

which should print


but will print



Looking at the code in /usr/src/lib/libc/sparc64/fpu/fpu_qp.c (I'm
looking at revision 1.3), it seems that the _QP_TTOQ() macro only
handles 32-bit signed integers since on line 63 of that file we have:

	fe.fe_f1.fp_sign = a[0] >> 31;

I think that this line should be

	fe.fe_f1.fp_sign = a[0] >> 63;

for `long' (_Qp_xtoq) and that the line should be completely absent
for `unsigned' (_Qp_uitoq) and `unsigned long' (_Qp_uxtoq).  Some
not-too-thorough testing seems to indicate that's right.

More information about the freebsd-sparc64 mailing list