After doing google search for "gcc 7fa00000" I have found the bug 57484 in GCC's bugzilla http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57484 with several useful comments.
Uroš Bizjak (i386 cpu port maintainer in GCC) says in comments 11,12,14 and in last one, that x86 ABI and x86-32 ABI are not designed to fully support IEEE754 standard on x87 and the "issue is unfortunately unfixable":
The ABI is just wrong for the underlying x87 hardware as far as NaNs are concerned.
This issue is unfortunately unfixable. x87 and x86-32 ABI are just not designed to handle all details of IEEE 754 standard.
According to Uroš, when using legacy x87 on x86 gcc target, loads of float and doubles from memory to the x87 FP registers (stack) is considered as format conversion with changing of signaling NANs (sNAN) into quiet NANs (qNAN). The -msse2 -mfpmath=sse
option set will help to do all math evaluations in SSE2, but function still returns FP value via x87 stack:
$ gcc-4.6.3 -msse2 -mfpmath=sse test.c -o sse2math.out
$ objdump -d sse2math.out
./c.out: file format elf32-i386
...
08048404 <func>:
8048404: 55 push %ebp
8048405: 89 e5 mov %esp,%ebp
8048407: 83 ec 04 sub $0x4,%esp
804840a: a1 14 a0 04 08 mov 0x804a014,%eax
804840f: 89 45 fc mov %eax,-0x4(%ebp)
8048412: f3 0f 10 45 fc movss -0x4(%ebp),%xmm0
8048417: f3 0f 11 45 fc movss %xmm0,-0x4(%ebp)
804841c: d9 45 fc flds -0x4(%ebp)
804841f: c9 leave
8048420: c3 ret
After adding one more option -mno-fp-ret-in-387
(full set is -msse2 -mfpmath=sse -mno-fp-ret-in-387
), x87 fp registers are not more used to pass float return:
08048404 <func>:
8048404: 55 push %ebp
8048405: 89 e5 mov %esp,%ebp
8048407: a1 14 a0 04 08 mov 0x804a014,%eax
804840c: 5d pop %ebp
804840d: c3 ret
But the -mno-fp-ret-in-387
option will change ABI, and may broke many libraries.