diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-12-01 21:05:17 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-12-01 21:05:17 +0000 |
commit | 75bd5adae1072ec96f2b05f35147891f977ab2b2 (patch) | |
tree | 8180a32dab64f00b8c46fedcdc5e7b9928102158 /gcc/real.c | |
parent | c50a498ccf40a4f355b138f6e51e500095895ba0 (diff) | |
download | gcc-75bd5adae1072ec96f2b05f35147891f977ab2b2.tar.gz |
* c-common.c (declare_function_name): Declare predefinied variable
`__func__'.
* c-decl.c (flag_isoc9x): Set to 1 by default.
(c_decode_option): Handle -std= option. Remove -flang-isoc9x.
(grokdeclarator): Always emit warning about implicit int for ISO C 9x.
* c-parse.in: Allow constructors in ISO C 9x.
Rewrite designator list handling.
Allow [*] parameters.
Don't warn about comma at end of enum definition for ISO C 9x.
* cccp.c (c9x): New variable.
(rest_extension): New variable.
(print_help): Document new -std= option.
(main): Recognize -std= option. Set c9x appropriately.
(create_definition): Recognize ISO C 9x vararg macros.
* gcc.c (default_compilers): Adjust specs for -std options.
(option_map): Add --std.
(display_help): Document -std.
* toplev.c (documented_lang_options): Add -std and remove
-flang-isoc9x.
* c-lex.c (yylex): Recognize hex FP constants and call REAL_VALUE_ATOF
or REAL_VALUE_HTOF based on base of the constants.
* fold-const.c (real_hex_to_f): New function. Replacement function
for hex FP conversion if REAL_ARITHMETIC is not defined.
* real.c (asctoeg): Add handling of hex FP constants.
* real.h: Define REAL_VALUE_HTOF if necessary using ereal_atof or
real_hex_to_f.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@24049 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/real.c')
-rw-r--r-- | gcc/real.c | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/gcc/real.c b/gcc/real.c index d40a0f374d0..cb3a3eb75d2 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -680,9 +680,9 @@ etruncui (x) } -/* This is the REAL_VALUE_ATOF function. It converts a decimal string to - binary, rounding off as indicated by the machine_mode argument. Then it - promotes the rounded value to REAL_VALUE_TYPE. */ +/* This is the REAL_VALUE_ATOF function. It converts a decimal or hexadecimal + string to binary, rounding off as indicated by the machine_mode argument. + Then it promotes the rounded value to REAL_VALUE_TYPE. */ REAL_VALUE_TYPE ereal_atof (s, t) @@ -5058,7 +5058,7 @@ asctoe (s, y) } /* Convert ASCII string SS to e type Y, with a specified rounding precision - of OPREC bits. */ + of OPREC bits. BASE is 16 for C9X hexadecimal floating constants. */ static void asctoeg (ss, y, oprec) @@ -5072,17 +5072,26 @@ asctoeg (ss, y, oprec) EMULONG lexp; unsigned EMUSHORT nsign, *p; char *sp, *s, *lstr; + int base = 10; /* Copy the input string. */ lstr = (char *) alloca (strlen (ss) + 1); + s = ss; while (*s == ' ') /* skip leading spaces */ ++s; + sp = lstr; while ((*sp++ = *s++) != '\0') ; s = lstr; + if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) + { + base = 16; + s += 2; + } + rndsav = rndprc; rndprc = NBITS; /* Set to full precision */ lost = 0; @@ -5096,8 +5105,13 @@ asctoeg (ss, y, oprec) trail = 0; nxtcom: + if (*s >= '0' && *s <= '9') k = *s - '0'; - if ((k >= 0) && (k <= 9)) + else if (*s >= 'a') + k = 10 + *s - 'a'; + else + k = 10 + *s - 'A'; + if ((k >= 0) && (k < base)) { /* Ignore leading zeros */ if ((prec == 0) && (decflg == 0) && (k == 0)) @@ -5106,11 +5120,15 @@ asctoeg (ss, y, oprec) if ((trail == 0) && (decflg != 0)) { sp = s; - while ((*sp >= '0') && (*sp <= '9')) + while ((*sp >= '0' && *sp <= '9') + || (base == 16 && ((*sp >= 'a' && *sp <= 'f') + || (*sp >= 'A' && *sp <= 'F')))) ++sp; /* Check for syntax error */ c = *sp & 0x7f; - if ((c != 'e') && (c != 'E') && (c != '\0') + if ((base != 10 || ((c != 'e') && (c != 'E'))) + && (base != 16 || ((c != 'p') && (c != 'P'))) + && (c != '\0') && (c != '\n') && (c != '\r') && (c != ' ') && (c != ',')) goto error; @@ -5129,13 +5147,28 @@ asctoeg (ss, y, oprec) if (yy[2] == 0) { + if (base == 16) + { if (decflg) + nexp += 4; /* count digits after decimal point */ + + eshup1 (yy); /* multiply current number by 16 */ + eshup1 (yy); + eshup1 (yy); + eshup1 (yy); + } + else + { + if (decflg) nexp += 1; /* count digits after decimal point */ + eshup1 (yy); /* multiply current number by 10 */ emovz (yy, xt); eshup1 (xt); eshup1 (xt); eaddm (xt, yy); + } + /* Insert the current digit. */ ecleaz (xt); xt[NI - 2] = (unsigned EMUSHORT) k; eaddm (xt, yy); @@ -5146,7 +5179,12 @@ asctoeg (ss, y, oprec) lost |= k; /* Count lost digits before the decimal point. */ if (decflg == 0) + { + if (base == 10) nexp -= 1; + else + nexp -= 4; + } } prec += 1; goto donchr; @@ -5158,6 +5196,8 @@ asctoeg (ss, y, oprec) break; case 'E': case 'e': + case 'P': + case 'p': goto expnt; case '.': /* decimal point */ if (decflg) @@ -5224,24 +5264,19 @@ read_expnt: { exp *= 10; exp += *s++ - '0'; - if (exp > -(MINDECEXP)) - { - if (esign < 0) - goto zero; - else - goto infinite; - } + if (exp > 999999) + break; } if (esign < 0) exp = -exp; - if (exp > MAXDECEXP) + if ((exp > MAXDECEXP) && (base == 10)) { infinite: ecleaz (yy); yy[E] = 0x7fff; /* infinity */ goto aexit; } - if (exp < MINDECEXP) + if ((exp < MINDECEXP) && (base == 10)) { zero: ecleaz (yy); @@ -5249,6 +5284,25 @@ read_expnt: } daldone: + if (base == 16) + { + /* Base 16 hexadecimal floating constant. */ + if ((k = enormlz (yy)) > NBITS) + { + ecleaz (yy); + goto aexit; + } + /* Adjust the exponent. NEXP is the number of hex digits, + EXP is a power of 2. */ + lexp = (EXONE - 1 + NBITS) - k + yy[E] + exp - nexp; + if (lexp > 0x7fff) + goto infinite; + if (lexp < 0) + goto zero; + yy[E] = lexp; + goto expdon; + } + nexp = exp - nexp; /* Pad trailing zeros to minimize power of 10, per IEEE spec. */ while ((nexp > 0) && (yy[2] == 0)) @@ -5270,6 +5324,7 @@ read_expnt: } lexp = (EXONE - 1 + NBITS) - k; emdnorm (yy, lost, 0, lexp, 64); + lost = 0; /* Convert to external format: @@ -5325,6 +5380,7 @@ read_expnt: k = emulm (tt, yy); lexp -= EXONE - 1; } + lost = k; expdon: @@ -5348,7 +5404,7 @@ read_expnt: lexp -= EXONE - 0201; #endif rndprc = oprec; - emdnorm (yy, k, 0, lexp, 64); + emdnorm (yy, lost, 0, lexp, 64); aexit: |