[uClibc]Bugs in libm double functions
John Laur
johnl at blurbco.com
Tue Oct 2 10:06:28 UTC 2001
Greetings,
In my endeavor to get perl compiled against uClibc to run on the
tuxscreen phone, I stumbled across some bugs in the double functions of
libm. These bugs, AFAIK, only affect the ARM processor, but perhaps they
also cause problems on others (SH3/4 come to mind). Basically, double
storage on ARM is unique.
rmk put it like this:
<rmk> dwmw2: ARM [floating point] is big endian
<dwmw2> ok, so just pretend it's BE and it should all work ok?
<rmk> well, the words are in little endian, but ordered in big endian
The libm code has a lot of this kind of stuff:
union { double y;
unsigned short sh[4];
} u;
On x86, if you had a double that corresponded to the following array of
shorts: {0, 1, 2, 3}, that same double would produce the following array
of shorts on arm: {2, 3, 0, 1}. It's kind of like big-endian only the
ends are twice as big. I was toying with the idea of some extra #define
for ARM. ARM right now finds itself lumped under IBMPC in my little
endian world, which obviously doesn't work. Erik Andersen suggested that
I post to this list to start discussion on whether a more elegant
solution can be devised.
<rmk> GoRK: iirc glibc's libm uses longs
Anyway, it's pretty much chaos trying to use uClibc's libm on arm. It
throws itself into infinite loops like crazy.
Here are my gdb logs from both arm and x86 to illustrate (u is defined
as the union above and x is a double that has a value of 2):
arm:
Breakpoint 3, frexp (x=2, pw2=0x400069f8) at floor.c:267
267 u.y = x;
(gdb) s
275 q = (short *)&u.sh[3];
(gdb) p x
$6 = 2
(gdb) p u.y
$7 = 2
(gdb) p u
$8 = {y = 2, sh = {0, 16384, 0, 0}}
(gdb)
x86:
Breakpoint 3, frexp (x=2, pw2=0xbffff6cc) at floor.c:267
267 u.y = x;
(gdb) s
275 q = (short *)&u.sh[3];
(gdb) p x
$8 = 2
(gdb) p u.y
$7 = 2
(gdb) p u
$9 = {y = 2, sh = {0, 0, 0, 16384}}
In other news, perl compiles against uClibc on X86 and failed only two
of its stress tests (which is probably not uClibc's fault). It already
compiles against uClibc on ARM, too, but fails a lot of tests or gets
into infinite loops because of this libm problem. I will post a test log
sometime when I can make it go 100% :) I can't think of many programs
that stress test a libc quite so well as a complex scripting language
such as perl.
Thanks for your comments,
John Laur
More information about the uClibc
mailing list