[PATCH] Fix rounding bug in emulation for double floatoperating

Kumar Gala galak at kernel.crashing.org
Wed Dec 12 02:26:43 EST 2007


>>
>> 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.

- k



More information about the Linuxppc-dev mailing list