gcc code generation problems

Peter Jeremy peterjeremy at acm.org
Mon Mar 8 19:03:11 UTC 2010

On 2010-Mar-01 06:23:30 +1100, Peter Jeremy <peterjeremy at acm.org> wrote:
>The correct answer is '53', but if optimisation is enabled, I'm
>getting '51' instead.  Disabling the printf() and/or using
>-fno-strict-aliasing has no effect.
>$ cc -DXXX -O tryfp.c; ./a.out
>a 4503599627370495 != 0
>$ cc -DXXX -O2 tryfp.c; ./a.out
>a 4503599627370495 != 0
>$ cc -DXXX tryfp.c; ./a.out
>a 18014398509481983 != 18014398509481984

I've done a bit more investigating and come to the conclusion that the
FP emulation code for fxtod is trashing %f12.  The problem does not
exist on OpenSolaris.  On FreeBSD, gcc expands a double to unsigned
long cast to:

	if (d >= (double)(1UL << 63)) {
		ul = (1UL << 63) ^ (long)(d - (double)(1UL << 63));
	} else {
		ul = (long)d;

In the sample code, gcc calculates (double)(1UL << 63) at the top of
the function and stores it in %f12.  Somehow, this register turns into
0 on the 51st iteration, though nothing updates it.  If I pick a
different unused register (I've tried %f16, %f24 and %f32) then the
code works.  The "UltraSPARC IIIi Processor User's Manual", indicates
that fxtod will trap for operands >= 2^51 (fdtox will trap for
operands >= 2^53 and is therefore executed in hardware) which seems to
point the finger at the FP emulation code in the userland trap handler.

I am still looking into the emulation code.

Peter Jeremy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-sparc64/attachments/20100308/1a98192f/attachment.pgp

More information about the freebsd-sparc64 mailing list