summaryrefslogtreecommitdiff
path: root/gcc/real.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1998-12-01 21:05:17 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1998-12-01 21:05:17 +0000
commit75bd5adae1072ec96f2b05f35147891f977ab2b2 (patch)
tree8180a32dab64f00b8c46fedcdc5e7b9928102158 /gcc/real.c
parentc50a498ccf40a4f355b138f6e51e500095895ba0 (diff)
downloadgcc-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.c90
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: