+2012-03-15 Janne Blomqvist <jb@gcc.gnu.org>
+
+ * f95-lang.c (gfc_init_builtin_functions): Initialize
+ BUILT_IN_IROUND.
+ * mathbuiltins.def: Add IROUND.
+ * trans-intrinsic.c (build_round_expr): Use BUILT_IN_IROUND if
+ type size matches.
+ (gfc_build_intrinsic_lib_fndecls): Build iround functions.
+
2012-03-12 Richard Guenther <rguenther@suse.de>
* f95-lang.c (builtin_type_for_size): Use gfc_type_for_size.
gfc_define_builtin ("__builtin_fmodf", mfunc_float[1],
BUILT_IN_FMODF, "fmodf", ATTR_CONST_NOTHROW_LEAF_LIST);
- /* lround{f,,l} and llround{f,,l} */
+ /* iround{f,,l}, lround{f,,l} and llround{f,,l} */
+ ftype = build_function_type_list (integer_type_node,
+ float_type_node, NULL_TREE);
+ gfc_define_builtin("__builtin_iroundf", ftype, BUILT_IN_IROUNDF,
+ "iroundf", ATTR_CONST_NOTHROW_LEAF_LIST);
ftype = build_function_type_list (long_integer_type_node,
float_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_lroundf", ftype, BUILT_IN_LROUNDF,
gfc_define_builtin ("__builtin_llroundf", ftype, BUILT_IN_LLROUNDF,
"llroundf", ATTR_CONST_NOTHROW_LEAF_LIST);
+ ftype = build_function_type_list (integer_type_node,
+ double_type_node, NULL_TREE);
+ gfc_define_builtin("__builtin_iround", ftype, BUILT_IN_IROUND,
+ "iround", ATTR_CONST_NOTHROW_LEAF_LIST);
ftype = build_function_type_list (long_integer_type_node,
double_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_lround", ftype, BUILT_IN_LROUND,
gfc_define_builtin ("__builtin_llround", ftype, BUILT_IN_LLROUND,
"llround", ATTR_CONST_NOTHROW_LEAF_LIST);
+ ftype = build_function_type_list (integer_type_node,
+ long_double_type_node, NULL_TREE);
+ gfc_define_builtin("__builtin_iroundl", ftype, BUILT_IN_IROUNDL,
+ "iroundl", ATTR_CONST_NOTHROW_LEAF_LIST);
ftype = build_function_type_list (long_integer_type_node,
long_double_type_node, NULL_TREE);
gfc_define_builtin ("__builtin_lroundl", ftype, BUILT_IN_LROUNDL,
OTHER_BUILTIN (FREXP, "frexp", frexp, false)
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 (ROUND, "round", 1, true)
{
tree argtype;
tree fn;
- bool longlong;
int argprec, resprec;
argtype = TREE_TYPE (arg);
argprec = TYPE_PRECISION (argtype);
resprec = TYPE_PRECISION (restype);
- /* Depending on the type of the result, choose the long int intrinsic
- (lround family) or long long intrinsic (llround). We might also
- need to convert the result afterwards. */
- if (resprec <= LONG_TYPE_SIZE)
- longlong = false;
+ /* Depending on the type of the result, choose the int intrinsic
+ (iround, available only as a builtin), long int intrinsic (lround
+ family) or long long intrinsic (llround). We might also need to
+ convert the result afterwards. */
+ if (resprec <= INT_TYPE_SIZE)
+ fn = builtin_decl_for_precision (BUILT_IN_IROUND, argprec);
+ else if (resprec <= LONG_TYPE_SIZE)
+ fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
else if (resprec <= LONG_LONG_TYPE_SIZE)
- longlong = true;
- else
- gcc_unreachable ();
-
- /* Now, depending on the argument type, we choose between intrinsics. */
- if (longlong)
fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
else
- fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
+ gcc_unreachable ();
return fold_convert (restype, build_call_expr_loc (input_location,
fn, 1, arg));
q-suffixed functions. */
tree type, complex_type, func_1, func_2, func_cabs, func_frexp;
- tree func_lround, func_llround, func_scalbn, func_cpow;
+ tree func_iround, func_lround, func_llround, func_scalbn, func_cpow;
memset (quad_decls, 0, sizeof(tree) * (END_BUILTINS + 1));
complex_type = complex_float128_type_node;
/* type (*) (type) */
func_1 = build_function_type_list (type, type, NULL_TREE);
+ /* int (*) (type) */
+ func_iround = build_function_type_list (integer_type_node,
+ type, NULL_TREE);
/* long (*) (type) */
func_lround = build_function_type_list (long_integer_type_node,
type, NULL_TREE);