This is the mail archive of the gcc-help@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]
Other format: [Raw text]

Re: __builtin_isnanl() and invalid x87 80-bit floating point numbers


On 2017/5/13 10:25, Vincent Lefevre wrote:
On 2017-05-12 23:46:09 +0800, Liu Hao wrote:
But if you do this, you're out of scope of the standards.

Moreover, I suppose that you will also get a floating-point exception
on a signaling NaN, in which case, on this example, this isn't
distinguishable from a signaling NaN.
A QNaN doesn't generate an exception regardless of the x87 control word.

To make a QNaN, replace the last three bytes of `data` with `0xc0, 0xff, 0x7f`. The last example would then exit normally with the output 'nan'. I will show an example later.

But the goal of Intel's x87 80-bit format and the IEEE 754-1985 spec
was to regard this format as a conforming double-extended format.
And AFAIK, the intent of IEEE 754-2008 was not to break this.

I don't think ISO C forbids existence of `trap representation` of
`long double`.

Anyway, this is not a trap representation as shown above.
It does generate an exception so why do you think it is not a trap representation?

FXAM is neither an IEEE 754 operation, nor an ISO C operation.

Let's try ==, which corresponds to the IEEE 754 equality operator:

#include <stdio.h>

int main (void)
{
   long double ld = 0;
   unsigned char data[10] = {
     0x5b, 0x01, 0x04, 0x5e, 0x85, 0x00, 0x00, 0x00, 0xd8, 0x59
   };
   __builtin_memcpy(&ld, data, 10);
   printf ("NaN? %s\n", ld == ld ? "no" : "yes");
   return 0;
}

This gives:

NaN? yes

So, it is regarded as a NaN.

Let's try `=` which corresponds to the IEEE 754 equality operator too:

-------------------------------------------------------
lh_mouse@lhmouse-dev:~$ cat test.c
#include <stdio.h>
#include <math.h>

int main (void)
{
   unsigned short fcw;
   __asm__ volatile (
     "fstcw %0; "
     "andw $-2, %0; "
     "fldcw %0; "
     : "=m"(fcw)
   );
   long double ld = 0;
   unsigned char data[10] = {
     0x5b, 0x01, 0x04, 0x5e, 0x85, 0x00, 0x00, 0x00, 0xd8, 0x59
   };
   __builtin_memcpy(&ld, data, 10);
   long double y = 1;
   y = ld;
   printf ("%Lg\n", y);
   return 0;
}
lh_mouse@lhmouse-dev:~$ gcc test.c -Wall -Wextra -pedantic -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out
5.11212e+1984
-------------------------------------------------------

Then replace it with a QNaN:

-------------------------------------------------------
lh_mouse@lhmouse-dev:~$ sed -i 's/0x00, 0xd8, 0x59/0xc0, 0xff, 0x7f/' test.c
lh_mouse@lhmouse-dev:~$ gcc test.c -Wall -Wextra -pedantic -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out
nan
-------------------------------------------------------

Then replace it with a SNaN:

-------------------------------------------------------
lh_mouse@lhmouse-dev:~$ gcc test.c -Wall -Wextra -pedantic -std=c99
lh_mouse@lhmouse-dev:~$ ./a.out
nan
-------------------------------------------------------

So, it is not regarded as a NaN.

--
Best regards,
LH_Mouse


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