diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -6258,6 +6258,61 @@ build_complex_type (tree component_type) return build_qualified_type (t, TYPE_QUALS (component_type)); } + +/* If TYPE is a real or complex floating-point type and the target + does not directly support arithmetic on TYPE then return the wider + type to be used for arithmetic on TYPE. Otherwise, return + NULL_TREE. */ + +tree +excess_precision_type (tree type) +{ + if (flag_excess_precision != EXCESS_PRECISION_FAST) + { + int flt_eval_method = TARGET_FLT_EVAL_METHOD; + switch (TREE_CODE (type)) + { + case REAL_TYPE: + switch (flt_eval_method) + { + case 1: + if (TYPE_MODE (type) == TYPE_MODE (float_type_node)) + return double_type_node; + break; + case 2: + if (TYPE_MODE (type) == TYPE_MODE (float_type_node) + || TYPE_MODE (type) == TYPE_MODE (double_type_node)) + return long_double_type_node; + break; + default: + gcc_unreachable (); + } + break; + case COMPLEX_TYPE: + if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE) + return NULL_TREE; + switch (flt_eval_method) + { + case 1: + if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node)) + return complex_double_type_node; + break; + case 2: + if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node) + || (TYPE_MODE (TREE_TYPE (type)) + == TYPE_MODE (double_type_node))) + return complex_long_double_type_node; + break; + default: + gcc_unreachable (); + } + break; + default: + break; + } + } + return NULL_TREE; +} /* Return OP, stripped of any conversions to wider types as much as is safe. Converting the value back to OP's type makes a value equivalent to OP. |