From ab5e26156fb28eb59e0a259ccb0ab49485a1b94c Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 4 Sep 2002 16:21:28 -0700 Subject: [PATCH] builtin-types.def (BT_FN_FLOAT): New. * builtin-types.def (BT_FN_FLOAT): New. (BT_FN_DOUBLE, BT_FN_LONG_DOUBLE): New. * builtins.def (BUILT_IN_INF, BUILT_IN_INFF, BUILT_IN_INFL, BUILT_IN_HUGE_VAL, BUILT_IN_HUGE_VALF, BUILT_IN_HUGE_VALL): New. * builtins.c (fold_builtin_inf): New. (fold_builtin): Call it. * real.c (ereal_inf): New. * real.h: Declare it. * doc/extend.texi: Document new builtins. From-SVN: r56820 --- gcc/ChangeLog | 12 +++++++++++ gcc/builtin-types.def | 3 +++ gcc/builtins.c | 24 ++++++++++++++++++++++ gcc/builtins.def | 26 ++++++++++++++++++++++++ gcc/doc/extend.texi | 30 +++++++++++++++++++++++++++ gcc/real.c | 47 +++++++++++++++++++++++++++++++++++++++++-- gcc/real.h | 1 + 7 files changed, 141 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d2d03983631..02e70570894 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-09-04 Richard Henderson + + * builtin-types.def (BT_FN_FLOAT): New. + (BT_FN_DOUBLE, BT_FN_LONG_DOUBLE): New. + * builtins.def (BUILT_IN_INF, BUILT_IN_INFF, BUILT_IN_INFL, + BUILT_IN_HUGE_VAL, BUILT_IN_HUGE_VALF, BUILT_IN_HUGE_VALL): New. + * builtins.c (fold_builtin_inf): New. + (fold_builtin): Call it. + * real.c (ereal_inf): New. + * real.h: Declare it. + * doc/extend.texi: Document new builtins. + 2002-09-04 Richard Henderson * cse.c (cse_insn): Avoid subreg games if the equivalence diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index 7a33ffd7894..89bd500b84c 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -84,6 +84,9 @@ DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node) DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID) DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR) DEF_FUNCTION_TYPE_0 (BT_FN_UNSIGNED, BT_UNSIGNED) +DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT) +DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE) +DEF_FUNCTION_TYPE_0 (BT_FN_LONG_DOUBLE, BT_LONG_DOUBLE) DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG) DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG) diff --git a/gcc/builtins.c b/gcc/builtins.c index b2ad5375b77..7b2841bcae9 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -148,6 +148,7 @@ static tree stabilize_va_list PARAMS ((tree, int)); static rtx expand_builtin_expect PARAMS ((tree, rtx)); static tree fold_builtin_constant_p PARAMS ((tree)); static tree fold_builtin_classify_type PARAMS ((tree)); +static tree fold_builtin_inf PARAMS ((tree, int)); static tree build_function_call_expr PARAMS ((tree, tree)); static int validate_arglist PARAMS ((tree, ...)); @@ -4132,6 +4133,19 @@ fold_builtin_classify_type (arglist) return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0); } +/* Fold a call to __builtin_inf or __builtin_huge_val. */ + +static tree +fold_builtin_inf (type, warn) + tree type; + int warn; +{ + if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn) + warning ("target format does not support infinity"); + + return build_real (type, ereal_inf (TYPE_MODE (type))); +} + /* Used by constant folding to eliminate some builtin calls early. EXP is the CALL_EXPR of a call to a builtin function. */ @@ -4163,6 +4177,16 @@ fold_builtin (exp) } break; + case BUILT_IN_INF: + case BUILT_IN_INFF: + case BUILT_IN_INFL: + return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), true); + + case BUILT_IN_HUGE_VAL: + case BUILT_IN_HUGE_VALF: + case BUILT_IN_HUGE_VALL: + return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), false); + default: break; } diff --git a/gcc/builtins.def b/gcc/builtins.def index 978b4a70d55..25ea430fd9e 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -401,6 +401,32 @@ DEF_LIB_BUILTIN(BUILT_IN_LOGL, ? ATTR_CONST_NOTHROW_LIST : ATTR_PURE_NOTHROW_LIST)) +DEF_GCC_BUILTIN(BUILT_IN_INF, + "__builtin_inf", + BT_FN_DOUBLE, + ATTR_PURE_NOTHROW_LIST) +DEF_GCC_BUILTIN(BUILT_IN_INFF, + "__builtin_inff", + BT_FN_FLOAT, + ATTR_PURE_NOTHROW_LIST) +DEF_GCC_BUILTIN(BUILT_IN_INFL, + "__builtin_infl", + BT_FN_LONG_DOUBLE, + ATTR_PURE_NOTHROW_LIST) + +DEF_GCC_BUILTIN(BUILT_IN_HUGE_VAL, + "__builtin_huge_val", + BT_FN_DOUBLE, + ATTR_PURE_NOTHROW_LIST) +DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALF, + "__builtin_huge_valf", + BT_FN_FLOAT, + ATTR_PURE_NOTHROW_LIST) +DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALL, + "__builtin_huge_vall", + BT_FN_LONG_DOUBLE, + ATTR_PURE_NOTHROW_LIST) + DEF_UNUSED_BUILTIN(BUILT_IN_GETEXP) DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 631ed9f663f..ec33daa020b 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -4833,6 +4833,36 @@ is evaluated if it includes side effects but no other code is generated and GCC does not issue a warning. @end deftypefn +@deftypefn {Built-in Function} double __builtin_huge_val (void) +Returns a positive infinity, if supported by the floating-point format, +else @code{DBL_MAX}. This function is suitable for implementing the +ISO C macro @code{HUGE_VAL}. +@end deftypefn + +@deftypefn {Built-in Function} float __builtin_huge_valf (void) +Similar to @code{__builtin_huge_val}, except the return type is @code{float}. +@end deftypefn + +@deftypefn {Built-in Function} long double __builtin_huge_vall (void) +Similar to @code{__builtin_huge_val}, except the return +type is @code{long double}. +@end deftypefn + +@deftypefn {Built-in Function} double __builtin_inf (void) +Similar to @code{__builtin_huge_val}, except a warning is generated +if the target floating-point format does not support infinities. +This function is suitable for implementing the ISO C99 macro @code{INFINITY}. +@end deftypefn + +@deftypefn {Built-in Function} float __builtin_inff (void) +Similar to @code{__builtin_inf}, except the return type is @code{float}. +@end deftypefn + +@deftypefn {Built-in Function} long double __builtin_infl (void) +Similar to @code{__builtin_inf}, except the return +type is @code{long double}. +@end deftypefn + @node Target Builtins @section Built-in Functions Specific to Particular Target Machines diff --git a/gcc/real.c b/gcc/real.c index 019821df408..077e313f349 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -1818,8 +1818,8 @@ eisnan (x) return (0); } -/* Fill e-type number X with infinity pattern (IEEE) - or largest possible number (non-IEEE). */ +/* Fill e-type number X with infinity pattern (IEEE) + or largest possible number (non-IEEE). */ static void einfin (x) @@ -1860,6 +1860,49 @@ einfin (x) #endif } +/* Similar, except return it as a REAL_VALUE_TYPE. */ + +REAL_VALUE_TYPE +ereal_inf (mode) + enum machine_mode mode; +{ + REAL_VALUE_TYPE r; + UEMUSHORT e[NE]; + int prec, rndsav; + + switch (mode) + { + case QFmode: + case SFmode: + prec = 24; + break; + case HFmode: + case DFmode: + prec = 53; + break; + case TFmode: + if (!INTEL_EXTENDED_IEEE_FORMAT) + { + prec = 113; + break; + } + /* FALLTHRU */ + case XFmode: + prec = 64; + break; + default: + abort (); + } + + rndsav = rndprc; + rndprc = prec; + einfin (e); + rndprc = rndsav; + + PUT_REAL (e, &r); + return r; +} + /* Output an e-type NaN. This generates Intel's quiet NaN pattern for extended real. The exponent is 7fff, the leading mantissa word is c000. */ diff --git a/gcc/real.h b/gcc/real.h index cf5fdf21aeb..f4265826ce9 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -292,6 +292,7 @@ extern int target_isinf PARAMS ((REAL_VALUE_TYPE)); extern int target_negative PARAMS ((REAL_VALUE_TYPE)); extern void debug_real PARAMS ((REAL_VALUE_TYPE)); extern REAL_VALUE_TYPE ereal_atof PARAMS ((const char *, enum machine_mode)); +extern REAL_VALUE_TYPE ereal_inf PARAMS ((enum machine_mode)); /* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node. */ extern tree build_real PARAMS ((tree, REAL_VALUE_TYPE));