205 lines
6.0 KiB
Diff
205 lines
6.0 KiB
Diff
|
|
From e2295dade838ad296e1e1cd1096177058139b6b3 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Jan Beulich <jbeulich@suse.com>
|
||
|
|
Date: Wed, 11 Aug 2021 08:30:26 +0200
|
||
|
|
Subject: [PATCH] x86/ELF: fix .tfloat output
|
||
|
|
|
||
|
|
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.
|
||
|
|
|
||
|
|
diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c
|
||
|
|
index fa988aa36ee..e6e8879b51b 100644
|
||
|
|
--- a/gas/config/atof-ieee.c
|
||
|
|
+++ b/gas/config/atof-ieee.c
|
||
|
|
@@ -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;
|
||
|
|
}
|
||
|
|
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
|
||
|
|
index cdc660f79a4..0fa8b0d5a04 100644
|
||
|
|
--- a/gas/config/tc-i386.c
|
||
|
|
+++ b/gas/config/tc-i386.c
|
||
|
|
@@ -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. */
|
||
|
|
|
||
|
|
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h
|
||
|
|
index 90d23da7d91..f94226edf78 100644
|
||
|
|
--- a/gas/config/tc-i386.h
|
||
|
|
+++ b/gas/config/tc-i386.h
|
||
|
|
@@ -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
|
||
|
|
index 00000000000..6ef9c83ac54
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gas/testsuite/gas/i386/fp-elf32.d
|
||
|
|
@@ -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
|
||
|
|
index 00000000000..2e68ac8ebca
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gas/testsuite/gas/i386/fp-elf64.d
|
||
|
|
@@ -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 .*
|
||
|
|
diff --git a/gas/testsuite/gas/i386/fp.s b/gas/testsuite/gas/i386/fp.s
|
||
|
|
index 11a50cf2683..fca56f29ac1 100644
|
||
|
|
--- a/gas/testsuite/gas/i386/fp.s
|
||
|
|
+++ b/gas/testsuite/gas/i386/fp.s
|
||
|
|
@@ -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
|
||
|
|
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
|
||
|
|
index 3464bc2702b..122da6a2315 100644
|
||
|
|
--- a/gas/testsuite/gas/i386/i386.exp
|
||
|
|
+++ b/gas/testsuite/gas/i386/i386.exp
|
||
|
|
@@ -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"
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|