Skip to content

Commit

Permalink
* f95-lang.c (gfc_init_builtin_functions): Add more floating-point
Browse files Browse the repository at this point in the history
	built-ins.
	* mathbuiltins.def (OTHER_BUILTIN): Define built-ins for logb,
	remainder, rint and signbit.
	* trans-decl.c (save_fp_state, restore_fp_state): Move to
	trans-intrinsic.c
	(gfc_generate_function_code): Use new names for these two functions.
	* trans-expr.c (gfc_conv_function_expr): Catch IEEE functions to
	emit code from the front-end.
	* trans-intrinsic.c (gfc_save_fp_state, gfc_restore_fp_state,
	conv_ieee_function_args, conv_intrinsic_ieee_builtin,
	conv_intrinsic_ieee_is_normal, conv_intrinsic_ieee_is_negative,
	conv_intrinsic_ieee_logb_rint, conv_intrinsic_ieee_rem,
	conv_intrinsic_ieee_next_after, conv_intrinsic_ieee_scalb,
	conv_intrinsic_ieee_copy_sign, gfc_conv_ieee_arithmetic_function):
	New functions.
	* trans.h (gfc_conv_ieee_arithmetic_function,
	gfc_save_fp_state, gfc_restore_fp_state): New prototypes.

	* ieee/ieee_helper.c (ieee_is_finite_*, ieee_is_nan_*,
	ieee_is_negative_*, ieee_is_normal_*, ieee_copy_sign_*,
	ieee_unordered_*, ieee_logb_*, ieee_rint_*, ieee_scalb_*,
	ieee_rem_*, ieee_next_after_*): Remove functions.
	* gfortran.map (GFORTRAN_1.5): Remove corresponding symbols.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216036 138bc75d-0d04-0410-961f-82ee72b054a4
  • Loading branch information
fxcoudert committed Oct 9, 2014
1 parent c0d7a1d commit d733353
Show file tree
Hide file tree
Showing 10 changed files with 442 additions and 354 deletions.
21 changes: 21 additions & 0 deletions gcc/fortran/ChangeLog
@@ -1,3 +1,24 @@
2014-10-09 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>

* f95-lang.c (gfc_init_builtin_functions): Add more floating-point
built-ins.
* mathbuiltins.def (OTHER_BUILTIN): Define built-ins for logb,
remainder, rint and signbit.
* trans-decl.c (save_fp_state, restore_fp_state): Move to
trans-intrinsic.c
(gfc_generate_function_code): Use new names for these two functions.
* trans-expr.c (gfc_conv_function_expr): Catch IEEE functions to
emit code from the front-end.
* trans-intrinsic.c (gfc_save_fp_state, gfc_restore_fp_state,
conv_ieee_function_args, conv_intrinsic_ieee_builtin,
conv_intrinsic_ieee_is_normal, conv_intrinsic_ieee_is_negative,
conv_intrinsic_ieee_logb_rint, conv_intrinsic_ieee_rem,
conv_intrinsic_ieee_next_after, conv_intrinsic_ieee_scalb,
conv_intrinsic_ieee_copy_sign, gfc_conv_ieee_arithmetic_function):
New functions.
* trans.h (gfc_conv_ieee_arithmetic_function,
gfc_save_fp_state, gfc_restore_fp_state): New prototypes.

2014-10-06 Manuel López-Ibáñez <manu@gcc.gnu.org>

PR fortran/44054
Expand Down
57 changes: 57 additions & 0 deletions gcc/fortran/f95-lang.c
Expand Up @@ -563,6 +563,7 @@ gfc_builtin_function (tree decl)
#define ATTR_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF)
#define ATTR_NOTHROW_LEAF_MALLOC_LIST (ECF_NOTHROW | ECF_LEAF | ECF_MALLOC)
#define ATTR_CONST_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_CONST)
#define ATTR_PURE_NOTHROW_LEAF_LIST (ECF_NOTHROW | ECF_LEAF | ECF_PURE)
#define ATTR_NOTHROW_LIST (ECF_NOTHROW)
#define ATTR_CONST_NOTHROW_LIST (ECF_NOTHROW | ECF_CONST)

Expand Down Expand Up @@ -683,6 +684,8 @@ gfc_init_builtin_functions (void)
tree ftype, ptype;
tree builtin_types[(int) BT_LAST + 1];

int attr;

build_builtin_fntypes (mfunc_float, float_type_node);
build_builtin_fntypes (mfunc_double, double_type_node);
build_builtin_fntypes (mfunc_longdouble, long_double_type_node);
Expand Down Expand Up @@ -770,6 +773,32 @@ gfc_init_builtin_functions (void)
BUILT_IN_NEXTAFTERF, "nextafterf",
ATTR_CONST_NOTHROW_LEAF_LIST);

/* Some built-ins depend on rounding mode. Depending on compilation options, they
will be "pure" or "const". */
attr = flag_rounding_math ? ATTR_PURE_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST;

gfc_define_builtin ("__builtin_rintl", mfunc_longdouble[0],
BUILT_IN_RINTL, "rintl", attr);
gfc_define_builtin ("__builtin_rint", mfunc_double[0],
BUILT_IN_RINT, "rint", attr);
gfc_define_builtin ("__builtin_rintf", mfunc_float[0],
BUILT_IN_RINTF, "rintf", attr);

gfc_define_builtin ("__builtin_remainderl", mfunc_longdouble[1],
BUILT_IN_REMAINDERL, "remainderl", attr);
gfc_define_builtin ("__builtin_remainder", mfunc_double[1],
BUILT_IN_REMAINDER, "remainder", attr);
gfc_define_builtin ("__builtin_remainderf", mfunc_float[1],
BUILT_IN_REMAINDERF, "remainderf", attr);

gfc_define_builtin ("__builtin_logbl", mfunc_longdouble[0],
BUILT_IN_LOGBL, "logbl", ATTR_CONST_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_logb", mfunc_double[0],
BUILT_IN_LOGB, "logb", ATTR_CONST_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_logbf", mfunc_float[0],
BUILT_IN_LOGBF, "logbf", ATTR_CONST_NOTHROW_LEAF_LIST);


gfc_define_builtin ("__builtin_frexpl", mfunc_longdouble[4],
BUILT_IN_FREXPL, "frexpl", ATTR_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_frexp", mfunc_double[4],
Expand Down Expand Up @@ -960,6 +989,34 @@ gfc_init_builtin_functions (void)
void_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_isnan", ftype, BUILT_IN_ISNAN,
"__builtin_isnan", ATTR_CONST_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_isfinite", ftype, BUILT_IN_ISFINITE,
"__builtin_isfinite", ATTR_CONST_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_isnormal", ftype, BUILT_IN_ISNORMAL,
"__builtin_isnormal", ATTR_CONST_NOTHROW_LEAF_LIST);

ftype = build_function_type_list (integer_type_node, void_type_node,
void_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_isunordered", ftype, BUILT_IN_ISUNORDERED,
"__builtin_isunordered", ATTR_CONST_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_islessequal", ftype, BUILT_IN_ISLESSEQUAL,
"__builtin_islessequal", ATTR_CONST_NOTHROW_LEAF_LIST);
gfc_define_builtin ("__builtin_isgreaterequal", ftype,
BUILT_IN_ISGREATEREQUAL, "__builtin_isgreaterequal",
ATTR_CONST_NOTHROW_LEAF_LIST);

ftype = build_function_type_list (integer_type_node,
float_type_node, NULL_TREE);
gfc_define_builtin("__builtin_signbitf", ftype, BUILT_IN_SIGNBITF,
"signbitf", ATTR_CONST_NOTHROW_LEAF_LIST);
ftype = build_function_type_list (integer_type_node,
double_type_node, NULL_TREE);
gfc_define_builtin("__builtin_signbit", ftype, BUILT_IN_SIGNBIT,
"signbit", ATTR_CONST_NOTHROW_LEAF_LIST);
ftype = build_function_type_list (integer_type_node,
long_double_type_node, NULL_TREE);
gfc_define_builtin("__builtin_signbitl", ftype, BUILT_IN_SIGNBITL,
"signbitl", ATTR_CONST_NOTHROW_LEAF_LIST);


#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
builtin_types[(int) ENUM] = VALUE;
Expand Down
6 changes: 5 additions & 1 deletion gcc/fortran/mathbuiltins.def
Expand Up @@ -62,11 +62,15 @@ OTHER_BUILTIN (CPOW, "cpow", cpow, true)
OTHER_BUILTIN (FABS, "fabs", 1, true)
OTHER_BUILTIN (FMOD, "fmod", 2, true)
OTHER_BUILTIN (FREXP, "frexp", frexp, false)
OTHER_BUILTIN (LOGB, "logb", 1, true)
OTHER_BUILTIN (LLROUND, "llround", llround, true)
OTHER_BUILTIN (LROUND, "lround", lround, true)
OTHER_BUILTIN (IROUND, "iround", iround, true)
OTHER_BUILTIN (NEXTAFTER, "nextafter", 2, true)
OTHER_BUILTIN (POW, "pow", 1, true)
OTHER_BUILTIN (POW, "pow", 2, true)
OTHER_BUILTIN (REMAINDER, "remainder", 2, true)
OTHER_BUILTIN (RINT, "rint", 1, true)
OTHER_BUILTIN (ROUND, "round", 1, true)
OTHER_BUILTIN (SCALBN, "scalbn", scalbn, true)
OTHER_BUILTIN (SIGNBIT, "signbit", iround, true)
OTHER_BUILTIN (TRUNC, "trunc", 1, true)
34 changes: 2 additions & 32 deletions gcc/fortran/trans-decl.c
Expand Up @@ -5619,36 +5619,6 @@ is_ieee_module_used (gfc_namespace *ns)
}


static tree
save_fp_state (stmtblock_t *block)
{
tree type, fpstate, tmp;

type = build_array_type (char_type_node,
build_range_type (size_type_node, size_zero_node,
size_int (32)));
fpstate = gfc_create_var (type, "fpstate");
fpstate = gfc_build_addr_expr (pvoid_type_node, fpstate);

tmp = build_call_expr_loc (input_location, gfor_fndecl_ieee_procedure_entry,
1, fpstate);
gfc_add_expr_to_block (block, tmp);

return fpstate;
}


static void
restore_fp_state (stmtblock_t *block, tree fpstate)
{
tree tmp;

tmp = build_call_expr_loc (input_location, gfor_fndecl_ieee_procedure_exit,
1, fpstate);
gfc_add_expr_to_block (block, tmp);
}


/* Generate code for a function. */

void
Expand Down Expand Up @@ -5760,7 +5730,7 @@ gfc_generate_function_code (gfc_namespace * ns)
the floating point state. */
ieee = is_ieee_module_used (ns);
if (ieee)
fpstate = save_fp_state (&init);
fpstate = gfc_save_fp_state (&init);

/* Now generate the code for the body of this function. */
gfc_init_block (&body);
Expand Down Expand Up @@ -5847,7 +5817,7 @@ gfc_generate_function_code (gfc_namespace * ns)

/* If IEEE modules are loaded, restore the floating-point state. */
if (ieee)
restore_fp_state (&cleanup, fpstate);
gfc_restore_fp_state (&cleanup, fpstate);

/* Finish the function body and add init and cleanup code. */
tmp = gfc_finish_block (&body);
Expand Down
5 changes: 5 additions & 0 deletions gcc/fortran/trans-expr.c
Expand Up @@ -5768,6 +5768,11 @@ gfc_conv_function_expr (gfc_se * se, gfc_expr * expr)
if (!sym)
sym = expr->symtree->n.sym;

/* The IEEE_ARITHMETIC functions are caught here. */
if (sym->from_intmod == INTMOD_IEEE_ARITHMETIC)
if (gfc_conv_ieee_arithmetic_function (se, expr))
return;

/* We distinguish statement functions from general functions to improve
runtime performance. */
if (sym->attr.proc == PROC_ST_FUNCTION)
Expand Down

0 comments on commit d733353

Please sign in to comment.