gas: support NaN flavors
authorJan Beulich <jbeulich@suse.com>
Wed, 11 Aug 2021 06:36:28 +0000 (08:36 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 11 Aug 2021 06:36:28 +0000 (08:36 +0200)
Like for infinity, there isn't just a single NaN. The sign bit may be
of interest and, going beyond infinity, whether the value is quiet or
signalling may be even more relevant to be able to encode.

Note that an anomaly with x86'es double extended precision NaN values
gets taken care of at the same time: For all other formats a positive
value with all mantissa bits set was used, while here a negative value
with all non-significant mantissa bits clear was chose for an unknown
reason.

For m68k, since I don't know their X_PRECISION floating point value
layout, a warning gets issued if any of the new flavors was attempted
to be encoded that way. However likely it may be that, given that the
code lives in a source file supposedly implementing IEEE-compliant
formats, the bit patterns of the individual words match x86'es, I didn't
want to guess so. And my very, very old paper doc doesn't even mention
floating point formats other than single and double.

gas/atof-generic.c
gas/config/atof-ieee.c
gas/config/tc-tic4x.c
gas/flonum.h
gas/testsuite/gas/all/float.s
gas/testsuite/gas/i386/fp-elf32.d
gas/testsuite/gas/i386/fp-elf64.d
gas/testsuite/gas/i386/fp.d
gas/testsuite/gas/i386/fp.s

index 91d8aba4814efb06abeadae96e381978b90e1cd2..e93353419e916cbc250051879398708b72d7e792 100644 (file)
@@ -113,11 +113,29 @@ atof_generic (/* return pointer to just AFTER number we read.  */
 
   switch (first_digit[0])
     {
+    case 's':
+    case 'S':
+    case 'q':
+    case 'Q':
+      if (!strncasecmp ("nan", first_digit + 1, 3))
+       {
+         address_of_generic_floating_point_number->sign =
+           digits_sign_char == '+' ? TOUPPER (first_digit[0])
+                                   : TOLOWER (first_digit[0]);
+         address_of_generic_floating_point_number->exponent = 0;
+         address_of_generic_floating_point_number->leader =
+           address_of_generic_floating_point_number->low;
+         *address_of_string_pointer = first_digit + 4;
+         return 0;
+       }
+      break;
+
     case 'n':
     case 'N':
       if (!strncasecmp ("nan", first_digit, 3))
        {
-         address_of_generic_floating_point_number->sign = 0;
+         address_of_generic_floating_point_number->sign =
+           digits_sign_char == '+' ? 0 : 'q';
          address_of_generic_floating_point_number->exponent = 0;
          address_of_generic_floating_point_number->leader =
            address_of_generic_floating_point_number->low;
index 7f95d05d8b0441f878e62032db8e3d59b7ef6c1d..9cf6aced4ab65e637260d8f3507d788385e80987 100644 (file)
@@ -19,6 +19,7 @@
    02110-1301, USA.  */
 
 #include "as.h"
+#include "safe-ctype.h"
 
 /* Flonums returned here.  */
 extern FLONUM_TYPE generic_floating_point_number;
@@ -324,24 +325,34 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
       return return_value;
     }
 
-  /* NaN:  Do the right thing.  */
-  if (generic_floating_point_number.sign == 0)
+  switch (generic_floating_point_number.sign)
     {
+    /* NaN:  Do the right thing.  */
+    case 0:
+    case 'Q': case 'q':
+    case 'S': case 's':
       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
        as_warn (_("NaNs are not supported by this target"));
 
       if (precision == H_PRECISION)
        {
-         words[0] = 0x7fff;
+         if (TOUPPER (generic_floating_point_number.sign) != 'S')
+           words[0] = 0x7fff;
+         else
+           words[0] = exponent_bits == 5 ? 0x7dff : 0x7fbf;
        }
       else if (precision == F_PRECISION)
        {
-         words[0] = 0x7fff;
+         words[0] = TOUPPER (generic_floating_point_number.sign) == 'S'
+                    ? 0x7fbf : 0x7fff;
          words[1] = 0xffff;
        }
       else if (precision == X_PRECISION)
        {
 #ifdef TC_M68K
+         if (generic_floating_point_number.sign)
+           as_warn (_("NaN flavors are not supported by this target"));
+
          words[0] = 0x7fff;
          words[1] = 0;
          words[2] = 0xffff;
@@ -350,11 +361,12 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
          words[5] = 0xffff;
 #else /* ! TC_M68K  */
 #ifdef TC_I386
-         words[0] = 0xffff;
-         words[1] = 0xc000;
-         words[2] = 0;
-         words[3] = 0;
-         words[4] = 0;
+         words[0] = 0x7fff;
+         words[1] = TOUPPER (generic_floating_point_number.sign) == 'S'
+                    ? 0xbfff : 0xffff;
+         words[2] = 0xffff;
+         words[3] = 0xffff;
+         words[4] = 0xffff;
 #else /* ! TC_I386  */
          abort ();
 #endif /* ! TC_I386  */
@@ -362,15 +374,19 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
        }
       else
        {
-         words[0] = 0x7fff;
+         words[0] = TOUPPER (generic_floating_point_number.sign) == 'S'
+                    ? 0x7ff7 : 0x7fff;
          words[1] = 0xffff;
          words[2] = 0xffff;
          words[3] = 0xffff;
        }
+
+      if (ISLOWER (generic_floating_point_number.sign))
+       words[0] |= 0x8000;
+
       return return_value;
-    }
-  else if (generic_floating_point_number.sign == 'P')
-    {
+
+    case 'P':
       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
        as_warn (_("Infinities are not supported by this target"));
 
@@ -413,9 +429,8 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
          words[3] = 0;
        }
       return return_value;
-    }
-  else if (generic_floating_point_number.sign == 'N')
-    {
+
+    case 'N':
       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
        as_warn (_("Infinities are not supported by this target"));
 
index c456dffbbad1f611d7f6ab522195609ac270f2b3..c00121c30badf337e4f5b8c04fd257c4b5ad8b6b 100644 (file)
@@ -384,8 +384,10 @@ tic4x_gen_to_words (FLONUM_TYPE flonum, LITTLENUM_TYPE *words, int precision)
   /* 0.0e0 or NaN seen.  */
   if (flonum.low > flonum.leader  /* = 0.0e0 */
       || flonum.sign == 0) /* = NaN */
+      || flonum.sign == 'Q' || flonum.sign == 'q' /* = QNaN */
+      || flonum.sign == 'S' || flonum.sign == 's' /* = SNaN */
     {
-      if(flonum.sign == 0)
+      if (flonum.sign != '+' && flonum.sign != '-')
         as_bad (_("Nan, using zero."));
       words[0] = 0x8000;
       return return_value;
index 1bb638b2f91c5bb5bc0ad2dd14858c98235794ab..59d582d570e78db286138a5b41f457e3b9ffba05 100644 (file)
 /* JF:  A sign value of 0 means we have been asked to assemble NaN
    A sign value of 'P' means we've been asked to assemble +Inf
    A sign value of 'N' means we've been asked to assemble -Inf
+   A sign value of 'Q' means we've been asked to assemble +QNaN
+   A sign value of 'q' means we've been asked to assemble -QNaN
+   A sign value of 'S' means we've been asked to assemble +SNaN
+   A sign value of 's' means we've been asked to assemble -SNaN
    */
 struct FLONUM_STRUCT {
   LITTLENUM_TYPE *low;         /* low order littlenum of a bignum */
index eabb24c3738f65d5bef04cee12f18535cd897617..f401ed31a842e6db41b7d21c8d8c65fb8a49c8d3 100644 (file)
@@ -7,6 +7,10 @@ foo:   .single 0r1.2345e+06
 
        .dc.s 1
        .dc.s 0f:1234
+       .dc.s Inf
+       .dc.s NaN
+       .dc.s QNaN
+       .dc.s SNaN
        .dcb.s 1
        .dcb.s 1, 1
        .dcb.s 1, 0s:4321
@@ -14,6 +18,10 @@ foo: .single 0r1.2345e+06
 
        .dc.d 1
        .dc.d 0d:1234
+       .dc.d +Inf
+       .dc.d -NaN
+       .dc.d +QNaN
+       .dc.d -SNaN
        .dcb.d 1
        .dcb.d 1, 1
        .dcb.d 1, 0r:4321
index 798cb6b83826ea45592be1eeb44dc90cf4198edf..ac67c2ae7217bb755154277b404a3ff5432be1db 100644 (file)
@@ -15,3 +15,27 @@ Contents of section .data:
  0070 00000080 fdbf0000 00000000 00000080  .*
  0080 ff030000 aaaaaaaa aaaaaaaa aaaaaaaa  .*
  0090 003c00c0 003c803f 00c0803f 55555555  .*
+ 00a0 007c807f 0000807f 00000000 0000f07f  .*
+ 00b0 00000000 00000080 ff7f0000 44444444  .*
+ 00c0 007c807f 0000807f 00000000 0000f07f  .*
+ 00d0 00000000 00000080 ff7f0000 33333333  .*
+ 00e0 00fc80ff 000080ff 00000000 0000f0ff  .*
+ 00f0 00000000 00000080 ffff0000 22222222  .*
+ 0100 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0110 ffffffff ffffffff ff7f0000 44444444  .*
+ 0120 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0130 ffffffff ffffffff ff7f0000 33333333  .*
+ 0140 ffffffff ffffffff ffffffff ffffffff  .*
+ 0150 ffffffff ffffffff ffff0000 22222222  .*
+ 0160 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0170 ffffffff ffffffff ff7f0000 44444444  .*
+ 0180 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0190 ffffffff ffffffff ff7f0000 33333333  .*
+ 01a0 ffffffff ffffffff ffffffff ffffffff  .*
+ 01b0 ffffffff ffffffff ffff0000 22222222  .*
+ 01c0 ff7dbf7f ffffbf7f ffffffff fffff77f  .*
+ 01d0 ffffffff ffffffbf ff7f0000 44444444  .*
+ 01e0 ff7dbf7f ffffbf7f ffffffff fffff77f  .*
+ 01f0 ffffffff ffffffbf ff7f0000 33333333  .*
+ 0200 fffdbfff ffffbfff ffffffff fffff7ff  .*
+ 0210 ffffffff ffffffbf ffff0000 22222222  .*
index fc96e53490f54dca919a32e3a7b1bab51c073f86..2b3b6b8b29ad4b4d1b81e5f9a3817e832f70e21c 100644 (file)
@@ -15,3 +15,27 @@ Contents of section .data:
  0070 00000000 00000080 fdbf0000 00000000  .*
  0080 00000000 00000080 ff030000 00000000  .*
  0090 003c00c0 003c803f 00c0803f 55555555  .*
+ 00a0 007c807f 0000807f 00000000 0000f07f  .*
+ 00b0 00000000 00000080 ff7f0000 00000000  .*
+ 00c0 007c807f 0000807f 00000000 0000f07f  .*
+ 00d0 00000000 00000080 ff7f0000 00000000  .*
+ 00e0 00fc80ff 000080ff 00000000 0000f0ff  .*
+ 00f0 00000000 00000080 ffff0000 00000000  .*
+ 0100 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0110 ffffffff ffffffff ff7f0000 00000000  .*
+ 0120 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0130 ffffffff ffffffff ff7f0000 00000000  .*
+ 0140 ffffffff ffffffff ffffffff ffffffff  .*
+ 0150 ffffffff ffffffff ffff0000 00000000  .*
+ 0160 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0170 ffffffff ffffffff ff7f0000 00000000  .*
+ 0180 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0190 ffffffff ffffffff ff7f0000 00000000  .*
+ 01a0 ffffffff ffffffff ffffffff ffffffff  .*
+ 01b0 ffffffff ffffffff ffff0000 00000000  .*
+ 01c0 ff7dbf7f ffffbf7f ffffffff fffff77f  .*
+ 01d0 ffffffff ffffffbf ff7f0000 00000000  .*
+ 01e0 ff7dbf7f ffffbf7f ffffffff fffff77f  .*
+ 01f0 ffffffff ffffffbf ff7f0000 00000000  .*
+ 0200 fffdbfff ffffbfff ffffffff fffff7ff  .*
+ 0210 ffffffff ffffffbf ffff0000 00000000  .*
index c2db0d25343ccd0b0628189caa8010ef36ac531a..ad0afcd60b8d66b22ed39c047b1db07b522581ca 100644 (file)
@@ -13,3 +13,27 @@ Contents of section .data:
  0060 00000000 00000080 fe3f0000 00000000  .*
  0070 0080fdbf 00000000 00000080 ff03aaaa  .*
  0080 003c00c0 003c803f 00c0803f 55555555  .*
+ 0090 007c807f 0000807f 00000000 0000f07f  .*
+ 00a0 00000000 00000080 ff7f4444 44444444  .*
+ 00b0 007c807f 0000807f 00000000 0000f07f  .*
+ 00c0 00000000 00000080 ff7f3333 33333333  .*
+ 00d0 00fc80ff 000080ff 00000000 0000f0ff  .*
+ 00e0 00000000 00000080 ffff2222 22222222  .*
+ 00f0 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0100 ffffffff ffffffff ff7f4444 44444444  .*
+ 0110 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0120 ffffffff ffffffff ff7f3333 33333333  .*
+ 0130 ffffffff ffffffff ffffffff ffffffff  .*
+ 0140 ffffffff ffffffff ffff2222 22222222  .*
+ 0150 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0160 ffffffff ffffffff ff7f4444 44444444  .*
+ 0170 ff7fff7f ffffff7f ffffffff ffffff7f  .*
+ 0180 ffffffff ffffffff ff7f3333 33333333  .*
+ 0190 ffffffff ffffffff ffffffff ffffffff  .*
+ 01a0 ffffffff ffffffff ffff2222 22222222  .*
+ 01b0 ff7dbf7f ffffbf7f ffffffff fffff77f  .*
+ 01c0 ffffffff ffffffbf ff7f4444 44444444  .*
+ 01d0 ff7dbf7f ffffbf7f ffffffff fffff77f  .*
+ 01e0 ffffffff ffffffbf ff7f3333 33333333  .*
+ 01f0 fffdbfff ffffbfff ffffffff fffff7ff  .*
+ 0200 ffffffff ffffffbf ffff2222 22222222  .*
index 8c5abb490b9825f3b0c1c0495a008a1b677f5457..a63464b6cd2321e7a14edebbe590647db0b20a23 100644 (file)
        .hfloat 1, -2, 0x:3c00
        .bfloat16 1, -2, 0x:3f80
        .p2align 4,0x55
+
+       .hfloat Inf
+       .bfloat16 Inf
+       .single Inf
+       .double Inf
+       .tfloat Inf
+       .p2align 4,0x44
+
+       .hfloat +Inf
+       .bfloat16 +Inf
+       .single +Inf
+       .double +Inf
+       .tfloat +Inf
+       .p2align 4,0x33
+
+       .hfloat -Inf
+       .bfloat16 -Inf
+       .single -Inf
+       .double -Inf
+       .tfloat -Inf
+       .p2align 4,0x22
+
+       .hfloat NaN
+       .bfloat16 NaN
+       .single NaN
+       .double NaN
+       .tfloat NaN
+       .p2align 4,0x44
+
+       .hfloat +NaN
+       .bfloat16 +NaN
+       .single +NaN
+       .double +NaN
+       .tfloat +NaN
+       .p2align 4,0x33
+
+       .hfloat -NaN
+       .bfloat16 -NaN
+       .single -NaN
+       .double -NaN
+       .tfloat -NaN
+       .p2align 4,0x22
+
+       .hfloat QNaN
+       .bfloat16 QNaN
+       .single QNaN
+       .double QNaN
+       .tfloat QNaN
+       .p2align 4,0x44
+
+       .hfloat +QNaN
+       .bfloat16 +QNaN
+       .single +QNaN
+       .double +QNaN
+       .tfloat +QNaN
+       .p2align 4,0x33
+
+       .hfloat -QNaN
+       .bfloat16 -QNaN
+       .single -QNaN
+       .double -QNaN
+       .tfloat -QNaN
+       .p2align 4,0x22
+
+       .hfloat SNaN
+       .bfloat16 SNaN
+       .single SNaN
+       .double SNaN
+       .tfloat SNaN
+       .p2align 4,0x44
+
+       .hfloat +SNaN
+       .bfloat16 +SNaN
+       .single +SNaN
+       .double +SNaN
+       .tfloat +SNaN
+       .p2align 4,0x33
+
+       .hfloat -SNaN
+       .bfloat16 -SNaN
+       .single -SNaN
+       .double -SNaN
+       .tfloat -SNaN
+       .p2align 4,0x22