aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-expr.c
diff options
context:
space:
mode:
authorFrancois-Xavier Coudert <fxcoudert@gcc.gnu.org>2010-09-01 08:40:53 +0000
committerFrançois-Xavier Coudert <fxcoudert@gcc.gnu.org>2010-09-01 08:40:53 +0000
commit166d08bddeffca222328dfb9806418910fe83729 (patch)
treecec56c33ee5ba903a41efda3b893888b045f87ea /gcc/fortran/trans-expr.c
parente14ca1cef69e39dd2a2ffffffdab47a51b803579 (diff)
downloadgcc-166d08bddeffca222328dfb9806418910fe83729.zip
gcc-166d08bddeffca222328dfb9806418910fe83729.tar.gz
gcc-166d08bddeffca222328dfb9806418910fe83729.tar.bz2
trans-expr.c (gfc_conv_power_op): Handle floating-point types other than long double.
* trans-expr.c (gfc_conv_power_op): Handle floating-point types other than long double. * mathbuiltins.def: Add builtins from the POW and CPOW family. * trans.h (gfc_builtin_decl_for_float_kind): New prototype. * trans-intrinsic.c (gfc_builtin_decl_for_float_kind): Add gfc_ prefix to function name. (gfc_build_intrinsic_lib_fndecls): Add cpow prototype. (gfc_conv_intrinsic_aint): Use gfc_builtin_decl_for_float_kind function name. (gfc_conv_intrinsic_exponent): Likewise. (gfc_conv_intrinsic_abs): Likewise. (gfc_conv_intrinsic_mod): Likewise. (gfc_conv_intrinsic_sign): Likewise. (gfc_conv_intrinsic_arith): Likewise. (gfc_conv_intrinsic_fraction): Likewise. (gfc_conv_intrinsic_nearest): Likewise. (gfc_conv_intrinsic_spacing): Likewise. (gfc_conv_intrinsic_rrspacing): Likewise. (gfc_conv_intrinsic_scale): Likewise. (gfc_conv_intrinsic_set_exponent): Likewise. From-SVN: r163721
Diffstat (limited to 'gcc/fortran/trans-expr.c')
-rw-r--r--gcc/fortran/trans-expr.c47
1 files changed, 14 insertions, 33 deletions
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 103bc24..b4bc8ca 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -958,7 +958,7 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
int ikind;
gfc_se lse;
gfc_se rse;
- tree fndecl;
+ tree fndecl = NULL;
gfc_init_se (&lse, se);
gfc_conv_expr_val (&lse, expr->value.op.op1);
@@ -1056,15 +1056,24 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
break;
case 2:
- case 3:
fndecl = built_in_decls[BUILT_IN_POWIL];
break;
+ case 3:
+ /* Use the __builtin_powil() only if real(kind=16) is
+ actually the C long double type. */
+ if (!gfc_real16_is_float128)
+ fndecl = built_in_decls[BUILT_IN_POWIL];
+ break;
+
default:
gcc_unreachable ();
}
}
- else
+
+ /* If we don't have a good builtin for this, go for the
+ library function. */
+ if (!fndecl)
fndecl = gfor_fndecl_math_powi[kind][ikind].real;
break;
@@ -1078,39 +1087,11 @@ gfc_conv_power_op (gfc_se * se, gfc_expr * expr)
break;
case BT_REAL:
- switch (kind)
- {
- case 4:
- fndecl = built_in_decls[BUILT_IN_POWF];
- break;
- case 8:
- fndecl = built_in_decls[BUILT_IN_POW];
- break;
- case 10:
- case 16:
- fndecl = built_in_decls[BUILT_IN_POWL];
- break;
- default:
- gcc_unreachable ();
- }
+ fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_POW, kind);
break;
case BT_COMPLEX:
- switch (kind)
- {
- case 4:
- fndecl = built_in_decls[BUILT_IN_CPOWF];
- break;
- case 8:
- fndecl = built_in_decls[BUILT_IN_CPOW];
- break;
- case 10:
- case 16:
- fndecl = built_in_decls[BUILT_IN_CPOWL];
- break;
- default:
- gcc_unreachable ();
- }
+ fndecl = gfc_builtin_decl_for_float_kind (BUILT_IN_CPOW, kind);
break;
default: