[uClibc]Kernel FPU emulation vs. -msoft-float?

Jeff Baitis baitisj at evolution.com
Sat Jun 7 01:03:10 UTC 2003


Note: Are you using little- or big-endian MIPS?

On Fri, Jun 06, 2003 at 05:20:55PM -0700, Jon Loeliger wrote:
> OK.  I _believe_ that the emulation is working fine for me as well.
> However, I suspect that either on the way in or out of the kernel,
> someone is trashing the user-land stack as a a result.

Yipes! 

> Oh yeah, in-kernel emulation is vaguely magic and real easy... if it
> works...:-)
> 
> I've got version 1.5 from a munged IDT release based on 2.4.18.
> Can I do better?

The linux-mips.org head is at kernel 2.4.21pre4, and has lots of people
hammering on it. I'm pretty sure we would have noticed this kind of corruption
by now, so maybe you might want to think about migrating to a linux-mips
kernel....


> > out-- and I'll contribute my findings. However, I've got this
> prototype
> > to attend to ; )
> 
> Uh, that would be me too... :-)
> 
> So, here's today's odd failure.  Take this example:
> 
> double a, b;
> 
> void fred(double x);
> 
> union {
>     double u_f;
>     int u_a[2];
> } fi;
> 
> main()
> {
>     fi.u_f = 3.1415926e-42;
>     printf("as a 1 %x\n", fi.u_a[0]);
>     printf("as a 0 %x\n", fi.u_a[1]);
> 
>     fi.u_f = 0;
>     a = 3.1415926e-42;
>     fred(a);
> }
> 
> void
> fred(double x)
> {
>     fi.u_f = x;
> 
>     if (x == x) {
> 	printf("as a l %x\n", fi.u_a[0]);
>         printf("as a l %x\n", fi.u_a[1]);
>     }
> }
> 
I compiled and executed it. Here's my output:

as a 1 aea37519
as a 0 375183d4
as a l aea37519
as a l 375183d4

> If you compile this, it will fail on my system at the
> floating point comparison of x == x.  However, if you
> modify the printf("as a l %x\n", fi.u_a[0]); in fred()
> to be "as a 0" and "as a 1" (like in main()) instead,
> then it works just fine.

Here's my modified test program: (pardon my formatting, vi on busybox sux):

double a, b;

void fred(double x);

union {
double u_f;
int u_a[2];
} fi;

main()
{
fi.u_f = 3.1415926e-42;
printf("as a 1 %x\n", fi.u_a[0]);
printf("as a 0 %x\n", fi.u_a[1]);

fi.u_f = 0;
a = 3.1415926e-42;
fred(a);
}

void
fred(double x)
{
fi.u_f = x;

if (x == x) {
printf("as a 0 %x\n", fi.u_a[0]);
printf("as a 1 %x\n", fi.u_a[1]);
    }
}

Here's my output:

as a 1 aea37519
as a 0 375183d4
as a 0 aea37519
as a 1 375183d4


.....

I think your kernel may be having issues!

> Let me say that differently: change an l (ell) to a 1
> (one) in the static string and the behaviour gets better.
> 
> I think the presence of the l (ell) causes the printf()
> code to parse the printf() format string into a bad
> state, or leaves it pointing onto the stack at some
> invalid local variable or something, and it gets
> corrupted by the kernel trap for x == x.
> 
> Dunno.
> 
> Insight?

I hope my output helps you, somehow!

-Jeff

-- 
         Jeffrey Baitis - Associate Software Engineer

                    Evolution Robotics, Inc.
                     130 West Union Street
                       Pasadena CA 91103

 tel: 626.535.2776  |  fax: 626.535.2777  |  baitisj at evolution.com 



More information about the uClibc mailing list