diff options
author | Matthew Malcomson <matthew.malcomson@arm.com> | 2019-11-07 17:03:54 +0000 |
---|---|---|
committer | Matthew Malcomson <matthew.malcomson@arm.com> | 2019-11-07 17:03:54 +0000 |
commit | 27cce8667f5c897751bb10d7c859b02b0bb26291 (patch) | |
tree | 6446644127a180b49c1171e4188a3be68d5e14f7 /gas | |
parent | c96f148b7bcaad8b6f1191faafbcd6c8cfdee7a3 (diff) | |
download | gdb-27cce8667f5c897751bb10d7c859b02b0bb26291.zip gdb-27cce8667f5c897751bb10d7c859b02b0bb26291.tar.gz gdb-27cce8667f5c897751bb10d7c859b02b0bb26291.tar.bz2 |
[Patch][binutils][arm] .bfloat16 directive for Arm [6/X]
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
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 8 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 47 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/bfloat16-directive-be.d | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/bfloat16-directive-le.d | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/bfloat16-directive.s | 19 |
5 files changed, 96 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 3b94f29..ce2bfdc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,6 +1,14 @@ 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> + * as.h (atof_ieee_detail): Add prototype for atof_ieee_detail function. (atof_ieee): Move some code into the atof_ieee_detail function. (atof_ieee_detail): Add function that provides a higher level of diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 8436b32..1d735a7 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -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 index 0000000..8862f83 --- /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 0000000..da94b6b --- /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 0000000..bffba75 --- /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 |