[Patch][binutils][arm] .bfloat16 directive for Arm [6/X]
authorMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 7 Nov 2019 17:03:54 +0000 (17:03 +0000)
committerMatthew Malcomson <matthew.malcomson@arm.com>
Thu, 7 Nov 2019 17:03:54 +0000 (17:03 +0000)
Hi,

This patch is part of a series that adds support for Armv8.6-A
(Matrix Multiply and BFloat16 extensions) to binutils.

This patch implements the '.bfloat16' directive for the Arm backend.

The syntax for the directive is:
  .bfloat16 <0-n numbers>
e.g.
  .bfloat16 12.0
  .bfloat16 0.123, 1.0, NaN, 5

This is implemented by utilizing the ieee_atof_detail function (included
in the previous patch) in order to encode the slightly different
bfloat16 format.

Added testcases to verify the correct encoding for various bfloat16
values (NaN, Infinity (+ & -), normals, subnormals etc...).

Cross compiled and tested on arm-none-eabi and arm-none-linux-gnueabihf
with no issues.

Committed on behalf of Mihail Ionescu.

gas/ChangeLog:

2019-10-21  Mihail Ionescu  <mihail.ionescu@arm.com>
2019-10-21  Barnaby Wilks  <barnaby.wilks@arm.com>

* config/tc-arm.c (md_atof): Add encoding for bfloat16
* testsuite/gas/arm/bfloat16-directive-le.d: New test.
* testsuite/gas/arm/bfloat16-directive-be.d: New test.
* testsuite/gas/arm/bfloat16-directive.s: New test.

Is it ok for trunk?

Regards,
Mihail

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/gas/arm/bfloat16-directive-be.d [new file with mode: 0644]
gas/testsuite/gas/arm/bfloat16-directive-le.d [new file with mode: 0644]
gas/testsuite/gas/arm/bfloat16-directive.s [new file with mode: 0644]

index 3b94f2975a04b013a6652edd8c2bae3d9f240a24..ce2bfdc0d350cfb83761e025085678f8032f5cf3 100644 (file)
@@ -1,3 +1,11 @@
+2019-11-07  Mihail Ionescu  <mihail.ionescu@arm.com>
+2019-11-07  Barnaby Wilks  <barnaby.wilks@arm.com>
+
+       * config/tc-arm.c (md_atof): Add encoding for bfloat16
+       * testsuite/gas/arm/bfloat16-directive-le.d: New test.
+       * testsuite/gas/arm/bfloat16-directive-be.d: New test.
+       * testsuite/gas/arm/bfloat16-directive.s: New test.
+
 2019-11-07  Mihail Ionescu  <mihail.ionescu@arm.com>
 2019-11-07  Barnaby Wilks  <barnaby.wilks@arm.com>
 
index 8436b32b04fde832bc1b58b1ae506e7463abb718..1d735a731ebbb500dbb6dbdd7393ff851e9d6d86 100644 (file)
@@ -1218,6 +1218,52 @@ md_atof (int type, char * litP, int * sizeP)
       prec = 1;
       break;
 
+    /* If this is a bfloat16, then parse it slightly differently, as it
+       does not follow the IEEE specification for floating point numbers
+       exactly.  */
+    case 'b':
+      {
+       FLONUM_TYPE generic_float;
+
+       t = atof_ieee_detail (input_line_pointer, 1, 8, words, &generic_float);
+
+       if (t)
+         input_line_pointer = t;
+       else
+         return _("invalid floating point number");
+
+       switch (generic_float.sign)
+         {
+         /* Is +Inf.  */
+         case 'P':
+           words[0] = 0x7f80;
+           break;
+
+         /* Is -Inf.  */
+         case 'N':
+           words[0] = 0xff80;
+           break;
+
+         /* Is NaN.  */
+         /* bfloat16 has two types of NaN - quiet and signalling.
+            Quiet NaN has bit[6] == 1 && faction != 0, whereas
+            signalling NaN's have bit[0] == 0 && fraction != 0.
+            Chosen this specific encoding as it is the same form
+            as used by other IEEE 754 encodings in GAS.  */
+         case 0:
+           words[0] = 0x7fff;
+           break;
+
+         default:
+           break;
+         }
+
+       *sizeP = 2;
+
+       md_number_to_chars (litP, (valueT) words[0], sizeof (LITTLENUM_TYPE));
+
+       return NULL;
+      }
     case 'f':
     case 'F':
     case 's':
@@ -5088,6 +5134,7 @@ const pseudo_typeS md_pseudo_table[] =
   { "extend",     float_cons, 'x' },
   { "ldouble",    float_cons, 'x' },
   { "packed",     float_cons, 'p' },
+  { "bfloat16",           float_cons, 'b' },
 #ifdef TE_PE
   {"secrel32", pe_directive_secrel, 0},
 #endif
diff --git a/gas/testsuite/gas/arm/bfloat16-directive-be.d b/gas/testsuite/gas/arm/bfloat16-directive-be.d
new file mode 100644 (file)
index 0000000..8862f83
--- /dev/null
@@ -0,0 +1,11 @@
+# name: Big endian bfloat16 literal directives
+# source: bfloat16-directive.s
+# objdump: -s --section=.data
+# as: -mbig-endian
+
+.*: +file format .*
+
+Contents of section \.data:
+ 0000 41403dfc 000042f7 8000c2f7 7fff7f80  .*
+ 0010 ff807f7f ff7f0080 80800001 8001007f  .*
+ 0020 807f3f80 bf804000 c0000000           .*
diff --git a/gas/testsuite/gas/arm/bfloat16-directive-le.d b/gas/testsuite/gas/arm/bfloat16-directive-le.d
new file mode 100644 (file)
index 0000000..da94b6b
--- /dev/null
@@ -0,0 +1,11 @@
+# name: Little endian bfloat16 literal directives
+# source: bfloat16-directive.s
+# objdump: -s --section=.data
+# as: -mlittle-endian
+
+.*: +file format .*
+
+Contents of section \.data:
+ 0000 4041fc3d 0000f742 0080f7c2 ff7f807f  .*
+ 0010 80ff7f7f 7fff8000 80800100 01807f00  .*
+ 0020 7f80803f 80bf0040 00c00000           .*
diff --git a/gas/testsuite/gas/arm/bfloat16-directive.s b/gas/testsuite/gas/arm/bfloat16-directive.s
new file mode 100644 (file)
index 0000000..bffba75
--- /dev/null
@@ -0,0 +1,19 @@
+.data
+       .bfloat16 12.0
+       .bfloat16 0.123
+       .bfloat16 +0.0
+       .bfloat16 123.4
+       .bfloat16 -0.0
+       .bfloat16 -123.4
+       .bfloat16 NaN
+       .bfloat16 Inf
+       .bfloat16 -Inf
+       .bfloat16 3.390e+38
+       .bfloat16 -3.390e+38
+       .bfloat16 1.175e-38
+       .bfloat16 -1.175e-38
+       .bfloat16 9.194e-41
+       .bfloat16 -9.194e-41
+       .bfloat16 1.167e-38
+       .bfloat16 -1.167e-38
+       .bfloat16 1.0, -1, 2.0, -2, 0