diff options
author | Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2010-09-01 08:40:53 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2010-09-01 08:40:53 +0000 |
commit | 166d08bddeffca222328dfb9806418910fe83729 (patch) | |
tree | cec56c33ee5ba903a41efda3b893888b045f87ea /gcc/fortran/trans-expr.c | |
parent | e14ca1cef69e39dd2a2ffffffdab47a51b803579 (diff) | |
download | gcc-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.c | 47 |
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: |