[Patch][binutils][arm] .bfloat16 directive for Arm [6/10]

Mihail Ionescu mihail.ionescu@foss.arm.com
Wed Nov 6 16:16:00 GMT 2019


Hi,

Small test fix for arm-wince-pe targets.

Regards,
Mihail

On 10/29/2019 03:20 PM, Mihail Ionescu wrote:
> 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.
> 
> 
> 
> gas/ChangeLog:
> 
> 2019-10-29  Mihail Ionescu  <mihail.ionescu@arm.com>
> 2019-10-29  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
> 
> 
> ###############     Attachment also inlined for ease of reply    ###############
> 
> 
> diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
> index 44502837b0dc29c46117d05a54d44541835e10b2..ef2e190688d40587c570db76af30d77eca56c408 100644
> --- a/gas/config/tc-arm.c
> +++ b/gas/config/tc-arm.c
> @@ -1217,6 +1217,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':
> @@ -5086,6 +5132,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
> index 0000000000000000000000000000000000000000..5ae06f6a7035c7042dc0ed9824d667292d4fca0c
> --- /dev/null
> +++ b/gas/testsuite/gas/arm/bfloat16-directive-be.d
> @@ -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 c000               .*
> diff --git a/gas/testsuite/gas/arm/bfloat16-directive-le.d b/gas/testsuite/gas/arm/bfloat16-directive-le.d
> new file mode 100644
> index 0000000000000000000000000000000000000000..d3ec16c52cc6e9192723aac545505bb0e49a674d
> --- /dev/null
> +++ b/gas/testsuite/gas/arm/bfloat16-directive-le.d
> @@ -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 00c0               .*
> diff --git a/gas/testsuite/gas/arm/bfloat16-directive.s b/gas/testsuite/gas/arm/bfloat16-directive.s
> new file mode 100644
> index 0000000000000000000000000000000000000000..66e17e4fc7da9b08098a0ca03660df2b5ab4f021
> --- /dev/null
> +++ b/gas/testsuite/gas/arm/bfloat16-directive.s
> @@ -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
> 


-------------- next part --------------
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index fb10f0b510f84b92b7cf58ac9091bf9667607ad0..120493791da669d4df230b1cff0bfb6476e732a9 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -1217,6 +1217,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':
@@ -5087,6 +5133,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
index 0000000000000000000000000000000000000000..8862f8302f7f101715a032614c1a6d2c4e3cf5a9
--- /dev/null
+++ b/gas/testsuite/gas/arm/bfloat16-directive-be.d
@@ -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
index 0000000000000000000000000000000000000000..da94b6b254c5b7889b0690535bea464e8c83bbf9
--- /dev/null
+++ b/gas/testsuite/gas/arm/bfloat16-directive-le.d
@@ -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
index 0000000000000000000000000000000000000000..bffba758303f0209a55ebaf1b4bfe78d5df1568c
--- /dev/null
+++ b/gas/testsuite/gas/arm/bfloat16-directive.s
@@ -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




More information about the Binutils mailing list