diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2022-01-10 23:34:56 +0100 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2022-01-10 23:34:56 +0100 |
commit | 8d87dd6069d5bdfab3f611bdb0399c7da5058041 (patch) | |
tree | 4e1376732b5e11edbebb89f893d89fb23cb3f5eb | |
parent | c03cad116dc759347ad5832c2910a72581610a0f (diff) | |
download | gcc-8d87dd6069d5bdfab3f611bdb0399c7da5058041.tar.gz |
Handle R16 conversion for POWER in the environment variables.
This patch handles the environment variables for the REAL(KIND=16)
variables like for the little/big-endian routines, so users without
who have no access to the source or are unwilling to recompile
can use this.
Syntax is, for example
GFORTRAN_CONVERT_UNIT="r16_ieee:10;little_endian:10" ./a.out
libgfortran/ChangeLog:
* runtime/environ.c (R16_IEEE): New macro.
(R16_IBM): New macro.
(next_token): Handle IBM R16 conversion cases.
(push_token): Likewise.
(mark_single): Likewise.
(do_parse): Likewise, initialize endian.
-rw-r--r-- | libgfortran/runtime/environ.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c index fe16c080797..ff10fe53f68 100644 --- a/libgfortran/runtime/environ.c +++ b/libgfortran/runtime/environ.c @@ -247,6 +247,11 @@ init_variables (void) #define SWAP 258 #define BIG 259 #define LITTLE 260 +#ifdef HAVE_GFC_REAL_17 +#define R16_IEEE 261 +#define R16_IBM 262 +#endif + /* Some space for additional tokens later. */ #define INTEGER 273 #define END (-1) @@ -392,6 +397,15 @@ next_token (void) result = match_word ("swap", SWAP); break; +#ifdef HAVE_GFC_REAL_17 + case 'r': + case 'R': + result = match_word ("r16_ieee", R16_IEEE); + if (result == ILLEGAL) + result = match_word ("r16_ibm", R16_IBM); + break; + +#endif case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': result = match_integer (); @@ -414,7 +428,8 @@ push_token (void) /* This is called when a unit is identified. If do_count is nonzero, increment the number of units by one. If do_count is zero, - put the unit into the table. */ + put the unit into the table. For POWER, we have to make sure that + we can also put in the conversion btween IBM and IEEE long double. */ static void mark_single (int unit) @@ -428,7 +443,11 @@ mark_single (int unit) } if (search_unit (unit, &i)) { +#ifdef HAVE_GFC_REAL_17 + elist[i].conv |= endian; +#else elist[i].conv = endian; +#endif } else { @@ -437,7 +456,11 @@ mark_single (int unit) n_elist += 1; elist[i].unit = unit; +#ifdef HAVE_GFC_REAL_17 + elist[i].conv |= endian; +#else elist[i].conv = endian; +#endif } } @@ -481,6 +504,8 @@ do_parse (void) /* Parse the string. First, let's look for a default. */ tok = next_token (); + endian = 0; + switch (tok) { case NATIVE: @@ -499,6 +524,15 @@ do_parse (void) endian = GFC_CONVERT_LITTLE; break; +#ifdef HAVE_GFC_REAL_17 + case R16_IEEE: + endian = GFC_CONVERT_R16_IEEE; + break; + + case R16_IBM: + endian = GFC_CONVERT_R16_IBM; + break; +#endif case INTEGER: /* A leading digit means that we are looking at an exception. Reset the position to the beginning, and continue processing @@ -571,6 +605,19 @@ do_parse (void) goto error; endian = GFC_CONVERT_BIG; break; +#ifdef HAVE_GFC_REAL_17 + case R16_IEEE: + if (next_token () != ':') + goto error; + endian = GFC_CONVERT_R16_IEEE; + break; + + case R16_IBM: + if (next_token () != ':') + goto error; + endian = GFC_CONVERT_R16_IBM; + break; +#endif case INTEGER: push_token (); |