[04/11] x86/ELF: fix .tfloat output with hex input

Message ID 71ac91ea-b59c-3d01-b848-ef4f8cad185d@suse.com
State New
Headers show
Series
  • gas: adjustments to floating point data directives handling
Related show

Commit Message

Paul Hua via Binutils July 23, 2021, 6:54 a.m.
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 hex_float() capable of
handling such padding.

Note that this brings the emitted data size of .dc.x / .dcb.x in line
also for non-ELF targets; so far they were different depending on input
format (dec vs hex).

Extend the existing x86 testcases.
---
There's an anomaly with how hex float values may be specified:
read.c:parse_one_float() treats the 0<alpha> prefix as optional, but
one can't uniformly omit it:

	.tfloat 0x:0123, :0123

is okay, but

	.tfloat :0123, :0123

gets read as

.tfloat: 0123, :0123

(i.e. a label instead of the directive).

Comments

Paul Hua via Binutils July 23, 2021, 1:17 p.m. | #1
On Thu, Jul 22, 2021 at 11:54 PM Jan Beulich <jbeulich@suse.com> wrote:
>

> 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 hex_float() capable of

> handling such padding.

>

> Note that this brings the emitted data size of .dc.x / .dcb.x in line

> also for non-ELF targets; so far they were different depending on input

> format (dec vs hex).

>

> Extend the existing x86 testcases.


The x86 part is OK.  Thanks.

> ---

> There's an anomaly with how hex float values may be specified:

> read.c:parse_one_float() treats the 0<alpha> prefix as optional, but

> one can't uniformly omit it:

>

>         .tfloat 0x:0123, :0123

>

> is okay, but

>

>         .tfloat :0123, :0123

>

> gets read as

>

> .tfloat: 0123, :0123

>

> (i.e. a label instead of the directive).

>

> --- a/gas/read.c

> +++ b/gas/read.c

> @@ -4847,7 +4847,7 @@ parse_repeat_cons (expressionS *exp, uns

>  static int

>  hex_float (int float_type, char *bytes)

>  {

> -  int length;

> +  int length, pad = 0;

>    int i;

>

>    switch (float_type)

> @@ -4868,12 +4868,22 @@ hex_float (int float_type, char *bytes)

>

>      case 'x':

>      case 'X':

> -      length = 12;

> +#ifdef X_PRECISION

> +      length = X_PRECISION * sizeof (LITTLENUM_TYPE);

> +      pad = X_PRECISION_PAD * sizeof (LITTLENUM_TYPE);

> +      if (!length)

> +#endif

> +       length = 12;

>        break;

>

>      case 'p':

>      case 'P':

> -      length = 12;

> +#ifdef P_PRECISION

> +      length = P_PRECISION * sizeof (LITTLENUM_TYPE);

> +      pad = P_PRECISION_PAD * sizeof (LITTLENUM_TYPE);

> +      if (!length)

> +#endif

> +       length = 12;

>        break;

>

>      default:

> @@ -4926,7 +4936,9 @@ hex_float (int float_type, char *bytes)

>         memset (bytes, 0, length - i);

>      }

>

> -  return length;

> +  memset (bytes + length, 0, pad);

> +

> +  return length + pad;

>  }

>

>  /*                     float_cons()

> --- a/gas/testsuite/gas/i386/fp-elf32.d

> +++ b/gas/testsuite/gas/i386/fp-elf32.d

> @@ -11,3 +11,6 @@ Contents of section .data:

>   0030 00000000 0000a044 01000000 0000a044  .*

>   0040 00000000 0000f03f 00000000 00000000  .*

>   0050 ffffffff ffffffff ffffffff cccccccc  .*

> + 0060 00000000 00000080 fe3f0000 00000000  .*

> + 0070 00000080 fdbf0000 00000000 00000080  .*

> + 0080 ff030000 aaaaaaaa aaaaaaaa aaaaaaaa  .*

> --- a/gas/testsuite/gas/i386/fp-elf64.d

> +++ b/gas/testsuite/gas/i386/fp-elf64.d

> @@ -11,3 +11,6 @@ Contents of section .data:

>   0030 00000000 0000a044 01000000 0000a044  .*

>   0040 00000000 0000f03f 00000000 00000000  .*

>   0050 ffffffff ffffffff ffffffff ffffffff  .*

> + 0060 00000000 00000080 fe3f0000 00000000  .*

> + 0070 00000000 00000080 fdbf0000 00000000  .*

> + 0080 00000000 00000080 ff030000 00000000  .*

> --- a/gas/testsuite/gas/i386/fp.d

> +++ b/gas/testsuite/gas/i386/fp.d

> @@ -10,3 +10,5 @@ Contents of section .data:

>   0030 00000000 0000a044 01000000 0000a044  .*

>   0040 00000000 0000f03f 00000000 00000000  .*

>   0050 ffffffff ffffffff ffffcccc cccccccc  .*

> + 0060 00000000 00000080 fe3f0000 00000000  .*

> + 0070 0080fdbf 00000000 00000080 ff03aaaa  .*

> --- a/gas/testsuite/gas/i386/fp.s

> +++ b/gas/testsuite/gas/i386/fp.s

> @@ -24,3 +24,8 @@

>

>         .ds.x 1, -1

>         .p2align 4,0xcc

> +

> +       .tfloat 0x:3ffe80

> +       .dc.x 0x:bffd80

> +       .dcb.x 1, 0x:03ff80

> +       .p2align 4,0xaa

>



-- 
H.J.

Patch

--- a/gas/read.c
+++ b/gas/read.c
@@ -4847,7 +4847,7 @@  parse_repeat_cons (expressionS *exp, uns
 static int
 hex_float (int float_type, char *bytes)
 {
-  int length;
+  int length, pad = 0;
   int i;
 
   switch (float_type)
@@ -4868,12 +4868,22 @@  hex_float (int float_type, char *bytes)
 
     case 'x':
     case 'X':
-      length = 12;
+#ifdef X_PRECISION
+      length = X_PRECISION * sizeof (LITTLENUM_TYPE);
+      pad = X_PRECISION_PAD * sizeof (LITTLENUM_TYPE);
+      if (!length)
+#endif
+	length = 12;
       break;
 
     case 'p':
     case 'P':
-      length = 12;
+#ifdef P_PRECISION
+      length = P_PRECISION * sizeof (LITTLENUM_TYPE);
+      pad = P_PRECISION_PAD * sizeof (LITTLENUM_TYPE);
+      if (!length)
+#endif
+	length = 12;
       break;
 
     default:
@@ -4926,7 +4936,9 @@  hex_float (int float_type, char *bytes)
 	memset (bytes, 0, length - i);
     }
 
-  return length;
+  memset (bytes + length, 0, pad);
+
+  return length + pad;
 }
 
 /*			float_cons()
--- a/gas/testsuite/gas/i386/fp-elf32.d
+++ b/gas/testsuite/gas/i386/fp-elf32.d
@@ -11,3 +11,6 @@  Contents of section .data:
  0030 00000000 0000a044 01000000 0000a044  .*
  0040 00000000 0000f03f 00000000 00000000  .*
  0050 ffffffff ffffffff ffffffff cccccccc  .*
+ 0060 00000000 00000080 fe3f0000 00000000  .*
+ 0070 00000080 fdbf0000 00000000 00000080  .*
+ 0080 ff030000 aaaaaaaa aaaaaaaa aaaaaaaa  .*
--- a/gas/testsuite/gas/i386/fp-elf64.d
+++ b/gas/testsuite/gas/i386/fp-elf64.d
@@ -11,3 +11,6 @@  Contents of section .data:
  0030 00000000 0000a044 01000000 0000a044  .*
  0040 00000000 0000f03f 00000000 00000000  .*
  0050 ffffffff ffffffff ffffffff ffffffff  .*
+ 0060 00000000 00000080 fe3f0000 00000000  .*
+ 0070 00000000 00000080 fdbf0000 00000000  .*
+ 0080 00000000 00000080 ff030000 00000000  .*
--- a/gas/testsuite/gas/i386/fp.d
+++ b/gas/testsuite/gas/i386/fp.d
@@ -10,3 +10,5 @@  Contents of section .data:
  0030 00000000 0000a044 01000000 0000a044  .*
  0040 00000000 0000f03f 00000000 00000000  .*
  0050 ffffffff ffffffff ffffcccc cccccccc  .*
+ 0060 00000000 00000080 fe3f0000 00000000  .*
+ 0070 0080fdbf 00000000 00000080 ff03aaaa  .*
--- a/gas/testsuite/gas/i386/fp.s
+++ b/gas/testsuite/gas/i386/fp.s
@@ -24,3 +24,8 @@ 
 
 	.ds.x 1, -1
 	.p2align 4,0xcc
+
+	.tfloat 0x:3ffe80
+	.dc.x 0x:bffd80
+	.dcb.x 1, 0x:03ff80
+	.p2align 4,0xaa