From eb5bbc482128b08d2ee8a2470951a74d8351146f Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Thu, 7 Nov 2019 17:07:32 +0000 Subject: [PATCH] [Patch][binutils][aarch64] .bfloat16 directive for AArch64 [7/10] 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 '.bfloat' directive for the AArch64 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 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 aarch64-none-elf and aarch64-none-linux-gnu with no issues. Committed on behalf of Mihail Ionescu. gas/ChangeLog: 2019-10-29 Mihail Ionescu 2019-10-29 Barnaby Wilks * config/tc-aarch64.c (md_atof): Add encoding for the bfloat16 format. * testsuite/gas/aarch64/bfloat16-directive-le.d: New test. * testsuite/gas/aarch64/bfloat16-directive-be.d: New test. * testsuite/gas/aarch64/bfloat16-directive.s: New test. Is it ok for trunk? Regards, Mihail --- gas/ChangeLog | 8 +++ gas/config/tc-aarch64.c | 49 +++++++++++++++++++ .../gas/aarch64/bfloat16-directive-be.d | 11 +++++ .../gas/aarch64/bfloat16-directive-le.d | 11 +++++ .../gas/aarch64/bfloat16-directive.s | 19 +++++++ 5 files changed, 98 insertions(+) create mode 100644 gas/testsuite/gas/aarch64/bfloat16-directive-be.d create mode 100644 gas/testsuite/gas/aarch64/bfloat16-directive-le.d create mode 100644 gas/testsuite/gas/aarch64/bfloat16-directive.s diff --git a/gas/ChangeLog b/gas/ChangeLog index ce2bfdc0d35..97054cc3f42 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2019-11-07 Mihail Ionescu +2019-11-07 Barnaby Wilks + + * config/tc-aarch64.c (md_atof): Add encoding for the bfloat16 format. + * testsuite/gas/aarch64/bfloat16-directive-le.d: New test. + * testsuite/gas/aarch64/bfloat16-directive-be.d: New test. + * testsuite/gas/aarch64/bfloat16-directive.s: New test. + 2019-11-07 Mihail Ionescu 2019-11-07 Barnaby Wilks diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 527d8590ca7..eea863b9a43 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -635,6 +635,54 @@ my_get_expression (expressionS * ep, char **str, int prefix_mode, const char * md_atof (int type, char *litP, int *sizeP) { + /* If this is a bfloat16 type, then parse it slightly differently - + as it does not follow the IEEE standard exactly. */ + if (type == 'b') + { + char * t; + LITTLENUM_TYPE words[MAX_LITTLENUMS]; + 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. + Chose 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; + } + return ieee_md_atof (type, litP, sizeP, target_big_endian); } @@ -2107,6 +2155,7 @@ const pseudo_typeS md_pseudo_table[] = { {"variant_pcs", s_variant_pcs, 0}, #endif {"float16", float_cons, 'h'}, + {"bfloat16", float_cons, 'b'}, {0, 0, 0} }; diff --git a/gas/testsuite/gas/aarch64/bfloat16-directive-be.d b/gas/testsuite/gas/aarch64/bfloat16-directive-be.d new file mode 100644 index 00000000000..132d04e44fa --- /dev/null +++ b/gas/testsuite/gas/aarch64/bfloat16-directive-be.d @@ -0,0 +1,11 @@ +# name: Big endian bfloat16 literal directives +# source: bfloat16-directive.s +# as: -mbig-endian +# objdump: -s --section=.data + +.*: +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/aarch64/bfloat16-directive-le.d b/gas/testsuite/gas/aarch64/bfloat16-directive-le.d new file mode 100644 index 00000000000..f22d610d84b --- /dev/null +++ b/gas/testsuite/gas/aarch64/bfloat16-directive-le.d @@ -0,0 +1,11 @@ +# name: Little endian bfloat16 literal directives +# source: bfloat16-directive.s +# as: -mlittle-endian +# objdump: -s --section=.data + +.*: +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/aarch64/bfloat16-directive.s b/gas/testsuite/gas/aarch64/bfloat16-directive.s new file mode 100644 index 00000000000..66e17e4fc7d --- /dev/null +++ b/gas/testsuite/gas/aarch64/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 -- 2.30.2