1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
28 #include "tm.h" /* For UNITS_PER_WORD. */
31 #include "diagnostic-core.h" /* For internal_error. */
32 #include "toplev.h" /* For rest_of_decl_compilation. */
36 #include "intrinsic.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43 #include "trans-stmt.h"
45 /* This maps fortran intrinsic math functions to external library or GCC
47 typedef struct GTY(()) gfc_intrinsic_map_t {
48 /* The explicit enum is required to work around inadequacies in the
49 garbage collection/gengtype parsing mechanism. */
52 /* Enum value from the "language-independent", aka C-centric, part
53 of gcc, or END_BUILTINS of no such value set. */
54 enum built_in_function float_built_in;
55 enum built_in_function double_built_in;
56 enum built_in_function long_double_built_in;
57 enum built_in_function complex_float_built_in;
58 enum built_in_function complex_double_built_in;
59 enum built_in_function complex_long_double_built_in;
61 /* True if the naming pattern is to prepend "c" for complex and
62 append "f" for kind=4. False if the naming pattern is to
63 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
66 /* True if a complex version of the function exists. */
67 bool complex_available;
69 /* True if the function should be marked const. */
72 /* The base library name of this function. */
75 /* Cache decls created for the various operand types. */
87 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
88 defines complex variants of all of the entries in mathbuiltins.def
90 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
91 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
92 BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
93 true, false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
94 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
96 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
97 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
98 BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, BUILT_IN_C ## ID, \
99 BUILT_IN_C ## ID ## L, true, true, true, NAME, NULL_TREE, NULL_TREE, \
100 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
102 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
103 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
104 END_BUILTINS, END_BUILTINS, END_BUILTINS, \
105 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
106 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
108 #define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
109 { GFC_ISYM_NONE, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
110 BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
111 true, false, CONST, NAME, NULL_TREE, NULL_TREE, \
112 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
114 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
116 /* Functions built into gcc itself (DEFINE_MATH_BUILTIN and
117 DEFINE_MATH_BUILTIN_C), then the built-ins that don't correspond
118 to any GFC_ISYM id directly, which use the OTHER_BUILTIN macro. */
119 #include "mathbuiltins.def"
121 /* Functions in libgfortran. */
122 LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
125 LIB_FUNCTION (NONE, NULL, false)
130 #undef DEFINE_MATH_BUILTIN
131 #undef DEFINE_MATH_BUILTIN_C
134 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
137 /* Find the correct variant of a given builtin from its argument. */
139 builtin_decl_for_precision (enum built_in_function base_built_in,
142 int i = END_BUILTINS;
144 gfc_intrinsic_map_t *m;
145 for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
148 if (precision == TYPE_PRECISION (float_type_node))
149 i = m->float_built_in;
150 else if (precision == TYPE_PRECISION (double_type_node))
151 i = m->double_built_in;
152 else if (precision == TYPE_PRECISION (long_double_type_node))
153 i = m->long_double_built_in;
154 else if (precision == TYPE_PRECISION (float128_type_node))
156 /* Special treatment, because it is not exactly a built-in, but
157 a library function. */
158 return m->real16_decl;
161 return (i == END_BUILTINS ? NULL_TREE : built_in_decls[i]);
166 gfc_builtin_decl_for_float_kind (enum built_in_function double_built_in,
169 int i = gfc_validate_kind (BT_REAL, kind, false);
171 if (gfc_real_kinds[i].c_float128)
173 /* For __float128, the story is a bit different, because we return
174 a decl to a library function rather than a built-in. */
175 gfc_intrinsic_map_t *m;
176 for (m = gfc_intrinsic_map; m->double_built_in != double_built_in ; m++)
179 return m->real16_decl;
182 return builtin_decl_for_precision (double_built_in,
183 gfc_real_kinds[i].mode_precision);
187 /* Evaluate the arguments to an intrinsic function. The value
188 of NARGS may be less than the actual number of arguments in EXPR
189 to allow optional "KIND" arguments that are not included in the
190 generated code to be ignored. */
193 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
194 tree *argarray, int nargs)
196 gfc_actual_arglist *actual;
198 gfc_intrinsic_arg *formal;
202 formal = expr->value.function.isym->formal;
203 actual = expr->value.function.actual;
205 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
206 actual = actual->next,
207 formal = formal ? formal->next : NULL)
211 /* Skip omitted optional arguments. */
218 /* Evaluate the parameter. This will substitute scalarized
219 references automatically. */
220 gfc_init_se (&argse, se);
222 if (e->ts.type == BT_CHARACTER)
224 gfc_conv_expr (&argse, e);
225 gfc_conv_string_parameter (&argse);
226 argarray[curr_arg++] = argse.string_length;
227 gcc_assert (curr_arg < nargs);
230 gfc_conv_expr_val (&argse, e);
232 /* If an optional argument is itself an optional dummy argument,
233 check its presence and substitute a null if absent. */
234 if (e->expr_type == EXPR_VARIABLE
235 && e->symtree->n.sym->attr.optional
238 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
240 gfc_add_block_to_block (&se->pre, &argse.pre);
241 gfc_add_block_to_block (&se->post, &argse.post);
242 argarray[curr_arg] = argse.expr;
246 /* Count the number of actual arguments to the intrinsic function EXPR
247 including any "hidden" string length arguments. */
250 gfc_intrinsic_argument_list_length (gfc_expr *expr)
253 gfc_actual_arglist *actual;
255 for (actual = expr->value.function.actual; actual; actual = actual->next)
260 if (actual->expr->ts.type == BT_CHARACTER)
270 /* Conversions between different types are output by the frontend as
271 intrinsic functions. We implement these directly with inline code. */
274 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
280 nargs = gfc_intrinsic_argument_list_length (expr);
281 args = XALLOCAVEC (tree, nargs);
283 /* Evaluate all the arguments passed. Whilst we're only interested in the
284 first one here, there are other parts of the front-end that assume this
285 and will trigger an ICE if it's not the case. */
286 type = gfc_typenode_for_spec (&expr->ts);
287 gcc_assert (expr->value.function.actual->expr);
288 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
290 /* Conversion between character kinds involves a call to a library
292 if (expr->ts.type == BT_CHARACTER)
294 tree fndecl, var, addr, tmp;
296 if (expr->ts.kind == 1
297 && expr->value.function.actual->expr->ts.kind == 4)
298 fndecl = gfor_fndecl_convert_char4_to_char1;
299 else if (expr->ts.kind == 4
300 && expr->value.function.actual->expr->ts.kind == 1)
301 fndecl = gfor_fndecl_convert_char1_to_char4;
305 /* Create the variable storing the converted value. */
306 type = gfc_get_pchar_type (expr->ts.kind);
307 var = gfc_create_var (type, "str");
308 addr = gfc_build_addr_expr (build_pointer_type (type), var);
310 /* Call the library function that will perform the conversion. */
311 gcc_assert (nargs >= 2);
312 tmp = build_call_expr_loc (input_location,
313 fndecl, 3, addr, args[0], args[1]);
314 gfc_add_expr_to_block (&se->pre, tmp);
316 /* Free the temporary afterwards. */
317 tmp = gfc_call_free (var);
318 gfc_add_expr_to_block (&se->post, tmp);
321 se->string_length = args[0];
326 /* Conversion from complex to non-complex involves taking the real
327 component of the value. */
328 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
329 && expr->ts.type != BT_COMPLEX)
333 artype = TREE_TYPE (TREE_TYPE (args[0]));
334 args[0] = fold_build1_loc (input_location, REALPART_EXPR, artype,
338 se->expr = convert (type, args[0]);
341 /* This is needed because the gcc backend only implements
342 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
343 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
344 Similarly for CEILING. */
347 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
354 argtype = TREE_TYPE (arg);
355 arg = gfc_evaluate_now (arg, pblock);
357 intval = convert (type, arg);
358 intval = gfc_evaluate_now (intval, pblock);
360 tmp = convert (argtype, intval);
361 cond = fold_build2_loc (input_location, up ? GE_EXPR : LE_EXPR,
362 boolean_type_node, tmp, arg);
364 tmp = fold_build2_loc (input_location, up ? PLUS_EXPR : MINUS_EXPR, type,
365 intval, build_int_cst (type, 1));
366 tmp = fold_build3_loc (input_location, COND_EXPR, type, cond, intval, tmp);
371 /* Round to nearest integer, away from zero. */
374 build_round_expr (tree arg, tree restype)
379 int argprec, resprec;
381 argtype = TREE_TYPE (arg);
382 argprec = TYPE_PRECISION (argtype);
383 resprec = TYPE_PRECISION (restype);
385 /* Depending on the type of the result, choose the long int intrinsic
386 (lround family) or long long intrinsic (llround). We might also
387 need to convert the result afterwards. */
388 if (resprec <= LONG_TYPE_SIZE)
390 else if (resprec <= LONG_LONG_TYPE_SIZE)
395 /* Now, depending on the argument type, we choose between intrinsics. */
397 fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
399 fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
401 return fold_convert (restype, build_call_expr_loc (input_location,
406 /* Convert a real to an integer using a specific rounding mode.
407 Ideally we would just build the corresponding GENERIC node,
408 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
411 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
412 enum rounding_mode op)
417 return build_fixbound_expr (pblock, arg, type, 0);
421 return build_fixbound_expr (pblock, arg, type, 1);
425 return build_round_expr (arg, type);
429 return fold_build1_loc (input_location, FIX_TRUNC_EXPR, type, arg);
438 /* Round a real value using the specified rounding mode.
439 We use a temporary integer of that same kind size as the result.
440 Values larger than those that can be represented by this kind are
441 unchanged, as they will not be accurate enough to represent the
443 huge = HUGE (KIND (a))
444 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
448 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
460 kind = expr->ts.kind;
461 nargs = gfc_intrinsic_argument_list_length (expr);
464 /* We have builtin functions for some cases. */
468 decl = gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
472 decl = gfc_builtin_decl_for_float_kind (BUILT_IN_TRUNC, kind);
479 /* Evaluate the argument. */
480 gcc_assert (expr->value.function.actual->expr);
481 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
483 /* Use a builtin function if one exists. */
484 if (decl != NULL_TREE)
486 se->expr = build_call_expr_loc (input_location, decl, 1, arg[0]);
490 /* This code is probably redundant, but we'll keep it lying around just
492 type = gfc_typenode_for_spec (&expr->ts);
493 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
495 /* Test if the value is too large to handle sensibly. */
496 gfc_set_model_kind (kind);
498 n = gfc_validate_kind (BT_INTEGER, kind, false);
499 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
500 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
501 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, arg[0],
504 mpfr_neg (huge, huge, GFC_RND_MODE);
505 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
506 tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, arg[0],
508 cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node,
510 itype = gfc_get_int_type (kind);
512 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
513 tmp = convert (type, tmp);
514 se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, tmp,
520 /* Convert to an integer using the specified rounding mode. */
523 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
529 nargs = gfc_intrinsic_argument_list_length (expr);
530 args = XALLOCAVEC (tree, nargs);
532 /* Evaluate the argument, we process all arguments even though we only
533 use the first one for code generation purposes. */
534 type = gfc_typenode_for_spec (&expr->ts);
535 gcc_assert (expr->value.function.actual->expr);
536 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
538 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
540 /* Conversion to a different integer kind. */
541 se->expr = convert (type, args[0]);
545 /* Conversion from complex to non-complex involves taking the real
546 component of the value. */
547 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
548 && expr->ts.type != BT_COMPLEX)
552 artype = TREE_TYPE (TREE_TYPE (args[0]));
553 args[0] = fold_build1_loc (input_location, REALPART_EXPR, artype,
557 se->expr = build_fix_expr (&se->pre, args[0], type, op);
562 /* Get the imaginary component of a value. */
565 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
569 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
570 se->expr = fold_build1_loc (input_location, IMAGPART_EXPR,
571 TREE_TYPE (TREE_TYPE (arg)), arg);
575 /* Get the complex conjugate of a value. */
578 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
582 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
583 se->expr = fold_build1_loc (input_location, CONJ_EXPR, TREE_TYPE (arg), arg);
589 define_quad_builtin (const char *name, tree type, bool is_const)
592 fndecl = build_decl (input_location, FUNCTION_DECL, get_identifier (name),
595 /* Mark the decl as external. */
596 DECL_EXTERNAL (fndecl) = 1;
597 TREE_PUBLIC (fndecl) = 1;
599 /* Mark it __attribute__((const)). */
600 TREE_READONLY (fndecl) = is_const;
602 rest_of_decl_compilation (fndecl, 1, 0);
609 /* Initialize function decls for library functions. The external functions
610 are created as required. Builtin functions are added here. */
613 gfc_build_intrinsic_lib_fndecls (void)
615 gfc_intrinsic_map_t *m;
616 tree quad_decls[END_BUILTINS + 1];
618 if (gfc_real16_is_float128)
620 /* If we have soft-float types, we create the decls for their
621 C99-like library functions. For now, we only handle __float128
622 q-suffixed functions. */
624 tree tmp, func_1, func_2, func_cabs, func_frexp;
625 tree func_lround, func_llround, func_scalbn, func_cpow;
627 memset (quad_decls, 0, sizeof(tree) * (END_BUILTINS + 1));
629 /* type (*) (type) */
630 tmp = tree_cons (NULL_TREE, float128_type_node, void_list_node);
631 func_1 = build_function_type (float128_type_node, tmp);
632 /* long (*) (type) */
633 func_lround = build_function_type (long_integer_type_node, tmp);
634 /* long long (*) (type) */
635 func_llround = build_function_type (long_long_integer_type_node, tmp);
636 /* type (*) (type, type) */
637 tmp = tree_cons (NULL_TREE, float128_type_node, tmp);
638 func_2 = build_function_type (float128_type_node, tmp);
639 /* type (*) (type, &int) */
640 tmp = tree_cons (NULL_TREE, float128_type_node, void_list_node);
641 tmp = tree_cons (NULL_TREE, build_pointer_type (integer_type_node), tmp);
642 func_frexp = build_function_type (float128_type_node, tmp);
643 /* type (*) (type, int) */
644 tmp = tree_cons (NULL_TREE, float128_type_node, void_list_node);
645 tmp = tree_cons (NULL_TREE, integer_type_node, tmp);
646 func_scalbn = build_function_type (float128_type_node, tmp);
647 /* type (*) (complex type) */
648 tmp = tree_cons (NULL_TREE, complex_float128_type_node, void_list_node);
649 func_cabs = build_function_type (float128_type_node, tmp);
650 /* complex type (*) (complex type, complex type) */
651 tmp = tree_cons (NULL_TREE, complex_float128_type_node, tmp);
652 func_cpow = build_function_type (complex_float128_type_node, tmp);
654 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE)
655 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE)
656 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX)
658 /* Only these built-ins are actually needed here. These are used directly
659 from the code, when calling builtin_decl_for_precision() or
660 builtin_decl_for_float_type(). The others are all constructed by
661 gfc_get_intrinsic_lib_fndecl(). */
662 #define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
663 quad_decls[BUILT_IN_ ## ID] = define_quad_builtin (NAME "q", func_ ## TYPE, CONST);
665 #include "mathbuiltins.def"
669 #undef DEFINE_MATH_BUILTIN
670 #undef DEFINE_MATH_BUILTIN_C
674 /* Add GCC builtin functions. */
675 for (m = gfc_intrinsic_map;
676 m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
678 if (m->float_built_in != END_BUILTINS)
679 m->real4_decl = built_in_decls[m->float_built_in];
680 if (m->complex_float_built_in != END_BUILTINS)
681 m->complex4_decl = built_in_decls[m->complex_float_built_in];
682 if (m->double_built_in != END_BUILTINS)
683 m->real8_decl = built_in_decls[m->double_built_in];
684 if (m->complex_double_built_in != END_BUILTINS)
685 m->complex8_decl = built_in_decls[m->complex_double_built_in];
687 /* If real(kind=10) exists, it is always long double. */
688 if (m->long_double_built_in != END_BUILTINS)
689 m->real10_decl = built_in_decls[m->long_double_built_in];
690 if (m->complex_long_double_built_in != END_BUILTINS)
691 m->complex10_decl = built_in_decls[m->complex_long_double_built_in];
693 if (!gfc_real16_is_float128)
695 if (m->long_double_built_in != END_BUILTINS)
696 m->real16_decl = built_in_decls[m->long_double_built_in];
697 if (m->complex_long_double_built_in != END_BUILTINS)
698 m->complex16_decl = built_in_decls[m->complex_long_double_built_in];
700 else if (quad_decls[m->double_built_in] != NULL_TREE)
702 /* Quad-precision function calls are constructed when first
703 needed by builtin_decl_for_precision(), except for those
704 that will be used directly (define by OTHER_BUILTIN). */
705 m->real16_decl = quad_decls[m->double_built_in];
707 else if (quad_decls[m->complex_double_built_in] != NULL_TREE)
709 /* Same thing for the complex ones. */
710 m->complex16_decl = quad_decls[m->double_built_in];
716 /* Create a fndecl for a simple intrinsic library function. */
719 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
724 gfc_actual_arglist *actual;
727 char name[GFC_MAX_SYMBOL_LEN + 3];
730 if (ts->type == BT_REAL)
735 pdecl = &m->real4_decl;
738 pdecl = &m->real8_decl;
741 pdecl = &m->real10_decl;
744 pdecl = &m->real16_decl;
750 else if (ts->type == BT_COMPLEX)
752 gcc_assert (m->complex_available);
757 pdecl = &m->complex4_decl;
760 pdecl = &m->complex8_decl;
763 pdecl = &m->complex10_decl;
766 pdecl = &m->complex16_decl;
780 int n = gfc_validate_kind (BT_REAL, ts->kind, false);
781 if (gfc_real_kinds[n].c_float)
782 snprintf (name, sizeof (name), "%s%s%s",
783 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
784 else if (gfc_real_kinds[n].c_double)
785 snprintf (name, sizeof (name), "%s%s",
786 ts->type == BT_COMPLEX ? "c" : "", m->name);
787 else if (gfc_real_kinds[n].c_long_double)
788 snprintf (name, sizeof (name), "%s%s%s",
789 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
790 else if (gfc_real_kinds[n].c_float128)
791 snprintf (name, sizeof (name), "%s%s%s",
792 ts->type == BT_COMPLEX ? "c" : "", m->name, "q");
798 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
799 ts->type == BT_COMPLEX ? 'c' : 'r',
803 argtypes = NULL_TREE;
804 for (actual = expr->value.function.actual; actual; actual = actual->next)
806 type = gfc_typenode_for_spec (&actual->expr->ts);
807 argtypes = gfc_chainon_list (argtypes, type);
809 argtypes = chainon (argtypes, void_list_node);
810 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
811 fndecl = build_decl (input_location,
812 FUNCTION_DECL, get_identifier (name), type);
814 /* Mark the decl as external. */
815 DECL_EXTERNAL (fndecl) = 1;
816 TREE_PUBLIC (fndecl) = 1;
818 /* Mark it __attribute__((const)), if possible. */
819 TREE_READONLY (fndecl) = m->is_constant;
821 rest_of_decl_compilation (fndecl, 1, 0);
828 /* Convert an intrinsic function into an external or builtin call. */
831 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
833 gfc_intrinsic_map_t *m;
837 unsigned int num_args;
840 id = expr->value.function.isym->id;
841 /* Find the entry for this function. */
842 for (m = gfc_intrinsic_map;
843 m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
849 if (m->id == GFC_ISYM_NONE)
851 internal_error ("Intrinsic function %s(%d) not recognized",
852 expr->value.function.name, id);
855 /* Get the decl and generate the call. */
856 num_args = gfc_intrinsic_argument_list_length (expr);
857 args = XALLOCAVEC (tree, num_args);
859 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
860 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
861 rettype = TREE_TYPE (TREE_TYPE (fndecl));
863 fndecl = build_addr (fndecl, current_function_decl);
864 se->expr = build_call_array_loc (input_location, rettype, fndecl, num_args, args);
868 /* If bounds-checking is enabled, create code to verify at runtime that the
869 string lengths for both expressions are the same (needed for e.g. MERGE).
870 If bounds-checking is not enabled, does nothing. */
873 gfc_trans_same_strlen_check (const char* intr_name, locus* where,
874 tree a, tree b, stmtblock_t* target)
879 /* If bounds-checking is disabled, do nothing. */
880 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
883 /* Compare the two string lengths. */
884 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, a, b);
886 /* Output the runtime-check. */
887 name = gfc_build_cstring_const (intr_name);
888 name = gfc_build_addr_expr (pchar_type_node, name);
889 gfc_trans_runtime_check (true, false, cond, target, where,
890 "Unequal character lengths (%ld/%ld) in %s",
891 fold_convert (long_integer_type_node, a),
892 fold_convert (long_integer_type_node, b), name);
896 /* The EXPONENT(s) intrinsic function is translated into
903 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
905 tree arg, type, res, tmp, frexp;
907 frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP,
908 expr->value.function.actual->expr->ts.kind);
910 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
912 res = gfc_create_var (integer_type_node, NULL);
913 tmp = build_call_expr_loc (input_location, frexp, 2, arg,
914 gfc_build_addr_expr (NULL_TREE, res));
915 gfc_add_expr_to_block (&se->pre, tmp);
917 type = gfc_typenode_for_spec (&expr->ts);
918 se->expr = fold_convert (type, res);
922 trans_this_image (gfc_se * se, gfc_expr *expr ATTRIBUTE_UNUSED)
924 gfc_init_coarray_decl ();
925 se->expr = gfort_gvar_caf_this_image;
929 trans_num_images (gfc_se * se)
931 gfc_init_coarray_decl ();
932 se->expr = gfort_gvar_caf_num_images;
936 /* Evaluate a single upper or lower bound. */
937 /* TODO: bound intrinsic generates way too much unnecessary code. */
940 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
942 gfc_actual_arglist *arg;
943 gfc_actual_arglist *arg2;
948 tree cond, cond1, cond3, cond4, size;
955 arg = expr->value.function.actual;
960 /* Create an implicit second parameter from the loop variable. */
961 gcc_assert (!arg2->expr);
962 gcc_assert (se->loop->dimen == 1);
963 gcc_assert (se->ss->expr == expr);
964 gfc_advance_se_ss_chain (se);
965 bound = se->loop->loopvar[0];
966 bound = fold_build2_loc (input_location, MINUS_EXPR,
967 gfc_array_index_type, bound,
972 /* use the passed argument. */
973 gcc_assert (arg2->expr);
974 gfc_init_se (&argse, NULL);
975 gfc_conv_expr_type (&argse, arg2->expr, gfc_array_index_type);
976 gfc_add_block_to_block (&se->pre, &argse.pre);
978 /* Convert from one based to zero based. */
979 bound = fold_build2_loc (input_location, MINUS_EXPR,
980 gfc_array_index_type, bound,
984 /* TODO: don't re-evaluate the descriptor on each iteration. */
985 /* Get a descriptor for the first parameter. */
986 ss = gfc_walk_expr (arg->expr);
987 gcc_assert (ss != gfc_ss_terminator);
988 gfc_init_se (&argse, NULL);
989 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
990 gfc_add_block_to_block (&se->pre, &argse.pre);
991 gfc_add_block_to_block (&se->post, &argse.post);
995 if (INTEGER_CST_P (bound))
999 hi = TREE_INT_CST_HIGH (bound);
1000 low = TREE_INT_CST_LOW (bound);
1001 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
1002 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
1003 "dimension index", upper ? "UBOUND" : "LBOUND",
1008 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1010 bound = gfc_evaluate_now (bound, &se->pre);
1011 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1012 bound, build_int_cst (TREE_TYPE (bound), 0));
1013 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
1014 tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
1016 cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
1017 boolean_type_node, cond, tmp);
1018 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
1023 ubound = gfc_conv_descriptor_ubound_get (desc, bound);
1024 lbound = gfc_conv_descriptor_lbound_get (desc, bound);
1026 as = gfc_get_full_arrayspec_from_expr (arg->expr);
1028 /* 13.14.53: Result value for LBOUND
1030 Case (i): For an array section or for an array expression other than a
1031 whole array or array structure component, LBOUND(ARRAY, DIM)
1032 has the value 1. For a whole array or array structure
1033 component, LBOUND(ARRAY, DIM) has the value:
1034 (a) equal to the lower bound for subscript DIM of ARRAY if
1035 dimension DIM of ARRAY does not have extent zero
1036 or if ARRAY is an assumed-size array of rank DIM,
1039 13.14.113: Result value for UBOUND
1041 Case (i): For an array section or for an array expression other than a
1042 whole array or array structure component, UBOUND(ARRAY, DIM)
1043 has the value equal to the number of elements in the given
1044 dimension; otherwise, it has a value equal to the upper bound
1045 for subscript DIM of ARRAY if dimension DIM of ARRAY does
1046 not have size zero and has value zero if dimension DIM has
1051 tree stride = gfc_conv_descriptor_stride_get (desc, bound);
1053 cond1 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
1055 cond3 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
1056 stride, gfc_index_zero_node);
1057 cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1058 boolean_type_node, cond3, cond1);
1059 cond4 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1060 stride, gfc_index_zero_node);
1065 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1066 boolean_type_node, cond3, cond4);
1067 cond5 = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1068 gfc_index_one_node, lbound);
1069 cond5 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1070 boolean_type_node, cond4, cond5);
1072 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1073 boolean_type_node, cond, cond5);
1075 se->expr = fold_build3_loc (input_location, COND_EXPR,
1076 gfc_array_index_type, cond,
1077 ubound, gfc_index_zero_node);
1081 if (as->type == AS_ASSUMED_SIZE)
1082 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1083 bound, build_int_cst (TREE_TYPE (bound),
1084 arg->expr->rank - 1));
1086 cond = boolean_false_node;
1088 cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1089 boolean_type_node, cond3, cond4);
1090 cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1091 boolean_type_node, cond, cond1);
1093 se->expr = fold_build3_loc (input_location, COND_EXPR,
1094 gfc_array_index_type, cond,
1095 lbound, gfc_index_one_node);
1102 size = fold_build2_loc (input_location, MINUS_EXPR,
1103 gfc_array_index_type, ubound, lbound);
1104 se->expr = fold_build2_loc (input_location, PLUS_EXPR,
1105 gfc_array_index_type, size,
1106 gfc_index_one_node);
1107 se->expr = fold_build2_loc (input_location, MAX_EXPR,
1108 gfc_array_index_type, se->expr,
1109 gfc_index_zero_node);
1112 se->expr = gfc_index_one_node;
1115 type = gfc_typenode_for_spec (&expr->ts);
1116 se->expr = convert (type, se->expr);
1121 conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
1123 gfc_actual_arglist *arg;
1124 gfc_actual_arglist *arg2;
1127 tree bound, resbound, resbound2, desc, cond, tmp;
1129 gfc_array_spec * as;
1132 gcc_assert (expr->value.function.isym->id == GFC_ISYM_LCOBOUND
1133 || expr->value.function.isym->id == GFC_ISYM_UCOBOUND
1134 || expr->value.function.isym->id == GFC_ISYM_THIS_IMAGE);
1136 arg = expr->value.function.actual;
1139 gcc_assert (arg->expr->expr_type == EXPR_VARIABLE);
1140 corank = gfc_get_corank (arg->expr);
1142 as = gfc_get_full_arrayspec_from_expr (arg->expr);
1145 ss = gfc_walk_expr (arg->expr);
1146 gcc_assert (ss != gfc_ss_terminator);
1147 ss->data.info.codimen = corank;
1148 gfc_init_se (&argse, NULL);
1150 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
1151 gfc_add_block_to_block (&se->pre, &argse.pre);
1152 gfc_add_block_to_block (&se->post, &argse.post);
1160 /* Create an implicit second parameter from the loop variable. */
1161 gcc_assert (!arg2->expr);
1162 gcc_assert (corank > 0);
1163 gcc_assert (se->loop->dimen == 1);
1164 gcc_assert (se->ss->expr == expr);
1166 mpz_init_set_ui (mpz_rank, arg->expr->rank);
1167 tree_rank = gfc_conv_mpz_to_tree (mpz_rank, gfc_index_integer_kind);
1169 bound = se->loop->loopvar[0];
1170 bound = fold_build2 (PLUS_EXPR, gfc_array_index_type, bound,
1171 se->ss->data.info.delta[0]);
1172 bound = fold_build2 (PLUS_EXPR, gfc_array_index_type, bound,
1174 gfc_advance_se_ss_chain (se);
1178 /* use the passed argument. */
1179 gcc_assert (arg2->expr);
1180 gfc_init_se (&argse, NULL);
1181 gfc_conv_expr_type (&argse, arg2->expr, gfc_array_index_type);
1182 gfc_add_block_to_block (&se->pre, &argse.pre);
1185 if (INTEGER_CST_P (bound))
1189 hi = TREE_INT_CST_HIGH (bound);
1190 low = TREE_INT_CST_LOW (bound);
1191 if (hi || low < 1 || low > GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc)))
1192 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
1193 "dimension index", expr->value.function.isym->name,
1196 else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1198 bound = gfc_evaluate_now (bound, &se->pre);
1199 cond = fold_build2 (LT_EXPR, boolean_type_node,
1200 bound, build_int_cst (TREE_TYPE (bound), 1));
1201 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))];
1202 tmp = fold_build2 (GT_EXPR, boolean_type_node, bound, tmp);
1203 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
1204 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
1209 /* Substract 1 to get to zero based and add dimensions. */
1210 switch (arg->expr->rank)
1213 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
1214 gfc_index_one_node);
1218 bound = fold_build2 (PLUS_EXPR, gfc_array_index_type, bound,
1219 gfc_rank_cst[arg->expr->rank - 1]);
1223 resbound = gfc_conv_descriptor_lbound_get (desc, bound);
1225 if (expr->value.function.isym->id == GFC_ISYM_UCOBOUND)
1227 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
1228 build_int_cst (TREE_TYPE (bound),
1229 arg->expr->rank + corank - 1));
1230 resbound2 = gfc_conv_descriptor_ubound_get (desc, bound);
1231 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
1232 resbound, resbound2);
1235 se->expr = resbound;
1237 type = gfc_typenode_for_spec (&expr->ts);
1238 se->expr = convert (type, se->expr);
1243 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
1247 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1249 switch (expr->value.function.actual->expr->ts.type)
1253 se->expr = fold_build1_loc (input_location, ABS_EXPR, TREE_TYPE (arg),
1258 cabs = gfc_builtin_decl_for_float_kind (BUILT_IN_CABS, expr->ts.kind);
1259 se->expr = build_call_expr_loc (input_location, cabs, 1, arg);
1268 /* Create a complex value from one or two real components. */
1271 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1277 unsigned int num_args;
1279 num_args = gfc_intrinsic_argument_list_length (expr);
1280 args = XALLOCAVEC (tree, num_args);
1282 type = gfc_typenode_for_spec (&expr->ts);
1283 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1284 real = convert (TREE_TYPE (type), args[0]);
1286 imag = convert (TREE_TYPE (type), args[1]);
1287 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1289 imag = fold_build1_loc (input_location, IMAGPART_EXPR,
1290 TREE_TYPE (TREE_TYPE (args[0])), args[0]);
1291 imag = convert (TREE_TYPE (type), imag);
1294 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1296 se->expr = fold_build2_loc (input_location, COMPLEX_EXPR, type, real, imag);
1299 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1300 MODULO(A, P) = A - FLOOR (A / P) * P */
1301 /* TODO: MOD(x, 0) */
1304 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1316 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1318 switch (expr->ts.type)
1321 /* Integer case is easy, we've got a builtin op. */
1322 type = TREE_TYPE (args[0]);
1325 se->expr = fold_build2_loc (input_location, FLOOR_MOD_EXPR, type,
1328 se->expr = fold_build2_loc (input_location, TRUNC_MOD_EXPR, type,
1334 /* Check if we have a builtin fmod. */
1335 fmod = gfc_builtin_decl_for_float_kind (BUILT_IN_FMOD, expr->ts.kind);
1337 /* Use it if it exists. */
1338 if (fmod != NULL_TREE)
1340 tmp = build_addr (fmod, current_function_decl);
1341 se->expr = build_call_array_loc (input_location,
1342 TREE_TYPE (TREE_TYPE (fmod)),
1348 type = TREE_TYPE (args[0]);
1350 args[0] = gfc_evaluate_now (args[0], &se->pre);
1351 args[1] = gfc_evaluate_now (args[1], &se->pre);
1354 modulo = arg - floor (arg/arg2) * arg2, so
1355 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1357 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1358 thereby avoiding another division and retaining the accuracy
1359 of the builtin function. */
1360 if (fmod != NULL_TREE && modulo)
1362 tree zero = gfc_build_const (type, integer_zero_node);
1363 tmp = gfc_evaluate_now (se->expr, &se->pre);
1364 test = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1366 test2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1368 test2 = fold_build2_loc (input_location, TRUTH_XOR_EXPR,
1369 boolean_type_node, test, test2);
1370 test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1372 test = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1373 boolean_type_node, test, test2);
1374 test = gfc_evaluate_now (test, &se->pre);
1375 se->expr = fold_build3_loc (input_location, COND_EXPR, type, test,
1376 fold_build2_loc (input_location, PLUS_EXPR,
1377 type, tmp, args[1]), tmp);
1381 /* If we do not have a built_in fmod, the calculation is going to
1382 have to be done longhand. */
1383 tmp = fold_build2_loc (input_location, RDIV_EXPR, type, args[0], args[1]);
1385 /* Test if the value is too large to handle sensibly. */
1386 gfc_set_model_kind (expr->ts.kind);
1388 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1389 ikind = expr->ts.kind;
1392 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1393 ikind = gfc_max_integer_kind;
1395 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1396 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1397 test2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1400 mpfr_neg (huge, huge, GFC_RND_MODE);
1401 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1402 test = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, tmp,
1404 test2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1405 boolean_type_node, test, test2);
1407 itype = gfc_get_int_type (ikind);
1409 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1411 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1412 tmp = convert (type, tmp);
1413 tmp = fold_build3_loc (input_location, COND_EXPR, type, test2, tmp,
1415 tmp = fold_build2_loc (input_location, MULT_EXPR, type, tmp, args[1]);
1416 se->expr = fold_build2_loc (input_location, MINUS_EXPR, type, args[0],
1426 /* DSHIFTL(I,J,S) = (I << S) | (J >> (BITSIZE(J) - S))
1427 DSHIFTR(I,J,S) = (I << (BITSIZE(I) - S)) | (J >> S)
1428 where the right shifts are logical (i.e. 0's are shifted in).
1429 Because SHIFT_EXPR's want shifts strictly smaller than the integral
1430 type width, we have to special-case both S == 0 and S == BITSIZE(J):
1432 DSHIFTL(I,J,BITSIZE) = J
1434 DSHIFTR(I,J,BITSIZE) = I. */
1437 gfc_conv_intrinsic_dshift (gfc_se * se, gfc_expr * expr, bool dshiftl)
1439 tree type, utype, stype, arg1, arg2, shift, res, left, right;
1440 tree args[3], cond, tmp;
1443 gfc_conv_intrinsic_function_args (se, expr, args, 3);
1445 gcc_assert (TREE_TYPE (args[0]) == TREE_TYPE (args[1]));
1446 type = TREE_TYPE (args[0]);
1447 bitsize = TYPE_PRECISION (type);
1448 utype = unsigned_type_for (type);
1449 stype = TREE_TYPE (args[2]);
1451 arg1 = gfc_evaluate_now (args[0], &se->pre);
1452 arg2 = gfc_evaluate_now (args[1], &se->pre);
1453 shift = gfc_evaluate_now (args[2], &se->pre);
1455 /* The generic case. */
1456 tmp = fold_build2_loc (input_location, MINUS_EXPR, stype,
1457 build_int_cst (stype, bitsize), shift);
1458 left = fold_build2_loc (input_location, LSHIFT_EXPR, type,
1459 arg1, dshiftl ? shift : tmp);
1461 right = fold_build2_loc (input_location, RSHIFT_EXPR, utype,
1462 fold_convert (utype, arg2), dshiftl ? tmp : shift);
1463 right = fold_convert (type, right);
1465 res = fold_build2_loc (input_location, BIT_IOR_EXPR, type, left, right);
1467 /* Special cases. */
1468 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, shift,
1469 build_int_cst (stype, 0));
1470 res = fold_build3_loc (input_location, COND_EXPR, type, cond,
1471 dshiftl ? arg1 : arg2, res);
1473 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, shift,
1474 build_int_cst (stype, bitsize));
1475 res = fold_build3_loc (input_location, COND_EXPR, type, cond,
1476 dshiftl ? arg2 : arg1, res);
1482 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1485 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1493 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1494 type = TREE_TYPE (args[0]);
1496 val = fold_build2_loc (input_location, MINUS_EXPR, type, args[0], args[1]);
1497 val = gfc_evaluate_now (val, &se->pre);
1499 zero = gfc_build_const (type, integer_zero_node);
1500 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, val, zero);
1501 se->expr = fold_build3_loc (input_location, COND_EXPR, type, tmp, zero, val);
1505 /* SIGN(A, B) is absolute value of A times sign of B.
1506 The real value versions use library functions to ensure the correct
1507 handling of negative zero. Integer case implemented as:
1508 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1512 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1518 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1519 if (expr->ts.type == BT_REAL)
1523 tmp = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
1524 abs = gfc_builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
1526 /* We explicitly have to ignore the minus sign. We do so by using
1527 result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1). */
1528 if (!gfc_option.flag_sign_zero
1529 && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
1532 zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
1533 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1535 se->expr = fold_build3_loc (input_location, COND_EXPR,
1536 TREE_TYPE (args[0]), cond,
1537 build_call_expr_loc (input_location, abs, 1,
1539 build_call_expr_loc (input_location, tmp, 2,
1543 se->expr = build_call_expr_loc (input_location, tmp, 2,
1548 /* Having excluded floating point types, we know we are now dealing
1549 with signed integer types. */
1550 type = TREE_TYPE (args[0]);
1552 /* Args[0] is used multiple times below. */
1553 args[0] = gfc_evaluate_now (args[0], &se->pre);
1555 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1556 the signs of A and B are the same, and of all ones if they differ. */
1557 tmp = fold_build2_loc (input_location, BIT_XOR_EXPR, type, args[0], args[1]);
1558 tmp = fold_build2_loc (input_location, RSHIFT_EXPR, type, tmp,
1559 build_int_cst (type, TYPE_PRECISION (type) - 1));
1560 tmp = gfc_evaluate_now (tmp, &se->pre);
1562 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1563 is all ones (i.e. -1). */
1564 se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, type,
1565 fold_build2_loc (input_location, PLUS_EXPR,
1566 type, args[0], tmp), tmp);
1570 /* Test for the presence of an optional argument. */
1573 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1577 arg = expr->value.function.actual->expr;
1578 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1579 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1580 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1584 /* Calculate the double precision product of two single precision values. */
1587 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1592 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1594 /* Convert the args to double precision before multiplying. */
1595 type = gfc_typenode_for_spec (&expr->ts);
1596 args[0] = convert (type, args[0]);
1597 args[1] = convert (type, args[1]);
1598 se->expr = fold_build2_loc (input_location, MULT_EXPR, type, args[0],
1603 /* Return a length one character string containing an ascii character. */
1606 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1611 unsigned int num_args;
1613 num_args = gfc_intrinsic_argument_list_length (expr);
1614 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1616 type = gfc_get_char_type (expr->ts.kind);
1617 var = gfc_create_var (type, "char");
1619 arg[0] = fold_build1_loc (input_location, NOP_EXPR, type, arg[0]);
1620 gfc_add_modify (&se->pre, var, arg[0]);
1621 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1622 se->string_length = build_int_cst (gfc_charlen_type_node, 1);
1627 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1635 unsigned int num_args;
1637 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1638 args = XALLOCAVEC (tree, num_args);
1640 var = gfc_create_var (pchar_type_node, "pstr");
1641 len = gfc_create_var (gfc_charlen_type_node, "len");
1643 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1644 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1645 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1647 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1648 tmp = build_call_array_loc (input_location,
1649 TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1650 fndecl, num_args, args);
1651 gfc_add_expr_to_block (&se->pre, tmp);
1653 /* Free the temporary afterwards, if necessary. */
1654 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1655 len, build_int_cst (TREE_TYPE (len), 0));
1656 tmp = gfc_call_free (var);
1657 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1658 gfc_add_expr_to_block (&se->post, tmp);
1661 se->string_length = len;
1666 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1674 unsigned int num_args;
1676 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1677 args = XALLOCAVEC (tree, num_args);
1679 var = gfc_create_var (pchar_type_node, "pstr");
1680 len = gfc_create_var (gfc_charlen_type_node, "len");
1682 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1683 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1684 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1686 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1687 tmp = build_call_array_loc (input_location,
1688 TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1689 fndecl, num_args, args);
1690 gfc_add_expr_to_block (&se->pre, tmp);
1692 /* Free the temporary afterwards, if necessary. */
1693 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1694 len, build_int_cst (TREE_TYPE (len), 0));
1695 tmp = gfc_call_free (var);
1696 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1697 gfc_add_expr_to_block (&se->post, tmp);
1700 se->string_length = len;
1704 /* Return a character string containing the tty name. */
1707 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1715 unsigned int num_args;
1717 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1718 args = XALLOCAVEC (tree, num_args);
1720 var = gfc_create_var (pchar_type_node, "pstr");
1721 len = gfc_create_var (gfc_charlen_type_node, "len");
1723 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1724 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1725 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1727 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1728 tmp = build_call_array_loc (input_location,
1729 TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1730 fndecl, num_args, args);
1731 gfc_add_expr_to_block (&se->pre, tmp);
1733 /* Free the temporary afterwards, if necessary. */
1734 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1735 len, build_int_cst (TREE_TYPE (len), 0));
1736 tmp = gfc_call_free (var);
1737 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1738 gfc_add_expr_to_block (&se->post, tmp);
1741 se->string_length = len;
1745 /* Get the minimum/maximum value of all the parameters.
1746 minmax (a1, a2, a3, ...)
1749 if (a2 .op. mvar || isnan(mvar))
1751 if (a3 .op. mvar || isnan(mvar))
1758 /* TODO: Mismatching types can occur when specific names are used.
1759 These should be handled during resolution. */
1761 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
1769 gfc_actual_arglist *argexpr;
1770 unsigned int i, nargs;
1772 nargs = gfc_intrinsic_argument_list_length (expr);
1773 args = XALLOCAVEC (tree, nargs);
1775 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1776 type = gfc_typenode_for_spec (&expr->ts);
1778 argexpr = expr->value.function.actual;
1779 if (TREE_TYPE (args[0]) != type)
1780 args[0] = convert (type, args[0]);
1781 /* Only evaluate the argument once. */
1782 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1783 args[0] = gfc_evaluate_now (args[0], &se->pre);
1785 mvar = gfc_create_var (type, "M");
1786 gfc_add_modify (&se->pre, mvar, args[0]);
1787 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1793 /* Handle absent optional arguments by ignoring the comparison. */
1794 if (argexpr->expr->expr_type == EXPR_VARIABLE
1795 && argexpr->expr->symtree->n.sym->attr.optional
1796 && TREE_CODE (val) == INDIRECT_REF)
1797 cond = fold_build2_loc (input_location,
1798 NE_EXPR, boolean_type_node,
1799 TREE_OPERAND (val, 0),
1800 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1805 /* Only evaluate the argument once. */
1806 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1807 val = gfc_evaluate_now (val, &se->pre);
1810 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1812 tmp = fold_build2_loc (input_location, op, boolean_type_node,
1813 convert (type, val), mvar);
1815 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1816 __builtin_isnan might be made dependent on that module being loaded,
1817 to help performance of programs that don't rely on IEEE semantics. */
1818 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1820 isnan = build_call_expr_loc (input_location,
1821 built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1822 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1823 boolean_type_node, tmp,
1824 fold_convert (boolean_type_node, isnan));
1826 tmp = build3_v (COND_EXPR, tmp, thencase,
1827 build_empty_stmt (input_location));
1829 if (cond != NULL_TREE)
1830 tmp = build3_v (COND_EXPR, cond, tmp,
1831 build_empty_stmt (input_location));
1833 gfc_add_expr_to_block (&se->pre, tmp);
1834 argexpr = argexpr->next;
1840 /* Generate library calls for MIN and MAX intrinsics for character
1843 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1846 tree var, len, fndecl, tmp, cond, function;
1849 nargs = gfc_intrinsic_argument_list_length (expr);
1850 args = XALLOCAVEC (tree, nargs + 4);
1851 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1853 /* Create the result variables. */
1854 len = gfc_create_var (gfc_charlen_type_node, "len");
1855 args[0] = gfc_build_addr_expr (NULL_TREE, len);
1856 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1857 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1858 args[2] = build_int_cst (NULL_TREE, op);
1859 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1861 if (expr->ts.kind == 1)
1862 function = gfor_fndecl_string_minmax;
1863 else if (expr->ts.kind == 4)
1864 function = gfor_fndecl_string_minmax_char4;
1868 /* Make the function call. */
1869 fndecl = build_addr (function, current_function_decl);
1870 tmp = build_call_array_loc (input_location,
1871 TREE_TYPE (TREE_TYPE (function)), fndecl,
1873 gfc_add_expr_to_block (&se->pre, tmp);
1875 /* Free the temporary afterwards, if necessary. */
1876 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1877 len, build_int_cst (TREE_TYPE (len), 0));
1878 tmp = gfc_call_free (var);
1879 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1880 gfc_add_expr_to_block (&se->post, tmp);
1883 se->string_length = len;
1887 /* Create a symbol node for this intrinsic. The symbol from the frontend
1888 has the generic name. */
1891 gfc_get_symbol_for_expr (gfc_expr * expr)
1895 /* TODO: Add symbols for intrinsic function to the global namespace. */
1896 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1897 sym = gfc_new_symbol (expr->value.function.name, NULL);
1900 sym->attr.external = 1;
1901 sym->attr.function = 1;
1902 sym->attr.always_explicit = 1;
1903 sym->attr.proc = PROC_INTRINSIC;
1904 sym->attr.flavor = FL_PROCEDURE;
1908 sym->attr.dimension = 1;
1909 sym->as = gfc_get_array_spec ();
1910 sym->as->type = AS_ASSUMED_SHAPE;
1911 sym->as->rank = expr->rank;
1914 gfc_copy_formal_args_intr (sym, expr->value.function.isym);
1919 /* Generate a call to an external intrinsic function. */
1921 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1924 VEC(tree,gc) *append_args;
1926 gcc_assert (!se->ss || se->ss->expr == expr);
1929 gcc_assert (expr->rank > 0);
1931 gcc_assert (expr->rank == 0);
1933 sym = gfc_get_symbol_for_expr (expr);
1935 /* Calls to libgfortran_matmul need to be appended special arguments,
1936 to be able to call the BLAS ?gemm functions if required and possible. */
1938 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1939 && sym->ts.type != BT_LOGICAL)
1941 tree cint = gfc_get_int_type (gfc_c_int_kind);
1943 if (gfc_option.flag_external_blas
1944 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1945 && (sym->ts.kind == gfc_default_real_kind
1946 || sym->ts.kind == gfc_default_double_kind))
1950 if (sym->ts.type == BT_REAL)
1952 if (sym->ts.kind == gfc_default_real_kind)
1953 gemm_fndecl = gfor_fndecl_sgemm;
1955 gemm_fndecl = gfor_fndecl_dgemm;
1959 if (sym->ts.kind == gfc_default_real_kind)
1960 gemm_fndecl = gfor_fndecl_cgemm;
1962 gemm_fndecl = gfor_fndecl_zgemm;
1965 append_args = VEC_alloc (tree, gc, 3);
1966 VEC_quick_push (tree, append_args, build_int_cst (cint, 1));
1967 VEC_quick_push (tree, append_args,
1968 build_int_cst (cint, gfc_option.blas_matmul_limit));
1969 VEC_quick_push (tree, append_args,
1970 gfc_build_addr_expr (NULL_TREE, gemm_fndecl));
1974 append_args = VEC_alloc (tree, gc, 3);
1975 VEC_quick_push (tree, append_args, build_int_cst (cint, 0));
1976 VEC_quick_push (tree, append_args, build_int_cst (cint, 0));
1977 VEC_quick_push (tree, append_args, null_pointer_node);
1981 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
1983 gfc_free_symbol (sym);
1986 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
2006 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
2015 gfc_actual_arglist *actual;
2022 gfc_conv_intrinsic_funcall (se, expr);
2026 actual = expr->value.function.actual;
2027 type = gfc_typenode_for_spec (&expr->ts);
2028 /* Initialize the result. */
2029 resvar = gfc_create_var (type, "test");
2031 tmp = convert (type, boolean_true_node);
2033 tmp = convert (type, boolean_false_node);
2034 gfc_add_modify (&se->pre, resvar, tmp);
2036 /* Walk the arguments. */
2037 arrayss = gfc_walk_expr (actual->expr);
2038 gcc_assert (arrayss != gfc_ss_terminator);
2040 /* Initialize the scalarizer. */
2041 gfc_init_loopinfo (&loop);
2042 exit_label = gfc_build_label_decl (NULL_TREE);
2043 TREE_USED (exit_label) = 1;
2044 gfc_add_ss_to_loop (&loop, arrayss);
2046 /* Initialize the loop. */
2047 gfc_conv_ss_startstride (&loop);
2048 gfc_conv_loop_setup (&loop, &expr->where);
2050 gfc_mark_ss_chain_used (arrayss, 1);
2051 /* Generate the loop body. */
2052 gfc_start_scalarized_body (&loop, &body);
2054 /* If the condition matches then set the return value. */
2055 gfc_start_block (&block);
2057 tmp = convert (type, boolean_false_node);
2059 tmp = convert (type, boolean_true_node);
2060 gfc_add_modify (&block, resvar, tmp);
2062 /* And break out of the loop. */
2063 tmp = build1_v (GOTO_EXPR, exit_label);
2064 gfc_add_expr_to_block (&block, tmp);
2066 found = gfc_finish_block (&block);
2068 /* Check this element. */
2069 gfc_init_se (&arrayse, NULL);
2070 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2071 arrayse.ss = arrayss;
2072 gfc_conv_expr_val (&arrayse, actual->expr);
2074 gfc_add_block_to_block (&body, &arrayse.pre);
2075 tmp = fold_build2_loc (input_location, op, boolean_type_node, arrayse.expr,
2076 build_int_cst (TREE_TYPE (arrayse.expr), 0));
2077 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
2078 gfc_add_expr_to_block (&body, tmp);
2079 gfc_add_block_to_block (&body, &arrayse.post);
2081 gfc_trans_scalarizing_loops (&loop, &body);
2083 /* Add the exit label. */
2084 tmp = build1_v (LABEL_EXPR, exit_label);
2085 gfc_add_expr_to_block (&loop.pre, tmp);
2087 gfc_add_block_to_block (&se->pre, &loop.pre);
2088 gfc_add_block_to_block (&se->pre, &loop.post);
2089 gfc_cleanup_loop (&loop);
2094 /* COUNT(A) = Number of true elements in A. */
2096 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
2103 gfc_actual_arglist *actual;
2109 gfc_conv_intrinsic_funcall (se, expr);
2113 actual = expr->value.function.actual;
2115 type = gfc_typenode_for_spec (&expr->ts);
2116 /* Initialize the result. */
2117 resvar = gfc_create_var (type, "count");
2118 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
2120 /* Walk the arguments. */
2121 arrayss = gfc_walk_expr (actual->expr);
2122 gcc_assert (arrayss != gfc_ss_terminator);
2124 /* Initialize the scalarizer. */
2125 gfc_init_loopinfo (&loop);
2126 gfc_add_ss_to_loop (&loop, arrayss);
2128 /* Initialize the loop. */
2129 gfc_conv_ss_startstride (&loop);
2130 gfc_conv_loop_setup (&loop, &expr->where);
2132 gfc_mark_ss_chain_used (arrayss, 1);
2133 /* Generate the loop body. */
2134 gfc_start_scalarized_body (&loop, &body);
2136 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (resvar),
2137 resvar, build_int_cst (TREE_TYPE (resvar), 1));
2138 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
2140 gfc_init_se (&arrayse, NULL);
2141 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2142 arrayse.ss = arrayss;
2143 gfc_conv_expr_val (&arrayse, actual->expr);
2144 tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
2145 build_empty_stmt (input_location));
2147 gfc_add_block_to_block (&body, &arrayse.pre);
2148 gfc_add_expr_to_block (&body, tmp);
2149 gfc_add_block_to_block (&body, &arrayse.post);
2151 gfc_trans_scalarizing_loops (&loop, &body);
2153 gfc_add_block_to_block (&se->pre, &loop.pre);
2154 gfc_add_block_to_block (&se->pre, &loop.post);
2155 gfc_cleanup_loop (&loop);
2160 /* Inline implementation of the sum and product intrinsics. */
2162 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op,
2166 tree scale = NULL_TREE;
2172 gfc_actual_arglist *actual;
2177 gfc_expr *arrayexpr;
2182 gfc_conv_intrinsic_funcall (se, expr);
2186 type = gfc_typenode_for_spec (&expr->ts);
2187 /* Initialize the result. */
2188 resvar = gfc_create_var (type, "val");
2193 scale = gfc_create_var (type, "scale");
2194 gfc_add_modify (&se->pre, scale,
2195 gfc_build_const (type, integer_one_node));
2196 tmp = gfc_build_const (type, integer_zero_node);
2198 else if (op == PLUS_EXPR || op == BIT_IOR_EXPR || op == BIT_XOR_EXPR)
2199 tmp = gfc_build_const (type, integer_zero_node);
2200 else if (op == NE_EXPR)
2202 tmp = convert (type, boolean_false_node);
2203 else if (op == BIT_AND_EXPR)
2204 tmp = gfc_build_const (type, fold_build1_loc (input_location, NEGATE_EXPR,
2205 type, integer_one_node));
2207 tmp = gfc_build_const (type, integer_one_node);
2209 gfc_add_modify (&se->pre, resvar, tmp);
2211 /* Walk the arguments. */
2212 actual = expr->value.function.actual;
2213 arrayexpr = actual->expr;
2214 arrayss = gfc_walk_expr (arrayexpr);
2215 gcc_assert (arrayss != gfc_ss_terminator);
2217 if (op == NE_EXPR || norm2)
2218 /* PARITY and NORM2. */
2222 actual = actual->next->next;
2223 gcc_assert (actual);
2224 maskexpr = actual->expr;
2227 if (maskexpr && maskexpr->rank != 0)
2229 maskss = gfc_walk_expr (maskexpr);
2230 gcc_assert (maskss != gfc_ss_terminator);
2235 /* Initialize the scalarizer. */
2236 gfc_init_loopinfo (&loop);
2237 gfc_add_ss_to_loop (&loop, arrayss);
2239 gfc_add_ss_to_loop (&loop, maskss);
2241 /* Initialize the loop. */
2242 gfc_conv_ss_startstride (&loop);
2243 gfc_conv_loop_setup (&loop, &expr->where);
2245 gfc_mark_ss_chain_used (arrayss, 1);
2247 gfc_mark_ss_chain_used (maskss, 1);
2248 /* Generate the loop body. */
2249 gfc_start_scalarized_body (&loop, &body);
2251 /* If we have a mask, only add this element if the mask is set. */
2254 gfc_init_se (&maskse, NULL);
2255 gfc_copy_loopinfo_to_se (&maskse, &loop);
2257 gfc_conv_expr_val (&maskse, maskexpr);
2258 gfc_add_block_to_block (&body, &maskse.pre);
2260 gfc_start_block (&block);
2263 gfc_init_block (&block);
2265 /* Do the actual summation/product. */
2266 gfc_init_se (&arrayse, NULL);
2267 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2268 arrayse.ss = arrayss;
2269 gfc_conv_expr_val (&arrayse, arrayexpr);
2270 gfc_add_block_to_block (&block, &arrayse.pre);
2280 result = 1.0 + result * val * val;
2286 result += val * val;
2289 tree res1, res2, cond, absX, val;
2290 stmtblock_t ifblock1, ifblock2, ifblock3;
2292 gfc_init_block (&ifblock1);
2294 absX = gfc_create_var (type, "absX");
2295 gfc_add_modify (&ifblock1, absX,
2296 fold_build1_loc (input_location, ABS_EXPR, type,
2298 val = gfc_create_var (type, "val");
2299 gfc_add_expr_to_block (&ifblock1, val);
2301 gfc_init_block (&ifblock2);
2302 gfc_add_modify (&ifblock2, val,
2303 fold_build2_loc (input_location, RDIV_EXPR, type, scale,
2305 res1 = fold_build2_loc (input_location, MULT_EXPR, type, val, val);
2306 res1 = fold_build2_loc (input_location, MULT_EXPR, type, resvar, res1);
2307 res1 = fold_build2_loc (input_location, PLUS_EXPR, type, res1,
2308 gfc_build_const (type, integer_one_node));
2309 gfc_add_modify (&ifblock2, resvar, res1);
2310 gfc_add_modify (&ifblock2, scale, absX);
2311 res1 = gfc_finish_block (&ifblock2);
2313 gfc_init_block (&ifblock3);
2314 gfc_add_modify (&ifblock3, val,
2315 fold_build2_loc (input_location, RDIV_EXPR, type, absX,
2317 res2 = fold_build2_loc (input_location, MULT_EXPR, type, val, val);
2318 res2 = fold_build2_loc (input_location, PLUS_EXPR, type, resvar, res2);
2319 gfc_add_modify (&ifblock3, resvar, res2);
2320 res2 = gfc_finish_block (&ifblock3);
2322 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2324 tmp = build3_v (COND_EXPR, cond, res1, res2);
2325 gfc_add_expr_to_block (&ifblock1, tmp);
2326 tmp = gfc_finish_block (&ifblock1);
2328 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
2330 gfc_build_const (type, integer_zero_node));
2332 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2333 gfc_add_expr_to_block (&block, tmp);
2337 tmp = fold_build2_loc (input_location, op, type, resvar, arrayse.expr);
2338 gfc_add_modify (&block, resvar, tmp);
2341 gfc_add_block_to_block (&block, &arrayse.post);
2345 /* We enclose the above in if (mask) {...} . */
2347 tmp = gfc_finish_block (&block);
2348 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2349 build_empty_stmt (input_location));
2352 tmp = gfc_finish_block (&block);
2353 gfc_add_expr_to_block (&body, tmp);
2355 gfc_trans_scalarizing_loops (&loop, &body);
2357 /* For a scalar mask, enclose the loop in an if statement. */
2358 if (maskexpr && maskss == NULL)
2360 gfc_init_se (&maskse, NULL);
2361 gfc_conv_expr_val (&maskse, maskexpr);
2362 gfc_init_block (&block);
2363 gfc_add_block_to_block (&block, &loop.pre);
2364 gfc_add_block_to_block (&block, &loop.post);
2365 tmp = gfc_finish_block (&block);
2367 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2368 build_empty_stmt (input_location));
2369 gfc_add_expr_to_block (&block, tmp);
2370 gfc_add_block_to_block (&se->pre, &block);
2374 gfc_add_block_to_block (&se->pre, &loop.pre);
2375 gfc_add_block_to_block (&se->pre, &loop.post);
2378 gfc_cleanup_loop (&loop);
2382 /* result = scale * sqrt(result). */
2384 sqrt = gfc_builtin_decl_for_float_kind (BUILT_IN_SQRT, expr->ts.kind);
2385 resvar = build_call_expr_loc (input_location,
2387 resvar = fold_build2_loc (input_location, MULT_EXPR, type, scale, resvar);
2394 /* Inline implementation of the dot_product intrinsic. This function
2395 is based on gfc_conv_intrinsic_arith (the previous function). */
2397 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
2405 gfc_actual_arglist *actual;
2406 gfc_ss *arrayss1, *arrayss2;
2407 gfc_se arrayse1, arrayse2;
2408 gfc_expr *arrayexpr1, *arrayexpr2;
2410 type = gfc_typenode_for_spec (&expr->ts);
2412 /* Initialize the result. */
2413 resvar = gfc_create_var (type, "val");
2414 if (expr->ts.type == BT_LOGICAL)
2415 tmp = build_int_cst (type, 0);
2417 tmp = gfc_build_const (type, integer_zero_node);
2419 gfc_add_modify (&se->pre, resvar, tmp);
2421 /* Walk argument #1. */
2422 actual = expr->value.function.actual;
2423 arrayexpr1 = actual->expr;
2424 arrayss1 = gfc_walk_expr (arrayexpr1);
2425 gcc_assert (arrayss1 != gfc_ss_terminator);
2427 /* Walk argument #2. */
2428 actual = actual->next;
2429 arrayexpr2 = actual->expr;
2430 arrayss2 = gfc_walk_expr (arrayexpr2);
2431 gcc_assert (arrayss2 != gfc_ss_terminator);
2433 /* Initialize the scalarizer. */
2434 gfc_init_loopinfo (&loop);
2435 gfc_add_ss_to_loop (&loop, arrayss1);
2436 gfc_add_ss_to_loop (&loop, arrayss2);
2438 /* Initialize the loop. */
2439 gfc_conv_ss_startstride (&loop);
2440 gfc_conv_loop_setup (&loop, &expr->where);
2442 gfc_mark_ss_chain_used (arrayss1, 1);
2443 gfc_mark_ss_chain_used (arrayss2, 1);
2445 /* Generate the loop body. */
2446 gfc_start_scalarized_body (&loop, &body);
2447 gfc_init_block (&block);
2449 /* Make the tree expression for [conjg(]array1[)]. */
2450 gfc_init_se (&arrayse1, NULL);
2451 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2452 arrayse1.ss = arrayss1;
2453 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2454 if (expr->ts.type == BT_COMPLEX)
2455 arrayse1.expr = fold_build1_loc (input_location, CONJ_EXPR, type,
2457 gfc_add_block_to_block (&block, &arrayse1.pre);
2459 /* Make the tree expression for array2. */
2460 gfc_init_se (&arrayse2, NULL);
2461 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2462 arrayse2.ss = arrayss2;
2463 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2464 gfc_add_block_to_block (&block, &arrayse2.pre);
2466 /* Do the actual product and sum. */
2467 if (expr->ts.type == BT_LOGICAL)
2469 tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, type,
2470 arrayse1.expr, arrayse2.expr);
2471 tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, type, resvar, tmp);
2475 tmp = fold_build2_loc (input_location, MULT_EXPR, type, arrayse1.expr,
2477 tmp = fold_build2_loc (input_location, PLUS_EXPR, type, resvar, tmp);
2479 gfc_add_modify (&block, resvar, tmp);
2481 /* Finish up the loop block and the loop. */
2482 tmp = gfc_finish_block (&block);
2483 gfc_add_expr_to_block (&body, tmp);
2485 gfc_trans_scalarizing_loops (&loop, &body);
2486 gfc_add_block_to_block (&se->pre, &loop.pre);
2487 gfc_add_block_to_block (&se->pre, &loop.post);
2488 gfc_cleanup_loop (&loop);
2494 /* Emit code for minloc or maxloc intrinsic. There are many different cases
2495 we need to handle. For performance reasons we sometimes create two
2496 loops instead of one, where the second one is much simpler.
2497 Examples for minloc intrinsic:
2498 1) Result is an array, a call is generated
2499 2) Array mask is used and NaNs need to be supported:
2505 if (pos == 0) pos = S + (1 - from);
2506 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2513 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2517 3) NaNs need to be supported, but it is known at compile time or cheaply
2518 at runtime whether array is nonempty or not:
2523 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2526 if (from <= to) pos = 1;
2530 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2534 4) NaNs aren't supported, array mask is used:
2535 limit = infinities_supported ? Infinity : huge (limit);
2539 if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2545 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2549 5) Same without array mask:
2550 limit = infinities_supported ? Infinity : huge (limit);
2551 pos = (from <= to) ? 1 : 0;
2554 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2557 For 3) and 5), if mask is scalar, this all goes into a conditional,
2558 setting pos = 0; in the else branch. */
2561 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
2565 stmtblock_t ifblock;
2566 stmtblock_t elseblock;
2577 gfc_actual_arglist *actual;
2582 gfc_expr *arrayexpr;
2589 gfc_conv_intrinsic_funcall (se, expr);
2593 /* Initialize the result. */
2594 pos = gfc_create_var (gfc_array_index_type, "pos");
2595 offset = gfc_create_var (gfc_array_index_type, "offset");
2596 type = gfc_typenode_for_spec (&expr->ts);
2598 /* Walk the arguments. */
2599 actual = expr->value.function.actual;
2600 arrayexpr = actual->expr;
2601 arrayss = gfc_walk_expr (arrayexpr);
2602 gcc_assert (arrayss != gfc_ss_terminator);
2604 actual = actual->next->next;
2605 gcc_assert (actual);
2606 maskexpr = actual->expr;
2608 if (maskexpr && maskexpr->rank != 0)
2610 maskss = gfc_walk_expr (maskexpr);
2611 gcc_assert (maskss != gfc_ss_terminator);
2616 if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2618 nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2620 nonempty = fold_build2_loc (input_location, GT_EXPR,
2621 boolean_type_node, nonempty,
2622 gfc_index_zero_node);
2627 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2628 switch (arrayexpr->ts.type)
2631 tmp = gfc_build_inf_or_huge (TREE_TYPE (limit), arrayexpr->ts.kind);
2635 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2636 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2637 arrayexpr->ts.kind);
2644 /* We start with the most negative possible value for MAXLOC, and the most
2645 positive possible value for MINLOC. The most negative possible value is
2646 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2647 possible value is HUGE in both cases. */
2649 tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2650 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2651 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp), tmp,
2652 build_int_cst (type, 1));
2654 gfc_add_modify (&se->pre, limit, tmp);
2656 /* Initialize the scalarizer. */
2657 gfc_init_loopinfo (&loop);
2658 gfc_add_ss_to_loop (&loop, arrayss);
2660 gfc_add_ss_to_loop (&loop, maskss);
2662 /* Initialize the loop. */
2663 gfc_conv_ss_startstride (&loop);
2664 gfc_conv_loop_setup (&loop, &expr->where);
2666 gcc_assert (loop.dimen == 1);
2667 if (nonempty == NULL && maskss == NULL && loop.from[0] && loop.to[0])
2668 nonempty = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
2669 loop.from[0], loop.to[0]);
2673 /* Initialize the position to zero, following Fortran 2003. We are free
2674 to do this because Fortran 95 allows the result of an entirely false
2675 mask to be processor dependent. If we know at compile time the array
2676 is non-empty and no MASK is used, we can initialize to 1 to simplify
2678 if (nonempty != NULL && !HONOR_NANS (DECL_MODE (limit)))
2679 gfc_add_modify (&loop.pre, pos,
2680 fold_build3_loc (input_location, COND_EXPR,
2681 gfc_array_index_type,
2682 nonempty, gfc_index_one_node,
2683 gfc_index_zero_node));
2686 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2687 lab1 = gfc_build_label_decl (NULL_TREE);
2688 TREE_USED (lab1) = 1;
2689 lab2 = gfc_build_label_decl (NULL_TREE);
2690 TREE_USED (lab2) = 1;
2693 gfc_mark_ss_chain_used (arrayss, 1);
2695 gfc_mark_ss_chain_used (maskss, 1);
2696 /* Generate the loop body. */
2697 gfc_start_scalarized_body (&loop, &body);
2699 /* If we have a mask, only check this element if the mask is set. */
2702 gfc_init_se (&maskse, NULL);
2703 gfc_copy_loopinfo_to_se (&maskse, &loop);
2705 gfc_conv_expr_val (&maskse, maskexpr);
2706 gfc_add_block_to_block (&body, &maskse.pre);
2708 gfc_start_block (&block);
2711 gfc_init_block (&block);
2713 /* Compare with the current limit. */
2714 gfc_init_se (&arrayse, NULL);
2715 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2716 arrayse.ss = arrayss;
2717 gfc_conv_expr_val (&arrayse, arrayexpr);
2718 gfc_add_block_to_block (&block, &arrayse.pre);
2720 /* We do the following if this is a more extreme value. */
2721 gfc_start_block (&ifblock);
2723 /* Assign the value to the limit... */
2724 gfc_add_modify (&ifblock, limit, arrayse.expr);
2726 /* Remember where we are. An offset must be added to the loop
2727 counter to obtain the required position. */
2729 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2730 gfc_index_one_node, loop.from[0]);
2732 tmp = gfc_index_one_node;
2734 gfc_add_modify (&block, offset, tmp);
2736 if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
2738 stmtblock_t ifblock2;
2741 gfc_start_block (&ifblock2);
2742 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
2743 loop.loopvar[0], offset);
2744 gfc_add_modify (&ifblock2, pos, tmp);
2745 ifbody2 = gfc_finish_block (&ifblock2);
2746 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pos,
2747 gfc_index_zero_node);
2748 tmp = build3_v (COND_EXPR, cond, ifbody2,
2749 build_empty_stmt (input_location));
2750 gfc_add_expr_to_block (&block, tmp);
2753 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
2754 loop.loopvar[0], offset);
2755 gfc_add_modify (&ifblock, pos, tmp);
2758 gfc_add_expr_to_block (&ifblock, build1_v (GOTO_EXPR, lab1));
2760 ifbody = gfc_finish_block (&ifblock);
2762 if (!lab1 || HONOR_NANS (DECL_MODE (limit)))
2765 cond = fold_build2_loc (input_location,
2766 op == GT_EXPR ? GE_EXPR : LE_EXPR,
2767 boolean_type_node, arrayse.expr, limit);
2769 cond = fold_build2_loc (input_location, op, boolean_type_node,
2770 arrayse.expr, limit);
2772 ifbody = build3_v (COND_EXPR, cond, ifbody,
2773 build_empty_stmt (input_location));
2775 gfc_add_expr_to_block (&block, ifbody);
2779 /* We enclose the above in if (mask) {...}. */
2780 tmp = gfc_finish_block (&block);
2782 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2783 build_empty_stmt (input_location));
2786 tmp = gfc_finish_block (&block);
2787 gfc_add_expr_to_block (&body, tmp);
2791 gfc_trans_scalarized_loop_end (&loop, 0, &body);
2793 if (HONOR_NANS (DECL_MODE (limit)))
2795 if (nonempty != NULL)
2797 ifbody = build2_v (MODIFY_EXPR, pos, gfc_index_one_node);
2798 tmp = build3_v (COND_EXPR, nonempty, ifbody,
2799 build_empty_stmt (input_location));
2800 gfc_add_expr_to_block (&loop.code[0], tmp);
2804 gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
2805 gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
2806 gfc_start_block (&body);
2808 /* If we have a mask, only check this element if the mask is set. */
2811 gfc_init_se (&maskse, NULL);
2812 gfc_copy_loopinfo_to_se (&maskse, &loop);
2814 gfc_conv_expr_val (&maskse, maskexpr);
2815 gfc_add_block_to_block (&body, &maskse.pre);
2817 gfc_start_block (&block);
2820 gfc_init_block (&block);
2822 /* Compare with the current limit. */
2823 gfc_init_se (&arrayse, NULL);
2824 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2825 arrayse.ss = arrayss;
2826 gfc_conv_expr_val (&arrayse, arrayexpr);
2827 gfc_add_block_to_block (&block, &arrayse.pre);
2829 /* We do the following if this is a more extreme value. */
2830 gfc_start_block (&ifblock);
2832 /* Assign the value to the limit... */
2833 gfc_add_modify (&ifblock, limit, arrayse.expr);
2835 /* Remember where we are. An offset must be added to the loop
2836 counter to obtain the required position. */
2838 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
2839 gfc_index_one_node, loop.from[0]);
2841 tmp = gfc_index_one_node;
2843 gfc_add_modify (&block, offset, tmp);
2845 tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
2846 loop.loopvar[0], offset);
2847 gfc_add_modify (&ifblock, pos, tmp);
2849 ifbody = gfc_finish_block (&ifblock);
2851 cond = fold_build2_loc (input_location, op, boolean_type_node,
2852 arrayse.expr, limit);
2854 tmp = build3_v (COND_EXPR, cond, ifbody,
2855 build_empty_stmt (input_location));
2856 gfc_add_expr_to_block (&block, tmp);
2860 /* We enclose the above in if (mask) {...}. */
2861 tmp = gfc_finish_block (&block);
2863 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2864 build_empty_stmt (input_location));
2867 tmp = gfc_finish_block (&block);
2868 gfc_add_expr_to_block (&body, tmp);
2869 /* Avoid initializing loopvar[0] again, it should be left where
2870 it finished by the first loop. */
2871 loop.from[0] = loop.loopvar[0];
2874 gfc_trans_scalarizing_loops (&loop, &body);
2877 gfc_add_expr_to_block (&loop.pre, build1_v (LABEL_EXPR, lab2));
2879 /* For a scalar mask, enclose the loop in an if statement. */
2880 if (maskexpr && maskss == NULL)
2882 gfc_init_se (&maskse, NULL);
2883 gfc_conv_expr_val (&maskse, maskexpr);
2884 gfc_init_block (&block);
2885 gfc_add_block_to_block (&block, &loop.pre);
2886 gfc_add_block_to_block (&block, &loop.post);
2887 tmp = gfc_finish_block (&block);
2889 /* For the else part of the scalar mask, just initialize
2890 the pos variable the same way as above. */
2892 gfc_init_block (&elseblock);
2893 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2894 elsetmp = gfc_finish_block (&elseblock);
2896 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2897 gfc_add_expr_to_block (&block, tmp);
2898 gfc_add_block_to_block (&se->pre, &block);
2902 gfc_add_block_to_block (&se->pre, &loop.pre);
2903 gfc_add_block_to_block (&se->pre, &loop.post);
2905 gfc_cleanup_loop (&loop);
2907 se->expr = convert (type, pos);
2910 /* Emit code for minval or maxval intrinsic. There are many different cases
2911 we need to handle. For performance reasons we sometimes create two
2912 loops instead of one, where the second one is much simpler.
2913 Examples for minval intrinsic:
2914 1) Result is an array, a call is generated
2915 2) Array mask is used and NaNs need to be supported, rank 1:
2920 if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
2923 limit = nonempty ? NaN : huge (limit);
2925 while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
2926 3) NaNs need to be supported, but it is known at compile time or cheaply
2927 at runtime whether array is nonempty or not, rank 1:
2930 while (S <= to) { if (a[S] <= limit) goto lab; S++; }
2931 limit = (from <= to) ? NaN : huge (limit);
2933 while (S <= to) { limit = min (a[S], limit); S++; }
2934 4) Array mask is used and NaNs need to be supported, rank > 1:
2943 if (fast) limit = min (a[S1][S2], limit);
2946 if (a[S1][S2] <= limit) {
2957 limit = nonempty ? NaN : huge (limit);
2958 5) NaNs need to be supported, but it is known at compile time or cheaply
2959 at runtime whether array is nonempty or not, rank > 1:
2966 if (fast) limit = min (a[S1][S2], limit);
2968 if (a[S1][S2] <= limit) {
2978 limit = (nonempty_array) ? NaN : huge (limit);
2979 6) NaNs aren't supported, but infinities are. Array mask is used:
2984 if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
2987 limit = nonempty ? limit : huge (limit);
2988 7) Same without array mask:
2991 while (S <= to) { limit = min (a[S], limit); S++; }
2992 limit = (from <= to) ? limit : huge (limit);
2993 8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
2994 limit = huge (limit);
2996 while (S <= to) { limit = min (a[S], limit); S++); }
2998 while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
2999 with array mask instead).
3000 For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
3001 setting limit = huge (limit); in the else branch. */
3004 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
3014 tree huge_cst = NULL, nan_cst = NULL;
3016 stmtblock_t block, block2;
3018 gfc_actual_arglist *actual;
3023 gfc_expr *arrayexpr;
3029 gfc_conv_intrinsic_funcall (se, expr);
3033 type = gfc_typenode_for_spec (&expr->ts);
3034 /* Initialize the result. */
3035 limit = gfc_create_var (type, "limit");
3036 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
3037 switch (expr->ts.type)
3040 huge_cst = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
3042 if (HONOR_INFINITIES (DECL_MODE (limit)))
3044 REAL_VALUE_TYPE real;
3046 tmp = build_real (type, real);
3050 if (HONOR_NANS (DECL_MODE (limit)))
3052 REAL_VALUE_TYPE real;
3053 real_nan (&real, "", 1, DECL_MODE (limit));
3054 nan_cst = build_real (type, real);
3059 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
3066 /* We start with the most negative possible value for MAXVAL, and the most
3067 positive possible value for MINVAL. The most negative possible value is
3068 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
3069 possible value is HUGE in both cases. */
3072 tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
3074 huge_cst = fold_build1_loc (input_location, NEGATE_EXPR,
3075 TREE_TYPE (huge_cst), huge_cst);
3078 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
3079 tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
3080 tmp, build_int_cst (type, 1));
3082 gfc_add_modify (&se->pre, limit, tmp);
3084 /* Walk the arguments. */
3085 actual = expr->value.function.actual;
3086 arrayexpr = actual->expr;
3087 arrayss = gfc_walk_expr (arrayexpr);
3088 gcc_assert (arrayss != gfc_ss_terminator);
3090 actual = actual->next->next;
3091 gcc_assert (actual);
3092 maskexpr = actual->expr;
3094 if (maskexpr && maskexpr->rank != 0)
3096 maskss = gfc_walk_expr (maskexpr);
3097 gcc_assert (maskss != gfc_ss_terminator);
3102 if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
3104 nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
3106 nonempty = fold_build2_loc (input_location, GT_EXPR,
3107 boolean_type_node, nonempty,
3108 gfc_index_zero_node);
3113 /* Initialize the scalarizer. */
3114 gfc_init_loopinfo (&loop);
3115 gfc_add_ss_to_loop (&loop, arrayss);
3117 gfc_add_ss_to_loop (&loop, maskss);
3119 /* Initialize the loop. */
3120 gfc_conv_ss_startstride (&loop);
3121 gfc_conv_loop_setup (&loop, &expr->where);
3123 if (nonempty == NULL && maskss == NULL
3124 && loop.dimen == 1 && loop.from[0] && loop.to[0])
3125 nonempty = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3126 loop.from[0], loop.to[0]);
3127 nonempty_var = NULL;
3128 if (nonempty == NULL
3129 && (HONOR_INFINITIES (DECL_MODE (limit))
3130 || HONOR_NANS (DECL_MODE (limit))))
3132 nonempty_var = gfc_create_var (boolean_type_node, "nonempty");
3133 gfc_add_modify (&se->pre, nonempty_var, boolean_false_node);
3134 nonempty = nonempty_var;
3138 if (HONOR_NANS (DECL_MODE (limit)))
3140 if (loop.dimen == 1)
3142 lab = gfc_build_label_decl (NULL_TREE);
3143 TREE_USED (lab) = 1;
3147 fast = gfc_create_var (boolean_type_node, "fast");
3148 gfc_add_modify (&se->pre, fast, boolean_false_node);
3152 gfc_mark_ss_chain_used (arrayss, 1);
3154 gfc_mark_ss_chain_used (maskss, 1);
3155 /* Generate the loop body. */
3156 gfc_start_scalarized_body (&loop, &body);
3158 /* If we have a mask, only add this element if the mask is set. */
3161 gfc_init_se (&maskse, NULL);
3162 gfc_copy_loopinfo_to_se (&maskse, &loop);
3164 gfc_conv_expr_val (&maskse, maskexpr);
3165 gfc_add_block_to_block (&body, &maskse.pre);
3167 gfc_start_block (&block);
3170 gfc_init_block (&block);
3172 /* Compare with the current limit. */
3173 gfc_init_se (&arrayse, NULL);
3174 gfc_copy_loopinfo_to_se (&arrayse, &loop);
3175 arrayse.ss = arrayss;
3176 gfc_conv_expr_val (&arrayse, arrayexpr);
3177 gfc_add_block_to_block (&block, &arrayse.pre);
3179 gfc_init_block (&block2);
3182 gfc_add_modify (&block2, nonempty_var, boolean_true_node);
3184 if (HONOR_NANS (DECL_MODE (limit)))
3186 tmp = fold_build2_loc (input_location, op == GT_EXPR ? GE_EXPR : LE_EXPR,
3187 boolean_type_node, arrayse.expr, limit);
3189 ifbody = build1_v (GOTO_EXPR, lab);
3192 stmtblock_t ifblock;
3194 gfc_init_block (&ifblock);
3195 gfc_add_modify (&ifblock, limit, arrayse.expr);
3196 gfc_add_modify (&ifblock, fast, boolean_true_node);
3197 ifbody = gfc_finish_block (&ifblock);
3199 tmp = build3_v (COND_EXPR, tmp, ifbody,
3200 build_empty_stmt (input_location));
3201 gfc_add_expr_to_block (&block2, tmp);
3205 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3207 if (HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
3209 tmp = fold_build2_loc (input_location, op, boolean_type_node,
3210 arrayse.expr, limit);
3211 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
3212 tmp = build3_v (COND_EXPR, tmp, ifbody,
3213 build_empty_stmt (input_location));
3214 gfc_add_expr_to_block (&block2, tmp);
3218 tmp = fold_build2_loc (input_location,
3219 op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
3220 type, arrayse.expr, limit);
3221 gfc_add_modify (&block2, limit, tmp);
3227 tree elsebody = gfc_finish_block (&block2);
3229 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3231 if (HONOR_NANS (DECL_MODE (limit))
3232 || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
3234 tmp = fold_build2_loc (input_location, op, boolean_type_node,
3235 arrayse.expr, limit);
3236 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
3237 ifbody = build3_v (COND_EXPR, tmp, ifbody,
3238 build_empty_stmt (input_location));
3242 tmp = fold_build2_loc (input_location,
3243 op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
3244 type, arrayse.expr, limit);
3245 ifbody = build2_v (MODIFY_EXPR, limit, tmp);
3247 tmp = build3_v (COND_EXPR, fast, ifbody, elsebody);
3248 gfc_add_expr_to_block (&block, tmp);
3251 gfc_add_block_to_block (&block, &block2);
3253 gfc_add_block_to_block (&block, &arrayse.post);
3255 tmp = gfc_finish_block (&block);
3257 /* We enclose the above in if (mask) {...}. */
3258 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
3259 build_empty_stmt (input_location));
3260 gfc_add_expr_to_block (&body, tmp);
3264 gfc_trans_scalarized_loop_end (&loop, 0, &body);
3266 tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
3268 gfc_add_modify (&loop.code[0], limit, tmp);
3269 gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));
3271 gfc_start_block (&body);
3273 /* If we have a mask, only add this element if the mask is set. */
3276 gfc_init_se (&maskse, NULL);
3277 gfc_copy_loopinfo_to_se (&maskse, &loop);
3279 gfc_conv_expr_val (&maskse, maskexpr);
3280 gfc_add_block_to_block (&body, &maskse.pre);
3282 gfc_start_block (&block);
3285 gfc_init_block (&block);
3287 /* Compare with the current limit. */
3288 gfc_init_se (&arrayse, NULL);
3289 gfc_copy_loopinfo_to_se (&arrayse, &loop);
3290 arrayse.ss = arrayss;
3291 gfc_conv_expr_val (&arrayse, arrayexpr);
3292 gfc_add_block_to_block (&block, &arrayse.pre);
3294 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3296 if (HONOR_NANS (DECL_MODE (limit))
3297 || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
3299 tmp = fold_build2_loc (input_location, op, boolean_type_node,
3300 arrayse.expr, limit);
3301 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
3302 tmp = build3_v (COND_EXPR, tmp, ifbody,
3303 build_empty_stmt (input_location));
3304 gfc_add_expr_to_block (&block, tmp);
3308 tmp = fold_build2_loc (input_location,
3309 op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
3310 type, arrayse.expr, limit);
3311 gfc_add_modify (&block, limit, tmp);
3314 gfc_add_block_to_block (&block, &arrayse.post);
3316 tmp = gfc_finish_block (&block);
3318 /* We enclose the above in if (mask) {...}. */
3319 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
3320 build_empty_stmt (input_location));
3321 gfc_add_expr_to_block (&body, tmp);
3322 /* Avoid initializing loopvar[0] again, it should be left where
3323 it finished by the first loop. */
3324 loop.from[0] = loop.loopvar[0];
3326 gfc_trans_scalarizing_loops (&loop, &body);
3330 tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
3332 ifbody = build2_v (MODIFY_EXPR, limit, tmp);
3333 tmp = build3_v (COND_EXPR, fast, build_empty_stmt (input_location),
3335 gfc_add_expr_to_block (&loop.pre, tmp);
3337 else if (HONOR_INFINITIES (DECL_MODE (limit)) && !lab)
3339 tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty, limit,
3341 gfc_add_modify (&loop.pre, limit, tmp);
3344 /* For a scalar mask, enclose the loop in an if statement. */
3345 if (maskexpr && maskss == NULL)
3349 gfc_init_se (&maskse, NULL);
3350 gfc_conv_expr_val (&maskse, maskexpr);
3351 gfc_init_block (&block);
3352 gfc_add_block_to_block (&block, &loop.pre);
3353 gfc_add_block_to_block (&block, &loop.post);
3354 tmp = gfc_finish_block (&block);
3356 if (HONOR_INFINITIES (DECL_MODE (limit)))
3357 else_stmt = build2_v (MODIFY_EXPR, limit, huge_cst);
3359 else_stmt = build_empty_stmt (input_location);
3360 tmp = build3_v (COND_EXPR, maskse.expr, tmp, else_stmt);
3361 gfc_add_expr_to_block (&block, tmp);
3362 gfc_add_block_to_block (&se->pre, &block);
3366 gfc_add_block_to_block (&se->pre, &loop.pre);
3367 gfc_add_block_to_block (&se->pre, &loop.post);
3370 gfc_cleanup_loop (&loop);
3375 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
3377 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
3383 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3384 type = TREE_TYPE (args[0]);
3386 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3387 build_int_cst (type, 1), args[1]);
3388 tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], tmp);
3389 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
3390 build_int_cst (type, 0));
3391 type = gfc_typenode_for_spec (&expr->ts);
3392 se->expr = convert (type, tmp);
3396 /* Generate code for BGE, BGT, BLE and BLT intrinsics. */
3398 gfc_conv_intrinsic_bitcomp (gfc_se * se, gfc_expr * expr, enum tree_code op)
3402 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3404 /* Convert both arguments to the unsigned type of the same size. */
3405 args[0] = fold_convert (unsigned_type_for (TREE_TYPE (args[0])), args[0]);
3406 args[1] = fold_convert (unsigned_type_for (TREE_TYPE (args[1])), args[1]);
3408 /* If they have unequal type size, convert to the larger one. */
3409 if (TYPE_PRECISION (TREE_TYPE (args[0]))
3410 > TYPE_PRECISION (TREE_TYPE (args[1])))
3411 args[1] = fold_convert (TREE_TYPE (args[0]), args[1]);
3412 else if (TYPE_PRECISION (TREE_TYPE (args[1]))
3413 > TYPE_PRECISION (TREE_TYPE (args[0])))
3414 args[0] = fold_convert (TREE_TYPE (args[1]), args[0]);
3416 /* Now, we compare them. */
3417 se->expr = fold_build2_loc (input_location, op, boolean_type_node,
3422 /* Generate code to perform the specified operation. */
3424 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
3428 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3429 se->expr = fold_build2_loc (input_location, op, TREE_TYPE (args[0]),
3435 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
3439 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3440 se->expr = fold_build1_loc (input_location, BIT_NOT_EXPR,
3441 TREE_TYPE (arg), arg);
3444 /* Set or clear a single bit. */
3446 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
3453 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3454 type = TREE_TYPE (args[0]);
3456 tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3457 build_int_cst (type, 1), args[1]);
3463 tmp = fold_build1_loc (input_location, BIT_NOT_EXPR, type, tmp);
3465 se->expr = fold_build2_loc (input_location, op, type, args[0], tmp);
3468 /* Extract a sequence of bits.
3469 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
3471 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
3478 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3479 type = TREE_TYPE (args[0]);
3481 mask = build_int_cst (type, -1);
3482 mask = fold_build2_loc (input_location, LSHIFT_EXPR, type, mask, args[2]);
3483 mask = fold_build1_loc (input_location, BIT_NOT_EXPR, type, mask);
3485 tmp = fold_build2_loc (input_location, RSHIFT_EXPR, type, args[0], args[1]);
3487 se->expr = fold_build2_loc (input_location, BIT_AND_EXPR, type, tmp, mask);
3491 gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
3494 tree args[2], type, num_bits, cond;
3496 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3498 args[0] = gfc_evaluate_now (args[0], &se->pre);
3499 args[1] = gfc_evaluate_now (args[1], &se->pre);
3500 type = TREE_TYPE (args[0]);
3503 args[0] = fold_convert (unsigned_type_for (type), args[0]);
3505 gcc_assert (right_shift);
3507 se->expr = fold_build2_loc (input_location,
3508 right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
3509 TREE_TYPE (args[0]), args[0], args[1]);
3512 se->expr = fold_convert (type, se->expr);
3514 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3515 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3517 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
3518 cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
3521 se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
3522 build_int_cst (type, 0), se->expr);
3525 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
3527 : ((shift >= 0) ? i << shift : i >> -shift)
3528 where all shifts are logical shifts. */
3530 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
3542 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3544 args[0] = gfc_evaluate_now (args[0], &se->pre);
3545 args[1] = gfc_evaluate_now (args[1], &se->pre);
3547 type = TREE_TYPE (args[0]);
3548 utype = unsigned_type_for (type);
3550 width = fold_build1_loc (input_location, ABS_EXPR, TREE_TYPE (args[1]),
3553 /* Left shift if positive. */
3554 lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type, args[0], width);
3556 /* Right shift if negative.
3557 We convert to an unsigned type because we want a logical shift.
3558 The standard doesn't define the case of shifting negative
3559 numbers, and we try to be compatible with other compilers, most
3560 notably g77, here. */
3561 rshift = fold_convert (type, fold_build2_loc (input_location, RSHIFT_EXPR,
3562 utype, convert (utype, args[0]), width));
3564 tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, args[1],
3565 build_int_cst (TREE_TYPE (args[1]), 0));
3566 tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp, lshift, rshift);
3568 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3569 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3571 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
3572 cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, width,
3574 se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
3575 build_int_cst (type, 0), tmp);
3579 /* Circular shift. AKA rotate or barrel shift. */
3582 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
3590 unsigned int num_args;
3592 num_args = gfc_intrinsic_argument_list_length (expr);
3593 args = XALLOCAVEC (tree, num_args);
3595 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3599 /* Use a library function for the 3 parameter version. */
3600 tree int4type = gfc_get_int_type (4);
3602 type = TREE_TYPE (args[0]);
3603 /* We convert the first argument to at least 4 bytes, and
3604 convert back afterwards. This removes the need for library
3605 functions for all argument sizes, and function will be
3606 aligned to at least 32 bits, so there's no loss. */
3607 if (expr->ts.kind < 4)
3608 args[0] = convert (int4type, args[0]);
3610 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
3611 need loads of library functions. They cannot have values >
3612 BIT_SIZE (I) so the conversion is safe. */
3613 args[1] = convert (int4type, args[1]);
3614 args[2] = convert (int4type, args[2]);
3616 switch (expr->ts.kind)
3621 tmp = gfor_fndecl_math_ishftc4;
3624 tmp = gfor_fndecl_math_ishftc8;
3627 tmp = gfor_fndecl_math_ishftc16;
3632 se->expr = build_call_expr_loc (input_location,
3633 tmp, 3, args[0], args[1], args[2]);
3634 /* Convert the result back to the original type, if we extended
3635 the first argument's width above. */
3636 if (expr->ts.kind < 4)
3637 se->expr = convert (type, se->expr);
3641 type = TREE_TYPE (args[0]);
3643 /* Evaluate arguments only once. */
3644 args[0] = gfc_evaluate_now (args[0], &se->pre);
3645 args[1] = gfc_evaluate_now (args[1], &se->pre);
3647 /* Rotate left if positive. */
3648 lrot = fold_build2_loc (input_location, LROTATE_EXPR, type, args[0], args[1]);
3650 /* Rotate right if negative. */
3651 tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (args[1]),
3653 rrot = fold_build2_loc (input_location,RROTATE_EXPR, type, args[0], tmp);
3655 zero = build_int_cst (TREE_TYPE (args[1]), 0);
3656 tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, args[1],
3658 rrot = fold_build3_loc (input_location, COND_EXPR, type, tmp, lrot, rrot);
3660 /* Do nothing if shift == 0. */
3661 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, args[1],
3663 se->expr = fold_build3_loc (input_location, COND_EXPR, type, tmp, args[0],
3668 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
3669 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
3671 The conditional expression is necessary because the result of LEADZ(0)
3672 is defined, but the result of __builtin_clz(0) is undefined for most
3675 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
3676 difference in bit size between the argument of LEADZ and the C int. */
3679 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
3691 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3692 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3694 /* Which variant of __builtin_clz* should we call? */
3695 if (argsize <= INT_TYPE_SIZE)
3697 arg_type = unsigned_type_node;
3698 func = built_in_decls[BUILT_IN_CLZ];
3700 else if (argsize <= LONG_TYPE_SIZE)
3702 arg_type = long_unsigned_type_node;
3703 func = built_in_decls[BUILT_IN_CLZL];
3705 else if (argsize <= LONG_LONG_TYPE_SIZE)
3707 arg_type = long_long_unsigned_type_node;
3708 func = built_in_decls[BUILT_IN_CLZLL];
3712 gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
3713 arg_type = gfc_build_uint_type (argsize);
3717 /* Convert the actual argument twice: first, to the unsigned type of the
3718 same size; then, to the proper argument type for the built-in
3719 function. But the return type is of the default INTEGER kind. */
3720 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3721 arg = fold_convert (arg_type, arg);
3722 arg = gfc_evaluate_now (arg, &se->pre);
3723 result_type = gfc_get_int_type (gfc_default_integer_kind);
3725 /* Compute LEADZ for the case i .ne. 0. */
3728 s = TYPE_PRECISION (arg_type) - argsize;
3729 tmp = fold_convert (result_type,
3730 build_call_expr_loc (input_location, func,
3732 leadz = fold_build2_loc (input_location, MINUS_EXPR, result_type,
3733 tmp, build_int_cst (result_type, s));
3737 /* We end up here if the argument type is larger than 'long long'.
3738 We generate this code:
3740 if (x & (ULL_MAX << ULL_SIZE) != 0)
3741 return clzll ((unsigned long long) (x >> ULLSIZE));
3743 return ULL_SIZE + clzll ((unsigned long long) x);
3744 where ULL_MAX is the largest value that a ULL_MAX can hold
3745 (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
3746 is the bit-size of the long long type (64 in this example). */
3747 tree ullsize, ullmax, tmp1, tmp2;
3749 ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
3750 ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
3751 long_long_unsigned_type_node,
3752 build_int_cst (long_long_unsigned_type_node,
3755 cond = fold_build2_loc (input_location, LSHIFT_EXPR, arg_type,
3756 fold_convert (arg_type, ullmax), ullsize);
3757 cond = fold_build2_loc (input_location, BIT_AND_EXPR, arg_type,
3759 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
3760 cond, build_int_cst (arg_type, 0));
3762 tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
3764 tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
3765 tmp1 = fold_convert (result_type,
3766 build_call_expr_loc (input_location,
3767 built_in_decls[BUILT_IN_CLZLL],
3770 tmp2 = fold_convert (long_long_unsigned_type_node, arg);
3771 tmp2 = fold_convert (result_type,
3772 build_call_expr_loc (input_location,
3773 built_in_decls[BUILT_IN_CLZLL],
3775 tmp2 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
3778 leadz = fold_build3_loc (input_location, COND_EXPR, result_type,
3782 /* Build BIT_SIZE. */
3783 bit_size = build_int_cst (result_type, argsize);
3785 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3786 arg, build_int_cst (arg_type, 0));
3787 se->expr = fold_build3_loc (input_location, COND_EXPR, result_type, cond,
3792 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
3794 The conditional expression is necessary because the result of TRAILZ(0)
3795 is defined, but the result of __builtin_ctz(0) is undefined for most
3799 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
3810 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3811 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3813 /* Which variant of __builtin_ctz* should we call? */
3814 if (argsize <= INT_TYPE_SIZE)
3816 arg_type = unsigned_type_node;
3817 func = built_in_decls[BUILT_IN_CTZ];
3819 else if (argsize <= LONG_TYPE_SIZE)
3821 arg_type = long_unsigned_type_node;
3822 func = built_in_decls[BUILT_IN_CTZL];
3824 else if (argsize <= LONG_LONG_TYPE_SIZE)
3826 arg_type = long_long_unsigned_type_node;
3827 func = built_in_decls[BUILT_IN_CTZLL];
3831 gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
3832 arg_type = gfc_build_uint_type (argsize);
3836 /* Convert the actual argument twice: first, to the unsigned type of the
3837 same size; then, to the proper argument type for the built-in
3838 function. But the return type is of the default INTEGER kind. */
3839 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3840 arg = fold_convert (arg_type, arg);
3841 arg = gfc_evaluate_now (arg, &se->pre);
3842 result_type = gfc_get_int_type (gfc_default_integer_kind);
3844 /* Compute TRAILZ for the case i .ne. 0. */
3846 trailz = fold_convert (result_type, build_call_expr_loc (input_location,
3850 /* We end up here if the argument type is larger than 'long long'.
3851 We generate this code:
3853 if ((x & ULL_MAX) == 0)
3854 return ULL_SIZE + ctzll ((unsigned long long) (x >> ULLSIZE));
3856 return ctzll ((unsigned long long) x);
3858 where ULL_MAX is the largest value that a ULL_MAX can hold
3859 (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
3860 is the bit-size of the long long type (64 in this example). */
3861 tree ullsize, ullmax, tmp1, tmp2;
3863 ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
3864 ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
3865 long_long_unsigned_type_node,
3866 build_int_cst (long_long_unsigned_type_node, 0));
3868 cond = fold_build2_loc (input_location, BIT_AND_EXPR, arg_type, arg,
3869 fold_convert (arg_type, ullmax));
3870 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, cond,
3871 build_int_cst (arg_type, 0));
3873 tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
3875 tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
3876 tmp1 = fold_convert (result_type,
3877 build_call_expr_loc (input_location,
3878 built_in_decls[BUILT_IN_CTZLL],
3880 tmp1 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
3883 tmp2 = fold_convert (long_long_unsigned_type_node, arg);
3884 tmp2 = fold_convert (result_type,
3885 build_call_expr_loc (input_location,
3886 built_in_decls[BUILT_IN_CTZLL],
3889 trailz = fold_build3_loc (input_location, COND_EXPR, result_type,
3893 /* Build BIT_SIZE. */
3894 bit_size = build_int_cst (result_type, argsize);
3896 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
3897 arg, build_int_cst (arg_type, 0));
3898 se->expr = fold_build3_loc (input_location, COND_EXPR, result_type, cond,
3902 /* Using __builtin_popcount for POPCNT and __builtin_parity for POPPAR;
3903 for types larger than "long long", we call the long long built-in for
3904 the lower and higher bits and combine the result. */
3907 gfc_conv_intrinsic_popcnt_poppar (gfc_se * se, gfc_expr *expr, int parity)
3915 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3916 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3917 result_type = gfc_get_int_type (gfc_default_integer_kind);
3919 /* Which variant of the builtin should we call? */
3920 if (argsize <= INT_TYPE_SIZE)
3922 arg_type = unsigned_type_node;
3923 func = built_in_decls[parity ? BUILT_IN_PARITY : BUILT_IN_POPCOUNT];
3925 else if (argsize <= LONG_TYPE_SIZE)
3927 arg_type = long_unsigned_type_node;
3928 func = built_in_decls[parity ? BUILT_IN_PARITYL : BUILT_IN_POPCOUNTL];
3930 else if (argsize <= LONG_LONG_TYPE_SIZE)
3932 arg_type = long_long_unsigned_type_node;
3933 func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
3937 /* Our argument type is larger than 'long long', which mean none
3938 of the POPCOUNT builtins covers it. We thus call the 'long long'
3939 variant multiple times, and add the results. */
3940 tree utype, arg2, call1, call2;
3942 /* For now, we only cover the case where argsize is twice as large
3944 gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
3946 func = built_in_decls[parity ? BUILT_IN_PARITYLL : BUILT_IN_POPCOUNTLL];
3948 /* Convert it to an integer, and store into a variable. */
3949 utype = gfc_build_uint_type (argsize);
3950 arg = fold_convert (utype, arg);
3951 arg = gfc_evaluate_now (arg, &se->pre);
3953 /* Call the builtin twice. */
3954 call1 = build_call_expr_loc (input_location, func, 1,
3955 fold_convert (long_long_unsigned_type_node,
3958 arg2 = fold_build2_loc (input_location, RSHIFT_EXPR, utype, arg,
3959 build_int_cst (utype, LONG_LONG_TYPE_SIZE));
3960 call2 = build_call_expr_loc (input_location, func, 1,
3961 fold_convert (long_long_unsigned_type_node,
3964 /* Combine the results. */
3966 se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, result_type,
3969 se->expr = fold_build2_loc (input_location, PLUS_EXPR, result_type,
3975 /* Convert the actual argument twice: first, to the unsigned type of the
3976 same size; then, to the proper argument type for the built-in
3978 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3979 arg = fold_convert (arg_type, arg);
3981 se->expr = fold_convert (result_type,
3982 build_call_expr_loc (input_location, func, 1, arg));
3986 /* Process an intrinsic with unspecified argument-types that has an optional
3987 argument (which could be of type character), e.g. EOSHIFT. For those, we
3988 need to append the string length of the optional argument if it is not
3989 present and the type is really character.
3990 primary specifies the position (starting at 1) of the non-optional argument
3991 specifying the type and optional gives the position of the optional
3992 argument in the arglist. */
3995 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
3996 unsigned primary, unsigned optional)
3998 gfc_actual_arglist* prim_arg;
3999 gfc_actual_arglist* opt_arg;
4001 gfc_actual_arglist* arg;
4003 VEC(tree,gc) *append_args;
4005 /* Find the two arguments given as position. */
4009 for (arg = expr->value.function.actual; arg; arg = arg->next)
4013 if (cur_pos == primary)
4015 if (cur_pos == optional)
4018 if (cur_pos >= primary && cur_pos >= optional)
4021 gcc_assert (prim_arg);
4022 gcc_assert (prim_arg->expr);
4023 gcc_assert (opt_arg);
4025 /* If we do have type CHARACTER and the optional argument is really absent,
4026 append a dummy 0 as string length. */
4028 if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
4032 dummy = build_int_cst (gfc_charlen_type_node, 0);
4033 append_args = VEC_alloc (tree, gc, 1);
4034 VEC_quick_push (tree, append_args, dummy);
4037 /* Build the call itself. */
4038 sym = gfc_get_symbol_for_expr (expr);
4039 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
4045 /* The length of a character string. */
4047 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
4057 gcc_assert (!se->ss);
4059 arg = expr->value.function.actual->expr;
4061 type = gfc_typenode_for_spec (&expr->ts);
4062 switch (arg->expr_type)
4065 len = build_int_cst (NULL_TREE, arg->value.character.length);
4069 /* Obtain the string length from the function used by
4070 trans-array.c(gfc_trans_array_constructor). */
4072 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
4076 if (arg->ref == NULL
4077 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
4079 /* This doesn't catch all cases.
4080 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
4081 and the surrounding thread. */
4082 sym = arg->symtree->n.sym;
4083 decl = gfc_get_symbol_decl (sym);
4084 if (decl == current_function_decl && sym->attr.function
4085 && (sym->result == sym))
4086 decl = gfc_get_fake_result_decl (sym, 0);
4088 len = sym->ts.u.cl->backend_decl;
4093 /* Otherwise fall through. */
4096 /* Anybody stupid enough to do this deserves inefficient code. */
4097 ss = gfc_walk_expr (arg);
4098 gfc_init_se (&argse, se);
4099 if (ss == gfc_ss_terminator)
4100 gfc_conv_expr (&argse, arg);
4102 gfc_conv_expr_descriptor (&argse, arg, ss);
4103 gfc_add_block_to_block (&se->pre, &argse.pre);
4104 gfc_add_block_to_block (&se->post, &argse.post);
4105 len = argse.string_length;
4108 se->expr = convert (type, len);
4111 /* The length of a character string not including trailing blanks. */
4113 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
4115 int kind = expr->value.function.actual->expr->ts.kind;
4116 tree args[2], type, fndecl;
4118 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4119 type = gfc_typenode_for_spec (&expr->ts);
4122 fndecl = gfor_fndecl_string_len_trim;
4124 fndecl = gfor_fndecl_string_len_trim_char4;
4128 se->expr = build_call_expr_loc (input_location,
4129 fndecl, 2, args[0], args[1]);
4130 se->expr = convert (type, se->expr);
4134 /* Returns the starting position of a substring within a string. */
4137 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
4140 tree logical4_type_node = gfc_get_logical_type (4);
4144 unsigned int num_args;
4146 args = XALLOCAVEC (tree, 5);
4148 /* Get number of arguments; characters count double due to the
4149 string length argument. Kind= is not passed to the library
4150 and thus ignored. */
4151 if (expr->value.function.actual->next->next->expr == NULL)
4156 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
4157 type = gfc_typenode_for_spec (&expr->ts);
4160 args[4] = build_int_cst (logical4_type_node, 0);
4162 args[4] = convert (logical4_type_node, args[4]);
4164 fndecl = build_addr (function, current_function_decl);
4165 se->expr = build_call_array_loc (input_location,
4166 TREE_TYPE (TREE_TYPE (function)), fndecl,
4168 se->expr = convert (type, se->expr);
4172 /* The ascii value for a single character. */
4174 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
4176 tree args[2], type, pchartype;
4178 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4179 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
4180 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
4181 args[1] = fold_build1_loc (input_location, NOP_EXPR, pchartype, args[1]);
4182 type = gfc_typenode_for_spec (&expr->ts);
4184 se->expr = build_fold_indirect_ref_loc (input_location,
4186 se->expr = convert (type, se->expr);
4190 /* Intrinsic ISNAN calls __builtin_isnan. */
4193 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
4197 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4198 se->expr = build_call_expr_loc (input_location,
4199 built_in_decls[BUILT_IN_ISNAN], 1, arg);
4200 STRIP_TYPE_NOPS (se->expr);
4201 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4205 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
4206 their argument against a constant integer value. */
4209 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
4213 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4214 se->expr = fold_build2_loc (input_location, EQ_EXPR,
4215 gfc_typenode_for_spec (&expr->ts),
4216 arg, build_int_cst (TREE_TYPE (arg), value));
4221 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
4224 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
4232 unsigned int num_args;
4234 num_args = gfc_intrinsic_argument_list_length (expr);
4235 args = XALLOCAVEC (tree, num_args);
4237 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
4238 if (expr->ts.type != BT_CHARACTER)
4246 /* We do the same as in the non-character case, but the argument
4247 list is different because of the string length arguments. We
4248 also have to set the string length for the result. */
4255 gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
4257 se->string_length = len;
4259 type = TREE_TYPE (tsource);
4260 se->expr = fold_build3_loc (input_location, COND_EXPR, type, mask, tsource,
4261 fold_convert (type, fsource));
4265 /* MERGE_BITS (I, J, MASK) = (I & MASK) | (I & (~MASK)). */
4268 gfc_conv_intrinsic_merge_bits (gfc_se * se, gfc_expr * expr)
4270 tree args[3], mask, type;
4272 gfc_conv_intrinsic_function_args (se, expr, args, 3);
4273 mask = gfc_evaluate_now (args[2], &se->pre);
4275 type = TREE_TYPE (args[0]);
4276 gcc_assert (TREE_TYPE (args[1]) == type);
4277 gcc_assert (TREE_TYPE (mask) == type);
4279 args[0] = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], mask);
4280 args[1] = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[1],
4281 fold_build1_loc (input_location, BIT_NOT_EXPR,
4283 se->expr = fold_build2_loc (input_location, BIT_IOR_EXPR, type,
4288 /* MASKL(n) = n == 0 ? 0 : (~0) << (BIT_SIZE - n)
4289 MASKR(n) = n == BIT_SIZE ? ~0 : ~((~0) << n) */
4292 gfc_conv_intrinsic_mask (gfc_se * se, gfc_expr * expr, int left)
4294 tree arg, allones, type, utype, res, cond, bitsize;
4297 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4298 arg = gfc_evaluate_now (arg, &se->pre);
4300 type = gfc_get_int_type (expr->ts.kind);
4301 utype = unsigned_type_for (type);
4303 i = gfc_validate_kind (BT_INTEGER, expr->ts.kind, false);
4304 bitsize = build_int_cst (TREE_TYPE (arg), gfc_integer_kinds[i].bit_size);
4306 allones = fold_build1_loc (input_location, BIT_NOT_EXPR, utype,
4307 build_int_cst (utype, 0));
4311 /* Left-justified mask. */
4312 res = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (arg),
4314 res = fold_build2_loc (input_location, LSHIFT_EXPR, utype, allones,
4315 fold_convert (utype, res));
4317 /* Special case arg == 0, because SHIFT_EXPR wants a shift strictly
4318 smaller than type width. */
4319 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, arg,
4320 build_int_cst (TREE_TYPE (arg), 0));
4321 res = fold_build3_loc (input_location, COND_EXPR, utype, cond,
4322 build_int_cst (utype, 0), res);
4326 /* Right-justified mask. */
4327 res = fold_build2_loc (input_location, LSHIFT_EXPR, utype, allones,
4328 fold_convert (utype, arg));
4329 res = fold_build1_loc (input_location, BIT_NOT_EXPR, utype, res);
4331 /* Special case agr == bit_size, because SHIFT_EXPR wants a shift
4332 strictly smaller than type width. */
4333 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4335 res = fold_build3_loc (input_location, COND_EXPR, utype,
4336 cond, allones, res);
4339 se->expr = fold_convert (type, res);
4343 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
4345 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
4347 tree arg, type, tmp, frexp;
4349 frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4351 type = gfc_typenode_for_spec (&expr->ts);
4352 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4353 tmp = gfc_create_var (integer_type_node, NULL);
4354 se->expr = build_call_expr_loc (input_location, frexp, 2,
4355 fold_convert (type, arg),
4356 gfc_build_addr_expr (NULL_TREE, tmp));
4357 se->expr = fold_convert (type, se->expr);
4361 /* NEAREST (s, dir) is translated into
4362 tmp = copysign (HUGE_VAL, dir);
4363 return nextafter (s, tmp);
4366 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
4368 tree args[2], type, tmp, nextafter, copysign, huge_val;
4370 nextafter = gfc_builtin_decl_for_float_kind (BUILT_IN_NEXTAFTER, expr->ts.kind);
4371 copysign = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
4373 type = gfc_typenode_for_spec (&expr->ts);
4374 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4376 huge_val = gfc_build_inf_or_huge (type, expr->ts.kind);
4377 tmp = build_call_expr_loc (input_location, copysign, 2, huge_val,
4378 fold_convert (type, args[1]));
4379 se->expr = build_call_expr_loc (input_location, nextafter, 2,
4380 fold_convert (type, args[0]), tmp);
4381 se->expr = fold_convert (type, se->expr);
4385 /* SPACING (s) is translated into
4393 e = MAX_EXPR (e, emin);
4394 res = scalbn (1., e);
4398 where prec is the precision of s, gfc_real_kinds[k].digits,
4399 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
4400 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
4403 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
4405 tree arg, type, prec, emin, tiny, res, e;
4406 tree cond, tmp, frexp, scalbn;
4410 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
4411 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
4412 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
4413 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
4415 frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4416 scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
4418 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4419 arg = gfc_evaluate_now (arg, &se->pre);
4421 type = gfc_typenode_for_spec (&expr->ts);
4422 e = gfc_create_var (integer_type_node, NULL);
4423 res = gfc_create_var (type, NULL);
4426 /* Build the block for s /= 0. */
4427 gfc_start_block (&block);
4428 tmp = build_call_expr_loc (input_location, frexp, 2, arg,
4429 gfc_build_addr_expr (NULL_TREE, e));
4430 gfc_add_expr_to_block (&block, tmp);
4432 tmp = fold_build2_loc (input_location, MINUS_EXPR, integer_type_node, e,
4434 gfc_add_modify (&block, e, fold_build2_loc (input_location, MAX_EXPR,
4435 integer_type_node, tmp, emin));
4437 tmp = build_call_expr_loc (input_location, scalbn, 2,
4438 build_real_from_int_cst (type, integer_one_node), e);
4439 gfc_add_modify (&block, res, tmp);
4441 /* Finish by building the IF statement. */
4442 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, arg,
4443 build_real_from_int_cst (type, integer_zero_node));
4444 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
4445 gfc_finish_block (&block));
4447 gfc_add_expr_to_block (&se->pre, tmp);
4452 /* RRSPACING (s) is translated into
4459 x = scalbn (x, precision - e);
4463 where precision is gfc_real_kinds[k].digits. */
4466 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
4468 tree arg, type, e, x, cond, stmt, tmp, frexp, scalbn, fabs;
4472 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
4473 prec = gfc_real_kinds[k].digits;
4475 frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4476 scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
4477 fabs = gfc_builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
4479 type = gfc_typenode_for_spec (&expr->ts);
4480 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4481 arg = gfc_evaluate_now (arg, &se->pre);
4483 e = gfc_create_var (integer_type_node, NULL);
4484 x = gfc_create_var (type, NULL);
4485 gfc_add_modify (&se->pre, x,
4486 build_call_expr_loc (input_location, fabs, 1, arg));
4489 gfc_start_block (&block);
4490 tmp = build_call_expr_loc (input_location, frexp, 2, arg,
4491 gfc_build_addr_expr (NULL_TREE, e));
4492 gfc_add_expr_to_block (&block, tmp);
4494 tmp = fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4495 build_int_cst (NULL_TREE, prec), e);
4496 tmp = build_call_expr_loc (input_location, scalbn, 2, x, tmp);
4497 gfc_add_modify (&block, x, tmp);
4498 stmt = gfc_finish_block (&block);
4500 cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, x,
4501 build_real_from_int_cst (type, integer_zero_node));
4502 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
4503 gfc_add_expr_to_block (&se->pre, tmp);
4505 se->expr = fold_convert (type, x);
4509 /* SCALE (s, i) is translated into scalbn (s, i). */
4511 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
4513 tree args[2], type, scalbn;
4515 scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
4517 type = gfc_typenode_for_spec (&expr->ts);
4518 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4519 se->expr = build_call_expr_loc (input_location, scalbn, 2,
4520 fold_convert (type, args[0]),
4521 fold_convert (integer_type_node, args[1]));
4522 se->expr = fold_convert (type, se->expr);
4526 /* SET_EXPONENT (s, i) is translated into
4527 scalbn (frexp (s, &dummy_int), i). */
4529 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
4531 tree args[2], type, tmp, frexp, scalbn;
4533 frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4534 scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
4536 type = gfc_typenode_for_spec (&expr->ts);
4537 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4539 tmp = gfc_create_var (integer_type_node, NULL);
4540 tmp = build_call_expr_loc (input_location, frexp, 2,
4541 fold_convert (type, args[0]),
4542 gfc_build_addr_expr (NULL_TREE, tmp));
4543 se->expr = build_call_expr_loc (input_location, scalbn, 2, tmp,
4544 fold_convert (integer_type_node, args[1]));
4545 se->expr = fold_convert (type, se->expr);
4550 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
4552 gfc_actual_arglist *actual;
4560 gfc_init_se (&argse, NULL);
4561 actual = expr->value.function.actual;
4563 ss = gfc_walk_expr (actual->expr);
4564 gcc_assert (ss != gfc_ss_terminator);
4565 argse.want_pointer = 1;
4566 argse.data_not_needed = 1;
4567 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
4568 gfc_add_block_to_block (&se->pre, &argse.pre);
4569 gfc_add_block_to_block (&se->post, &argse.post);
4570 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
4572 /* Build the call to size0. */
4573 fncall0 = build_call_expr_loc (input_location,
4574 gfor_fndecl_size0, 1, arg1);
4576 actual = actual->next;
4580 gfc_init_se (&argse, NULL);
4581 gfc_conv_expr_type (&argse, actual->expr,
4582 gfc_array_index_type);
4583 gfc_add_block_to_block (&se->pre, &argse.pre);
4585 /* Unusually, for an intrinsic, size does not exclude
4586 an optional arg2, so we must test for it. */
4587 if (actual->expr->expr_type == EXPR_VARIABLE
4588 && actual->expr->symtree->n.sym->attr.dummy
4589 && actual->expr->symtree->n.sym->attr.optional)
4592 /* Build the call to size1. */
4593 fncall1 = build_call_expr_loc (input_location,
4594 gfor_fndecl_size1, 2,
4597 gfc_init_se (&argse, NULL);
4598 argse.want_pointer = 1;
4599 argse.data_not_needed = 1;
4600 gfc_conv_expr (&argse, actual->expr);
4601 gfc_add_block_to_block (&se->pre, &argse.pre);
4602 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
4603 argse.expr, null_pointer_node);
4604 tmp = gfc_evaluate_now (tmp, &se->pre);
4605 se->expr = fold_build3_loc (input_location, COND_EXPR,
4606 pvoid_type_node, tmp, fncall1, fncall0);
4610 se->expr = NULL_TREE;
4611 argse.expr = fold_build2_loc (input_location, MINUS_EXPR,
4612 gfc_array_index_type,
4613 argse.expr, gfc_index_one_node);
4616 else if (expr->value.function.actual->expr->rank == 1)
4618 argse.expr = gfc_index_zero_node;
4619 se->expr = NULL_TREE;
4624 if (se->expr == NULL_TREE)
4626 tree ubound, lbound;
4628 arg1 = build_fold_indirect_ref_loc (input_location,
4630 ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
4631 lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
4632 se->expr = fold_build2_loc (input_location, MINUS_EXPR,
4633 gfc_array_index_type, ubound, lbound);
4634 se->expr = fold_build2_loc (input_location, PLUS_EXPR,
4635 gfc_array_index_type,
4636 se->expr, gfc_index_one_node);
4637 se->expr = fold_build2_loc (input_location, MAX_EXPR,
4638 gfc_array_index_type, se->expr,
4639 gfc_index_zero_node);
4642 type = gfc_typenode_for_spec (&expr->ts);
4643 se->expr = convert (type, se->expr);
4647 /* Helper function to compute the size of a character variable,
4648 excluding the terminating null characters. The result has
4649 gfc_array_index_type type. */
4652 size_of_string_in_bytes (int kind, tree string_length)
4655 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
4657 bytesize = build_int_cst (gfc_array_index_type,
4658 gfc_character_kinds[i].bit_size / 8);
4660 return fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
4662 fold_convert (gfc_array_index_type, string_length));
4667 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
4679 arg = expr->value.function.actual->expr;
4681 gfc_init_se (&argse, NULL);
4682 ss = gfc_walk_expr (arg);
4684 if (ss == gfc_ss_terminator)
4686 if (arg->ts.type == BT_CLASS)
4687 gfc_add_data_component (arg);
4689 gfc_conv_expr_reference (&argse, arg);
4691 type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4694 /* Obtain the source word length. */
4695 if (arg->ts.type == BT_CHARACTER)
4696 se->expr = size_of_string_in_bytes (arg->ts.kind,
4697 argse.string_length);
4699 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
4703 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
4704 argse.want_pointer = 0;
4705 gfc_conv_expr_descriptor (&argse, arg, ss);
4706 type = gfc_get_element_type (TREE_TYPE (argse.expr));
4708 /* Obtain the argument's word length. */
4709 if (arg->ts.type == BT_CHARACTER)
4710 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
4712 tmp = fold_convert (gfc_array_index_type,
4713 size_in_bytes (type));
4714 gfc_add_modify (&argse.pre, source_bytes, tmp);
4716 /* Obtain the size of the array in bytes. */
4717 for (n = 0; n < arg->rank; n++)
4720 idx = gfc_rank_cst[n];
4721 lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
4722 upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
4723 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4724 gfc_array_index_type, upper, lower);
4725 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4726 gfc_array_index_type, tmp, gfc_index_one_node);
4727 tmp = fold_build2_loc (input_location, MULT_EXPR,
4728 gfc_array_index_type, tmp, source_bytes);
4729 gfc_add_modify (&argse.pre, source_bytes, tmp);
4731 se->expr = source_bytes;
4734 gfc_add_block_to_block (&se->pre, &argse.pre);
4739 gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
4744 tree type, result_type, tmp;
4746 arg = expr->value.function.actual->expr;
4747 gfc_init_se (&eight, NULL);
4748 gfc_conv_expr (&eight, gfc_get_int_expr (expr->ts.kind, NULL, 8));
4750 gfc_init_se (&argse, NULL);
4751 ss = gfc_walk_expr (arg);
4752 result_type = gfc_get_int_type (expr->ts.kind);
4754 if (ss == gfc_ss_terminator)
4756 if (arg->ts.type == BT_CLASS)
4758 gfc_add_vptr_component (arg);
4759 gfc_add_size_component (arg);
4760 gfc_conv_expr (&argse, arg);
4761 tmp = fold_convert (result_type, argse.expr);
4765 gfc_conv_expr_reference (&argse, arg);
4766 type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4771 argse.want_pointer = 0;
4772 gfc_conv_expr_descriptor (&argse, arg, ss);
4773 type = gfc_get_element_type (TREE_TYPE (argse.expr));
4776 /* Obtain the argument's word length. */
4777 if (arg->ts.type == BT_CHARACTER)
4778 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
4780 tmp = fold_convert (result_type, size_in_bytes (type));
4783 se->expr = fold_build2_loc (input_location, MULT_EXPR, result_type, tmp,
4785 gfc_add_block_to_block (&se->pre, &argse.pre);
4789 /* Intrinsic string comparison functions. */
4792 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
4796 gfc_conv_intrinsic_function_args (se, expr, args, 4);
4799 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
4800 expr->value.function.actual->expr->ts.kind,
4802 se->expr = fold_build2_loc (input_location, op,
4803 gfc_typenode_for_spec (&expr->ts), se->expr,
4804 build_int_cst (TREE_TYPE (se->expr), 0));
4807 /* Generate a call to the adjustl/adjustr library function. */
4809 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
4817 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
4820 type = TREE_TYPE (args[2]);
4821 var = gfc_conv_string_tmp (se, type, len);
4824 tmp = build_call_expr_loc (input_location,
4825 fndecl, 3, args[0], args[1], args[2]);
4826 gfc_add_expr_to_block (&se->pre, tmp);
4828 se->string_length = len;
4832 /* Generate code for the TRANSFER intrinsic:
4834 DEST = TRANSFER (SOURCE, MOLD)
4836 typeof<DEST> = typeof<MOLD>
4841 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
4843 typeof<DEST> = typeof<MOLD>
4845 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
4846 sizeof (DEST(0) * SIZE). */
4848 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
4864 gfc_actual_arglist *arg;
4874 info = &se->ss->data.info;
4876 /* Convert SOURCE. The output from this stage is:-
4877 source_bytes = length of the source in bytes
4878 source = pointer to the source data. */
4879 arg = expr->value.function.actual;
4881 /* Ensure double transfer through LOGICAL preserves all
4883 if (arg->expr->expr_type == EXPR_FUNCTION
4884 && arg->expr->value.function.esym == NULL
4885 && arg->expr->value.function.isym != NULL
4886 && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
4887 && arg->expr->ts.type == BT_LOGICAL
4888 && expr->ts.type != arg->expr->ts.type)
4889 arg->expr->value.function.name = "__transfer_in_transfer";
4891 gfc_init_se (&argse, NULL);
4892 ss = gfc_walk_expr (arg->expr);
4894 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
4896 /* Obtain the pointer to source and the length of source in bytes. */
4897 if (ss == gfc_ss_terminator)
4899 gfc_conv_expr_reference (&argse, arg->expr);
4900 source = argse.expr;
4902 source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4905 /* Obtain the source word length. */
4906 if (arg->expr->ts.type == BT_CHARACTER)
4907 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4908 argse.string_length);
4910 tmp = fold_convert (gfc_array_index_type,
4911 size_in_bytes (source_type));
4915 argse.want_pointer = 0;
4916 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4917 source = gfc_conv_descriptor_data_get (argse.expr);
4918 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4920 /* Repack the source if not a full variable array. */
4921 if (arg->expr->expr_type == EXPR_VARIABLE
4922 && arg->expr->ref->u.ar.type != AR_FULL)
4924 tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
4926 if (gfc_option.warn_array_temp)
4927 gfc_warning ("Creating array temporary at %L", &expr->where);
4929 source = build_call_expr_loc (input_location,
4930 gfor_fndecl_in_pack, 1, tmp);
4931 source = gfc_evaluate_now (source, &argse.pre);
4933 /* Free the temporary. */
4934 gfc_start_block (&block);
4935 tmp = gfc_call_free (convert (pvoid_type_node, source));
4936 gfc_add_expr_to_block (&block, tmp);
4937 stmt = gfc_finish_block (&block);
4939 /* Clean up if it was repacked. */
4940 gfc_init_block (&block);
4941 tmp = gfc_conv_array_data (argse.expr);
4942 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
4944 tmp = build3_v (COND_EXPR, tmp, stmt,
4945 build_empty_stmt (input_location));
4946 gfc_add_expr_to_block (&block, tmp);
4947 gfc_add_block_to_block (&block, &se->post);
4948 gfc_init_block (&se->post);
4949 gfc_add_block_to_block (&se->post, &block);
4952 /* Obtain the source word length. */
4953 if (arg->expr->ts.type == BT_CHARACTER)
4954 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4955 argse.string_length);
4957 tmp = fold_convert (gfc_array_index_type,
4958 size_in_bytes (source_type));
4960 /* Obtain the size of the array in bytes. */
4961 extent = gfc_create_var (gfc_array_index_type, NULL);
4962 for (n = 0; n < arg->expr->rank; n++)
4965 idx = gfc_rank_cst[n];
4966 gfc_add_modify (&argse.pre, source_bytes, tmp);
4967 lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
4968 upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
4969 tmp = fold_build2_loc (input_location, MINUS_EXPR,
4970 gfc_array_index_type, upper, lower);
4971 gfc_add_modify (&argse.pre, extent, tmp);
4972 tmp = fold_build2_loc (input_location, PLUS_EXPR,
4973 gfc_array_index_type, extent,
4974 gfc_index_one_node);
4975 tmp = fold_build2_loc (input_location, MULT_EXPR,
4976 gfc_array_index_type, tmp, source_bytes);
4980 gfc_add_modify (&argse.pre, source_bytes, tmp);
4981 gfc_add_block_to_block (&se->pre, &argse.pre);
4982 gfc_add_block_to_block (&se->post, &argse.post);
4984 /* Now convert MOLD. The outputs are:
4985 mold_type = the TREE type of MOLD
4986 dest_word_len = destination word length in bytes. */
4989 gfc_init_se (&argse, NULL);
4990 ss = gfc_walk_expr (arg->expr);
4992 scalar_mold = arg->expr->rank == 0;
4994 if (ss == gfc_ss_terminator)
4996 gfc_conv_expr_reference (&argse, arg->expr);
4997 mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
5002 gfc_init_se (&argse, NULL);
5003 argse.want_pointer = 0;
5004 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
5005 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
5008 gfc_add_block_to_block (&se->pre, &argse.pre);
5009 gfc_add_block_to_block (&se->post, &argse.post);
5011 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
5013 /* If this TRANSFER is nested in another TRANSFER, use a type
5014 that preserves all bits. */
5015 if (arg->expr->ts.type == BT_LOGICAL)
5016 mold_type = gfc_get_int_type (arg->expr->ts.kind);
5019 if (arg->expr->ts.type == BT_CHARACTER)
5021 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
5022 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
5025 tmp = fold_convert (gfc_array_index_type,
5026 size_in_bytes (mold_type));
5028 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
5029 gfc_add_modify (&se->pre, dest_word_len, tmp);
5031 /* Finally convert SIZE, if it is present. */
5033 size_words = gfc_create_var (gfc_array_index_type, NULL);
5037 gfc_init_se (&argse, NULL);
5038 gfc_conv_expr_reference (&argse, arg->expr);
5039 tmp = convert (gfc_array_index_type,
5040 build_fold_indirect_ref_loc (input_location,
5042 gfc_add_block_to_block (&se->pre, &argse.pre);
5043 gfc_add_block_to_block (&se->post, &argse.post);
5048 /* Separate array and scalar results. */
5049 if (scalar_mold && tmp == NULL_TREE)
5050 goto scalar_transfer;
5052 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
5053 if (tmp != NULL_TREE)
5054 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5055 tmp, dest_word_len);
5059 gfc_add_modify (&se->pre, size_bytes, tmp);
5060 gfc_add_modify (&se->pre, size_words,
5061 fold_build2_loc (input_location, CEIL_DIV_EXPR,
5062 gfc_array_index_type,
5063 size_bytes, dest_word_len));
5065 /* Evaluate the bounds of the result. If the loop range exists, we have
5066 to check if it is too large. If so, we modify loop->to be consistent
5067 with min(size, size(source)). Otherwise, size is made consistent with
5068 the loop range, so that the right number of bytes is transferred.*/
5069 n = se->loop->order[0];
5070 if (se->loop->to[n] != NULL_TREE)
5072 tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5073 se->loop->to[n], se->loop->from[n]);
5074 tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5075 tmp, gfc_index_one_node);
5076 tmp = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
5078 gfc_add_modify (&se->pre, size_words, tmp);
5079 gfc_add_modify (&se->pre, size_bytes,
5080 fold_build2_loc (input_location, MULT_EXPR,
5081 gfc_array_index_type,
5082 size_words, dest_word_len));
5083 upper = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5084 size_words, se->loop->from[n]);
5085 upper = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5086 upper, gfc_index_one_node);
5090 upper = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5091 size_words, gfc_index_one_node);
5092 se->loop->from[n] = gfc_index_zero_node;
5095 se->loop->to[n] = upper;
5097 /* Build a destination descriptor, using the pointer, source, as the
5099 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
5100 info, mold_type, NULL_TREE, false, true, false,
5103 /* Cast the pointer to the result. */
5104 tmp = gfc_conv_descriptor_data_get (info->descriptor);
5105 tmp = fold_convert (pvoid_type_node, tmp);
5107 /* Use memcpy to do the transfer. */
5108 tmp = build_call_expr_loc (input_location,
5109 built_in_decls[BUILT_IN_MEMCPY],
5112 fold_convert (pvoid_type_node, source),
5113 fold_build2_loc (input_location, MIN_EXPR,
5114 gfc_array_index_type,
5115 size_bytes, source_bytes));
5116 gfc_add_expr_to_block (&se->pre, tmp);
5118 se->expr = info->descriptor;
5119 if (expr->ts.type == BT_CHARACTER)
5120 se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len);
5124 /* Deal with scalar results. */
5126 extent = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
5127 dest_word_len, source_bytes);
5128 extent = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
5129 extent, gfc_index_zero_node);
5131 if (expr->ts.type == BT_CHARACTER)
5136 ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
5137 tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
5140 /* If source is longer than the destination, use a pointer to
5141 the source directly. */
5142 gfc_init_block (&block);
5143 gfc_add_modify (&block, tmpdecl, ptr);
5144 direct = gfc_finish_block (&block);
5146 /* Otherwise, allocate a string with the length of the destination
5147 and copy the source into it. */
5148 gfc_init_block (&block);
5149 tmp = gfc_get_pchar_type (expr->ts.kind);
5150 tmp = gfc_call_malloc (&block, tmp, dest_word_len);
5151 gfc_add_modify (&block, tmpdecl,
5152 fold_convert (TREE_TYPE (ptr), tmp));
5153 tmp = build_call_expr_loc (input_location,
5154 built_in_decls[BUILT_IN_MEMCPY], 3,
5155 fold_convert (pvoid_type_node, tmpdecl),
5156 fold_convert (pvoid_type_node, ptr),
5158 gfc_add_expr_to_block (&block, tmp);
5159 indirect = gfc_finish_block (&block);
5161 /* Wrap it up with the condition. */
5162 tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
5163 dest_word_len, source_bytes);
5164 tmp = build3_v (COND_EXPR, tmp, direct, indirect);
5165 gfc_add_expr_to_block (&se->pre, tmp);
5168 se->string_length = dest_word_len;
5172 tmpdecl = gfc_create_var (mold_type, "transfer");
5174 ptr = convert (build_pointer_type (mold_type), source);
5176 /* Use memcpy to do the transfer. */
5177 tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
5178 tmp = build_call_expr_loc (input_location,
5179 built_in_decls[BUILT_IN_MEMCPY], 3,
5180 fold_convert (pvoid_type_node, tmp),
5181 fold_convert (pvoid_type_node, ptr),
5183 gfc_add_expr_to_block (&se->pre, tmp);
5190 /* Generate code for the ALLOCATED intrinsic.
5191 Generate inline code that directly check the address of the argument. */
5194 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
5196 gfc_actual_arglist *arg1;
5201 gfc_init_se (&arg1se, NULL);
5202 arg1 = expr->value.function.actual;
5203 ss1 = gfc_walk_expr (arg1->expr);
5205 if (ss1 == gfc_ss_terminator)
5207 /* Allocatable scalar. */
5208 arg1se.want_pointer = 1;
5209 if (arg1->expr->ts.type == BT_CLASS)
5210 gfc_add_data_component (arg1->expr);
5211 gfc_conv_expr (&arg1se, arg1->expr);
5216 /* Allocatable array. */
5217 arg1se.descriptor_only = 1;
5218 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
5219 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
5222 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
5223 fold_convert (TREE_TYPE (tmp), null_pointer_node));
5224 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
5228 /* Generate code for the ASSOCIATED intrinsic.
5229 If both POINTER and TARGET are arrays, generate a call to library function
5230 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
5231 In other cases, generate inline code that directly compare the address of
5232 POINTER with the address of TARGET. */
5235 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
5237 gfc_actual_arglist *arg1;
5238 gfc_actual_arglist *arg2;
5243 tree nonzero_charlen;
5244 tree nonzero_arraylen;
5247 gfc_init_se (&arg1se, NULL);
5248 gfc_init_se (&arg2se, NULL);
5249 arg1 = expr->value.function.actual;
5250 if (arg1->expr->ts.type == BT_CLASS)
5251 gfc_add_data_component (arg1->expr);
5253 ss1 = gfc_walk_expr (arg1->expr);
5257 /* No optional target. */
5258 if (ss1 == gfc_ss_terminator)
5260 /* A pointer to a scalar. */
5261 arg1se.want_pointer = 1;
5262 gfc_conv_expr (&arg1se, arg1->expr);
5267 /* A pointer to an array. */
5268 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
5269 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
5271 gfc_add_block_to_block (&se->pre, &arg1se.pre);
5272 gfc_add_block_to_block (&se->post, &arg1se.post);
5273 tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp2,
5274 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
5279 /* An optional target. */
5280 if (arg2->expr->ts.type == BT_CLASS)
5281 gfc_add_data_component (arg2->expr);
5282 ss2 = gfc_walk_expr (arg2->expr);
5284 nonzero_charlen = NULL_TREE;
5285 if (arg1->expr->ts.type == BT_CHARACTER)
5286 nonzero_charlen = fold_build2_loc (input_location, NE_EXPR,
5288 arg1->expr->ts.u.cl->backend_decl,
5291 if (ss1 == gfc_ss_terminator)
5293 /* A pointer to a scalar. */
5294 gcc_assert (ss2 == gfc_ss_terminator);
5295 arg1se.want_pointer = 1;
5296 gfc_conv_expr (&arg1se, arg1->expr);
5297 arg2se.want_pointer = 1;
5298 gfc_conv_expr (&arg2se, arg2->expr);
5299 gfc_add_block_to_block (&se->pre, &arg1se.pre);
5300 gfc_add_block_to_block (&se->post, &arg1se.post);
5301 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5302 arg1se.expr, arg2se.expr);
5303 tmp2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5304 arg1se.expr, null_pointer_node);
5305 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5306 boolean_type_node, tmp, tmp2);
5310 /* An array pointer of zero length is not associated if target is
5312 arg1se.descriptor_only = 1;
5313 gfc_conv_expr_lhs (&arg1se, arg1->expr);
5314 tmp = gfc_conv_descriptor_stride_get (arg1se.expr,
5315 gfc_rank_cst[arg1->expr->rank - 1]);
5316 nonzero_arraylen = fold_build2_loc (input_location, NE_EXPR,
5317 boolean_type_node, tmp,
5318 build_int_cst (TREE_TYPE (tmp), 0));
5320 /* A pointer to an array, call library function _gfor_associated. */
5321 gcc_assert (ss2 != gfc_ss_terminator);
5322 arg1se.want_pointer = 1;
5323 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
5325 arg2se.want_pointer = 1;
5326 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
5327 gfc_add_block_to_block (&se->pre, &arg2se.pre);
5328 gfc_add_block_to_block (&se->post, &arg2se.post);
5329 se->expr = build_call_expr_loc (input_location,
5330 gfor_fndecl_associated, 2,
5331 arg1se.expr, arg2se.expr);
5332 se->expr = convert (boolean_type_node, se->expr);
5333 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5334 boolean_type_node, se->expr,
5338 /* If target is present zero character length pointers cannot
5340 if (nonzero_charlen != NULL_TREE)
5341 se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5343 se->expr, nonzero_charlen);
5346 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
5350 /* Generate code for the SAME_TYPE_AS intrinsic.
5351 Generate inline code that directly checks the vindices. */
5354 gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
5360 gfc_init_se (&se1, NULL);
5361 gfc_init_se (&se2, NULL);
5363 a = expr->value.function.actual->expr;
5364 b = expr->value.function.actual->next->expr;
5366 if (a->ts.type == BT_CLASS)
5368 gfc_add_vptr_component (a);
5369 gfc_add_hash_component (a);
5371 else if (a->ts.type == BT_DERIVED)
5372 a = gfc_get_int_expr (gfc_default_integer_kind, NULL,
5373 a->ts.u.derived->hash_value);
5375 if (b->ts.type == BT_CLASS)
5377 gfc_add_vptr_component (b);
5378 gfc_add_hash_component (b);
5380 else if (b->ts.type == BT_DERIVED)
5381 b = gfc_get_int_expr (gfc_default_integer_kind, NULL,
5382 b->ts.u.derived->hash_value);
5384 gfc_conv_expr (&se1, a);
5385 gfc_conv_expr (&se2, b);
5387 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5388 se1.expr, fold_convert (TREE_TYPE (se1.expr), se2.expr));
5389 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
5393 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
5396 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
5400 gfc_conv_intrinsic_function_args (se, expr, args, 2);
5401 se->expr = build_call_expr_loc (input_location,
5402 gfor_fndecl_sc_kind, 2, args[0], args[1]);
5403 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
5407 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
5410 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
5414 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
5416 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
5417 type = gfc_get_int_type (4);
5418 arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
5420 /* Convert it to the required type. */
5421 type = gfc_typenode_for_spec (&expr->ts);
5422 se->expr = build_call_expr_loc (input_location,
5423 gfor_fndecl_si_kind, 1, arg);
5424 se->expr = fold_convert (type, se->expr);
5428 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
5431 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
5433 gfc_actual_arglist *actual;
5436 VEC(tree,gc) *args = NULL;
5438 for (actual = expr->value.function.actual; actual; actual = actual->next)
5440 gfc_init_se (&argse, se);
5442 /* Pass a NULL pointer for an absent arg. */
5443 if (actual->expr == NULL)
5444 argse.expr = null_pointer_node;
5450 if (actual->expr->ts.kind != gfc_c_int_kind)
5452 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
5453 ts.type = BT_INTEGER;
5454 ts.kind = gfc_c_int_kind;
5455 gfc_convert_type (actual->expr, &ts, 2);
5457 gfc_conv_expr_reference (&argse, actual->expr);
5460 gfc_add_block_to_block (&se->pre, &argse.pre);
5461 gfc_add_block_to_block (&se->post, &argse.post);
5462 VEC_safe_push (tree, gc, args, argse.expr);
5465 /* Convert it to the required type. */
5466 type = gfc_typenode_for_spec (&expr->ts);
5467 se->expr = build_call_expr_loc_vec (input_location,
5468 gfor_fndecl_sr_kind, args);
5469 se->expr = fold_convert (type, se->expr);
5473 /* Generate code for TRIM (A) intrinsic function. */
5476 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
5486 unsigned int num_args;
5488 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
5489 args = XALLOCAVEC (tree, num_args);
5491 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
5492 addr = gfc_build_addr_expr (ppvoid_type_node, var);
5493 len = gfc_create_var (gfc_charlen_type_node, "len");
5495 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
5496 args[0] = gfc_build_addr_expr (NULL_TREE, len);
5499 if (expr->ts.kind == 1)
5500 function = gfor_fndecl_string_trim;
5501 else if (expr->ts.kind == 4)
5502 function = gfor_fndecl_string_trim_char4;
5506 fndecl = build_addr (function, current_function_decl);
5507 tmp = build_call_array_loc (input_location,
5508 TREE_TYPE (TREE_TYPE (function)), fndecl,
5510 gfc_add_expr_to_block (&se->pre, tmp);
5512 /* Free the temporary afterwards, if necessary. */
5513 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
5514 len, build_int_cst (TREE_TYPE (len), 0));
5515 tmp = gfc_call_free (var);
5516 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
5517 gfc_add_expr_to_block (&se->post, tmp);
5520 se->string_length = len;
5524 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
5527 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
5529 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
5530 tree type, cond, tmp, count, exit_label, n, max, largest;
5532 stmtblock_t block, body;
5535 /* We store in charsize the size of a character. */
5536 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
5537 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
5539 /* Get the arguments. */
5540 gfc_conv_intrinsic_function_args (se, expr, args, 3);
5541 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
5543 ncopies = gfc_evaluate_now (args[2], &se->pre);
5544 ncopies_type = TREE_TYPE (ncopies);
5546 /* Check that NCOPIES is not negative. */
5547 cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, ncopies,
5548 build_int_cst (ncopies_type, 0));
5549 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
5550 "Argument NCOPIES of REPEAT intrinsic is negative "
5551 "(its value is %lld)",
5552 fold_convert (long_integer_type_node, ncopies));
5554 /* If the source length is zero, any non negative value of NCOPIES
5555 is valid, and nothing happens. */
5556 n = gfc_create_var (ncopies_type, "ncopies");
5557 cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, slen,
5558 build_int_cst (size_type_node, 0));
5559 tmp = fold_build3_loc (input_location, COND_EXPR, ncopies_type, cond,
5560 build_int_cst (ncopies_type, 0), ncopies);
5561 gfc_add_modify (&se->pre, n, tmp);
5564 /* Check that ncopies is not too large: ncopies should be less than
5565 (or equal to) MAX / slen, where MAX is the maximal integer of
5566 the gfc_charlen_type_node type. If slen == 0, we need a special
5567 case to avoid the division by zero. */
5568 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
5569 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
5570 max = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
5571 fold_convert (size_type_node, max), slen);
5572 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
5573 ? size_type_node : ncopies_type;
5574 cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
5575 fold_convert (largest, ncopies),
5576 fold_convert (largest, max));
5577 tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, slen,
5578 build_int_cst (size_type_node, 0));
5579 cond = fold_build3_loc (input_location, COND_EXPR, boolean_type_node, tmp,
5580 boolean_false_node, cond);
5581 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
5582 "Argument NCOPIES of REPEAT intrinsic is too large");
5584 /* Compute the destination length. */
5585 dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
5586 fold_convert (gfc_charlen_type_node, slen),
5587 fold_convert (gfc_charlen_type_node, ncopies));
5588 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
5589 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
5591 /* Generate the code to do the repeat operation:
5592 for (i = 0; i < ncopies; i++)
5593 memmove (dest + (i * slen * size), src, slen*size); */
5594 gfc_start_block (&block);
5595 count = gfc_create_var (ncopies_type, "count");
5596 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
5597 exit_label = gfc_build_label_decl (NULL_TREE);
5599 /* Start the loop body. */
5600 gfc_start_block (&body);
5602 /* Exit the loop if count >= ncopies. */
5603 cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, count,
5605 tmp = build1_v (GOTO_EXPR, exit_label);
5606 TREE_USED (exit_label) = 1;
5607 tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
5608 build_empty_stmt (input_location));
5609 gfc_add_expr_to_block (&body, tmp);
5611 /* Call memmove (dest + (i*slen*size), src, slen*size). */
5612 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
5613 fold_convert (gfc_charlen_type_node, slen),
5614 fold_convert (gfc_charlen_type_node, count));
5615 tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
5616 tmp, fold_convert (gfc_charlen_type_node, size));
5617 tmp = fold_build2_loc (input_location, POINTER_PLUS_EXPR, pvoid_type_node,
5618 fold_convert (pvoid_type_node, dest),
5619 fold_convert (sizetype, tmp));
5620 tmp = build_call_expr_loc (input_location,
5621 built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
5622 fold_build2_loc (input_location, MULT_EXPR,
5623 size_type_node, slen,
5624 fold_convert (size_type_node,
5626 gfc_add_expr_to_block (&body, tmp);
5628 /* Increment count. */
5629 tmp = fold_build2_loc (input_location, PLUS_EXPR, ncopies_type,
5630 count, build_int_cst (TREE_TYPE (count), 1));
5631 gfc_add_modify (&body, count, tmp);
5633 /* Build the loop. */
5634 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
5635 gfc_add_expr_to_block (&block, tmp);
5637 /* Add the exit label. */
5638 tmp = build1_v (LABEL_EXPR, exit_label);
5639 gfc_add_expr_to_block (&block, tmp);
5641 /* Finish the block. */
5642 tmp = gfc_finish_block (&block);
5643 gfc_add_expr_to_block (&se->pre, tmp);
5645 /* Set the result value. */
5647 se->string_length = dlen;
5651 /* Generate code for the IARGC intrinsic. */
5654 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
5660 /* Call the library function. This always returns an INTEGER(4). */
5661 fndecl = gfor_fndecl_iargc;
5662 tmp = build_call_expr_loc (input_location,
5665 /* Convert it to the required type. */
5666 type = gfc_typenode_for_spec (&expr->ts);
5667 tmp = fold_convert (type, tmp);
5673 /* The loc intrinsic returns the address of its argument as
5674 gfc_index_integer_kind integer. */
5677 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
5683 gcc_assert (!se->ss);
5685 arg_expr = expr->value.function.actual->expr;
5686 ss = gfc_walk_expr (arg_expr);
5687 if (ss == gfc_ss_terminator)
5688 gfc_conv_expr_reference (se, arg_expr);
5690 gfc_conv_array_parameter (se, arg_expr, ss, true, NULL, NULL, NULL);
5691 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
5693 /* Create a temporary variable for loc return value. Without this,
5694 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
5695 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
5696 gfc_add_modify (&se->pre, temp_var, se->expr);
5697 se->expr = temp_var;
5700 /* Generate code for an intrinsic function. Some map directly to library
5701 calls, others get special handling. In some cases the name of the function
5702 used depends on the type specifiers. */
5705 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
5711 name = &expr->value.function.name[2];
5715 lib = gfc_is_intrinsic_libcall (expr);
5719 se->ignore_optional = 1;
5721 switch (expr->value.function.isym->id)
5723 case GFC_ISYM_EOSHIFT:
5725 case GFC_ISYM_RESHAPE:
5726 /* For all of those the first argument specifies the type and the
5727 third is optional. */
5728 conv_generic_with_optional_char_arg (se, expr, 1, 3);
5732 gfc_conv_intrinsic_funcall (se, expr);
5740 switch (expr->value.function.isym->id)
5745 case GFC_ISYM_REPEAT:
5746 gfc_conv_intrinsic_repeat (se, expr);
5750 gfc_conv_intrinsic_trim (se, expr);
5753 case GFC_ISYM_SC_KIND:
5754 gfc_conv_intrinsic_sc_kind (se, expr);
5757 case GFC_ISYM_SI_KIND:
5758 gfc_conv_intrinsic_si_kind (se, expr);
5761 case GFC_ISYM_SR_KIND:
5762 gfc_conv_intrinsic_sr_kind (se, expr);
5765 case GFC_ISYM_EXPONENT:
5766 gfc_conv_intrinsic_exponent (se, expr);
5770 kind = expr->value.function.actual->expr->ts.kind;
5772 fndecl = gfor_fndecl_string_scan;
5774 fndecl = gfor_fndecl_string_scan_char4;
5778 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5781 case GFC_ISYM_VERIFY:
5782 kind = expr->value.function.actual->expr->ts.kind;
5784 fndecl = gfor_fndecl_string_verify;
5786 fndecl = gfor_fndecl_string_verify_char4;
5790 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5793 case GFC_ISYM_ALLOCATED:
5794 gfc_conv_allocated (se, expr);
5797 case GFC_ISYM_ASSOCIATED:
5798 gfc_conv_associated(se, expr);
5801 case GFC_ISYM_SAME_TYPE_AS:
5802 gfc_conv_same_type_as (se, expr);
5806 gfc_conv_intrinsic_abs (se, expr);
5809 case GFC_ISYM_ADJUSTL:
5810 if (expr->ts.kind == 1)
5811 fndecl = gfor_fndecl_adjustl;
5812 else if (expr->ts.kind == 4)
5813 fndecl = gfor_fndecl_adjustl_char4;
5817 gfc_conv_intrinsic_adjust (se, expr, fndecl);
5820 case GFC_ISYM_ADJUSTR:
5821 if (expr->ts.kind == 1)
5822 fndecl = gfor_fndecl_adjustr;
5823 else if (expr->ts.kind == 4)
5824 fndecl = gfor_fndecl_adjustr_char4;
5828 gfc_conv_intrinsic_adjust (se, expr, fndecl);
5831 case GFC_ISYM_AIMAG:
5832 gfc_conv_intrinsic_imagpart (se, expr);
5836 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
5840 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
5843 case GFC_ISYM_ANINT:
5844 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
5848 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5852 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
5855 case GFC_ISYM_BTEST:
5856 gfc_conv_intrinsic_btest (se, expr);
5860 gfc_conv_intrinsic_bitcomp (se, expr, GE_EXPR);
5864 gfc_conv_intrinsic_bitcomp (se, expr, GT_EXPR);
5868 gfc_conv_intrinsic_bitcomp (se, expr, LE_EXPR);
5872 gfc_conv_intrinsic_bitcomp (se, expr, LT_EXPR);
5875 case GFC_ISYM_ACHAR:
5877 gfc_conv_intrinsic_char (se, expr);
5880 case GFC_ISYM_CONVERSION:
5882 case GFC_ISYM_LOGICAL:
5884 gfc_conv_intrinsic_conversion (se, expr);
5887 /* Integer conversions are handled separately to make sure we get the
5888 correct rounding mode. */
5893 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
5897 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
5900 case GFC_ISYM_CEILING:
5901 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
5904 case GFC_ISYM_FLOOR:
5905 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
5909 gfc_conv_intrinsic_mod (se, expr, 0);
5912 case GFC_ISYM_MODULO:
5913 gfc_conv_intrinsic_mod (se, expr, 1);
5916 case GFC_ISYM_CMPLX:
5917 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
5920 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
5921 gfc_conv_intrinsic_iargc (se, expr);
5924 case GFC_ISYM_COMPLEX:
5925 gfc_conv_intrinsic_cmplx (se, expr, 1);
5928 case GFC_ISYM_CONJG:
5929 gfc_conv_intrinsic_conjg (se, expr);
5932 case GFC_ISYM_COUNT:
5933 gfc_conv_intrinsic_count (se, expr);
5936 case GFC_ISYM_CTIME:
5937 gfc_conv_intrinsic_ctime (se, expr);
5941 gfc_conv_intrinsic_dim (se, expr);
5944 case GFC_ISYM_DOT_PRODUCT:
5945 gfc_conv_intrinsic_dot_product (se, expr);
5948 case GFC_ISYM_DPROD:
5949 gfc_conv_intrinsic_dprod (se, expr);
5952 case GFC_ISYM_DSHIFTL:
5953 gfc_conv_intrinsic_dshift (se, expr, true);
5956 case GFC_ISYM_DSHIFTR:
5957 gfc_conv_intrinsic_dshift (se, expr, false);
5960 case GFC_ISYM_FDATE:
5961 gfc_conv_intrinsic_fdate (se, expr);
5964 case GFC_ISYM_FRACTION:
5965 gfc_conv_intrinsic_fraction (se, expr);
5969 gfc_conv_intrinsic_arith (se, expr, BIT_AND_EXPR, false);
5973 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5977 gfc_conv_intrinsic_arith (se, expr, BIT_IOR_EXPR, false);
5980 case GFC_ISYM_IBCLR:
5981 gfc_conv_intrinsic_singlebitop (se, expr, 0);
5984 case GFC_ISYM_IBITS:
5985 gfc_conv_intrinsic_ibits (se, expr);
5988 case GFC_ISYM_IBSET:
5989 gfc_conv_intrinsic_singlebitop (se, expr, 1);
5992 case GFC_ISYM_IACHAR:
5993 case GFC_ISYM_ICHAR:
5994 /* We assume ASCII character sequence. */
5995 gfc_conv_intrinsic_ichar (se, expr);
5998 case GFC_ISYM_IARGC:
5999 gfc_conv_intrinsic_iargc (se, expr);
6003 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
6006 case GFC_ISYM_INDEX:
6007 kind = expr->value.function.actual->expr->ts.kind;
6009 fndecl = gfor_fndecl_string_index;
6011 fndecl = gfor_fndecl_string_index_char4;
6015 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
6019 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
6022 case GFC_ISYM_IPARITY:
6023 gfc_conv_intrinsic_arith (se, expr, BIT_XOR_EXPR, false);
6026 case GFC_ISYM_IS_IOSTAT_END:
6027 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
6030 case GFC_ISYM_IS_IOSTAT_EOR:
6031 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
6034 case GFC_ISYM_ISNAN:
6035 gfc_conv_intrinsic_isnan (se, expr);
6038 case GFC_ISYM_LSHIFT:
6039 gfc_conv_intrinsic_shift (se, expr, false, false);
6042 case GFC_ISYM_RSHIFT:
6043 gfc_conv_intrinsic_shift (se, expr, true, true);
6046 case GFC_ISYM_SHIFTA:
6047 gfc_conv_intrinsic_shift (se, expr, true, true);
6050 case GFC_ISYM_SHIFTL:
6051 gfc_conv_intrinsic_shift (se, expr, false, false);
6054 case GFC_ISYM_SHIFTR:
6055 gfc_conv_intrinsic_shift (se, expr, true, false);
6058 case GFC_ISYM_ISHFT:
6059 gfc_conv_intrinsic_ishft (se, expr);
6062 case GFC_ISYM_ISHFTC:
6063 gfc_conv_intrinsic_ishftc (se, expr);
6066 case GFC_ISYM_LEADZ:
6067 gfc_conv_intrinsic_leadz (se, expr);
6070 case GFC_ISYM_TRAILZ:
6071 gfc_conv_intrinsic_trailz (se, expr);
6074 case GFC_ISYM_POPCNT:
6075 gfc_conv_intrinsic_popcnt_poppar (se, expr, 0);
6078 case GFC_ISYM_POPPAR:
6079 gfc_conv_intrinsic_popcnt_poppar (se, expr, 1);
6082 case GFC_ISYM_LBOUND:
6083 gfc_conv_intrinsic_bound (se, expr, 0);
6086 case GFC_ISYM_LCOBOUND:
6087 conv_intrinsic_cobound (se, expr);
6090 case GFC_ISYM_TRANSPOSE:
6091 /* The scalarizer has already been set up for reversed dimension access
6092 order ; now we just get the argument value normally. */
6093 gfc_conv_expr (se, expr->value.function.actual->expr);
6097 gfc_conv_intrinsic_len (se, expr);
6100 case GFC_ISYM_LEN_TRIM:
6101 gfc_conv_intrinsic_len_trim (se, expr);
6105 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
6109 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
6113 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
6117 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
6120 case GFC_ISYM_MASKL:
6121 gfc_conv_intrinsic_mask (se, expr, 1);
6124 case GFC_ISYM_MASKR:
6125 gfc_conv_intrinsic_mask (se, expr, 0);
6129 if (expr->ts.type == BT_CHARACTER)
6130 gfc_conv_intrinsic_minmax_char (se, expr, 1);
6132 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
6135 case GFC_ISYM_MAXLOC:
6136 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
6139 case GFC_ISYM_MAXVAL:
6140 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
6143 case GFC_ISYM_MERGE:
6144 gfc_conv_intrinsic_merge (se, expr);
6147 case GFC_ISYM_MERGE_BITS:
6148 gfc_conv_intrinsic_merge_bits (se, expr);
6152 if (expr->ts.type == BT_CHARACTER)
6153 gfc_conv_intrinsic_minmax_char (se, expr, -1);
6155 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
6158 case GFC_ISYM_MINLOC:
6159 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
6162 case GFC_ISYM_MINVAL:
6163 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
6166 case GFC_ISYM_NEAREST:
6167 gfc_conv_intrinsic_nearest (se, expr);
6170 case GFC_ISYM_NORM2:
6171 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, true);
6175 gfc_conv_intrinsic_not (se, expr);
6179 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
6182 case GFC_ISYM_PARITY:
6183 gfc_conv_intrinsic_arith (se, expr, NE_EXPR, false);
6186 case GFC_ISYM_PRESENT:
6187 gfc_conv_intrinsic_present (se, expr);
6190 case GFC_ISYM_PRODUCT:
6191 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR, false);
6194 case GFC_ISYM_RRSPACING:
6195 gfc_conv_intrinsic_rrspacing (se, expr);
6198 case GFC_ISYM_SET_EXPONENT:
6199 gfc_conv_intrinsic_set_exponent (se, expr);
6202 case GFC_ISYM_SCALE:
6203 gfc_conv_intrinsic_scale (se, expr);
6207 gfc_conv_intrinsic_sign (se, expr);
6211 gfc_conv_intrinsic_size (se, expr);
6214 case GFC_ISYM_SIZEOF:
6215 case GFC_ISYM_C_SIZEOF:
6216 gfc_conv_intrinsic_sizeof (se, expr);
6219 case GFC_ISYM_STORAGE_SIZE:
6220 gfc_conv_intrinsic_storage_size (se, expr);
6223 case GFC_ISYM_SPACING:
6224 gfc_conv_intrinsic_spacing (se, expr);
6228 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false);
6231 case GFC_ISYM_TRANSFER:
6232 if (se->ss && se->ss->useflags)
6233 /* Access the previously obtained result. */
6234 gfc_conv_tmp_array_ref (se);
6236 gfc_conv_intrinsic_transfer (se, expr);
6239 case GFC_ISYM_TTYNAM:
6240 gfc_conv_intrinsic_ttynam (se, expr);
6243 case GFC_ISYM_UBOUND:
6244 gfc_conv_intrinsic_bound (se, expr, 1);
6247 case GFC_ISYM_UCOBOUND:
6248 conv_intrinsic_cobound (se, expr);
6252 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
6256 gfc_conv_intrinsic_loc (se, expr);
6259 case GFC_ISYM_THIS_IMAGE:
6260 if (expr->value.function.actual)
6261 conv_intrinsic_cobound (se, expr);
6263 trans_this_image (se, expr);
6266 case GFC_ISYM_NUM_IMAGES:
6267 trans_num_images (se);
6270 case GFC_ISYM_ACCESS:
6271 case GFC_ISYM_CHDIR:
6272 case GFC_ISYM_CHMOD:
6273 case GFC_ISYM_DTIME:
6274 case GFC_ISYM_ETIME:
6275 case GFC_ISYM_EXTENDS_TYPE_OF:
6277 case GFC_ISYM_FGETC:
6280 case GFC_ISYM_FPUTC:
6281 case GFC_ISYM_FSTAT:
6282 case GFC_ISYM_FTELL:
6283 case GFC_ISYM_GETCWD:
6284 case GFC_ISYM_GETGID:
6285 case GFC_ISYM_GETPID:
6286 case GFC_ISYM_GETUID:
6287 case GFC_ISYM_HOSTNM:
6289 case GFC_ISYM_IERRNO:
6290 case GFC_ISYM_IRAND:
6291 case GFC_ISYM_ISATTY:
6294 case GFC_ISYM_LSTAT:
6295 case GFC_ISYM_MALLOC:
6296 case GFC_ISYM_MATMUL:
6297 case GFC_ISYM_MCLOCK:
6298 case GFC_ISYM_MCLOCK8:
6300 case GFC_ISYM_RENAME:
6301 case GFC_ISYM_SECOND:
6302 case GFC_ISYM_SECNDS:
6303 case GFC_ISYM_SIGNAL:
6305 case GFC_ISYM_SYMLNK:
6306 case GFC_ISYM_SYSTEM:
6308 case GFC_ISYM_TIME8:
6309 case GFC_ISYM_UMASK:
6310 case GFC_ISYM_UNLINK:
6312 gfc_conv_intrinsic_funcall (se, expr);
6315 case GFC_ISYM_EOSHIFT:
6317 case GFC_ISYM_RESHAPE:
6318 /* For those, expr->rank should always be >0 and thus the if above the
6319 switch should have matched. */
6324 gfc_conv_intrinsic_lib_function (se, expr);
6331 walk_inline_intrinsic_transpose (gfc_ss *ss, gfc_expr *expr)
6333 gfc_ss *arg_ss, *tmp_ss;
6334 gfc_actual_arglist *arg;
6336 arg = expr->value.function.actual;
6338 gcc_assert (arg->expr);
6340 arg_ss = gfc_walk_subexpr (gfc_ss_terminator, arg->expr);
6341 gcc_assert (arg_ss != gfc_ss_terminator);
6343 for (tmp_ss = arg_ss; ; tmp_ss = tmp_ss->next)
6345 if (tmp_ss->type != GFC_SS_SCALAR
6346 && tmp_ss->type != GFC_SS_REFERENCE)
6351 info = &tmp_ss->data.info;
6352 gcc_assert (info->dimen == 2);
6354 /* We just invert dimensions. */
6355 tmp_dim = info->dim[0];
6356 info->dim[0] = info->dim[1];
6357 info->dim[1] = tmp_dim;
6360 /* Stop when tmp_ss points to the last valid element of the chain... */
6361 if (tmp_ss->next == gfc_ss_terminator)
6365 /* ... so that we can attach the rest of the chain to it. */
6373 walk_inline_intrinsic_function (gfc_ss * ss, gfc_expr * expr)
6376 switch (expr->value.function.isym->id)
6378 case GFC_ISYM_TRANSPOSE:
6379 return walk_inline_intrinsic_transpose (ss, expr);
6388 /* This generates code to execute before entering the scalarization loop.
6389 Currently does nothing. */
6392 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
6394 switch (ss->expr->value.function.isym->id)
6396 case GFC_ISYM_UBOUND:
6397 case GFC_ISYM_LBOUND:
6398 case GFC_ISYM_UCOBOUND:
6399 case GFC_ISYM_LCOBOUND:
6400 case GFC_ISYM_THIS_IMAGE:
6409 /* The LBOUND, LCOBOUND, UBOUND and UCOBOUND intrinsics with one parameter
6410 are expanded into code inside the scalarization loop. */
6413 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
6417 /* The two argument version returns a scalar. */
6418 if (expr->value.function.actual->next->expr)
6421 newss = gfc_get_ss ();
6422 newss->type = GFC_SS_INTRINSIC;
6425 newss->data.info.dimen = 1;
6431 /* Walk an intrinsic array libcall. */
6434 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
6439 gcc_assert (expr->rank > 0);
6441 newss = gfc_get_ss ();
6442 newss->type = GFC_SS_FUNCTION;
6445 newss->data.info.dimen = expr->rank;
6446 for (n = 0; n < newss->data.info.dimen; n++)
6447 newss->data.info.dim[n] = n;
6453 /* Return whether the function call expression EXPR will be expanded
6454 inline by gfc_conv_intrinsic_function. */
6457 gfc_inline_intrinsic_function_p (gfc_expr *expr)
6459 if (!expr->value.function.isym)
6462 switch (expr->value.function.isym->id)
6464 case GFC_ISYM_TRANSPOSE:
6473 /* Returns nonzero if the specified intrinsic function call maps directly to
6474 an external library call. Should only be used for functions that return
6478 gfc_is_intrinsic_libcall (gfc_expr * expr)
6480 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
6481 gcc_assert (expr->rank > 0);
6483 if (gfc_inline_intrinsic_function_p (expr))
6486 switch (expr->value.function.isym->id)
6490 case GFC_ISYM_COUNT:
6494 case GFC_ISYM_IPARITY:
6495 case GFC_ISYM_MATMUL:
6496 case GFC_ISYM_MAXLOC:
6497 case GFC_ISYM_MAXVAL:
6498 case GFC_ISYM_MINLOC:
6499 case GFC_ISYM_MINVAL:
6500 case GFC_ISYM_NORM2:
6501 case GFC_ISYM_PARITY:
6502 case GFC_ISYM_PRODUCT:
6504 case GFC_ISYM_SHAPE:
6505 case GFC_ISYM_SPREAD:
6507 /* Ignore absent optional parameters. */
6510 case GFC_ISYM_RESHAPE:
6511 case GFC_ISYM_CSHIFT:
6512 case GFC_ISYM_EOSHIFT:
6514 case GFC_ISYM_UNPACK:
6515 /* Pass absent optional parameters. */
6523 /* Walk an intrinsic function. */
6525 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
6526 gfc_intrinsic_sym * isym)
6530 if (isym->elemental)
6531 return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
6534 if (expr->rank == 0)
6537 if (gfc_inline_intrinsic_function_p (expr))
6538 return walk_inline_intrinsic_function (ss, expr);
6540 if (gfc_is_intrinsic_libcall (expr))
6541 return gfc_walk_intrinsic_libfunc (ss, expr);
6543 /* Special cases. */
6546 case GFC_ISYM_LBOUND:
6547 case GFC_ISYM_LCOBOUND:
6548 case GFC_ISYM_UBOUND:
6549 case GFC_ISYM_UCOBOUND:
6550 case GFC_ISYM_THIS_IMAGE:
6551 return gfc_walk_intrinsic_bound (ss, expr);
6553 case GFC_ISYM_TRANSFER:
6554 return gfc_walk_intrinsic_libfunc (ss, expr);
6557 /* This probably meant someone forgot to add an intrinsic to the above
6558 list(s) when they implemented it, or something's gone horribly
6566 gfc_conv_intrinsic_move_alloc (gfc_code *code)
6568 if (code->ext.actual->expr->rank == 0)
6570 /* Scalar arguments: Generate pointer assignments. */
6571 gfc_expr *from, *to;
6575 from = code->ext.actual->expr;
6576 to = code->ext.actual->next->expr;
6578 gfc_start_block (&block);
6580 if (to->ts.type == BT_CLASS)
6581 tmp = gfc_trans_class_assign (to, from, EXEC_POINTER_ASSIGN);
6583 tmp = gfc_trans_pointer_assignment (to, from);
6584 gfc_add_expr_to_block (&block, tmp);
6586 if (from->ts.type == BT_CLASS)
6587 tmp = gfc_trans_class_assign (from, gfc_get_null_expr (NULL),
6588 EXEC_POINTER_ASSIGN);
6590 tmp = gfc_trans_pointer_assignment (from,
6591 gfc_get_null_expr (NULL));
6592 gfc_add_expr_to_block (&block, tmp);
6594 return gfc_finish_block (&block);
6597 /* Array arguments: Generate library code. */
6598 return gfc_trans_call (code, false, NULL_TREE, NULL_TREE, false);
6602 #include "gt-fortran-trans-intrinsic.h"