This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Floating point trouble on m68k


Hello,

OS: Linux/m68k kernel version 2.2.3pre1
CPU: 68060
gcc version: all, tested with gcc 2.7.2.3 and egcs 1.1.2
Options to gcc: -O2 (not important)

First, let me include a mail I sent to the Linux/m68k mailing list which
provoked some discussion:

------------------------------------------------------------------------------
I'm working with the Blackdown Java porting team to get Linux/m68k a working
version of the Java Development Kit version 1.2.
Before I'm allowed to distribute it, I have to pass the Java Compatibility
Kit, and this is where my problems start.
I have a 68060 CPU, and 2 floating point tests fail. They both concern the
single precision float multiplication, fsglmul.s and denormalized results.
I have converted one of the testcases to C, and here's the result:

rounding is double, result = 0x640006, expected result = 0x640005
rounding is float, result = 0x640006, expected result = 0x640005

The test passes on Linux/x86 and Solaris/Sparc, however.
I am very curious whether this test also fails on the 68881/68882 copros.
If not, the 68060 FPSP has a bug, and I'll report it to Motorola.
I'm also very curious about the 68040, because that has denormalized numbers
handled in software as well.

So, could those of you that have a 68040, 68881 or 68882 please compile and
run this test and mail the results?
The test does pass if I use the soft-float implementation from libgcc1, by
the way. Which is what I will use as a workaround for now.
The status of the JDK on Linux/m68k is quite good already, by the way. I pass
over 98% of the JCK.

Kars.

Here's the test:

---- Cut here ----
#include <stdio.h>
#include <string.h>

unsigned long darr[] = { 0x800007, 0x3f480000, 0x640005 };

int main() {
	float i, j, x;
	unsigned long result, *darrp = darr;

#ifdef __i386__
	asm("	pushl $575");
	asm("	fldcw (%esp)");
	asm("	addl $4,%esp");
#endif
#ifdef __mc68000__
	asm("	fmovel #0x80,%fpcr");
#endif
	memcpy(&i, darrp++, sizeof(float));
	memcpy(&j, darrp++, sizeof(float));
	x = i * j;
	memcpy(&result, &x, sizeof(float));
	printf("rounding is double, result = 0x%x, expected result = 0x%x\n", result, *darrp);
#ifdef __mc68000__
	asm("	fmovel #0x40,%fpcr");
#endif
	x = i * j;
	memcpy(&result, &x, sizeof(float));
	printf("rounding is float, result = 0x%x, expected result = 0x%x\n", result, *darrp);
	return 0;
}
---- Cut here ----
------------------------------------------------------------------------------

Several people with a 68040 and 68881/2 tried the test, and they all got the
same results as me.

The relevant code section in this case is this, the multiplication:

        fmove.s -4(%a6),%fp0
        fsglmul.s -8(%a6),%fp0
        fmove.s %fp0,-12(%a6)

After this I did a test. I made gcc output its assembler file, manually changed
the instruction it used (fsglmul.s) to fmul.s AND IT PASSES!

The Java language requires a strictly IEEE 754 compliant FPU, at double
precision (no more, no less) and using Round to Nearest rounding mode. This
is what I set the FPU to at the start of every thread, and the Intel port
does the same. Apparently using the fsglmul.s instruction for single
precision floating point is NOT equivalent to using fmul.s in terms of the
result, and I doubt this was intended, especially seeing in the .md file that
if compiling for a 68060 or 68040 the fsmul.s instruction is used (which makes
the test pass too).
My suggestion: don't use the fsgl variants of the mul and div instructions,
not even for single precision floats. Or at least have a flag like the Alpha
or Intel have for strict IEEE results. I'd prefer the former though.

Kars.
-- 
------------------------------------------------------------------------------
Kars de Jong             Signaalkamp rules the waves!       Turrican@Discworld
--------======]**-----|      jongk@cs.utwente.nl      |-----**[======---------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]