diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-30 01:50:44 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-03-30 01:50:44 +0000 |
commit | c6418a4e44bad350f57aac0ce1d0f6ce6c6a1c9f (patch) | |
tree | 07c0a2aef08a00219e11f34b2e1a27c0dd432823 /gcc/toplev.c | |
parent | 7666d572f2a547f09f39811c7af07f9532251a02 (diff) | |
download | gcc-c6418a4e44bad350f57aac0ce1d0f6ce6c6a1c9f.tar.gz |
PR rtl-optimization/323
* c-common.c (c_fully_fold, convert_and_check,
c_common_truthvalue_conversion): Handle EXCESS_PRECISION_EXPR.
(c_fully_fold_internal): Disallow EXCESS_PRECISION_EXPR.
* c-common.def (EXCESS_PRECISION_EXPR): New.
* c-cppbuiltin.c (builtin_define_float_constants): Define
constants with enough digits for long double.
* c-lex.c (interpret_float): Interpret constant with excess
precision where appropriate.
* c-opts.c (c_common_post_options): Set
flag_excess_precision_cmdline. Give an error for
-fexcess-precision=standard for C++ for processors where the
option is significant.
* c-parser.c (c_parser_conditional_expression): Handle excess
precision in condition.
* c-typeck.c (convert_arguments): Handle arguments with excess
precision.
(build_unary_op): Move excess precision outside operation.
(build_conditional_expr): Likewise.
(build_compound_expr): Likewise.
(build_c_cast): Do cast on operand of EXCESS_PRECISION_EXPR.
(build_modify_expr): Handle excess precision in RHS.
(convert_for_assignment): Handle excess precision in converted
value.
(digest_init, output_init_element, process_init_element): Handle
excess precision in initializer.
(c_finish_return): Handle excess precision in return value.
(build_binary_op): Handle excess precision in operands and add
excess precision as needed for operation.
* common.opt (-fexcess-precision=): New option.
* config/i386/i386.h (X87_ENABLE_ARITH, X87_ENABLE_FLOAT): New.
* config/i386/i386.md (float<SSEMODEI24:mode><X87MODEF:mode>2):
For standard excess precision, output explicit conversion to and
truncation from XFmode.
(*float<SSEMODEI24:mode><X87MODEF:mode>2_1,
*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp,
*float<SSEMODEI24:mode><X87MODEF:mode>2_i387, two unnamed
define_splits, floatdi<X87MODEF:mode>2_i387_with_xmm, two unnamed
define_splits, *floatunssi<mode>2_1, two unnamed define_splits,
floatunssi<mode>2, add<mode>3, sub<mode>3, mul<mode>3, divdf3,
divsf3, *fop_<mode>_comm_i387, *fop_<mode>_1_i387,
*fop_<MODEF:mode>_2_i387, *fop_<MODEF:mode>_3_i387,
*fop_df_4_i387, *fop_df_5_i387, *fop_df_6_i387, two unnamed
define_splits, sqrt<mode>2): Disable where appropriate for
standard excess precision.
* convert.c (convert_to_real): Do not shorten arithmetic to type
for which excess precision would be used.
* defaults.h (TARGET_FLT_EVAL_METHOD_NON_DEFAULT): Define.
* doc/invoke.texi (-fexcess-precision=): Document option.
(-mfpmath=): Correct index entry.
* flags.h (enum excess_precision, flag_excess_precision_cmdline,
flag_excess_precision): New.
* langhooks.c (lhd_post_options): Set
flag_excess_precision_cmdline.
* opts.c (common_handle_option): Handle -fexcess-precision=.
* toplev.c (flag_excess_precision_cmdline, flag_excess_precision,
init_excess_precision): New.
(lang_dependent_init_target): Call init_excess_precision.
* tree.c (excess_precision_type): New.
* tree.h (excess_precision_type): Declare.
ada:
* gcc-interface/misc.c (gnat_post_options): Set
flag_excess_precision_cmdline. Give an error for
-fexcess-precision=standard for processors where the option is
significant.
fortran:
* options.c (gfc_post_options): Set
flag_excess_precision_cmdline. Give an error for
-fexcess-precision=standard for processors where the option is
significant.
java:
* lang.c (java_post_options): Set flag_excess_precision_cmdline.
Give an error for -fexcess-precision=standard for processors where
the option is significant.
testsuite:
* gcc.target/i386/excess-precision-1.c,
gcc.target/i386/excess-precision-2.c,
gcc.target/i386/excess-precision-3.c,
gcc.target/i386/excess-precision-4.c,
gcc.target/i386/excess-precision-5.c,
gcc.target/i386/excess-precision-6.c: New tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@145272 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/toplev.c')
-rw-r--r-- | gcc/toplev.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/toplev.c b/gcc/toplev.c index 8417cfed6cb..72f3d3087d3 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -281,6 +281,11 @@ enum ira_region flag_ira_region = IRA_REGION_MIXED; unsigned int flag_ira_verbose = 5; +/* Set the default for excess precision. */ + +enum excess_precision flag_excess_precision_cmdline = EXCESS_PRECISION_DEFAULT; +enum excess_precision flag_excess_precision = EXCESS_PRECISION_DEFAULT; + /* Nonzero means change certain warnings into errors. Usually these are warnings about failure to conform to some standard. */ @@ -2033,11 +2038,51 @@ backend_init (void) backend_init_target (); } +/* Initialize excess precision settings. */ +static void +init_excess_precision (void) +{ + /* Adjust excess precision handling based on the target options. If + the front end cannot handle it, flag_excess_precision_cmdline + will already have been set accordingly in the post_options + hook. */ + gcc_assert (flag_excess_precision_cmdline != EXCESS_PRECISION_DEFAULT); + flag_excess_precision = flag_excess_precision_cmdline; + if (flag_unsafe_math_optimizations) + flag_excess_precision = EXCESS_PRECISION_FAST; + if (flag_excess_precision == EXCESS_PRECISION_STANDARD) + { + int flt_eval_method = TARGET_FLT_EVAL_METHOD; + switch (flt_eval_method) + { + case -1: + case 0: + /* Either the target acts unpredictably (-1) or has all the + operations required not to have excess precision (0). */ + flag_excess_precision = EXCESS_PRECISION_FAST; + break; + case 1: + case 2: + /* In these cases, predictable excess precision makes + sense. */ + break; + default: + /* Any other implementation-defined FLT_EVAL_METHOD values + require the compiler to handle the associated excess + precision rules in excess_precision_type. */ + gcc_unreachable (); + } + } +} + /* Initialize things that are both lang-dependent and target-dependent. This function can be called more than once if target parameters change. */ static void lang_dependent_init_target (void) { + /* This determines excess precision settings. */ + init_excess_precision (); + /* This creates various _DECL nodes, so needs to be called after the front end is initialized. It also depends on the HAVE_xxx macros generated from the target machine description. */ |