Subject: Re: [PATCH] Fix rounding bug in emulation for double floatoperating

From: Zang Roy-r61911 <[email-masked]>
Date: 12 Dec 2007 16:30:24 +0800

On Tue, 2007-12-11 at 23:26, Kumar Gala wrote:
> >>
> >> how did you find this?
> >>
> > It supposed to run the following test case on a powerpc platform.
> > Yu's patch fixes the issue.
> > Could you help to merge this patch in your tree?
> > ---
> > #include <stdio.h>
> > #include <math.h>
> > #include <bits/nan.h>
> > #ifdef __SPE__
> > #include <spe.h>
> > int
> > getSPEFSCR()
> > {
> >    return __builtin_spe_mfspefscr();
> > }
> >
> > void
> > setSPEFSCR(int i)
> > {
> >    __builtin_spe_mtspefscr(i);
> > }
> > #else
> > int
> > getSPEFSCR()
> > {
> >    return 0;
> > }
> >
> > void
> > setSPEFSCR(int i)
> > {
> > }
> > #endif
> >
> > void
> > dmul(double d, double d1, double expected)
> > {
> >    double d2;
> >    int before, after;
> >
> >    before = getSPEFSCR();
> >    d2 = d * d1;
> >    after = getSPEFSCR();
> >
> >    printf("dmul %llx * %llx = %llx expected %llx %s [0x%x 0x%x]\n", 
> > d, d1, d2, expected,
> >           (d2 == expected) ? "(PASS)" : "(FAIL)", before, after);
> > }
> >
> > void
> > ddiv(double d, double d1, double expected)
> > {
> >    register double d2;
> >    int before, after;
> >
> >    before = getSPEFSCR();
> >    d2 = d / d1;
> >    after = getSPEFSCR();
> >
> >    printf("ddiv %llx / %llx = %llx expected %llx %s [0x%x 0x%x]\n", 
> > d, d1, d2, expected,
> >           (d2 == expected) ? "(PASS)" : "(FAIL)", before, after);
> > }
> >
> > main()
> > {
> >    const double min_double = 4.9406564584124654e-324L;
> >
> >    printf("\n");
> >    dmul(0.5L, min_double, 0.0L);
> >    dmul(-0.5L, min_double, 0.0L);
> >    dmul(-min_double, -0.5L, 0.0L);
> >    printf("\n");
> >    ddiv(min_double, 2.0L, 0.0L);
> > }
> 
> When I run this on a G5 (w/HW FP) I get:
> 
> dmul 3fe0000000000000 * 1 = 0 expected 0 (PASS)
> dmul bfe0000000000000 * 1 = 8000000000000000 expected 0 (PASS)
> dmul 8000000000000001 * bfe0000000000000 = 0 expected 0 (PASS)
> 
> ddiv 1 / 4000000000000000 = 0 expected 0 (PASS)
> 
> and on the 85xx w/FP emu:
> 
> dmul 3fe0000000000000 * 1 = 0 expected 0 (PASS)
> dmul bfe0000000000000 * 1 = 8000000000000000 expected 0 (PASS)
> dmul 8000000000000001 * bfe0000000000000 = 0 expected 0 (PASS)
> 
> ddiv 1 / 4000000000000000 = 0 expected 0 (PASS)
> 
> Maybe I'm missing where the error is.
I am missing ...
It is supposed to run based on previous IEEE 754 patch.
http://ozlabs.org/pipermail/linuxppc-dev/2007-February/031351.html
Roy