On Mon, 2007-12-10 at 23:00, Kumar Gala wrote: > On Dec 9, 2007, at 11:25 PM, Liu Yu wrote: > > > >> -----Original Message----- > >> From: David Gibson [mailto:[EMAIL PROTECTED] > >> Sent: Monday, December 10, 2007 12:56 PM > >> To: Liu Yu > >> Cc: linuxppc-dev@ozlabs.org > >> Subject: Re: [PATCH] Fix rounding bug in emulation for double > >> floatoperating > >> > >> > >> On Mon, Dec 10, 2007 at 01:00:52PM +0800, Liu Yu wrote: > >>> > >>> This patch fixes rounding bug in emulation for double float > >> operating on PowerPC platform. > >>> > >>> When pack double float operand, it need to truncate the > >> tail due to the limited precision. > >>> If the truncated part is not zero, the last bit of work bit > >> (totally 3 bits) need to '|' 1. > >>> > >>> This patch is completed in _FP_FRAC_SRS_2(X,N,sz) > >> (arch/powerpc/math-emu/op-2.h). > >>> Originally the code leftwards rotates the operand to just keep the > >>> truncated part, then check whether it is zero. However, the > >> number it > >>> rotates is not correct when N is not smaller than > >> _FP_W_TYPE_SIZE, and it will cause the work bit '|' 1 in the > >> improper case. > >>> > >>> This patch fixes this issue. > >>> > >>> Signed-off-by: Liu Yu <[EMAIL PROTECTED]> > >> > >> Wow someone deciphered the hideous macro hell of the math > >> emulation code enough to fix a bug. I don't suppose you'd > >> care to fix the millions of warnings that the math-emu code > >> generates...? > > > > Oh, I don't like macro define either. But it's really a bug... > > > 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); } _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-dev