x86/ELF: fix .tfloat output
authorJan Beulich <jbeulich@suse.com>
Wed, 11 Aug 2021 06:30:26 +0000 (08:30 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 11 Aug 2021 06:30:26 +0000 (08:30 +0200)
The ELF psABI-s are quite clear here: On 32-bit the data type is 12
bytes long (with 2 bytes of trailing padding), while on 64-bit it is 16
bytes long (with 6 bytes of padding). Make ieee_md_atof() capable of
handling such padding, and specify the needed padding for x86 (leaving
non-ELF targets alone for now). Split the existing x86 testcase.

gas/config/atof-ieee.c
gas/config/tc-i386.c
gas/config/tc-i386.h
gas/testsuite/gas/i386/fp-elf32.d [new file with mode: 0644]
gas/testsuite/gas/i386/fp-elf64.d [new file with mode: 0644]
gas/testsuite/gas/i386/fp.s
gas/testsuite/gas/i386/i386.exp

index fa988aa36ee1fa577b342fa707c45a7ff9d47159..e6e8879b51bd6b2362eb893e0e095552d263ea85 100644 (file)
@@ -30,7 +30,13 @@ extern FLONUM_TYPE generic_floating_point_number;
 #define F_PRECISION    2
 #define D_PRECISION    4
 #define X_PRECISION    5
+#ifndef X_PRECISION_PAD
+#define X_PRECISION_PAD 0
+#endif
 #define P_PRECISION    5
+#ifndef P_PRECISION_PAD
+#define P_PRECISION_PAD X_PRECISION_PAD
+#endif
 
 /* Length in LittleNums of guard bits.  */
 #define GUARD          2
@@ -760,7 +766,7 @@ ieee_md_atof (int type,
   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   LITTLENUM_TYPE *wordP;
   char *t;
-  int prec = 0;
+  int prec = 0, pad = 0;
 
   if (strchr (FLT_CHARS, type) != NULL)
     {
@@ -788,6 +794,7 @@ ieee_md_atof (int type,
        case 't':
        case 'T':
          prec = X_PRECISION;
+         pad = X_PRECISION_PAD;
          type = 'x';           /* This is what atof_ieee() understands.  */
          break;
 
@@ -803,6 +810,7 @@ ieee_md_atof (int type,
 #else
          prec = P_PRECISION;
 #endif
+         pad = P_PRECISION_PAD;
          break;
 
        default:
@@ -835,7 +843,7 @@ ieee_md_atof (int type,
   if (t)
     input_line_pointer = t;
 
-  *sizeP = prec * sizeof (LITTLENUM_TYPE);
+  *sizeP = (prec + pad) * sizeof (LITTLENUM_TYPE);
 
   if (big_wordian)
     {
@@ -854,5 +862,8 @@ ieee_md_atof (int type,
        }
     }
 
+  memset (litP, 0, pad * sizeof (LITTLENUM_TYPE));
+  litP += pad * sizeof (LITTLENUM_TYPE);
+
   return NULL;
 }
index cdc660f79a4469ee42d3ddcedc7519b1ccba3ce8..0fa8b0d5a045bc64579de7362408d6bc70534d66 100644 (file)
@@ -10229,6 +10229,19 @@ x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len,
   fix_new_exp (frag, off, len, exp, 0, r);
 }
 
+/* Return the number of padding LITTLENUMs following a tbyte floating
+   point value.  */
+
+int
+x86_tfloat_pad (void)
+{
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+   if (IS_ELF)
+     return object_64bit ? 3 : 1;
+#endif
+   return 0;
+}
+
 /* Export the ABI address size for use by TC_ADDRESS_BYTES for the
    purpose of the `.dc.a' internal pseudo-op.  */
 
index 90d23da7d91b480e41a538924d128baa96cf5034..f94226edf7862a3422a0d518beedbdf8e7da34ae 100644 (file)
@@ -134,6 +134,9 @@ extern bfd_reloc_code_real_type x86_cons (expressionS *, int);
 extern void x86_cons_fix_new
 (fragS *, unsigned int, unsigned int, expressionS *, bfd_reloc_code_real_type);
 
+#define X_PRECISION_PAD x86_tfloat_pad ()
+extern int x86_tfloat_pad (void);
+
 #define TC_ADDRESS_BYTES x86_address_bytes
 extern int x86_address_bytes (void);
 
diff --git a/gas/testsuite/gas/i386/fp-elf32.d b/gas/testsuite/gas/i386/fp-elf32.d
new file mode 100644 (file)
index 0000000..6ef9c83
--- /dev/null
@@ -0,0 +1,12 @@
+#objdump: -s -j .data
+#name: i386 fp (ELF)
+#source: fp.s
+
+.*:     file format .*
+
+Contents of section .data:
+ 0000 00881bcd 4b789ad4 00400000 71a37909  .*
+ 0010 4f930a40 789a5440 789a5440 00000000  .*
+ 0020 e65e1710 20395e3b e65e1710 20395e3b  .*
+ 0030 00000000 0000a044 01000000 0000a044  .*
+ 0040 00000000 0000f03f .*
diff --git a/gas/testsuite/gas/i386/fp-elf64.d b/gas/testsuite/gas/i386/fp-elf64.d
new file mode 100644 (file)
index 0000000..2e68ac8
--- /dev/null
@@ -0,0 +1,12 @@
+#objdump: -s -j .data
+#name: x86-64 fp (ELF)
+#source: fp.s
+
+.*:     file format .*
+
+Contents of section .data:
+ 0000 00881bcd 4b789ad4 00400000 00000000  .*
+ 0010 71a37909 4f930a40 789a5440 789a5440  .*
+ 0020 e65e1710 20395e3b e65e1710 20395e3b  .*
+ 0030 00000000 0000a044 01000000 0000a044  .*
+ 0040 00000000 0000f03f .*
index 11a50cf268365d521073e20dfc6431a69ecd1a97..fca56f29ac160366653ecb78eacc325fe8fa9b91 100644 (file)
@@ -7,10 +7,10 @@
 #      .byte 0x71, 0xa3, 0x79, 0x09, 0x4f, 0x93, 0x0a, 0x40
 # The next two are 32-bit floating point format.
        .float 3.32192809488736218171e0
-#      .byte 0x78, 0x9a, 0x54, 0x40, 0, 0, 0, 0
+#      .byte 0x78, 0x9a, 0x54, 0x40
        .single 3.32192809488736218171e0
-#      .byte 0x78, 0x9a, 0x54, 0x40, 0, 0, 0, 0
-       .byte 0, 0, 0, 0, 0, 0
+#      .byte 0x78, 0x9a, 0x54, 0x40
+       .p2align 4,0
 
 # The assembler used to treat the next value as zero instead of 1e-22.
         .double .0000000000000000000001
index 3464bc2702be481377ad3c3da2f17af6e3d3ffcd..122da6a2315b1c4bf55ee49f4247047a6886fff1 100644 (file)
@@ -118,7 +118,6 @@ if [gas_32_check] then {
     run_list_test "lockbad-1" "-al"
     run_dump_test "long-1"
     run_dump_test "long-1-intel"
-    run_dump_test "fp"
     run_dump_test "nops"
     run_dump_test "nops16-1"
     run_dump_test "nops-1"
@@ -624,6 +623,7 @@ if [gas_32_check] then {
        run_dump_test "intel-movs16"
        run_dump_test "intel-cmps32"
        run_dump_test "intel-cmps16"
+       run_dump_test "fp-elf32"
        run_list_test "inval-equ-1" "-al"
        run_list_test "inval-equ-2" "-al"
        run_dump_test "ifunc"
@@ -697,6 +697,8 @@ if [gas_32_check] then {
            run_dump_test "iamcu-5"
            run_list_test "iamcu-inval-1" "-march=iamcu -al"
        }
+    } else {
+       run_dump_test "fp"
     }
 
     # This is a PE specific test.
@@ -1274,6 +1276,7 @@ if [gas_64_check] then {
        run_list_test "reloc64" "--defsym _bad_=1"
        run_dump_test "mixed-mode-reloc64"
        run_dump_test "rela"
+       run_dump_test "fp-elf64"
        run_dump_test "x86-64-ifunc"
        run_dump_test "x86-64-opcode-inval"
        run_dump_test "x86-64-opcode-inval-intel"