From: Matthew Malcomson Date: Thu, 7 Nov 2019 17:01:04 +0000 (+0000) Subject: [Patch][binutils] Generic support for parsing numbers in bfloat16 format [5/X] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c96f148b7bcaad8b6f1191faafbcd6c8cfdee7a3;p=binutils-gdb.git [Patch][binutils] Generic support for parsing numbers in bfloat16 format [5/X] Hi, This patch is part of a series that adds support for Armv8.6-A (Matrix Multiply and BFloat16 extensions). This patch contains some general refactoring of the atof_ieee function, exposing a function that allows a higher level of control over the format of IEEE-like floating point numbers. This has been done in order to be able to add a directive for assembling floating point literals in the bfloat16 format in the following patches. Committed on behalf of Mihail Ionescu. Tested on arm-none-eabi, arm-none-linux-gnueabihf, aarch64-none-elf and aarch64-none-linux-gnuwith no issues. gas/ChangeLog: 2019-10-21 Mihail Ionescu 2019-10-21 Barnaby Wilks * 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 control over generating IEEE-like numbers. Is it ok for trunk? Regards, Mihail --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 57ee5cd1795..3b94f2975a0 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2019-11-07 Mihail Ionescu +2019-11-07 Barnaby Wilks + + * 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 + control over generating IEEE-like numbers. + 2019-11-07 Mihail Ionescu 2019-11-07 Matthew Malcomson diff --git a/gas/as.h b/gas/as.h index 5b604a45342..d996697bed8 100644 --- a/gas/as.h +++ b/gas/as.h @@ -484,6 +484,7 @@ char * app_push (void); #define MAX_LITTLENUMS 6 char * atof_ieee (char *, int, LITTLENUM_TYPE *); +char * atof_ieee_detail (char *, int, int, LITTLENUM_TYPE *, FLONUM_TYPE *); const char * ieee_md_atof (int, char *, int *, bfd_boolean); const char * vax_md_atof (int, char *, int *); char * input_scrub_include_file (const char *, char *); diff --git a/gas/config/atof-ieee.c b/gas/config/atof-ieee.c index 944c8a46ff4..03f90bea75d 100644 --- a/gas/config/atof-ieee.c +++ b/gas/config/atof-ieee.c @@ -146,29 +146,30 @@ make_invalid_floating_point_number (LITTLENUM_TYPE *words) words[4] = (LITTLENUM_TYPE) -1; words[5] = (LITTLENUM_TYPE) -1; } - -/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to - figure out any alignment problems and to conspire for the - bytes/word to be emitted in the right order. Bigendians beware! */ -/* Note that atof-ieee always has X and P precisions enabled. it is up - to md_atof to filter them out if the target machine does not support - them. */ +/* Build a floating point constant at str into a IEEE floating + point number. This function does the same thing as atof_ieee + however it allows more control over the exact format, i.e. + explicitly specifying the precision and number of exponent bits + instead of relying on this infomation being deduced from a given type. -/* Returns pointer past text consumed. */ + If generic_float_info is not NULL then it will be set to contain generic + infomation about the parsed floating point number. + Returns pointer past text consumed. */ char * -atof_ieee (char *str, /* Text to convert to binary. */ - int what_kind, /* 'd', 'f', 'x', 'p'. */ - LITTLENUM_TYPE *words) /* Build the binary here. */ +atof_ieee_detail (char * str, + int precision, + int exponent_bits, + LITTLENUM_TYPE * words, + FLONUM_TYPE * generic_float_info) { /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are zeroed, the last contain flonum bits. */ static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD]; char *return_value; + /* Number of 16-bit words in the format. */ - int precision; - long exponent_bits; FLONUM_TYPE save_gen_flonum; /* We have to save the generic_floating_point_number because it @@ -189,6 +190,45 @@ atof_ieee (char *str, /* Text to convert to binary. */ memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION); + generic_floating_point_number.high + = generic_floating_point_number.low + precision - 1 + GUARD; + + if (atof_generic (&return_value, ".", EXP_CHARS, + &generic_floating_point_number)) + { + make_invalid_floating_point_number (words); + return NULL; + } + + if (generic_float_info) + *generic_float_info = generic_floating_point_number; + + gen_to_words (words, precision, exponent_bits); + + /* Restore the generic_floating_point_number's storage alloc (and + everything else). */ + generic_floating_point_number = save_gen_flonum; + + return return_value; +} + +/* Warning: This returns 16-bit LITTLENUMs. It is up to the caller to + figure out any alignment problems and to conspire for the + bytes/word to be emitted in the right order. Bigendians beware! */ + +/* Note that atof-ieee always has X and P precisions enabled. it is up + to md_atof to filter them out if the target machine does not support + them. */ + +/* Returns pointer past text consumed. */ +char * +atof_ieee (char *str, /* Text to convert to binary. */ + int what_kind, /* 'd', 'f', 'x', 'p'. */ + LITTLENUM_TYPE *words) /* Build the binary here. */ +{ + int precision; + long exponent_bits; + switch (what_kind) { case 'h': @@ -232,22 +272,7 @@ atof_ieee (char *str, /* Text to convert to binary. */ return (NULL); } - generic_floating_point_number.high - = generic_floating_point_number.low + precision - 1 + GUARD; - - if (atof_generic (&return_value, ".", EXP_CHARS, - &generic_floating_point_number)) - { - make_invalid_floating_point_number (words); - return NULL; - } - gen_to_words (words, precision, exponent_bits); - - /* Restore the generic_floating_point_number's storage alloc (and - everything else). */ - generic_floating_point_number = save_gen_flonum; - - return return_value; + return atof_ieee_detail (str, precision, exponent_bits, words, NULL); } /* Turn generic_floating_point_number into a real float/double/extended. */