1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
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"
37 #include "intrinsic.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
44 #include "trans-stmt.h"
46 /* This maps fortran intrinsic math functions to external library or GCC
48 typedef struct GTY(()) gfc_intrinsic_map_t {
49 /* The explicit enum is required to work around inadequacies in the
50 garbage collection/gengtype parsing mechanism. */
53 /* Enum value from the "language-independent", aka C-centric, part
54 of gcc, or END_BUILTINS of no such value set. */
55 enum built_in_function code_r4;
56 enum built_in_function code_r8;
57 enum built_in_function code_r10;
58 enum built_in_function code_r16;
59 enum built_in_function code_c4;
60 enum built_in_function code_c8;
61 enum built_in_function code_c10;
62 enum built_in_function code_c16;
64 /* True if the naming pattern is to prepend "c" for complex and
65 append "f" for kind=4. False if the naming pattern is to
66 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
69 /* True if a complex version of the function exists. */
70 bool complex_available;
72 /* True if the function should be marked const. */
75 /* The base library name of this function. */
78 /* Cache decls created for the various operand types. */
90 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
91 defines complex variants of all of the entries in mathbuiltins.def
93 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
94 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
95 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, (enum built_in_function) 0, \
96 (enum built_in_function) 0, (enum built_in_function) 0, \
97 (enum built_in_function) 0, true, false, true, NAME, NULL_TREE, \
98 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
101 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
102 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
103 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
104 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
105 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
106 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
108 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
109 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
111 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
112 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. */
117 #include "mathbuiltins.def"
119 /* Functions in libgfortran. */
120 LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
123 LIB_FUNCTION (NONE, NULL, false)
127 #undef DEFINE_MATH_BUILTIN
128 #undef DEFINE_MATH_BUILTIN_C
130 /* Structure for storing components of a floating number to be used by
131 elemental functions to manipulate reals. */
134 tree arg; /* Variable tree to view convert to integer. */
135 tree expn; /* Variable tree to save exponent. */
136 tree frac; /* Variable tree to save fraction. */
137 tree smask; /* Constant tree of sign's mask. */
138 tree emask; /* Constant tree of exponent's mask. */
139 tree fmask; /* Constant tree of fraction's mask. */
140 tree edigits; /* Constant tree of the number of exponent bits. */
141 tree fdigits; /* Constant tree of the number of fraction bits. */
142 tree f1; /* Constant tree of the f1 defined in the real model. */
143 tree bias; /* Constant tree of the bias of exponent in the memory. */
144 tree type; /* Type tree of arg1. */
145 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
149 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
151 /* Evaluate the arguments to an intrinsic function. The value
152 of NARGS may be less than the actual number of arguments in EXPR
153 to allow optional "KIND" arguments that are not included in the
154 generated code to be ignored. */
157 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
158 tree *argarray, int nargs)
160 gfc_actual_arglist *actual;
162 gfc_intrinsic_arg *formal;
166 formal = expr->value.function.isym->formal;
167 actual = expr->value.function.actual;
169 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
170 actual = actual->next,
171 formal = formal ? formal->next : NULL)
175 /* Skip omitted optional arguments. */
182 /* Evaluate the parameter. This will substitute scalarized
183 references automatically. */
184 gfc_init_se (&argse, se);
186 if (e->ts.type == BT_CHARACTER)
188 gfc_conv_expr (&argse, e);
189 gfc_conv_string_parameter (&argse);
190 argarray[curr_arg++] = argse.string_length;
191 gcc_assert (curr_arg < nargs);
194 gfc_conv_expr_val (&argse, e);
196 /* If an optional argument is itself an optional dummy argument,
197 check its presence and substitute a null if absent. */
198 if (e->expr_type == EXPR_VARIABLE
199 && e->symtree->n.sym->attr.optional
202 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
204 gfc_add_block_to_block (&se->pre, &argse.pre);
205 gfc_add_block_to_block (&se->post, &argse.post);
206 argarray[curr_arg] = argse.expr;
210 /* Count the number of actual arguments to the intrinsic function EXPR
211 including any "hidden" string length arguments. */
214 gfc_intrinsic_argument_list_length (gfc_expr *expr)
217 gfc_actual_arglist *actual;
219 for (actual = expr->value.function.actual; actual; actual = actual->next)
224 if (actual->expr->ts.type == BT_CHARACTER)
234 /* Conversions between different types are output by the frontend as
235 intrinsic functions. We implement these directly with inline code. */
238 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
244 nargs = gfc_intrinsic_argument_list_length (expr);
245 args = (tree *) alloca (sizeof (tree) * nargs);
247 /* Evaluate all the arguments passed. Whilst we're only interested in the
248 first one here, there are other parts of the front-end that assume this
249 and will trigger an ICE if it's not the case. */
250 type = gfc_typenode_for_spec (&expr->ts);
251 gcc_assert (expr->value.function.actual->expr);
252 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
254 /* Conversion between character kinds involves a call to a library
256 if (expr->ts.type == BT_CHARACTER)
258 tree fndecl, var, addr, tmp;
260 if (expr->ts.kind == 1
261 && expr->value.function.actual->expr->ts.kind == 4)
262 fndecl = gfor_fndecl_convert_char4_to_char1;
263 else if (expr->ts.kind == 4
264 && expr->value.function.actual->expr->ts.kind == 1)
265 fndecl = gfor_fndecl_convert_char1_to_char4;
269 /* Create the variable storing the converted value. */
270 type = gfc_get_pchar_type (expr->ts.kind);
271 var = gfc_create_var (type, "str");
272 addr = gfc_build_addr_expr (build_pointer_type (type), var);
274 /* Call the library function that will perform the conversion. */
275 gcc_assert (nargs >= 2);
276 tmp = build_call_expr_loc (input_location,
277 fndecl, 3, addr, args[0], args[1]);
278 gfc_add_expr_to_block (&se->pre, tmp);
280 /* Free the temporary afterwards. */
281 tmp = gfc_call_free (var);
282 gfc_add_expr_to_block (&se->post, tmp);
285 se->string_length = args[0];
290 /* Conversion from complex to non-complex involves taking the real
291 component of the value. */
292 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
293 && expr->ts.type != BT_COMPLEX)
297 artype = TREE_TYPE (TREE_TYPE (args[0]));
298 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
301 se->expr = convert (type, args[0]);
304 /* This is needed because the gcc backend only implements
305 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
306 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
307 Similarly for CEILING. */
310 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
317 argtype = TREE_TYPE (arg);
318 arg = gfc_evaluate_now (arg, pblock);
320 intval = convert (type, arg);
321 intval = gfc_evaluate_now (intval, pblock);
323 tmp = convert (argtype, intval);
324 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
326 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
327 build_int_cst (type, 1));
328 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
333 /* Round to nearest integer, away from zero. */
336 build_round_expr (tree arg, tree restype)
341 int argprec, resprec;
343 argtype = TREE_TYPE (arg);
344 argprec = TYPE_PRECISION (argtype);
345 resprec = TYPE_PRECISION (restype);
347 /* Depending on the type of the result, choose the long int intrinsic
348 (lround family) or long long intrinsic (llround). We might also
349 need to convert the result afterwards. */
350 if (resprec <= LONG_TYPE_SIZE)
352 else if (resprec <= LONG_LONG_TYPE_SIZE)
357 /* Now, depending on the argument type, we choose between intrinsics. */
358 if (argprec == TYPE_PRECISION (float_type_node))
359 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
360 else if (argprec == TYPE_PRECISION (double_type_node))
361 fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
362 else if (argprec == TYPE_PRECISION (long_double_type_node))
363 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
367 return fold_convert (restype, build_call_expr_loc (input_location,
372 /* Convert a real to an integer using a specific rounding mode.
373 Ideally we would just build the corresponding GENERIC node,
374 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
377 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
378 enum rounding_mode op)
383 return build_fixbound_expr (pblock, arg, type, 0);
387 return build_fixbound_expr (pblock, arg, type, 1);
391 return build_round_expr (arg, type);
395 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
404 /* Round a real value using the specified rounding mode.
405 We use a temporary integer of that same kind size as the result.
406 Values larger than those that can be represented by this kind are
407 unchanged, as they will not be accurate enough to represent the
409 huge = HUGE (KIND (a))
410 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
414 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
425 kind = expr->ts.kind;
426 nargs = gfc_intrinsic_argument_list_length (expr);
429 /* We have builtin functions for some cases. */
472 /* Evaluate the argument. */
473 gcc_assert (expr->value.function.actual->expr);
474 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
476 /* Use a builtin function if one exists. */
477 if (n != END_BUILTINS)
479 tmp = built_in_decls[n];
480 se->expr = build_call_expr_loc (input_location,
485 /* This code is probably redundant, but we'll keep it lying around just
487 type = gfc_typenode_for_spec (&expr->ts);
488 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
490 /* Test if the value is too large to handle sensibly. */
491 gfc_set_model_kind (kind);
493 n = gfc_validate_kind (BT_INTEGER, kind, false);
494 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
495 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
496 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
498 mpfr_neg (huge, huge, GFC_RND_MODE);
499 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
500 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
501 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
502 itype = gfc_get_int_type (kind);
504 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
505 tmp = convert (type, tmp);
506 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
511 /* Convert to an integer using the specified rounding mode. */
514 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
520 nargs = gfc_intrinsic_argument_list_length (expr);
521 args = (tree *) alloca (sizeof (tree) * nargs);
523 /* Evaluate the argument, we process all arguments even though we only
524 use the first one for code generation purposes. */
525 type = gfc_typenode_for_spec (&expr->ts);
526 gcc_assert (expr->value.function.actual->expr);
527 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
529 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
531 /* Conversion to a different integer kind. */
532 se->expr = convert (type, args[0]);
536 /* Conversion from complex to non-complex involves taking the real
537 component of the value. */
538 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
539 && expr->ts.type != BT_COMPLEX)
543 artype = TREE_TYPE (TREE_TYPE (args[0]));
544 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
547 se->expr = build_fix_expr (&se->pre, args[0], type, op);
552 /* Get the imaginary component of a value. */
555 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
559 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
560 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
564 /* Get the complex conjugate of a value. */
567 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
571 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
572 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
576 /* Initialize function decls for library functions. The external functions
577 are created as required. Builtin functions are added here. */
580 gfc_build_intrinsic_lib_fndecls (void)
582 gfc_intrinsic_map_t *m;
584 /* Add GCC builtin functions. */
585 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
587 if (m->code_r4 != END_BUILTINS)
588 m->real4_decl = built_in_decls[m->code_r4];
589 if (m->code_r8 != END_BUILTINS)
590 m->real8_decl = built_in_decls[m->code_r8];
591 if (m->code_r10 != END_BUILTINS)
592 m->real10_decl = built_in_decls[m->code_r10];
593 if (m->code_r16 != END_BUILTINS)
594 m->real16_decl = built_in_decls[m->code_r16];
595 if (m->code_c4 != END_BUILTINS)
596 m->complex4_decl = built_in_decls[m->code_c4];
597 if (m->code_c8 != END_BUILTINS)
598 m->complex8_decl = built_in_decls[m->code_c8];
599 if (m->code_c10 != END_BUILTINS)
600 m->complex10_decl = built_in_decls[m->code_c10];
601 if (m->code_c16 != END_BUILTINS)
602 m->complex16_decl = built_in_decls[m->code_c16];
607 /* Create a fndecl for a simple intrinsic library function. */
610 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
615 gfc_actual_arglist *actual;
618 char name[GFC_MAX_SYMBOL_LEN + 3];
621 if (ts->type == BT_REAL)
626 pdecl = &m->real4_decl;
629 pdecl = &m->real8_decl;
632 pdecl = &m->real10_decl;
635 pdecl = &m->real16_decl;
641 else if (ts->type == BT_COMPLEX)
643 gcc_assert (m->complex_available);
648 pdecl = &m->complex4_decl;
651 pdecl = &m->complex8_decl;
654 pdecl = &m->complex10_decl;
657 pdecl = &m->complex16_decl;
672 snprintf (name, sizeof (name), "%s%s%s",
673 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
674 else if (ts->kind == 8)
675 snprintf (name, sizeof (name), "%s%s",
676 ts->type == BT_COMPLEX ? "c" : "", m->name);
679 gcc_assert (ts->kind == 10 || ts->kind == 16);
680 snprintf (name, sizeof (name), "%s%s%s",
681 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
686 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
687 ts->type == BT_COMPLEX ? 'c' : 'r',
691 argtypes = NULL_TREE;
692 for (actual = expr->value.function.actual; actual; actual = actual->next)
694 type = gfc_typenode_for_spec (&actual->expr->ts);
695 argtypes = gfc_chainon_list (argtypes, type);
697 argtypes = gfc_chainon_list (argtypes, void_type_node);
698 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
699 fndecl = build_decl (input_location,
700 FUNCTION_DECL, get_identifier (name), type);
702 /* Mark the decl as external. */
703 DECL_EXTERNAL (fndecl) = 1;
704 TREE_PUBLIC (fndecl) = 1;
706 /* Mark it __attribute__((const)), if possible. */
707 TREE_READONLY (fndecl) = m->is_constant;
709 rest_of_decl_compilation (fndecl, 1, 0);
716 /* Convert an intrinsic function into an external or builtin call. */
719 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
721 gfc_intrinsic_map_t *m;
725 unsigned int num_args;
728 id = expr->value.function.isym->id;
729 /* Find the entry for this function. */
730 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
736 if (m->id == GFC_ISYM_NONE)
738 internal_error ("Intrinsic function %s(%d) not recognized",
739 expr->value.function.name, id);
742 /* Get the decl and generate the call. */
743 num_args = gfc_intrinsic_argument_list_length (expr);
744 args = (tree *) alloca (sizeof (tree) * num_args);
746 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
747 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
748 rettype = TREE_TYPE (TREE_TYPE (fndecl));
750 fndecl = build_addr (fndecl, current_function_decl);
751 se->expr = build_call_array_loc (input_location, rettype, fndecl, num_args, args);
755 /* If bounds-checking is enabled, create code to verify at runtime that the
756 string lengths for both expressions are the same (needed for e.g. MERGE).
757 If bounds-checking is not enabled, does nothing. */
760 gfc_trans_same_strlen_check (const char* intr_name, locus* where,
761 tree a, tree b, stmtblock_t* target)
766 /* If bounds-checking is disabled, do nothing. */
767 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
770 /* Compare the two string lengths. */
771 cond = fold_build2 (NE_EXPR, boolean_type_node, a, b);
773 /* Output the runtime-check. */
774 name = gfc_build_cstring_const (intr_name);
775 name = gfc_build_addr_expr (pchar_type_node, name);
776 gfc_trans_runtime_check (true, false, cond, target, where,
777 "Unequal character lengths (%ld/%ld) in %s",
778 fold_convert (long_integer_type_node, a),
779 fold_convert (long_integer_type_node, b), name);
783 /* The EXPONENT(s) intrinsic function is translated into
790 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
792 tree arg, type, res, tmp;
795 switch (expr->value.function.actual->expr->ts.kind)
798 frexp = BUILT_IN_FREXPF;
801 frexp = BUILT_IN_FREXP;
805 frexp = BUILT_IN_FREXPL;
811 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
813 res = gfc_create_var (integer_type_node, NULL);
814 tmp = build_call_expr_loc (input_location,
815 built_in_decls[frexp], 2, arg,
816 gfc_build_addr_expr (NULL_TREE, res));
817 gfc_add_expr_to_block (&se->pre, tmp);
819 type = gfc_typenode_for_spec (&expr->ts);
820 se->expr = fold_convert (type, res);
823 /* Evaluate a single upper or lower bound. */
824 /* TODO: bound intrinsic generates way too much unnecessary code. */
827 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
829 gfc_actual_arglist *arg;
830 gfc_actual_arglist *arg2;
835 tree cond, cond1, cond3, cond4, size;
843 arg = expr->value.function.actual;
848 /* Create an implicit second parameter from the loop variable. */
849 gcc_assert (!arg2->expr);
850 gcc_assert (se->loop->dimen == 1);
851 gcc_assert (se->ss->expr == expr);
852 gfc_advance_se_ss_chain (se);
853 bound = se->loop->loopvar[0];
854 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
859 /* use the passed argument. */
860 gcc_assert (arg->next->expr);
861 gfc_init_se (&argse, NULL);
862 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
863 gfc_add_block_to_block (&se->pre, &argse.pre);
865 /* Convert from one based to zero based. */
866 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
870 /* TODO: don't re-evaluate the descriptor on each iteration. */
871 /* Get a descriptor for the first parameter. */
872 ss = gfc_walk_expr (arg->expr);
873 gcc_assert (ss != gfc_ss_terminator);
874 gfc_init_se (&argse, NULL);
875 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
876 gfc_add_block_to_block (&se->pre, &argse.pre);
877 gfc_add_block_to_block (&se->post, &argse.post);
881 if (INTEGER_CST_P (bound))
885 hi = TREE_INT_CST_HIGH (bound);
886 low = TREE_INT_CST_LOW (bound);
887 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
888 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
889 "dimension index", upper ? "UBOUND" : "LBOUND",
894 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
896 bound = gfc_evaluate_now (bound, &se->pre);
897 cond = fold_build2 (LT_EXPR, boolean_type_node,
898 bound, build_int_cst (TREE_TYPE (bound), 0));
899 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
900 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
901 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
902 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
907 ubound = gfc_conv_descriptor_ubound_get (desc, bound);
908 lbound = gfc_conv_descriptor_lbound_get (desc, bound);
910 /* Follow any component references. */
911 if (arg->expr->expr_type == EXPR_VARIABLE
912 || arg->expr->expr_type == EXPR_CONSTANT)
914 as = arg->expr->symtree->n.sym->as;
915 for (ref = arg->expr->ref; ref; ref = ref->next)
920 as = ref->u.c.component->as;
928 switch (ref->u.ar.type)
947 /* 13.14.53: Result value for LBOUND
949 Case (i): For an array section or for an array expression other than a
950 whole array or array structure component, LBOUND(ARRAY, DIM)
951 has the value 1. For a whole array or array structure
952 component, LBOUND(ARRAY, DIM) has the value:
953 (a) equal to the lower bound for subscript DIM of ARRAY if
954 dimension DIM of ARRAY does not have extent zero
955 or if ARRAY is an assumed-size array of rank DIM,
958 13.14.113: Result value for UBOUND
960 Case (i): For an array section or for an array expression other than a
961 whole array or array structure component, UBOUND(ARRAY, DIM)
962 has the value equal to the number of elements in the given
963 dimension; otherwise, it has a value equal to the upper bound
964 for subscript DIM of ARRAY if dimension DIM of ARRAY does
965 not have size zero and has value zero if dimension DIM has
970 tree stride = gfc_conv_descriptor_stride_get (desc, bound);
972 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
974 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
975 gfc_index_zero_node);
976 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
978 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
979 gfc_index_zero_node);
984 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
986 cond5 = fold_build2 (EQ_EXPR, boolean_type_node, gfc_index_one_node, lbound);
987 cond5 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond5);
989 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond5);
991 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
992 ubound, gfc_index_zero_node);
996 if (as->type == AS_ASSUMED_SIZE)
997 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
998 build_int_cst (TREE_TYPE (bound),
999 arg->expr->rank - 1));
1001 cond = boolean_false_node;
1003 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
1004 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
1006 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
1007 lbound, gfc_index_one_node);
1014 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
1015 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
1016 gfc_index_one_node);
1017 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
1018 gfc_index_zero_node);
1021 se->expr = gfc_index_one_node;
1024 type = gfc_typenode_for_spec (&expr->ts);
1025 se->expr = convert (type, se->expr);
1030 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
1035 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1037 switch (expr->value.function.actual->expr->ts.type)
1041 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
1045 switch (expr->ts.kind)
1060 se->expr = build_call_expr_loc (input_location,
1061 built_in_decls[n], 1, arg);
1070 /* Create a complex value from one or two real components. */
1073 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1079 unsigned int num_args;
1081 num_args = gfc_intrinsic_argument_list_length (expr);
1082 args = (tree *) alloca (sizeof (tree) * num_args);
1084 type = gfc_typenode_for_spec (&expr->ts);
1085 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1086 real = convert (TREE_TYPE (type), args[0]);
1088 imag = convert (TREE_TYPE (type), args[1]);
1089 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1091 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1093 imag = convert (TREE_TYPE (type), imag);
1096 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1098 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1101 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1102 MODULO(A, P) = A - FLOOR (A / P) * P */
1103 /* TODO: MOD(x, 0) */
1106 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1117 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1119 switch (expr->ts.type)
1122 /* Integer case is easy, we've got a builtin op. */
1123 type = TREE_TYPE (args[0]);
1126 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1128 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1133 /* Check if we have a builtin fmod. */
1134 switch (expr->ts.kind)
1153 /* Use it if it exists. */
1154 if (n != END_BUILTINS)
1156 tmp = build_addr (built_in_decls[n], current_function_decl);
1157 se->expr = build_call_array_loc (input_location,
1158 TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1164 type = TREE_TYPE (args[0]);
1166 args[0] = gfc_evaluate_now (args[0], &se->pre);
1167 args[1] = gfc_evaluate_now (args[1], &se->pre);
1170 modulo = arg - floor (arg/arg2) * arg2, so
1171 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1173 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1174 thereby avoiding another division and retaining the accuracy
1175 of the builtin function. */
1176 if (n != END_BUILTINS && modulo)
1178 tree zero = gfc_build_const (type, integer_zero_node);
1179 tmp = gfc_evaluate_now (se->expr, &se->pre);
1180 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1181 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1182 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1183 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1184 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1185 test = gfc_evaluate_now (test, &se->pre);
1186 se->expr = fold_build3 (COND_EXPR, type, test,
1187 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1192 /* If we do not have a built_in fmod, the calculation is going to
1193 have to be done longhand. */
1194 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1196 /* Test if the value is too large to handle sensibly. */
1197 gfc_set_model_kind (expr->ts.kind);
1199 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1200 ikind = expr->ts.kind;
1203 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1204 ikind = gfc_max_integer_kind;
1206 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1207 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1208 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1210 mpfr_neg (huge, huge, GFC_RND_MODE);
1211 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1212 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1213 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1215 itype = gfc_get_int_type (ikind);
1217 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1219 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1220 tmp = convert (type, tmp);
1221 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1222 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1223 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1232 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1235 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1243 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1244 type = TREE_TYPE (args[0]);
1246 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1247 val = gfc_evaluate_now (val, &se->pre);
1249 zero = gfc_build_const (type, integer_zero_node);
1250 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1251 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1255 /* SIGN(A, B) is absolute value of A times sign of B.
1256 The real value versions use library functions to ensure the correct
1257 handling of negative zero. Integer case implemented as:
1258 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1262 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1268 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1269 if (expr->ts.type == BT_REAL)
1273 switch (expr->ts.kind)
1276 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1277 abs = built_in_decls[BUILT_IN_FABSF];
1280 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1281 abs = built_in_decls[BUILT_IN_FABS];
1285 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1286 abs = built_in_decls[BUILT_IN_FABSL];
1292 /* We explicitly have to ignore the minus sign. We do so by using
1293 result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1). */
1294 if (!gfc_option.flag_sign_zero
1295 && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
1298 zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
1299 cond = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
1300 se->expr = fold_build3 (COND_EXPR, TREE_TYPE (args[0]), cond,
1301 build_call_expr (abs, 1, args[0]),
1302 build_call_expr (tmp, 2, args[0], args[1]));
1305 se->expr = build_call_expr_loc (input_location,
1306 tmp, 2, args[0], args[1]);
1310 /* Having excluded floating point types, we know we are now dealing
1311 with signed integer types. */
1312 type = TREE_TYPE (args[0]);
1314 /* Args[0] is used multiple times below. */
1315 args[0] = gfc_evaluate_now (args[0], &se->pre);
1317 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1318 the signs of A and B are the same, and of all ones if they differ. */
1319 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1320 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1321 build_int_cst (type, TYPE_PRECISION (type) - 1));
1322 tmp = gfc_evaluate_now (tmp, &se->pre);
1324 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1325 is all ones (i.e. -1). */
1326 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1327 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1332 /* Test for the presence of an optional argument. */
1335 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1339 arg = expr->value.function.actual->expr;
1340 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1341 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1342 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1346 /* Calculate the double precision product of two single precision values. */
1349 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1354 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1356 /* Convert the args to double precision before multiplying. */
1357 type = gfc_typenode_for_spec (&expr->ts);
1358 args[0] = convert (type, args[0]);
1359 args[1] = convert (type, args[1]);
1360 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1364 /* Return a length one character string containing an ascii character. */
1367 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1372 unsigned int num_args;
1374 num_args = gfc_intrinsic_argument_list_length (expr);
1375 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1377 type = gfc_get_char_type (expr->ts.kind);
1378 var = gfc_create_var (type, "char");
1380 arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1381 gfc_add_modify (&se->pre, var, arg[0]);
1382 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1383 se->string_length = integer_one_node;
1388 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1396 unsigned int num_args;
1398 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1399 args = (tree *) alloca (sizeof (tree) * num_args);
1401 var = gfc_create_var (pchar_type_node, "pstr");
1402 len = gfc_create_var (gfc_get_int_type (8), "len");
1404 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1405 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1406 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1408 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1409 tmp = build_call_array_loc (input_location,
1410 TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1411 fndecl, num_args, args);
1412 gfc_add_expr_to_block (&se->pre, tmp);
1414 /* Free the temporary afterwards, if necessary. */
1415 cond = fold_build2 (GT_EXPR, boolean_type_node,
1416 len, build_int_cst (TREE_TYPE (len), 0));
1417 tmp = gfc_call_free (var);
1418 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1419 gfc_add_expr_to_block (&se->post, tmp);
1422 se->string_length = len;
1427 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1435 unsigned int num_args;
1437 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1438 args = (tree *) alloca (sizeof (tree) * num_args);
1440 var = gfc_create_var (pchar_type_node, "pstr");
1441 len = gfc_create_var (gfc_get_int_type (4), "len");
1443 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1444 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1445 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1447 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1448 tmp = build_call_array_loc (input_location,
1449 TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1450 fndecl, num_args, args);
1451 gfc_add_expr_to_block (&se->pre, tmp);
1453 /* Free the temporary afterwards, if necessary. */
1454 cond = fold_build2 (GT_EXPR, boolean_type_node,
1455 len, build_int_cst (TREE_TYPE (len), 0));
1456 tmp = gfc_call_free (var);
1457 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1458 gfc_add_expr_to_block (&se->post, tmp);
1461 se->string_length = len;
1465 /* Return a character string containing the tty name. */
1468 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1476 unsigned int num_args;
1478 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1479 args = (tree *) alloca (sizeof (tree) * num_args);
1481 var = gfc_create_var (pchar_type_node, "pstr");
1482 len = gfc_create_var (gfc_get_int_type (4), "len");
1484 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1485 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1486 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1488 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1489 tmp = build_call_array_loc (input_location,
1490 TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1491 fndecl, num_args, args);
1492 gfc_add_expr_to_block (&se->pre, tmp);
1494 /* Free the temporary afterwards, if necessary. */
1495 cond = fold_build2 (GT_EXPR, boolean_type_node,
1496 len, build_int_cst (TREE_TYPE (len), 0));
1497 tmp = gfc_call_free (var);
1498 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1499 gfc_add_expr_to_block (&se->post, tmp);
1502 se->string_length = len;
1506 /* Get the minimum/maximum value of all the parameters.
1507 minmax (a1, a2, a3, ...)
1510 if (a2 .op. mvar || isnan(mvar))
1512 if (a3 .op. mvar || isnan(mvar))
1519 /* TODO: Mismatching types can occur when specific names are used.
1520 These should be handled during resolution. */
1522 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
1530 gfc_actual_arglist *argexpr;
1531 unsigned int i, nargs;
1533 nargs = gfc_intrinsic_argument_list_length (expr);
1534 args = (tree *) alloca (sizeof (tree) * nargs);
1536 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1537 type = gfc_typenode_for_spec (&expr->ts);
1539 argexpr = expr->value.function.actual;
1540 if (TREE_TYPE (args[0]) != type)
1541 args[0] = convert (type, args[0]);
1542 /* Only evaluate the argument once. */
1543 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1544 args[0] = gfc_evaluate_now (args[0], &se->pre);
1546 mvar = gfc_create_var (type, "M");
1547 gfc_add_modify (&se->pre, mvar, args[0]);
1548 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1554 /* Handle absent optional arguments by ignoring the comparison. */
1555 if (argexpr->expr->expr_type == EXPR_VARIABLE
1556 && argexpr->expr->symtree->n.sym->attr.optional
1557 && TREE_CODE (val) == INDIRECT_REF)
1558 cond = fold_build2_loc (input_location,
1559 NE_EXPR, boolean_type_node,
1560 TREE_OPERAND (val, 0),
1561 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1566 /* Only evaluate the argument once. */
1567 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1568 val = gfc_evaluate_now (val, &se->pre);
1571 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1573 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1575 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1576 __builtin_isnan might be made dependent on that module being loaded,
1577 to help performance of programs that don't rely on IEEE semantics. */
1578 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1580 isnan = build_call_expr_loc (input_location,
1581 built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1582 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1583 fold_convert (boolean_type_node, isnan));
1585 tmp = build3_v (COND_EXPR, tmp, thencase,
1586 build_empty_stmt (input_location));
1588 if (cond != NULL_TREE)
1589 tmp = build3_v (COND_EXPR, cond, tmp,
1590 build_empty_stmt (input_location));
1592 gfc_add_expr_to_block (&se->pre, tmp);
1593 argexpr = argexpr->next;
1599 /* Generate library calls for MIN and MAX intrinsics for character
1602 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1605 tree var, len, fndecl, tmp, cond, function;
1608 nargs = gfc_intrinsic_argument_list_length (expr);
1609 args = (tree *) alloca (sizeof (tree) * (nargs + 4));
1610 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1612 /* Create the result variables. */
1613 len = gfc_create_var (gfc_charlen_type_node, "len");
1614 args[0] = gfc_build_addr_expr (NULL_TREE, len);
1615 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1616 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1617 args[2] = build_int_cst (NULL_TREE, op);
1618 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1620 if (expr->ts.kind == 1)
1621 function = gfor_fndecl_string_minmax;
1622 else if (expr->ts.kind == 4)
1623 function = gfor_fndecl_string_minmax_char4;
1627 /* Make the function call. */
1628 fndecl = build_addr (function, current_function_decl);
1629 tmp = build_call_array_loc (input_location,
1630 TREE_TYPE (TREE_TYPE (function)), fndecl,
1632 gfc_add_expr_to_block (&se->pre, tmp);
1634 /* Free the temporary afterwards, if necessary. */
1635 cond = fold_build2 (GT_EXPR, boolean_type_node,
1636 len, build_int_cst (TREE_TYPE (len), 0));
1637 tmp = gfc_call_free (var);
1638 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1639 gfc_add_expr_to_block (&se->post, tmp);
1642 se->string_length = len;
1646 /* Create a symbol node for this intrinsic. The symbol from the frontend
1647 has the generic name. */
1650 gfc_get_symbol_for_expr (gfc_expr * expr)
1654 /* TODO: Add symbols for intrinsic function to the global namespace. */
1655 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1656 sym = gfc_new_symbol (expr->value.function.name, NULL);
1659 sym->attr.external = 1;
1660 sym->attr.function = 1;
1661 sym->attr.always_explicit = 1;
1662 sym->attr.proc = PROC_INTRINSIC;
1663 sym->attr.flavor = FL_PROCEDURE;
1667 sym->attr.dimension = 1;
1668 sym->as = gfc_get_array_spec ();
1669 sym->as->type = AS_ASSUMED_SHAPE;
1670 sym->as->rank = expr->rank;
1673 /* TODO: proper argument lists for external intrinsics. */
1677 /* Generate a call to an external intrinsic function. */
1679 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1684 gcc_assert (!se->ss || se->ss->expr == expr);
1687 gcc_assert (expr->rank > 0);
1689 gcc_assert (expr->rank == 0);
1691 sym = gfc_get_symbol_for_expr (expr);
1693 /* Calls to libgfortran_matmul need to be appended special arguments,
1694 to be able to call the BLAS ?gemm functions if required and possible. */
1695 append_args = NULL_TREE;
1696 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1697 && sym->ts.type != BT_LOGICAL)
1699 tree cint = gfc_get_int_type (gfc_c_int_kind);
1701 if (gfc_option.flag_external_blas
1702 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1703 && (sym->ts.kind == gfc_default_real_kind
1704 || sym->ts.kind == gfc_default_double_kind))
1708 if (sym->ts.type == BT_REAL)
1710 if (sym->ts.kind == gfc_default_real_kind)
1711 gemm_fndecl = gfor_fndecl_sgemm;
1713 gemm_fndecl = gfor_fndecl_dgemm;
1717 if (sym->ts.kind == gfc_default_real_kind)
1718 gemm_fndecl = gfor_fndecl_cgemm;
1720 gemm_fndecl = gfor_fndecl_zgemm;
1723 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1724 append_args = gfc_chainon_list
1725 (append_args, build_int_cst
1726 (cint, gfc_option.blas_matmul_limit));
1727 append_args = gfc_chainon_list (append_args,
1728 gfc_build_addr_expr (NULL_TREE,
1733 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1734 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1735 append_args = gfc_chainon_list (append_args, null_pointer_node);
1739 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
1744 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1764 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
1773 gfc_actual_arglist *actual;
1780 gfc_conv_intrinsic_funcall (se, expr);
1784 actual = expr->value.function.actual;
1785 type = gfc_typenode_for_spec (&expr->ts);
1786 /* Initialize the result. */
1787 resvar = gfc_create_var (type, "test");
1789 tmp = convert (type, boolean_true_node);
1791 tmp = convert (type, boolean_false_node);
1792 gfc_add_modify (&se->pre, resvar, tmp);
1794 /* Walk the arguments. */
1795 arrayss = gfc_walk_expr (actual->expr);
1796 gcc_assert (arrayss != gfc_ss_terminator);
1798 /* Initialize the scalarizer. */
1799 gfc_init_loopinfo (&loop);
1800 exit_label = gfc_build_label_decl (NULL_TREE);
1801 TREE_USED (exit_label) = 1;
1802 gfc_add_ss_to_loop (&loop, arrayss);
1804 /* Initialize the loop. */
1805 gfc_conv_ss_startstride (&loop);
1806 gfc_conv_loop_setup (&loop, &expr->where);
1808 gfc_mark_ss_chain_used (arrayss, 1);
1809 /* Generate the loop body. */
1810 gfc_start_scalarized_body (&loop, &body);
1812 /* If the condition matches then set the return value. */
1813 gfc_start_block (&block);
1815 tmp = convert (type, boolean_false_node);
1817 tmp = convert (type, boolean_true_node);
1818 gfc_add_modify (&block, resvar, tmp);
1820 /* And break out of the loop. */
1821 tmp = build1_v (GOTO_EXPR, exit_label);
1822 gfc_add_expr_to_block (&block, tmp);
1824 found = gfc_finish_block (&block);
1826 /* Check this element. */
1827 gfc_init_se (&arrayse, NULL);
1828 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1829 arrayse.ss = arrayss;
1830 gfc_conv_expr_val (&arrayse, actual->expr);
1832 gfc_add_block_to_block (&body, &arrayse.pre);
1833 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1834 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1835 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
1836 gfc_add_expr_to_block (&body, tmp);
1837 gfc_add_block_to_block (&body, &arrayse.post);
1839 gfc_trans_scalarizing_loops (&loop, &body);
1841 /* Add the exit label. */
1842 tmp = build1_v (LABEL_EXPR, exit_label);
1843 gfc_add_expr_to_block (&loop.pre, tmp);
1845 gfc_add_block_to_block (&se->pre, &loop.pre);
1846 gfc_add_block_to_block (&se->pre, &loop.post);
1847 gfc_cleanup_loop (&loop);
1852 /* COUNT(A) = Number of true elements in A. */
1854 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1861 gfc_actual_arglist *actual;
1867 gfc_conv_intrinsic_funcall (se, expr);
1871 actual = expr->value.function.actual;
1873 type = gfc_typenode_for_spec (&expr->ts);
1874 /* Initialize the result. */
1875 resvar = gfc_create_var (type, "count");
1876 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1878 /* Walk the arguments. */
1879 arrayss = gfc_walk_expr (actual->expr);
1880 gcc_assert (arrayss != gfc_ss_terminator);
1882 /* Initialize the scalarizer. */
1883 gfc_init_loopinfo (&loop);
1884 gfc_add_ss_to_loop (&loop, arrayss);
1886 /* Initialize the loop. */
1887 gfc_conv_ss_startstride (&loop);
1888 gfc_conv_loop_setup (&loop, &expr->where);
1890 gfc_mark_ss_chain_used (arrayss, 1);
1891 /* Generate the loop body. */
1892 gfc_start_scalarized_body (&loop, &body);
1894 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1895 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1896 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1898 gfc_init_se (&arrayse, NULL);
1899 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1900 arrayse.ss = arrayss;
1901 gfc_conv_expr_val (&arrayse, actual->expr);
1902 tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
1903 build_empty_stmt (input_location));
1905 gfc_add_block_to_block (&body, &arrayse.pre);
1906 gfc_add_expr_to_block (&body, tmp);
1907 gfc_add_block_to_block (&body, &arrayse.post);
1909 gfc_trans_scalarizing_loops (&loop, &body);
1911 gfc_add_block_to_block (&se->pre, &loop.pre);
1912 gfc_add_block_to_block (&se->pre, &loop.post);
1913 gfc_cleanup_loop (&loop);
1918 /* Inline implementation of the sum and product intrinsics. */
1920 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
1928 gfc_actual_arglist *actual;
1933 gfc_expr *arrayexpr;
1938 gfc_conv_intrinsic_funcall (se, expr);
1942 type = gfc_typenode_for_spec (&expr->ts);
1943 /* Initialize the result. */
1944 resvar = gfc_create_var (type, "val");
1945 if (op == PLUS_EXPR)
1946 tmp = gfc_build_const (type, integer_zero_node);
1948 tmp = gfc_build_const (type, integer_one_node);
1950 gfc_add_modify (&se->pre, resvar, tmp);
1952 /* Walk the arguments. */
1953 actual = expr->value.function.actual;
1954 arrayexpr = actual->expr;
1955 arrayss = gfc_walk_expr (arrayexpr);
1956 gcc_assert (arrayss != gfc_ss_terminator);
1958 actual = actual->next->next;
1959 gcc_assert (actual);
1960 maskexpr = actual->expr;
1961 if (maskexpr && maskexpr->rank != 0)
1963 maskss = gfc_walk_expr (maskexpr);
1964 gcc_assert (maskss != gfc_ss_terminator);
1969 /* Initialize the scalarizer. */
1970 gfc_init_loopinfo (&loop);
1971 gfc_add_ss_to_loop (&loop, arrayss);
1973 gfc_add_ss_to_loop (&loop, maskss);
1975 /* Initialize the loop. */
1976 gfc_conv_ss_startstride (&loop);
1977 gfc_conv_loop_setup (&loop, &expr->where);
1979 gfc_mark_ss_chain_used (arrayss, 1);
1981 gfc_mark_ss_chain_used (maskss, 1);
1982 /* Generate the loop body. */
1983 gfc_start_scalarized_body (&loop, &body);
1985 /* If we have a mask, only add this element if the mask is set. */
1988 gfc_init_se (&maskse, NULL);
1989 gfc_copy_loopinfo_to_se (&maskse, &loop);
1991 gfc_conv_expr_val (&maskse, maskexpr);
1992 gfc_add_block_to_block (&body, &maskse.pre);
1994 gfc_start_block (&block);
1997 gfc_init_block (&block);
1999 /* Do the actual summation/product. */
2000 gfc_init_se (&arrayse, NULL);
2001 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2002 arrayse.ss = arrayss;
2003 gfc_conv_expr_val (&arrayse, arrayexpr);
2004 gfc_add_block_to_block (&block, &arrayse.pre);
2006 tmp = fold_build2 (op, type, resvar, arrayse.expr);
2007 gfc_add_modify (&block, resvar, tmp);
2008 gfc_add_block_to_block (&block, &arrayse.post);
2012 /* We enclose the above in if (mask) {...} . */
2013 tmp = gfc_finish_block (&block);
2015 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2016 build_empty_stmt (input_location));
2019 tmp = gfc_finish_block (&block);
2020 gfc_add_expr_to_block (&body, tmp);
2022 gfc_trans_scalarizing_loops (&loop, &body);
2024 /* For a scalar mask, enclose the loop in an if statement. */
2025 if (maskexpr && maskss == NULL)
2027 gfc_init_se (&maskse, NULL);
2028 gfc_conv_expr_val (&maskse, maskexpr);
2029 gfc_init_block (&block);
2030 gfc_add_block_to_block (&block, &loop.pre);
2031 gfc_add_block_to_block (&block, &loop.post);
2032 tmp = gfc_finish_block (&block);
2034 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2035 build_empty_stmt (input_location));
2036 gfc_add_expr_to_block (&block, tmp);
2037 gfc_add_block_to_block (&se->pre, &block);
2041 gfc_add_block_to_block (&se->pre, &loop.pre);
2042 gfc_add_block_to_block (&se->pre, &loop.post);
2045 gfc_cleanup_loop (&loop);
2051 /* Inline implementation of the dot_product intrinsic. This function
2052 is based on gfc_conv_intrinsic_arith (the previous function). */
2054 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
2062 gfc_actual_arglist *actual;
2063 gfc_ss *arrayss1, *arrayss2;
2064 gfc_se arrayse1, arrayse2;
2065 gfc_expr *arrayexpr1, *arrayexpr2;
2067 type = gfc_typenode_for_spec (&expr->ts);
2069 /* Initialize the result. */
2070 resvar = gfc_create_var (type, "val");
2071 if (expr->ts.type == BT_LOGICAL)
2072 tmp = build_int_cst (type, 0);
2074 tmp = gfc_build_const (type, integer_zero_node);
2076 gfc_add_modify (&se->pre, resvar, tmp);
2078 /* Walk argument #1. */
2079 actual = expr->value.function.actual;
2080 arrayexpr1 = actual->expr;
2081 arrayss1 = gfc_walk_expr (arrayexpr1);
2082 gcc_assert (arrayss1 != gfc_ss_terminator);
2084 /* Walk argument #2. */
2085 actual = actual->next;
2086 arrayexpr2 = actual->expr;
2087 arrayss2 = gfc_walk_expr (arrayexpr2);
2088 gcc_assert (arrayss2 != gfc_ss_terminator);
2090 /* Initialize the scalarizer. */
2091 gfc_init_loopinfo (&loop);
2092 gfc_add_ss_to_loop (&loop, arrayss1);
2093 gfc_add_ss_to_loop (&loop, arrayss2);
2095 /* Initialize the loop. */
2096 gfc_conv_ss_startstride (&loop);
2097 gfc_conv_loop_setup (&loop, &expr->where);
2099 gfc_mark_ss_chain_used (arrayss1, 1);
2100 gfc_mark_ss_chain_used (arrayss2, 1);
2102 /* Generate the loop body. */
2103 gfc_start_scalarized_body (&loop, &body);
2104 gfc_init_block (&block);
2106 /* Make the tree expression for [conjg(]array1[)]. */
2107 gfc_init_se (&arrayse1, NULL);
2108 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2109 arrayse1.ss = arrayss1;
2110 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2111 if (expr->ts.type == BT_COMPLEX)
2112 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2113 gfc_add_block_to_block (&block, &arrayse1.pre);
2115 /* Make the tree expression for array2. */
2116 gfc_init_se (&arrayse2, NULL);
2117 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2118 arrayse2.ss = arrayss2;
2119 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2120 gfc_add_block_to_block (&block, &arrayse2.pre);
2122 /* Do the actual product and sum. */
2123 if (expr->ts.type == BT_LOGICAL)
2125 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2126 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2130 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2131 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2133 gfc_add_modify (&block, resvar, tmp);
2135 /* Finish up the loop block and the loop. */
2136 tmp = gfc_finish_block (&block);
2137 gfc_add_expr_to_block (&body, tmp);
2139 gfc_trans_scalarizing_loops (&loop, &body);
2140 gfc_add_block_to_block (&se->pre, &loop.pre);
2141 gfc_add_block_to_block (&se->pre, &loop.post);
2142 gfc_cleanup_loop (&loop);
2148 /* Emit code for minloc or maxloc intrinsic. There are many different cases
2149 we need to handle. For performance reasons we sometimes create two
2150 loops instead of one, where the second one is much simpler.
2151 Examples for minloc intrinsic:
2152 1) Result is an array, a call is generated
2153 2) Array mask is used and NaNs need to be supported:
2159 if (pos == 0) pos = S + (1 - from);
2160 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2167 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2171 3) NaNs need to be supported, but it is known at compile time or cheaply
2172 at runtime whether array is nonempty or not:
2177 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2180 if (from <= to) pos = 1;
2184 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2188 4) NaNs aren't supported, array mask is used:
2189 limit = infinities_supported ? Infinity : huge (limit);
2193 if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2199 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2203 5) Same without array mask:
2204 limit = infinities_supported ? Infinity : huge (limit);
2205 pos = (from <= to) ? 1 : 0;
2208 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2211 For 3) and 5), if mask is scalar, this all goes into a conditional,
2212 setting pos = 0; in the else branch. */
2215 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
2219 stmtblock_t ifblock;
2220 stmtblock_t elseblock;
2231 gfc_actual_arglist *actual;
2236 gfc_expr *arrayexpr;
2243 gfc_conv_intrinsic_funcall (se, expr);
2247 /* Initialize the result. */
2248 pos = gfc_create_var (gfc_array_index_type, "pos");
2249 offset = gfc_create_var (gfc_array_index_type, "offset");
2250 type = gfc_typenode_for_spec (&expr->ts);
2252 /* Walk the arguments. */
2253 actual = expr->value.function.actual;
2254 arrayexpr = actual->expr;
2255 arrayss = gfc_walk_expr (arrayexpr);
2256 gcc_assert (arrayss != gfc_ss_terminator);
2258 actual = actual->next->next;
2259 gcc_assert (actual);
2260 maskexpr = actual->expr;
2262 if (maskexpr && maskexpr->rank != 0)
2264 maskss = gfc_walk_expr (maskexpr);
2265 gcc_assert (maskss != gfc_ss_terminator);
2270 if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2272 nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2274 nonempty = fold_build2 (GT_EXPR, boolean_type_node, nonempty,
2275 gfc_index_zero_node);
2280 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2281 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2282 switch (arrayexpr->ts.type)
2285 if (HONOR_INFINITIES (DECL_MODE (limit)))
2287 REAL_VALUE_TYPE real;
2289 tmp = build_real (TREE_TYPE (limit), real);
2292 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2293 arrayexpr->ts.kind, 0);
2297 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2298 arrayexpr->ts.kind);
2305 /* We start with the most negative possible value for MAXLOC, and the most
2306 positive possible value for MINLOC. The most negative possible value is
2307 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2308 possible value is HUGE in both cases. */
2310 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2311 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2312 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2313 build_int_cst (type, 1));
2315 gfc_add_modify (&se->pre, limit, tmp);
2317 /* Initialize the scalarizer. */
2318 gfc_init_loopinfo (&loop);
2319 gfc_add_ss_to_loop (&loop, arrayss);
2321 gfc_add_ss_to_loop (&loop, maskss);
2323 /* Initialize the loop. */
2324 gfc_conv_ss_startstride (&loop);
2325 gfc_conv_loop_setup (&loop, &expr->where);
2327 gcc_assert (loop.dimen == 1);
2328 if (nonempty == NULL && maskss == NULL && loop.from[0] && loop.to[0])
2329 nonempty = fold_build2 (LE_EXPR, boolean_type_node, loop.from[0],
2334 /* Initialize the position to zero, following Fortran 2003. We are free
2335 to do this because Fortran 95 allows the result of an entirely false
2336 mask to be processor dependent. If we know at compile time the array
2337 is non-empty and no MASK is used, we can initialize to 1 to simplify
2339 if (nonempty != NULL && !HONOR_NANS (DECL_MODE (limit)))
2340 gfc_add_modify (&loop.pre, pos,
2341 fold_build3 (COND_EXPR, gfc_array_index_type,
2342 nonempty, gfc_index_one_node,
2343 gfc_index_zero_node));
2346 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2347 lab1 = gfc_build_label_decl (NULL_TREE);
2348 TREE_USED (lab1) = 1;
2349 lab2 = gfc_build_label_decl (NULL_TREE);
2350 TREE_USED (lab2) = 1;
2353 gfc_mark_ss_chain_used (arrayss, 1);
2355 gfc_mark_ss_chain_used (maskss, 1);
2356 /* Generate the loop body. */
2357 gfc_start_scalarized_body (&loop, &body);
2359 /* If we have a mask, only check this element if the mask is set. */
2362 gfc_init_se (&maskse, NULL);
2363 gfc_copy_loopinfo_to_se (&maskse, &loop);
2365 gfc_conv_expr_val (&maskse, maskexpr);
2366 gfc_add_block_to_block (&body, &maskse.pre);
2368 gfc_start_block (&block);
2371 gfc_init_block (&block);
2373 /* Compare with the current limit. */
2374 gfc_init_se (&arrayse, NULL);
2375 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2376 arrayse.ss = arrayss;
2377 gfc_conv_expr_val (&arrayse, arrayexpr);
2378 gfc_add_block_to_block (&block, &arrayse.pre);
2380 /* We do the following if this is a more extreme value. */
2381 gfc_start_block (&ifblock);
2383 /* Assign the value to the limit... */
2384 gfc_add_modify (&ifblock, limit, arrayse.expr);
2386 /* Remember where we are. An offset must be added to the loop
2387 counter to obtain the required position. */
2389 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2390 gfc_index_one_node, loop.from[0]);
2392 tmp = gfc_index_one_node;
2394 gfc_add_modify (&block, offset, tmp);
2396 if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
2398 stmtblock_t ifblock2;
2401 gfc_start_block (&ifblock2);
2402 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2403 loop.loopvar[0], offset);
2404 gfc_add_modify (&ifblock2, pos, tmp);
2405 ifbody2 = gfc_finish_block (&ifblock2);
2406 cond = fold_build2 (EQ_EXPR, boolean_type_node, pos,
2407 gfc_index_zero_node);
2408 tmp = build3_v (COND_EXPR, cond, ifbody2,
2409 build_empty_stmt (input_location));
2410 gfc_add_expr_to_block (&block, tmp);
2413 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2414 loop.loopvar[0], offset);
2415 gfc_add_modify (&ifblock, pos, tmp);
2418 gfc_add_expr_to_block (&ifblock, build1_v (GOTO_EXPR, lab1));
2420 ifbody = gfc_finish_block (&ifblock);
2422 if (!lab1 || HONOR_NANS (DECL_MODE (limit)))
2425 cond = fold_build2 (op == GT_EXPR ? GE_EXPR : LE_EXPR,
2426 boolean_type_node, arrayse.expr, limit);
2428 cond = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2430 ifbody = build3_v (COND_EXPR, cond, ifbody,
2431 build_empty_stmt (input_location));
2433 gfc_add_expr_to_block (&block, ifbody);
2437 /* We enclose the above in if (mask) {...}. */
2438 tmp = gfc_finish_block (&block);
2440 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2441 build_empty_stmt (input_location));
2444 tmp = gfc_finish_block (&block);
2445 gfc_add_expr_to_block (&body, tmp);
2449 gfc_trans_scalarized_loop_end (&loop, 0, &body);
2451 if (HONOR_NANS (DECL_MODE (limit)))
2453 if (nonempty != NULL)
2455 ifbody = build2_v (MODIFY_EXPR, pos, gfc_index_one_node);
2456 tmp = build3_v (COND_EXPR, nonempty, ifbody,
2457 build_empty_stmt (input_location));
2458 gfc_add_expr_to_block (&loop.code[0], tmp);
2462 gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
2463 gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
2464 gfc_start_block (&body);
2466 /* If we have a mask, only check this element if the mask is set. */
2469 gfc_init_se (&maskse, NULL);
2470 gfc_copy_loopinfo_to_se (&maskse, &loop);
2472 gfc_conv_expr_val (&maskse, maskexpr);
2473 gfc_add_block_to_block (&body, &maskse.pre);
2475 gfc_start_block (&block);
2478 gfc_init_block (&block);
2480 /* Compare with the current limit. */
2481 gfc_init_se (&arrayse, NULL);
2482 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2483 arrayse.ss = arrayss;
2484 gfc_conv_expr_val (&arrayse, arrayexpr);
2485 gfc_add_block_to_block (&block, &arrayse.pre);
2487 /* We do the following if this is a more extreme value. */
2488 gfc_start_block (&ifblock);
2490 /* Assign the value to the limit... */
2491 gfc_add_modify (&ifblock, limit, arrayse.expr);
2493 /* Remember where we are. An offset must be added to the loop
2494 counter to obtain the required position. */
2496 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2497 gfc_index_one_node, loop.from[0]);
2499 tmp = gfc_index_one_node;
2501 gfc_add_modify (&block, offset, tmp);
2503 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2504 loop.loopvar[0], offset);
2505 gfc_add_modify (&ifblock, pos, tmp);
2507 ifbody = gfc_finish_block (&ifblock);
2509 cond = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2511 tmp = build3_v (COND_EXPR, cond, ifbody,
2512 build_empty_stmt (input_location));
2513 gfc_add_expr_to_block (&block, tmp);
2517 /* We enclose the above in if (mask) {...}. */
2518 tmp = gfc_finish_block (&block);
2520 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2521 build_empty_stmt (input_location));
2524 tmp = gfc_finish_block (&block);
2525 gfc_add_expr_to_block (&body, tmp);
2526 /* Avoid initializing loopvar[0] again, it should be left where
2527 it finished by the first loop. */
2528 loop.from[0] = loop.loopvar[0];
2531 gfc_trans_scalarizing_loops (&loop, &body);
2534 gfc_add_expr_to_block (&loop.pre, build1_v (LABEL_EXPR, lab2));
2536 /* For a scalar mask, enclose the loop in an if statement. */
2537 if (maskexpr && maskss == NULL)
2539 gfc_init_se (&maskse, NULL);
2540 gfc_conv_expr_val (&maskse, maskexpr);
2541 gfc_init_block (&block);
2542 gfc_add_block_to_block (&block, &loop.pre);
2543 gfc_add_block_to_block (&block, &loop.post);
2544 tmp = gfc_finish_block (&block);
2546 /* For the else part of the scalar mask, just initialize
2547 the pos variable the same way as above. */
2549 gfc_init_block (&elseblock);
2550 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2551 elsetmp = gfc_finish_block (&elseblock);
2553 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2554 gfc_add_expr_to_block (&block, tmp);
2555 gfc_add_block_to_block (&se->pre, &block);
2559 gfc_add_block_to_block (&se->pre, &loop.pre);
2560 gfc_add_block_to_block (&se->pre, &loop.post);
2562 gfc_cleanup_loop (&loop);
2564 se->expr = convert (type, pos);
2567 /* Emit code for minval or maxval intrinsic. There are many different cases
2568 we need to handle. For performance reasons we sometimes create two
2569 loops instead of one, where the second one is much simpler.
2570 Examples for minval intrinsic:
2571 1) Result is an array, a call is generated
2572 2) Array mask is used and NaNs need to be supported, rank 1:
2577 if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
2580 limit = nonempty ? NaN : huge (limit);
2582 while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
2583 3) NaNs need to be supported, but it is known at compile time or cheaply
2584 at runtime whether array is nonempty or not, rank 1:
2587 while (S <= to) { if (a[S] <= limit) goto lab; S++; }
2588 limit = (from <= to) ? NaN : huge (limit);
2590 while (S <= to) { limit = min (a[S], limit); S++; }
2591 4) Array mask is used and NaNs need to be supported, rank > 1:
2600 if (fast) limit = min (a[S1][S2], limit);
2603 if (a[S1][S2] <= limit) {
2614 limit = nonempty ? NaN : huge (limit);
2615 5) NaNs need to be supported, but it is known at compile time or cheaply
2616 at runtime whether array is nonempty or not, rank > 1:
2623 if (fast) limit = min (a[S1][S2], limit);
2625 if (a[S1][S2] <= limit) {
2635 limit = (nonempty_array) ? NaN : huge (limit);
2636 6) NaNs aren't supported, but infinities are. Array mask is used:
2641 if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
2644 limit = nonempty ? limit : huge (limit);
2645 7) Same without array mask:
2648 while (S <= to) { limit = min (a[S], limit); S++; }
2649 limit = (from <= to) ? limit : huge (limit);
2650 8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
2651 limit = huge (limit);
2653 while (S <= to) { limit = min (a[S], limit); S++); }
2655 while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
2656 with array mask instead).
2657 For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
2658 setting limit = huge (limit); in the else branch. */
2661 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
2671 tree huge_cst = NULL, nan_cst = NULL;
2673 stmtblock_t block, block2;
2675 gfc_actual_arglist *actual;
2680 gfc_expr *arrayexpr;
2686 gfc_conv_intrinsic_funcall (se, expr);
2690 type = gfc_typenode_for_spec (&expr->ts);
2691 /* Initialize the result. */
2692 limit = gfc_create_var (type, "limit");
2693 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2694 switch (expr->ts.type)
2697 huge_cst = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2699 if (HONOR_INFINITIES (DECL_MODE (limit)))
2701 REAL_VALUE_TYPE real;
2703 tmp = build_real (type, real);
2707 if (HONOR_NANS (DECL_MODE (limit)))
2709 REAL_VALUE_TYPE real;
2710 real_nan (&real, "", 1, DECL_MODE (limit));
2711 nan_cst = build_real (type, real);
2716 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2723 /* We start with the most negative possible value for MAXVAL, and the most
2724 positive possible value for MINVAL. The most negative possible value is
2725 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2726 possible value is HUGE in both cases. */
2729 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2731 huge_cst = fold_build1 (NEGATE_EXPR, TREE_TYPE (huge_cst), huge_cst);
2734 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2735 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2736 tmp, build_int_cst (type, 1));
2738 gfc_add_modify (&se->pre, limit, tmp);
2740 /* Walk the arguments. */
2741 actual = expr->value.function.actual;
2742 arrayexpr = actual->expr;
2743 arrayss = gfc_walk_expr (arrayexpr);
2744 gcc_assert (arrayss != gfc_ss_terminator);
2746 actual = actual->next->next;
2747 gcc_assert (actual);
2748 maskexpr = actual->expr;
2750 if (maskexpr && maskexpr->rank != 0)
2752 maskss = gfc_walk_expr (maskexpr);
2753 gcc_assert (maskss != gfc_ss_terminator);
2758 if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2760 nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2762 nonempty = fold_build2 (GT_EXPR, boolean_type_node, nonempty,
2763 gfc_index_zero_node);
2768 /* Initialize the scalarizer. */
2769 gfc_init_loopinfo (&loop);
2770 gfc_add_ss_to_loop (&loop, arrayss);
2772 gfc_add_ss_to_loop (&loop, maskss);
2774 /* Initialize the loop. */
2775 gfc_conv_ss_startstride (&loop);
2776 gfc_conv_loop_setup (&loop, &expr->where);
2778 if (nonempty == NULL && maskss == NULL
2779 && loop.dimen == 1 && loop.from[0] && loop.to[0])
2780 nonempty = fold_build2 (LE_EXPR, boolean_type_node, loop.from[0],
2782 nonempty_var = NULL;
2783 if (nonempty == NULL
2784 && (HONOR_INFINITIES (DECL_MODE (limit))
2785 || HONOR_NANS (DECL_MODE (limit))))
2787 nonempty_var = gfc_create_var (boolean_type_node, "nonempty");
2788 gfc_add_modify (&se->pre, nonempty_var, boolean_false_node);
2789 nonempty = nonempty_var;
2793 if (HONOR_NANS (DECL_MODE (limit)))
2795 if (loop.dimen == 1)
2797 lab = gfc_build_label_decl (NULL_TREE);
2798 TREE_USED (lab) = 1;
2802 fast = gfc_create_var (boolean_type_node, "fast");
2803 gfc_add_modify (&se->pre, fast, boolean_false_node);
2807 gfc_mark_ss_chain_used (arrayss, 1);
2809 gfc_mark_ss_chain_used (maskss, 1);
2810 /* Generate the loop body. */
2811 gfc_start_scalarized_body (&loop, &body);
2813 /* If we have a mask, only add this element if the mask is set. */
2816 gfc_init_se (&maskse, NULL);
2817 gfc_copy_loopinfo_to_se (&maskse, &loop);
2819 gfc_conv_expr_val (&maskse, maskexpr);
2820 gfc_add_block_to_block (&body, &maskse.pre);
2822 gfc_start_block (&block);
2825 gfc_init_block (&block);
2827 /* Compare with the current limit. */
2828 gfc_init_se (&arrayse, NULL);
2829 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2830 arrayse.ss = arrayss;
2831 gfc_conv_expr_val (&arrayse, arrayexpr);
2832 gfc_add_block_to_block (&block, &arrayse.pre);
2834 gfc_init_block (&block2);
2837 gfc_add_modify (&block2, nonempty_var, boolean_true_node);
2839 if (HONOR_NANS (DECL_MODE (limit)))
2841 tmp = fold_build2 (op == GT_EXPR ? GE_EXPR : LE_EXPR,
2842 boolean_type_node, arrayse.expr, limit);
2844 ifbody = build1_v (GOTO_EXPR, lab);
2847 stmtblock_t ifblock;
2849 gfc_init_block (&ifblock);
2850 gfc_add_modify (&ifblock, limit, arrayse.expr);
2851 gfc_add_modify (&ifblock, fast, boolean_true_node);
2852 ifbody = gfc_finish_block (&ifblock);
2854 tmp = build3_v (COND_EXPR, tmp, ifbody,
2855 build_empty_stmt (input_location));
2856 gfc_add_expr_to_block (&block2, tmp);
2860 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2862 if (HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2864 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2865 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2866 tmp = build3_v (COND_EXPR, tmp, ifbody,
2867 build_empty_stmt (input_location));
2868 gfc_add_expr_to_block (&block2, tmp);
2872 tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2873 type, arrayse.expr, limit);
2874 gfc_add_modify (&block2, limit, tmp);
2880 tree elsebody = gfc_finish_block (&block2);
2882 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2884 if (HONOR_NANS (DECL_MODE (limit))
2885 || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2887 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2888 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2889 ifbody = build3_v (COND_EXPR, tmp, ifbody,
2890 build_empty_stmt (input_location));
2894 tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2895 type, arrayse.expr, limit);
2896 ifbody = build2_v (MODIFY_EXPR, limit, tmp);
2898 tmp = build3_v (COND_EXPR, fast, ifbody, elsebody);
2899 gfc_add_expr_to_block (&block, tmp);
2902 gfc_add_block_to_block (&block, &block2);
2904 gfc_add_block_to_block (&block, &arrayse.post);
2906 tmp = gfc_finish_block (&block);
2908 /* We enclose the above in if (mask) {...}. */
2909 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2910 build_empty_stmt (input_location));
2911 gfc_add_expr_to_block (&body, tmp);
2915 gfc_trans_scalarized_loop_end (&loop, 0, &body);
2917 tmp = fold_build3 (COND_EXPR, type, nonempty, nan_cst, huge_cst);
2918 gfc_add_modify (&loop.code[0], limit, tmp);
2919 gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));
2921 gfc_start_block (&body);
2923 /* If we have a mask, only add this element if the mask is set. */
2926 gfc_init_se (&maskse, NULL);
2927 gfc_copy_loopinfo_to_se (&maskse, &loop);
2929 gfc_conv_expr_val (&maskse, maskexpr);
2930 gfc_add_block_to_block (&body, &maskse.pre);
2932 gfc_start_block (&block);
2935 gfc_init_block (&block);
2937 /* Compare with the current limit. */
2938 gfc_init_se (&arrayse, NULL);
2939 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2940 arrayse.ss = arrayss;
2941 gfc_conv_expr_val (&arrayse, arrayexpr);
2942 gfc_add_block_to_block (&block, &arrayse.pre);
2944 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2946 if (HONOR_NANS (DECL_MODE (limit))
2947 || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2949 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2950 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2951 tmp = build3_v (COND_EXPR, tmp, ifbody,
2952 build_empty_stmt (input_location));
2953 gfc_add_expr_to_block (&block, tmp);
2957 tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2958 type, arrayse.expr, limit);
2959 gfc_add_modify (&block, limit, tmp);
2962 gfc_add_block_to_block (&block, &arrayse.post);
2964 tmp = gfc_finish_block (&block);
2966 /* We enclose the above in if (mask) {...}. */
2967 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2968 build_empty_stmt (input_location));
2969 gfc_add_expr_to_block (&body, tmp);
2970 /* Avoid initializing loopvar[0] again, it should be left where
2971 it finished by the first loop. */
2972 loop.from[0] = loop.loopvar[0];
2974 gfc_trans_scalarizing_loops (&loop, &body);
2978 tmp = fold_build3 (COND_EXPR, type, nonempty, nan_cst, huge_cst);
2979 ifbody = build2_v (MODIFY_EXPR, limit, tmp);
2980 tmp = build3_v (COND_EXPR, fast, build_empty_stmt (input_location),
2982 gfc_add_expr_to_block (&loop.pre, tmp);
2984 else if (HONOR_INFINITIES (DECL_MODE (limit)) && !lab)
2986 tmp = fold_build3 (COND_EXPR, type, nonempty, limit, huge_cst);
2987 gfc_add_modify (&loop.pre, limit, tmp);
2990 /* For a scalar mask, enclose the loop in an if statement. */
2991 if (maskexpr && maskss == NULL)
2995 gfc_init_se (&maskse, NULL);
2996 gfc_conv_expr_val (&maskse, maskexpr);
2997 gfc_init_block (&block);
2998 gfc_add_block_to_block (&block, &loop.pre);
2999 gfc_add_block_to_block (&block, &loop.post);
3000 tmp = gfc_finish_block (&block);
3002 if (HONOR_INFINITIES (DECL_MODE (limit)))
3003 else_stmt = build2_v (MODIFY_EXPR, limit, huge_cst);
3005 else_stmt = build_empty_stmt (input_location);
3006 tmp = build3_v (COND_EXPR, maskse.expr, tmp, else_stmt);
3007 gfc_add_expr_to_block (&block, tmp);
3008 gfc_add_block_to_block (&se->pre, &block);
3012 gfc_add_block_to_block (&se->pre, &loop.pre);
3013 gfc_add_block_to_block (&se->pre, &loop.post);
3016 gfc_cleanup_loop (&loop);
3021 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
3023 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
3029 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3030 type = TREE_TYPE (args[0]);
3032 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
3033 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
3034 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
3035 build_int_cst (type, 0));
3036 type = gfc_typenode_for_spec (&expr->ts);
3037 se->expr = convert (type, tmp);
3040 /* Generate code to perform the specified operation. */
3042 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
3046 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3047 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
3052 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
3056 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3057 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
3060 /* Set or clear a single bit. */
3062 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
3069 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3070 type = TREE_TYPE (args[0]);
3072 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
3078 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
3080 se->expr = fold_build2 (op, type, args[0], tmp);
3083 /* Extract a sequence of bits.
3084 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
3086 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
3093 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3094 type = TREE_TYPE (args[0]);
3096 mask = build_int_cst (type, -1);
3097 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
3098 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
3100 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
3102 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
3105 /* RSHIFT (I, SHIFT) = I >> SHIFT
3106 LSHIFT (I, SHIFT) = I << SHIFT */
3108 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
3112 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3114 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
3115 TREE_TYPE (args[0]), args[0], args[1]);
3118 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
3120 : ((shift >= 0) ? i << shift : i >> -shift)
3121 where all shifts are logical shifts. */
3123 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
3135 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3136 type = TREE_TYPE (args[0]);
3137 utype = unsigned_type_for (type);
3139 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
3141 /* Left shift if positive. */
3142 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
3144 /* Right shift if negative.
3145 We convert to an unsigned type because we want a logical shift.
3146 The standard doesn't define the case of shifting negative
3147 numbers, and we try to be compatible with other compilers, most
3148 notably g77, here. */
3149 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
3150 convert (utype, args[0]), width));
3152 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
3153 build_int_cst (TREE_TYPE (args[1]), 0));
3154 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
3156 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3157 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3159 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
3160 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
3162 se->expr = fold_build3 (COND_EXPR, type, cond,
3163 build_int_cst (type, 0), tmp);
3167 /* Circular shift. AKA rotate or barrel shift. */
3170 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
3178 unsigned int num_args;
3180 num_args = gfc_intrinsic_argument_list_length (expr);
3181 args = (tree *) alloca (sizeof (tree) * num_args);
3183 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3187 /* Use a library function for the 3 parameter version. */
3188 tree int4type = gfc_get_int_type (4);
3190 type = TREE_TYPE (args[0]);
3191 /* We convert the first argument to at least 4 bytes, and
3192 convert back afterwards. This removes the need for library
3193 functions for all argument sizes, and function will be
3194 aligned to at least 32 bits, so there's no loss. */
3195 if (expr->ts.kind < 4)
3196 args[0] = convert (int4type, args[0]);
3198 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
3199 need loads of library functions. They cannot have values >
3200 BIT_SIZE (I) so the conversion is safe. */
3201 args[1] = convert (int4type, args[1]);
3202 args[2] = convert (int4type, args[2]);
3204 switch (expr->ts.kind)
3209 tmp = gfor_fndecl_math_ishftc4;
3212 tmp = gfor_fndecl_math_ishftc8;
3215 tmp = gfor_fndecl_math_ishftc16;
3220 se->expr = build_call_expr_loc (input_location,
3221 tmp, 3, args[0], args[1], args[2]);
3222 /* Convert the result back to the original type, if we extended
3223 the first argument's width above. */
3224 if (expr->ts.kind < 4)
3225 se->expr = convert (type, se->expr);
3229 type = TREE_TYPE (args[0]);
3231 /* Rotate left if positive. */
3232 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
3234 /* Rotate right if negative. */
3235 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
3236 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
3238 zero = build_int_cst (TREE_TYPE (args[1]), 0);
3239 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
3240 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
3242 /* Do nothing if shift == 0. */
3243 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
3244 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
3247 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
3248 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
3250 The conditional expression is necessary because the result of LEADZ(0)
3251 is defined, but the result of __builtin_clz(0) is undefined for most
3254 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
3255 difference in bit size between the argument of LEADZ and the C int. */
3258 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
3270 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3271 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3273 /* Which variant of __builtin_clz* should we call? */
3274 if (argsize <= INT_TYPE_SIZE)
3276 arg_type = unsigned_type_node;
3277 func = built_in_decls[BUILT_IN_CLZ];
3279 else if (argsize <= LONG_TYPE_SIZE)
3281 arg_type = long_unsigned_type_node;
3282 func = built_in_decls[BUILT_IN_CLZL];
3284 else if (argsize <= LONG_LONG_TYPE_SIZE)
3286 arg_type = long_long_unsigned_type_node;
3287 func = built_in_decls[BUILT_IN_CLZLL];
3291 gcc_assert (argsize == 128);
3292 arg_type = gfc_build_uint_type (argsize);
3293 func = gfor_fndecl_clz128;
3296 /* Convert the actual argument twice: first, to the unsigned type of the
3297 same size; then, to the proper argument type for the built-in
3298 function. But the return type is of the default INTEGER kind. */
3299 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3300 arg = fold_convert (arg_type, arg);
3301 result_type = gfc_get_int_type (gfc_default_integer_kind);
3303 /* Compute LEADZ for the case i .ne. 0. */
3304 s = TYPE_PRECISION (arg_type) - argsize;
3305 tmp = fold_convert (result_type, build_call_expr (func, 1, arg));
3306 leadz = fold_build2 (MINUS_EXPR, result_type,
3307 tmp, build_int_cst (result_type, s));
3309 /* Build BIT_SIZE. */
3310 bit_size = build_int_cst (result_type, argsize);
3312 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3313 arg, build_int_cst (arg_type, 0));
3314 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
3317 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
3319 The conditional expression is necessary because the result of TRAILZ(0)
3320 is defined, but the result of __builtin_ctz(0) is undefined for most
3324 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
3335 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3336 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3338 /* Which variant of __builtin_ctz* should we call? */
3339 if (argsize <= INT_TYPE_SIZE)
3341 arg_type = unsigned_type_node;
3342 func = built_in_decls[BUILT_IN_CTZ];
3344 else if (argsize <= LONG_TYPE_SIZE)
3346 arg_type = long_unsigned_type_node;
3347 func = built_in_decls[BUILT_IN_CTZL];
3349 else if (argsize <= LONG_LONG_TYPE_SIZE)
3351 arg_type = long_long_unsigned_type_node;
3352 func = built_in_decls[BUILT_IN_CTZLL];
3356 gcc_assert (argsize == 128);
3357 arg_type = gfc_build_uint_type (argsize);
3358 func = gfor_fndecl_ctz128;
3361 /* Convert the actual argument twice: first, to the unsigned type of the
3362 same size; then, to the proper argument type for the built-in
3363 function. But the return type is of the default INTEGER kind. */
3364 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3365 arg = fold_convert (arg_type, arg);
3366 result_type = gfc_get_int_type (gfc_default_integer_kind);
3368 /* Compute TRAILZ for the case i .ne. 0. */
3369 trailz = fold_convert (result_type, build_call_expr_loc (input_location,
3372 /* Build BIT_SIZE. */
3373 bit_size = build_int_cst (result_type, argsize);
3375 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3376 arg, build_int_cst (arg_type, 0));
3377 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
3380 /* Process an intrinsic with unspecified argument-types that has an optional
3381 argument (which could be of type character), e.g. EOSHIFT. For those, we
3382 need to append the string length of the optional argument if it is not
3383 present and the type is really character.
3384 primary specifies the position (starting at 1) of the non-optional argument
3385 specifying the type and optional gives the position of the optional
3386 argument in the arglist. */
3389 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
3390 unsigned primary, unsigned optional)
3392 gfc_actual_arglist* prim_arg;
3393 gfc_actual_arglist* opt_arg;
3395 gfc_actual_arglist* arg;
3399 /* Find the two arguments given as position. */
3403 for (arg = expr->value.function.actual; arg; arg = arg->next)
3407 if (cur_pos == primary)
3409 if (cur_pos == optional)
3412 if (cur_pos >= primary && cur_pos >= optional)
3415 gcc_assert (prim_arg);
3416 gcc_assert (prim_arg->expr);
3417 gcc_assert (opt_arg);
3419 /* If we do have type CHARACTER and the optional argument is really absent,
3420 append a dummy 0 as string length. */
3421 append_args = NULL_TREE;
3422 if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
3426 dummy = build_int_cst (gfc_charlen_type_node, 0);
3427 append_args = gfc_chainon_list (append_args, dummy);
3430 /* Build the call itself. */
3431 sym = gfc_get_symbol_for_expr (expr);
3432 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3438 /* The length of a character string. */
3440 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
3450 gcc_assert (!se->ss);
3452 arg = expr->value.function.actual->expr;
3454 type = gfc_typenode_for_spec (&expr->ts);
3455 switch (arg->expr_type)
3458 len = build_int_cst (NULL_TREE, arg->value.character.length);
3462 /* Obtain the string length from the function used by
3463 trans-array.c(gfc_trans_array_constructor). */
3465 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
3469 if (arg->ref == NULL
3470 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
3472 /* This doesn't catch all cases.
3473 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
3474 and the surrounding thread. */
3475 sym = arg->symtree->n.sym;
3476 decl = gfc_get_symbol_decl (sym);
3477 if (decl == current_function_decl && sym->attr.function
3478 && (sym->result == sym))
3479 decl = gfc_get_fake_result_decl (sym, 0);
3481 len = sym->ts.u.cl->backend_decl;
3486 /* Otherwise fall through. */
3489 /* Anybody stupid enough to do this deserves inefficient code. */
3490 ss = gfc_walk_expr (arg);
3491 gfc_init_se (&argse, se);
3492 if (ss == gfc_ss_terminator)
3493 gfc_conv_expr (&argse, arg);
3495 gfc_conv_expr_descriptor (&argse, arg, ss);
3496 gfc_add_block_to_block (&se->pre, &argse.pre);
3497 gfc_add_block_to_block (&se->post, &argse.post);
3498 len = argse.string_length;
3501 se->expr = convert (type, len);
3504 /* The length of a character string not including trailing blanks. */
3506 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
3508 int kind = expr->value.function.actual->expr->ts.kind;
3509 tree args[2], type, fndecl;
3511 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3512 type = gfc_typenode_for_spec (&expr->ts);
3515 fndecl = gfor_fndecl_string_len_trim;
3517 fndecl = gfor_fndecl_string_len_trim_char4;
3521 se->expr = build_call_expr_loc (input_location,
3522 fndecl, 2, args[0], args[1]);
3523 se->expr = convert (type, se->expr);
3527 /* Returns the starting position of a substring within a string. */
3530 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
3533 tree logical4_type_node = gfc_get_logical_type (4);
3537 unsigned int num_args;
3539 args = (tree *) alloca (sizeof (tree) * 5);
3541 /* Get number of arguments; characters count double due to the
3542 string length argument. Kind= is not passed to the library
3543 and thus ignored. */
3544 if (expr->value.function.actual->next->next->expr == NULL)
3549 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3550 type = gfc_typenode_for_spec (&expr->ts);
3553 args[4] = build_int_cst (logical4_type_node, 0);
3555 args[4] = convert (logical4_type_node, args[4]);
3557 fndecl = build_addr (function, current_function_decl);
3558 se->expr = build_call_array_loc (input_location,
3559 TREE_TYPE (TREE_TYPE (function)), fndecl,
3561 se->expr = convert (type, se->expr);
3565 /* The ascii value for a single character. */
3567 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
3569 tree args[2], type, pchartype;
3571 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3572 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
3573 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
3574 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
3575 type = gfc_typenode_for_spec (&expr->ts);
3577 se->expr = build_fold_indirect_ref_loc (input_location,
3579 se->expr = convert (type, se->expr);
3583 /* Intrinsic ISNAN calls __builtin_isnan. */
3586 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
3590 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3591 se->expr = build_call_expr_loc (input_location,
3592 built_in_decls[BUILT_IN_ISNAN], 1, arg);
3593 STRIP_TYPE_NOPS (se->expr);
3594 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3598 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
3599 their argument against a constant integer value. */
3602 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
3606 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3607 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
3608 arg, build_int_cst (TREE_TYPE (arg), value));
3613 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
3616 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
3624 unsigned int num_args;
3626 num_args = gfc_intrinsic_argument_list_length (expr);
3627 args = (tree *) alloca (sizeof (tree) * num_args);
3629 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3630 if (expr->ts.type != BT_CHARACTER)
3638 /* We do the same as in the non-character case, but the argument
3639 list is different because of the string length arguments. We
3640 also have to set the string length for the result. */
3647 gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
3649 se->string_length = len;
3651 type = TREE_TYPE (tsource);
3652 se->expr = fold_build3 (COND_EXPR, type, mask, tsource,
3653 fold_convert (type, fsource));
3657 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
3659 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
3661 tree arg, type, tmp;
3664 switch (expr->ts.kind)
3667 frexp = BUILT_IN_FREXPF;
3670 frexp = BUILT_IN_FREXP;
3674 frexp = BUILT_IN_FREXPL;
3680 type = gfc_typenode_for_spec (&expr->ts);
3681 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3682 tmp = gfc_create_var (integer_type_node, NULL);
3683 se->expr = build_call_expr_loc (input_location,
3684 built_in_decls[frexp], 2,
3685 fold_convert (type, arg),
3686 gfc_build_addr_expr (NULL_TREE, tmp));
3687 se->expr = fold_convert (type, se->expr);
3691 /* NEAREST (s, dir) is translated into
3692 tmp = copysign (HUGE_VAL, dir);
3693 return nextafter (s, tmp);
3696 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
3698 tree args[2], type, tmp;
3699 int nextafter, copysign, huge_val;
3701 switch (expr->ts.kind)
3704 nextafter = BUILT_IN_NEXTAFTERF;
3705 copysign = BUILT_IN_COPYSIGNF;
3706 huge_val = BUILT_IN_HUGE_VALF;
3709 nextafter = BUILT_IN_NEXTAFTER;
3710 copysign = BUILT_IN_COPYSIGN;
3711 huge_val = BUILT_IN_HUGE_VAL;
3715 nextafter = BUILT_IN_NEXTAFTERL;
3716 copysign = BUILT_IN_COPYSIGNL;
3717 huge_val = BUILT_IN_HUGE_VALL;
3723 type = gfc_typenode_for_spec (&expr->ts);
3724 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3725 tmp = build_call_expr_loc (input_location,
3726 built_in_decls[copysign], 2,
3727 build_call_expr_loc (input_location,
3728 built_in_decls[huge_val], 0),
3729 fold_convert (type, args[1]));
3730 se->expr = build_call_expr_loc (input_location,
3731 built_in_decls[nextafter], 2,
3732 fold_convert (type, args[0]), tmp);
3733 se->expr = fold_convert (type, se->expr);
3737 /* SPACING (s) is translated into
3745 e = MAX_EXPR (e, emin);
3746 res = scalbn (1., e);
3750 where prec is the precision of s, gfc_real_kinds[k].digits,
3751 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
3752 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
3755 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
3757 tree arg, type, prec, emin, tiny, res, e;
3759 int frexp, scalbn, k;
3762 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3763 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
3764 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
3765 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
3767 switch (expr->ts.kind)
3770 frexp = BUILT_IN_FREXPF;
3771 scalbn = BUILT_IN_SCALBNF;
3774 frexp = BUILT_IN_FREXP;
3775 scalbn = BUILT_IN_SCALBN;
3779 frexp = BUILT_IN_FREXPL;
3780 scalbn = BUILT_IN_SCALBNL;
3786 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3787 arg = gfc_evaluate_now (arg, &se->pre);
3789 type = gfc_typenode_for_spec (&expr->ts);
3790 e = gfc_create_var (integer_type_node, NULL);
3791 res = gfc_create_var (type, NULL);
3794 /* Build the block for s /= 0. */
3795 gfc_start_block (&block);
3796 tmp = build_call_expr_loc (input_location,
3797 built_in_decls[frexp], 2, arg,
3798 gfc_build_addr_expr (NULL_TREE, e));
3799 gfc_add_expr_to_block (&block, tmp);
3801 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3802 gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3805 tmp = build_call_expr_loc (input_location,
3806 built_in_decls[scalbn], 2,
3807 build_real_from_int_cst (type, integer_one_node), e);
3808 gfc_add_modify (&block, res, tmp);
3810 /* Finish by building the IF statement. */
3811 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3812 build_real_from_int_cst (type, integer_zero_node));
3813 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3814 gfc_finish_block (&block));
3816 gfc_add_expr_to_block (&se->pre, tmp);
3821 /* RRSPACING (s) is translated into
3828 x = scalbn (x, precision - e);
3832 where precision is gfc_real_kinds[k].digits. */
3835 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3837 tree arg, type, e, x, cond, stmt, tmp;
3838 int frexp, scalbn, fabs, prec, k;
3841 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3842 prec = gfc_real_kinds[k].digits;
3843 switch (expr->ts.kind)
3846 frexp = BUILT_IN_FREXPF;
3847 scalbn = BUILT_IN_SCALBNF;
3848 fabs = BUILT_IN_FABSF;
3851 frexp = BUILT_IN_FREXP;
3852 scalbn = BUILT_IN_SCALBN;
3853 fabs = BUILT_IN_FABS;
3857 frexp = BUILT_IN_FREXPL;
3858 scalbn = BUILT_IN_SCALBNL;
3859 fabs = BUILT_IN_FABSL;
3865 type = gfc_typenode_for_spec (&expr->ts);
3866 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3867 arg = gfc_evaluate_now (arg, &se->pre);
3869 e = gfc_create_var (integer_type_node, NULL);
3870 x = gfc_create_var (type, NULL);
3871 gfc_add_modify (&se->pre, x,
3872 build_call_expr_loc (input_location,
3873 built_in_decls[fabs], 1, arg));
3876 gfc_start_block (&block);
3877 tmp = build_call_expr_loc (input_location,
3878 built_in_decls[frexp], 2, arg,
3879 gfc_build_addr_expr (NULL_TREE, e));
3880 gfc_add_expr_to_block (&block, tmp);
3882 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3883 build_int_cst (NULL_TREE, prec), e);
3884 tmp = build_call_expr_loc (input_location,
3885 built_in_decls[scalbn], 2, x, tmp);
3886 gfc_add_modify (&block, x, tmp);
3887 stmt = gfc_finish_block (&block);
3889 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3890 build_real_from_int_cst (type, integer_zero_node));
3891 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
3892 gfc_add_expr_to_block (&se->pre, tmp);
3894 se->expr = fold_convert (type, x);
3898 /* SCALE (s, i) is translated into scalbn (s, i). */
3900 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3905 switch (expr->ts.kind)
3908 scalbn = BUILT_IN_SCALBNF;
3911 scalbn = BUILT_IN_SCALBN;
3915 scalbn = BUILT_IN_SCALBNL;
3921 type = gfc_typenode_for_spec (&expr->ts);
3922 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3923 se->expr = build_call_expr_loc (input_location,
3924 built_in_decls[scalbn], 2,
3925 fold_convert (type, args[0]),
3926 fold_convert (integer_type_node, args[1]));
3927 se->expr = fold_convert (type, se->expr);
3931 /* SET_EXPONENT (s, i) is translated into
3932 scalbn (frexp (s, &dummy_int), i). */
3934 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3936 tree args[2], type, tmp;
3939 switch (expr->ts.kind)
3942 frexp = BUILT_IN_FREXPF;
3943 scalbn = BUILT_IN_SCALBNF;
3946 frexp = BUILT_IN_FREXP;
3947 scalbn = BUILT_IN_SCALBN;
3951 frexp = BUILT_IN_FREXPL;
3952 scalbn = BUILT_IN_SCALBNL;
3958 type = gfc_typenode_for_spec (&expr->ts);
3959 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3961 tmp = gfc_create_var (integer_type_node, NULL);
3962 tmp = build_call_expr_loc (input_location,
3963 built_in_decls[frexp], 2,
3964 fold_convert (type, args[0]),
3965 gfc_build_addr_expr (NULL_TREE, tmp));
3966 se->expr = build_call_expr_loc (input_location,
3967 built_in_decls[scalbn], 2, tmp,
3968 fold_convert (integer_type_node, args[1]));
3969 se->expr = fold_convert (type, se->expr);
3974 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3976 gfc_actual_arglist *actual;
3984 gfc_init_se (&argse, NULL);
3985 actual = expr->value.function.actual;
3987 ss = gfc_walk_expr (actual->expr);
3988 gcc_assert (ss != gfc_ss_terminator);
3989 argse.want_pointer = 1;
3990 argse.data_not_needed = 1;
3991 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3992 gfc_add_block_to_block (&se->pre, &argse.pre);
3993 gfc_add_block_to_block (&se->post, &argse.post);
3994 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3996 /* Build the call to size0. */
3997 fncall0 = build_call_expr_loc (input_location,
3998 gfor_fndecl_size0, 1, arg1);
4000 actual = actual->next;
4004 gfc_init_se (&argse, NULL);
4005 gfc_conv_expr_type (&argse, actual->expr,
4006 gfc_array_index_type);
4007 gfc_add_block_to_block (&se->pre, &argse.pre);
4009 /* Unusually, for an intrinsic, size does not exclude
4010 an optional arg2, so we must test for it. */
4011 if (actual->expr->expr_type == EXPR_VARIABLE
4012 && actual->expr->symtree->n.sym->attr.dummy
4013 && actual->expr->symtree->n.sym->attr.optional)
4016 /* Build the call to size1. */
4017 fncall1 = build_call_expr_loc (input_location,
4018 gfor_fndecl_size1, 2,
4021 gfc_init_se (&argse, NULL);
4022 argse.want_pointer = 1;
4023 argse.data_not_needed = 1;
4024 gfc_conv_expr (&argse, actual->expr);
4025 gfc_add_block_to_block (&se->pre, &argse.pre);
4026 tmp = fold_build2 (NE_EXPR, boolean_type_node,
4027 argse.expr, null_pointer_node);
4028 tmp = gfc_evaluate_now (tmp, &se->pre);
4029 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
4030 tmp, fncall1, fncall0);
4034 se->expr = NULL_TREE;
4035 argse.expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4036 argse.expr, gfc_index_one_node);
4039 else if (expr->value.function.actual->expr->rank == 1)
4041 argse.expr = gfc_index_zero_node;
4042 se->expr = NULL_TREE;
4047 if (se->expr == NULL_TREE)
4049 tree ubound, lbound;
4051 arg1 = build_fold_indirect_ref_loc (input_location,
4053 ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
4054 lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
4055 se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4057 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
4058 gfc_index_one_node);
4059 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
4060 gfc_index_zero_node);
4063 type = gfc_typenode_for_spec (&expr->ts);
4064 se->expr = convert (type, se->expr);
4068 /* Helper function to compute the size of a character variable,
4069 excluding the terminating null characters. The result has
4070 gfc_array_index_type type. */
4073 size_of_string_in_bytes (int kind, tree string_length)
4076 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
4078 bytesize = build_int_cst (gfc_array_index_type,
4079 gfc_character_kinds[i].bit_size / 8);
4081 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
4082 fold_convert (gfc_array_index_type, string_length));
4087 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
4099 arg = expr->value.function.actual->expr;
4101 gfc_init_se (&argse, NULL);
4102 ss = gfc_walk_expr (arg);
4104 if (ss == gfc_ss_terminator)
4106 gfc_conv_expr_reference (&argse, arg);
4108 type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4111 /* Obtain the source word length. */
4112 if (arg->ts.type == BT_CHARACTER)
4113 se->expr = size_of_string_in_bytes (arg->ts.kind,
4114 argse.string_length);
4116 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
4120 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
4121 argse.want_pointer = 0;
4122 gfc_conv_expr_descriptor (&argse, arg, ss);
4123 type = gfc_get_element_type (TREE_TYPE (argse.expr));
4125 /* Obtain the argument's word length. */
4126 if (arg->ts.type == BT_CHARACTER)
4127 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
4129 tmp = fold_convert (gfc_array_index_type,
4130 size_in_bytes (type));
4131 gfc_add_modify (&argse.pre, source_bytes, tmp);
4133 /* Obtain the size of the array in bytes. */
4134 for (n = 0; n < arg->rank; n++)
4137 idx = gfc_rank_cst[n];
4138 lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
4139 upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
4140 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4142 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4143 tmp, gfc_index_one_node);
4144 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4146 gfc_add_modify (&argse.pre, source_bytes, tmp);
4148 se->expr = source_bytes;
4151 gfc_add_block_to_block (&se->pre, &argse.pre);
4155 /* Intrinsic string comparison functions. */
4158 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
4162 gfc_conv_intrinsic_function_args (se, expr, args, 4);
4165 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
4166 expr->value.function.actual->expr->ts.kind);
4167 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
4168 build_int_cst (TREE_TYPE (se->expr), 0));
4171 /* Generate a call to the adjustl/adjustr library function. */
4173 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
4181 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
4184 type = TREE_TYPE (args[2]);
4185 var = gfc_conv_string_tmp (se, type, len);
4188 tmp = build_call_expr_loc (input_location,
4189 fndecl, 3, args[0], args[1], args[2]);
4190 gfc_add_expr_to_block (&se->pre, tmp);
4192 se->string_length = len;
4196 /* Generate code for the TRANSFER intrinsic:
4198 DEST = TRANSFER (SOURCE, MOLD)
4200 typeof<DEST> = typeof<MOLD>
4205 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
4207 typeof<DEST> = typeof<MOLD>
4209 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
4210 sizeof (DEST(0) * SIZE). */
4212 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
4228 gfc_actual_arglist *arg;
4238 info = &se->ss->data.info;
4240 /* Convert SOURCE. The output from this stage is:-
4241 source_bytes = length of the source in bytes
4242 source = pointer to the source data. */
4243 arg = expr->value.function.actual;
4245 /* Ensure double transfer through LOGICAL preserves all
4247 if (arg->expr->expr_type == EXPR_FUNCTION
4248 && arg->expr->value.function.esym == NULL
4249 && arg->expr->value.function.isym != NULL
4250 && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
4251 && arg->expr->ts.type == BT_LOGICAL
4252 && expr->ts.type != arg->expr->ts.type)
4253 arg->expr->value.function.name = "__transfer_in_transfer";
4255 gfc_init_se (&argse, NULL);
4256 ss = gfc_walk_expr (arg->expr);
4258 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
4260 /* Obtain the pointer to source and the length of source in bytes. */
4261 if (ss == gfc_ss_terminator)
4263 gfc_conv_expr_reference (&argse, arg->expr);
4264 source = argse.expr;
4266 source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4269 /* Obtain the source word length. */
4270 if (arg->expr->ts.type == BT_CHARACTER)
4271 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4272 argse.string_length);
4274 tmp = fold_convert (gfc_array_index_type,
4275 size_in_bytes (source_type));
4279 argse.want_pointer = 0;
4280 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4281 source = gfc_conv_descriptor_data_get (argse.expr);
4282 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4284 /* Repack the source if not a full variable array. */
4285 if (arg->expr->expr_type == EXPR_VARIABLE
4286 && arg->expr->ref->u.ar.type != AR_FULL)
4288 tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
4290 if (gfc_option.warn_array_temp)
4291 gfc_warning ("Creating array temporary at %L", &expr->where);
4293 source = build_call_expr_loc (input_location,
4294 gfor_fndecl_in_pack, 1, tmp);
4295 source = gfc_evaluate_now (source, &argse.pre);
4297 /* Free the temporary. */
4298 gfc_start_block (&block);
4299 tmp = gfc_call_free (convert (pvoid_type_node, source));
4300 gfc_add_expr_to_block (&block, tmp);
4301 stmt = gfc_finish_block (&block);
4303 /* Clean up if it was repacked. */
4304 gfc_init_block (&block);
4305 tmp = gfc_conv_array_data (argse.expr);
4306 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
4307 tmp = build3_v (COND_EXPR, tmp, stmt,
4308 build_empty_stmt (input_location));
4309 gfc_add_expr_to_block (&block, tmp);
4310 gfc_add_block_to_block (&block, &se->post);
4311 gfc_init_block (&se->post);
4312 gfc_add_block_to_block (&se->post, &block);
4315 /* Obtain the source word length. */
4316 if (arg->expr->ts.type == BT_CHARACTER)
4317 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4318 argse.string_length);
4320 tmp = fold_convert (gfc_array_index_type,
4321 size_in_bytes (source_type));
4323 /* Obtain the size of the array in bytes. */
4324 extent = gfc_create_var (gfc_array_index_type, NULL);
4325 for (n = 0; n < arg->expr->rank; n++)
4328 idx = gfc_rank_cst[n];
4329 gfc_add_modify (&argse.pre, source_bytes, tmp);
4330 lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
4331 upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
4332 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4334 gfc_add_modify (&argse.pre, extent, tmp);
4335 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4336 extent, gfc_index_one_node);
4337 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4342 gfc_add_modify (&argse.pre, source_bytes, tmp);
4343 gfc_add_block_to_block (&se->pre, &argse.pre);
4344 gfc_add_block_to_block (&se->post, &argse.post);
4346 /* Now convert MOLD. The outputs are:
4347 mold_type = the TREE type of MOLD
4348 dest_word_len = destination word length in bytes. */
4351 gfc_init_se (&argse, NULL);
4352 ss = gfc_walk_expr (arg->expr);
4354 scalar_mold = arg->expr->rank == 0;
4356 if (ss == gfc_ss_terminator)
4358 gfc_conv_expr_reference (&argse, arg->expr);
4359 mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4364 gfc_init_se (&argse, NULL);
4365 argse.want_pointer = 0;
4366 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4367 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4370 gfc_add_block_to_block (&se->pre, &argse.pre);
4371 gfc_add_block_to_block (&se->post, &argse.post);
4373 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
4375 /* If this TRANSFER is nested in another TRANSFER, use a type
4376 that preserves all bits. */
4377 if (arg->expr->ts.type == BT_LOGICAL)
4378 mold_type = gfc_get_int_type (arg->expr->ts.kind);
4381 if (arg->expr->ts.type == BT_CHARACTER)
4383 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
4384 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
4387 tmp = fold_convert (gfc_array_index_type,
4388 size_in_bytes (mold_type));
4390 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
4391 gfc_add_modify (&se->pre, dest_word_len, tmp);
4393 /* Finally convert SIZE, if it is present. */
4395 size_words = gfc_create_var (gfc_array_index_type, NULL);
4399 gfc_init_se (&argse, NULL);
4400 gfc_conv_expr_reference (&argse, arg->expr);
4401 tmp = convert (gfc_array_index_type,
4402 build_fold_indirect_ref_loc (input_location,
4404 gfc_add_block_to_block (&se->pre, &argse.pre);
4405 gfc_add_block_to_block (&se->post, &argse.post);
4410 /* Separate array and scalar results. */
4411 if (scalar_mold && tmp == NULL_TREE)
4412 goto scalar_transfer;
4414 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
4415 if (tmp != NULL_TREE)
4416 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4417 tmp, dest_word_len);
4421 gfc_add_modify (&se->pre, size_bytes, tmp);
4422 gfc_add_modify (&se->pre, size_words,
4423 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
4424 size_bytes, dest_word_len));
4426 /* Evaluate the bounds of the result. If the loop range exists, we have
4427 to check if it is too large. If so, we modify loop->to be consistent
4428 with min(size, size(source)). Otherwise, size is made consistent with
4429 the loop range, so that the right number of bytes is transferred.*/
4430 n = se->loop->order[0];
4431 if (se->loop->to[n] != NULL_TREE)
4433 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4434 se->loop->to[n], se->loop->from[n]);
4435 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4436 tmp, gfc_index_one_node);
4437 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
4439 gfc_add_modify (&se->pre, size_words, tmp);
4440 gfc_add_modify (&se->pre, size_bytes,
4441 fold_build2 (MULT_EXPR, gfc_array_index_type,
4442 size_words, dest_word_len));
4443 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4444 size_words, se->loop->from[n]);
4445 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4446 upper, gfc_index_one_node);
4450 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4451 size_words, gfc_index_one_node);
4452 se->loop->from[n] = gfc_index_zero_node;
4455 se->loop->to[n] = upper;
4457 /* Build a destination descriptor, using the pointer, source, as the
4459 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
4460 info, mold_type, NULL_TREE, false, true, false,
4463 /* Cast the pointer to the result. */
4464 tmp = gfc_conv_descriptor_data_get (info->descriptor);
4465 tmp = fold_convert (pvoid_type_node, tmp);
4467 /* Use memcpy to do the transfer. */
4468 tmp = build_call_expr_loc (input_location,
4469 built_in_decls[BUILT_IN_MEMCPY],
4472 fold_convert (pvoid_type_node, source),
4473 fold_build2 (MIN_EXPR, gfc_array_index_type,
4474 size_bytes, source_bytes));
4475 gfc_add_expr_to_block (&se->pre, tmp);
4477 se->expr = info->descriptor;
4478 if (expr->ts.type == BT_CHARACTER)
4479 se->string_length = dest_word_len;
4483 /* Deal with scalar results. */
4485 extent = fold_build2 (MIN_EXPR, gfc_array_index_type,
4486 dest_word_len, source_bytes);
4487 extent = fold_build2 (MAX_EXPR, gfc_array_index_type,
4488 extent, gfc_index_zero_node);
4490 if (expr->ts.type == BT_CHARACTER)
4495 ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
4496 tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
4499 /* If source is longer than the destination, use a pointer to
4500 the source directly. */
4501 gfc_init_block (&block);
4502 gfc_add_modify (&block, tmpdecl, ptr);
4503 direct = gfc_finish_block (&block);
4505 /* Otherwise, allocate a string with the length of the destination
4506 and copy the source into it. */
4507 gfc_init_block (&block);
4508 tmp = gfc_get_pchar_type (expr->ts.kind);
4509 tmp = gfc_call_malloc (&block, tmp, dest_word_len);
4510 gfc_add_modify (&block, tmpdecl,
4511 fold_convert (TREE_TYPE (ptr), tmp));
4512 tmp = build_call_expr_loc (input_location,
4513 built_in_decls[BUILT_IN_MEMCPY], 3,
4514 fold_convert (pvoid_type_node, tmpdecl),
4515 fold_convert (pvoid_type_node, ptr),
4517 gfc_add_expr_to_block (&block, tmp);
4518 indirect = gfc_finish_block (&block);
4520 /* Wrap it up with the condition. */
4521 tmp = fold_build2 (LE_EXPR, boolean_type_node,
4522 dest_word_len, source_bytes);
4523 tmp = build3_v (COND_EXPR, tmp, direct, indirect);
4524 gfc_add_expr_to_block (&se->pre, tmp);
4527 se->string_length = dest_word_len;
4531 tmpdecl = gfc_create_var (mold_type, "transfer");
4533 ptr = convert (build_pointer_type (mold_type), source);
4535 /* Use memcpy to do the transfer. */
4536 tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
4537 tmp = build_call_expr_loc (input_location,
4538 built_in_decls[BUILT_IN_MEMCPY], 3,
4539 fold_convert (pvoid_type_node, tmp),
4540 fold_convert (pvoid_type_node, ptr),
4542 gfc_add_expr_to_block (&se->pre, tmp);
4549 /* Generate code for the ALLOCATED intrinsic.
4550 Generate inline code that directly check the address of the argument. */
4553 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
4555 gfc_actual_arglist *arg1;
4560 gfc_init_se (&arg1se, NULL);
4561 arg1 = expr->value.function.actual;
4562 ss1 = gfc_walk_expr (arg1->expr);
4564 if (ss1 == gfc_ss_terminator)
4566 /* Allocatable scalar. */
4567 arg1se.want_pointer = 1;
4568 gfc_conv_expr (&arg1se, arg1->expr);
4573 /* Allocatable array. */
4574 arg1se.descriptor_only = 1;
4575 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4576 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
4579 tmp = fold_build2 (NE_EXPR, boolean_type_node,
4580 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
4581 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
4585 /* Generate code for the ASSOCIATED intrinsic.
4586 If both POINTER and TARGET are arrays, generate a call to library function
4587 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
4588 In other cases, generate inline code that directly compare the address of
4589 POINTER with the address of TARGET. */
4592 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
4594 gfc_actual_arglist *arg1;
4595 gfc_actual_arglist *arg2;
4600 tree nonzero_charlen;
4601 tree nonzero_arraylen;
4604 gfc_init_se (&arg1se, NULL);
4605 gfc_init_se (&arg2se, NULL);
4606 arg1 = expr->value.function.actual;
4607 if (arg1->expr->ts.type == BT_CLASS)
4608 gfc_add_component_ref (arg1->expr, "$data");
4610 ss1 = gfc_walk_expr (arg1->expr);
4614 /* No optional target. */
4615 if (ss1 == gfc_ss_terminator)
4617 /* A pointer to a scalar. */
4618 arg1se.want_pointer = 1;
4619 gfc_conv_expr (&arg1se, arg1->expr);
4624 /* A pointer to an array. */
4625 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4626 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
4628 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4629 gfc_add_block_to_block (&se->post, &arg1se.post);
4630 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
4631 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
4636 /* An optional target. */
4637 ss2 = gfc_walk_expr (arg2->expr);
4639 nonzero_charlen = NULL_TREE;
4640 if (arg1->expr->ts.type == BT_CHARACTER)
4641 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
4642 arg1->expr->ts.u.cl->backend_decl,
4645 if (ss1 == gfc_ss_terminator)
4647 /* A pointer to a scalar. */
4648 gcc_assert (ss2 == gfc_ss_terminator);
4649 arg1se.want_pointer = 1;
4650 gfc_conv_expr (&arg1se, arg1->expr);
4651 arg2se.want_pointer = 1;
4652 gfc_conv_expr (&arg2se, arg2->expr);
4653 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4654 gfc_add_block_to_block (&se->post, &arg1se.post);
4655 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4656 arg1se.expr, arg2se.expr);
4657 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
4658 arg1se.expr, null_pointer_node);
4659 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4664 /* An array pointer of zero length is not associated if target is
4666 arg1se.descriptor_only = 1;
4667 gfc_conv_expr_lhs (&arg1se, arg1->expr);
4668 tmp = gfc_conv_descriptor_stride_get (arg1se.expr,
4669 gfc_rank_cst[arg1->expr->rank - 1]);
4670 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
4671 build_int_cst (TREE_TYPE (tmp), 0));
4673 /* A pointer to an array, call library function _gfor_associated. */
4674 gcc_assert (ss2 != gfc_ss_terminator);
4675 arg1se.want_pointer = 1;
4676 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4678 arg2se.want_pointer = 1;
4679 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
4680 gfc_add_block_to_block (&se->pre, &arg2se.pre);
4681 gfc_add_block_to_block (&se->post, &arg2se.post);
4682 se->expr = build_call_expr_loc (input_location,
4683 gfor_fndecl_associated, 2,
4684 arg1se.expr, arg2se.expr);
4685 se->expr = convert (boolean_type_node, se->expr);
4686 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4687 se->expr, nonzero_arraylen);
4690 /* If target is present zero character length pointers cannot
4692 if (nonzero_charlen != NULL_TREE)
4693 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4694 se->expr, nonzero_charlen);
4697 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4701 /* Generate code for the SAME_TYPE_AS intrinsic.
4702 Generate inline code that directly checks the vindices. */
4705 gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
4711 gfc_init_se (&se1, NULL);
4712 gfc_init_se (&se2, NULL);
4714 a = expr->value.function.actual->expr;
4715 b = expr->value.function.actual->next->expr;
4717 if (a->ts.type == BT_CLASS)
4718 gfc_add_component_ref (a, "$vindex");
4719 else if (a->ts.type == BT_DERIVED)
4720 a = gfc_int_expr (a->ts.u.derived->vindex);
4722 if (b->ts.type == BT_CLASS)
4723 gfc_add_component_ref (b, "$vindex");
4724 else if (b->ts.type == BT_DERIVED)
4725 b = gfc_int_expr (b->ts.u.derived->vindex);
4727 gfc_conv_expr (&se1, a);
4728 gfc_conv_expr (&se2, b);
4730 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4731 se1.expr, fold_convert (TREE_TYPE (se1.expr), se2.expr));
4732 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
4736 /* Generate code for the EXTENDS_TYPE_OF intrinsic. */
4739 gfc_conv_extends_type_of (gfc_se *se, gfc_expr *expr)
4742 /* TODO: Implement EXTENDS_TYPE_OF. */
4743 gfc_error ("Intrinsic EXTENDS_TYPE_OF at %L not yet implemented",
4745 /* Just return 'false' for now. */
4746 e = gfc_logical_expr (false, &expr->where);
4747 gfc_conv_expr (se, e);
4751 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
4754 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
4758 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4759 se->expr = build_call_expr_loc (input_location,
4760 gfor_fndecl_sc_kind, 2, args[0], args[1]);
4761 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4765 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
4768 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
4772 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4774 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
4775 type = gfc_get_int_type (4);
4776 arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
4778 /* Convert it to the required type. */
4779 type = gfc_typenode_for_spec (&expr->ts);
4780 se->expr = build_call_expr_loc (input_location,
4781 gfor_fndecl_si_kind, 1, arg);
4782 se->expr = fold_convert (type, se->expr);
4786 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
4789 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
4791 gfc_actual_arglist *actual;
4796 for (actual = expr->value.function.actual; actual; actual = actual->next)
4798 gfc_init_se (&argse, se);
4800 /* Pass a NULL pointer for an absent arg. */
4801 if (actual->expr == NULL)
4802 argse.expr = null_pointer_node;
4808 if (actual->expr->ts.kind != gfc_c_int_kind)
4810 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
4811 ts.type = BT_INTEGER;
4812 ts.kind = gfc_c_int_kind;
4813 gfc_convert_type (actual->expr, &ts, 2);
4815 gfc_conv_expr_reference (&argse, actual->expr);
4818 gfc_add_block_to_block (&se->pre, &argse.pre);
4819 gfc_add_block_to_block (&se->post, &argse.post);
4820 args = gfc_chainon_list (args, argse.expr);
4823 /* Convert it to the required type. */
4824 type = gfc_typenode_for_spec (&expr->ts);
4825 se->expr = build_function_call_expr (input_location,
4826 gfor_fndecl_sr_kind, args);
4827 se->expr = fold_convert (type, se->expr);
4831 /* Generate code for TRIM (A) intrinsic function. */
4834 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
4844 unsigned int num_args;
4846 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
4847 args = (tree *) alloca (sizeof (tree) * num_args);
4849 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
4850 addr = gfc_build_addr_expr (ppvoid_type_node, var);
4851 len = gfc_create_var (gfc_get_int_type (4), "len");
4853 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
4854 args[0] = gfc_build_addr_expr (NULL_TREE, len);
4857 if (expr->ts.kind == 1)
4858 function = gfor_fndecl_string_trim;
4859 else if (expr->ts.kind == 4)
4860 function = gfor_fndecl_string_trim_char4;
4864 fndecl = build_addr (function, current_function_decl);
4865 tmp = build_call_array_loc (input_location,
4866 TREE_TYPE (TREE_TYPE (function)), fndecl,
4868 gfc_add_expr_to_block (&se->pre, tmp);
4870 /* Free the temporary afterwards, if necessary. */
4871 cond = fold_build2 (GT_EXPR, boolean_type_node,
4872 len, build_int_cst (TREE_TYPE (len), 0));
4873 tmp = gfc_call_free (var);
4874 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
4875 gfc_add_expr_to_block (&se->post, tmp);
4878 se->string_length = len;
4882 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
4885 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
4887 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
4888 tree type, cond, tmp, count, exit_label, n, max, largest;
4890 stmtblock_t block, body;
4893 /* We store in charsize the size of a character. */
4894 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
4895 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
4897 /* Get the arguments. */
4898 gfc_conv_intrinsic_function_args (se, expr, args, 3);
4899 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
4901 ncopies = gfc_evaluate_now (args[2], &se->pre);
4902 ncopies_type = TREE_TYPE (ncopies);
4904 /* Check that NCOPIES is not negative. */
4905 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
4906 build_int_cst (ncopies_type, 0));
4907 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4908 "Argument NCOPIES of REPEAT intrinsic is negative "
4909 "(its value is %lld)",
4910 fold_convert (long_integer_type_node, ncopies));
4912 /* If the source length is zero, any non negative value of NCOPIES
4913 is valid, and nothing happens. */
4914 n = gfc_create_var (ncopies_type, "ncopies");
4915 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4916 build_int_cst (size_type_node, 0));
4917 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
4918 build_int_cst (ncopies_type, 0), ncopies);
4919 gfc_add_modify (&se->pre, n, tmp);
4922 /* Check that ncopies is not too large: ncopies should be less than
4923 (or equal to) MAX / slen, where MAX is the maximal integer of
4924 the gfc_charlen_type_node type. If slen == 0, we need a special
4925 case to avoid the division by zero. */
4926 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
4927 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
4928 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
4929 fold_convert (size_type_node, max), slen);
4930 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
4931 ? size_type_node : ncopies_type;
4932 cond = fold_build2 (GT_EXPR, boolean_type_node,
4933 fold_convert (largest, ncopies),
4934 fold_convert (largest, max));
4935 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4936 build_int_cst (size_type_node, 0));
4937 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
4939 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4940 "Argument NCOPIES of REPEAT intrinsic is too large");
4942 /* Compute the destination length. */
4943 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4944 fold_convert (gfc_charlen_type_node, slen),
4945 fold_convert (gfc_charlen_type_node, ncopies));
4946 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
4947 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4949 /* Generate the code to do the repeat operation:
4950 for (i = 0; i < ncopies; i++)
4951 memmove (dest + (i * slen * size), src, slen*size); */
4952 gfc_start_block (&block);
4953 count = gfc_create_var (ncopies_type, "count");
4954 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4955 exit_label = gfc_build_label_decl (NULL_TREE);
4957 /* Start the loop body. */
4958 gfc_start_block (&body);
4960 /* Exit the loop if count >= ncopies. */
4961 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4962 tmp = build1_v (GOTO_EXPR, exit_label);
4963 TREE_USED (exit_label) = 1;
4964 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4965 build_empty_stmt (input_location));
4966 gfc_add_expr_to_block (&body, tmp);
4968 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4969 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4970 fold_convert (gfc_charlen_type_node, slen),
4971 fold_convert (gfc_charlen_type_node, count));
4972 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4973 tmp, fold_convert (gfc_charlen_type_node, size));
4974 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4975 fold_convert (pvoid_type_node, dest),
4976 fold_convert (sizetype, tmp));
4977 tmp = build_call_expr_loc (input_location,
4978 built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4979 fold_build2 (MULT_EXPR, size_type_node, slen,
4980 fold_convert (size_type_node, size)));
4981 gfc_add_expr_to_block (&body, tmp);
4983 /* Increment count. */
4984 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4985 count, build_int_cst (TREE_TYPE (count), 1));
4986 gfc_add_modify (&body, count, tmp);
4988 /* Build the loop. */
4989 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4990 gfc_add_expr_to_block (&block, tmp);
4992 /* Add the exit label. */
4993 tmp = build1_v (LABEL_EXPR, exit_label);
4994 gfc_add_expr_to_block (&block, tmp);
4996 /* Finish the block. */
4997 tmp = gfc_finish_block (&block);
4998 gfc_add_expr_to_block (&se->pre, tmp);
5000 /* Set the result value. */
5002 se->string_length = dlen;
5006 /* Generate code for the IARGC intrinsic. */
5009 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
5015 /* Call the library function. This always returns an INTEGER(4). */
5016 fndecl = gfor_fndecl_iargc;
5017 tmp = build_call_expr_loc (input_location,
5020 /* Convert it to the required type. */
5021 type = gfc_typenode_for_spec (&expr->ts);
5022 tmp = fold_convert (type, tmp);
5028 /* The loc intrinsic returns the address of its argument as
5029 gfc_index_integer_kind integer. */
5032 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
5038 gcc_assert (!se->ss);
5040 arg_expr = expr->value.function.actual->expr;
5041 ss = gfc_walk_expr (arg_expr);
5042 if (ss == gfc_ss_terminator)
5043 gfc_conv_expr_reference (se, arg_expr);
5045 gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL, NULL);
5046 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
5048 /* Create a temporary variable for loc return value. Without this,
5049 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
5050 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
5051 gfc_add_modify (&se->pre, temp_var, se->expr);
5052 se->expr = temp_var;
5055 /* Generate code for an intrinsic function. Some map directly to library
5056 calls, others get special handling. In some cases the name of the function
5057 used depends on the type specifiers. */
5060 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
5066 name = &expr->value.function.name[2];
5068 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
5070 lib = gfc_is_intrinsic_libcall (expr);
5074 se->ignore_optional = 1;
5076 switch (expr->value.function.isym->id)
5078 case GFC_ISYM_EOSHIFT:
5080 case GFC_ISYM_RESHAPE:
5081 /* For all of those the first argument specifies the type and the
5082 third is optional. */
5083 conv_generic_with_optional_char_arg (se, expr, 1, 3);
5087 gfc_conv_intrinsic_funcall (se, expr);
5095 switch (expr->value.function.isym->id)
5100 case GFC_ISYM_REPEAT:
5101 gfc_conv_intrinsic_repeat (se, expr);
5105 gfc_conv_intrinsic_trim (se, expr);
5108 case GFC_ISYM_SC_KIND:
5109 gfc_conv_intrinsic_sc_kind (se, expr);
5112 case GFC_ISYM_SI_KIND:
5113 gfc_conv_intrinsic_si_kind (se, expr);
5116 case GFC_ISYM_SR_KIND:
5117 gfc_conv_intrinsic_sr_kind (se, expr);
5120 case GFC_ISYM_EXPONENT:
5121 gfc_conv_intrinsic_exponent (se, expr);
5125 kind = expr->value.function.actual->expr->ts.kind;
5127 fndecl = gfor_fndecl_string_scan;
5129 fndecl = gfor_fndecl_string_scan_char4;
5133 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5136 case GFC_ISYM_VERIFY:
5137 kind = expr->value.function.actual->expr->ts.kind;
5139 fndecl = gfor_fndecl_string_verify;
5141 fndecl = gfor_fndecl_string_verify_char4;
5145 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5148 case GFC_ISYM_ALLOCATED:
5149 gfc_conv_allocated (se, expr);
5152 case GFC_ISYM_ASSOCIATED:
5153 gfc_conv_associated(se, expr);
5156 case GFC_ISYM_SAME_TYPE_AS:
5157 gfc_conv_same_type_as (se, expr);
5160 case GFC_ISYM_EXTENDS_TYPE_OF:
5161 gfc_conv_extends_type_of (se, expr);
5165 gfc_conv_intrinsic_abs (se, expr);
5168 case GFC_ISYM_ADJUSTL:
5169 if (expr->ts.kind == 1)
5170 fndecl = gfor_fndecl_adjustl;
5171 else if (expr->ts.kind == 4)
5172 fndecl = gfor_fndecl_adjustl_char4;
5176 gfc_conv_intrinsic_adjust (se, expr, fndecl);
5179 case GFC_ISYM_ADJUSTR:
5180 if (expr->ts.kind == 1)
5181 fndecl = gfor_fndecl_adjustr;
5182 else if (expr->ts.kind == 4)
5183 fndecl = gfor_fndecl_adjustr_char4;
5187 gfc_conv_intrinsic_adjust (se, expr, fndecl);
5190 case GFC_ISYM_AIMAG:
5191 gfc_conv_intrinsic_imagpart (se, expr);
5195 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
5199 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
5202 case GFC_ISYM_ANINT:
5203 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
5207 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5211 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
5214 case GFC_ISYM_BTEST:
5215 gfc_conv_intrinsic_btest (se, expr);
5218 case GFC_ISYM_ACHAR:
5220 gfc_conv_intrinsic_char (se, expr);
5223 case GFC_ISYM_CONVERSION:
5225 case GFC_ISYM_LOGICAL:
5227 gfc_conv_intrinsic_conversion (se, expr);
5230 /* Integer conversions are handled separately to make sure we get the
5231 correct rounding mode. */
5236 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
5240 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
5243 case GFC_ISYM_CEILING:
5244 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
5247 case GFC_ISYM_FLOOR:
5248 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
5252 gfc_conv_intrinsic_mod (se, expr, 0);
5255 case GFC_ISYM_MODULO:
5256 gfc_conv_intrinsic_mod (se, expr, 1);
5259 case GFC_ISYM_CMPLX:
5260 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
5263 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
5264 gfc_conv_intrinsic_iargc (se, expr);
5267 case GFC_ISYM_COMPLEX:
5268 gfc_conv_intrinsic_cmplx (se, expr, 1);
5271 case GFC_ISYM_CONJG:
5272 gfc_conv_intrinsic_conjg (se, expr);
5275 case GFC_ISYM_COUNT:
5276 gfc_conv_intrinsic_count (se, expr);
5279 case GFC_ISYM_CTIME:
5280 gfc_conv_intrinsic_ctime (se, expr);
5284 gfc_conv_intrinsic_dim (se, expr);
5287 case GFC_ISYM_DOT_PRODUCT:
5288 gfc_conv_intrinsic_dot_product (se, expr);
5291 case GFC_ISYM_DPROD:
5292 gfc_conv_intrinsic_dprod (se, expr);
5295 case GFC_ISYM_FDATE:
5296 gfc_conv_intrinsic_fdate (se, expr);
5299 case GFC_ISYM_FRACTION:
5300 gfc_conv_intrinsic_fraction (se, expr);
5304 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5307 case GFC_ISYM_IBCLR:
5308 gfc_conv_intrinsic_singlebitop (se, expr, 0);
5311 case GFC_ISYM_IBITS:
5312 gfc_conv_intrinsic_ibits (se, expr);
5315 case GFC_ISYM_IBSET:
5316 gfc_conv_intrinsic_singlebitop (se, expr, 1);
5319 case GFC_ISYM_IACHAR:
5320 case GFC_ISYM_ICHAR:
5321 /* We assume ASCII character sequence. */
5322 gfc_conv_intrinsic_ichar (se, expr);
5325 case GFC_ISYM_IARGC:
5326 gfc_conv_intrinsic_iargc (se, expr);
5330 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
5333 case GFC_ISYM_INDEX:
5334 kind = expr->value.function.actual->expr->ts.kind;
5336 fndecl = gfor_fndecl_string_index;
5338 fndecl = gfor_fndecl_string_index_char4;
5342 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5346 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
5349 case GFC_ISYM_IS_IOSTAT_END:
5350 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
5353 case GFC_ISYM_IS_IOSTAT_EOR:
5354 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
5357 case GFC_ISYM_ISNAN:
5358 gfc_conv_intrinsic_isnan (se, expr);
5361 case GFC_ISYM_LSHIFT:
5362 gfc_conv_intrinsic_rlshift (se, expr, 0);
5365 case GFC_ISYM_RSHIFT:
5366 gfc_conv_intrinsic_rlshift (se, expr, 1);
5369 case GFC_ISYM_ISHFT:
5370 gfc_conv_intrinsic_ishft (se, expr);
5373 case GFC_ISYM_ISHFTC:
5374 gfc_conv_intrinsic_ishftc (se, expr);
5377 case GFC_ISYM_LEADZ:
5378 gfc_conv_intrinsic_leadz (se, expr);
5381 case GFC_ISYM_TRAILZ:
5382 gfc_conv_intrinsic_trailz (se, expr);
5385 case GFC_ISYM_LBOUND:
5386 gfc_conv_intrinsic_bound (se, expr, 0);
5389 case GFC_ISYM_TRANSPOSE:
5390 if (se->ss && se->ss->useflags)
5392 gfc_conv_tmp_array_ref (se);
5393 gfc_advance_se_ss_chain (se);
5396 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
5400 gfc_conv_intrinsic_len (se, expr);
5403 case GFC_ISYM_LEN_TRIM:
5404 gfc_conv_intrinsic_len_trim (se, expr);
5408 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
5412 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
5416 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
5420 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
5424 if (expr->ts.type == BT_CHARACTER)
5425 gfc_conv_intrinsic_minmax_char (se, expr, 1);
5427 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
5430 case GFC_ISYM_MAXLOC:
5431 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
5434 case GFC_ISYM_MAXVAL:
5435 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
5438 case GFC_ISYM_MERGE:
5439 gfc_conv_intrinsic_merge (se, expr);
5443 if (expr->ts.type == BT_CHARACTER)
5444 gfc_conv_intrinsic_minmax_char (se, expr, -1);
5446 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
5449 case GFC_ISYM_MINLOC:
5450 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
5453 case GFC_ISYM_MINVAL:
5454 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
5457 case GFC_ISYM_NEAREST:
5458 gfc_conv_intrinsic_nearest (se, expr);
5462 gfc_conv_intrinsic_not (se, expr);
5466 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
5469 case GFC_ISYM_PRESENT:
5470 gfc_conv_intrinsic_present (se, expr);
5473 case GFC_ISYM_PRODUCT:
5474 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
5477 case GFC_ISYM_RRSPACING:
5478 gfc_conv_intrinsic_rrspacing (se, expr);
5481 case GFC_ISYM_SET_EXPONENT:
5482 gfc_conv_intrinsic_set_exponent (se, expr);
5485 case GFC_ISYM_SCALE:
5486 gfc_conv_intrinsic_scale (se, expr);
5490 gfc_conv_intrinsic_sign (se, expr);
5494 gfc_conv_intrinsic_size (se, expr);
5497 case GFC_ISYM_SIZEOF:
5498 gfc_conv_intrinsic_sizeof (se, expr);
5501 case GFC_ISYM_SPACING:
5502 gfc_conv_intrinsic_spacing (se, expr);
5506 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
5509 case GFC_ISYM_TRANSFER:
5510 if (se->ss && se->ss->useflags)
5512 /* Access the previously obtained result. */
5513 gfc_conv_tmp_array_ref (se);
5514 gfc_advance_se_ss_chain (se);
5517 gfc_conv_intrinsic_transfer (se, expr);
5520 case GFC_ISYM_TTYNAM:
5521 gfc_conv_intrinsic_ttynam (se, expr);
5524 case GFC_ISYM_UBOUND:
5525 gfc_conv_intrinsic_bound (se, expr, 1);
5529 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
5533 gfc_conv_intrinsic_loc (se, expr);
5536 case GFC_ISYM_ACCESS:
5537 case GFC_ISYM_CHDIR:
5538 case GFC_ISYM_CHMOD:
5539 case GFC_ISYM_DTIME:
5540 case GFC_ISYM_ETIME:
5542 case GFC_ISYM_FGETC:
5545 case GFC_ISYM_FPUTC:
5546 case GFC_ISYM_FSTAT:
5547 case GFC_ISYM_FTELL:
5548 case GFC_ISYM_GETCWD:
5549 case GFC_ISYM_GETGID:
5550 case GFC_ISYM_GETPID:
5551 case GFC_ISYM_GETUID:
5552 case GFC_ISYM_HOSTNM:
5554 case GFC_ISYM_IERRNO:
5555 case GFC_ISYM_IRAND:
5556 case GFC_ISYM_ISATTY:
5558 case GFC_ISYM_LSTAT:
5559 case GFC_ISYM_MALLOC:
5560 case GFC_ISYM_MATMUL:
5561 case GFC_ISYM_MCLOCK:
5562 case GFC_ISYM_MCLOCK8:
5564 case GFC_ISYM_RENAME:
5565 case GFC_ISYM_SECOND:
5566 case GFC_ISYM_SECNDS:
5567 case GFC_ISYM_SIGNAL:
5569 case GFC_ISYM_SYMLNK:
5570 case GFC_ISYM_SYSTEM:
5572 case GFC_ISYM_TIME8:
5573 case GFC_ISYM_UMASK:
5574 case GFC_ISYM_UNLINK:
5575 gfc_conv_intrinsic_funcall (se, expr);
5578 case GFC_ISYM_EOSHIFT:
5580 case GFC_ISYM_RESHAPE:
5581 /* For those, expr->rank should always be >0 and thus the if above the
5582 switch should have matched. */
5587 gfc_conv_intrinsic_lib_function (se, expr);
5593 /* This generates code to execute before entering the scalarization loop.
5594 Currently does nothing. */
5597 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
5599 switch (ss->expr->value.function.isym->id)
5601 case GFC_ISYM_UBOUND:
5602 case GFC_ISYM_LBOUND:
5611 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
5612 inside the scalarization loop. */
5615 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
5619 /* The two argument version returns a scalar. */
5620 if (expr->value.function.actual->next->expr)
5623 newss = gfc_get_ss ();
5624 newss->type = GFC_SS_INTRINSIC;
5627 newss->data.info.dimen = 1;
5633 /* Walk an intrinsic array libcall. */
5636 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
5640 gcc_assert (expr->rank > 0);
5642 newss = gfc_get_ss ();
5643 newss->type = GFC_SS_FUNCTION;
5646 newss->data.info.dimen = expr->rank;
5652 /* Returns nonzero if the specified intrinsic function call maps directly to
5653 an external library call. Should only be used for functions that return
5657 gfc_is_intrinsic_libcall (gfc_expr * expr)
5659 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
5660 gcc_assert (expr->rank > 0);
5662 switch (expr->value.function.isym->id)
5666 case GFC_ISYM_COUNT:
5667 case GFC_ISYM_MATMUL:
5668 case GFC_ISYM_MAXLOC:
5669 case GFC_ISYM_MAXVAL:
5670 case GFC_ISYM_MINLOC:
5671 case GFC_ISYM_MINVAL:
5672 case GFC_ISYM_PRODUCT:
5674 case GFC_ISYM_SHAPE:
5675 case GFC_ISYM_SPREAD:
5676 case GFC_ISYM_TRANSPOSE:
5677 /* Ignore absent optional parameters. */
5680 case GFC_ISYM_RESHAPE:
5681 case GFC_ISYM_CSHIFT:
5682 case GFC_ISYM_EOSHIFT:
5684 case GFC_ISYM_UNPACK:
5685 /* Pass absent optional parameters. */
5693 /* Walk an intrinsic function. */
5695 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
5696 gfc_intrinsic_sym * isym)
5700 if (isym->elemental)
5701 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
5703 if (expr->rank == 0)
5706 if (gfc_is_intrinsic_libcall (expr))
5707 return gfc_walk_intrinsic_libfunc (ss, expr);
5709 /* Special cases. */
5712 case GFC_ISYM_LBOUND:
5713 case GFC_ISYM_UBOUND:
5714 return gfc_walk_intrinsic_bound (ss, expr);
5716 case GFC_ISYM_TRANSFER:
5717 return gfc_walk_intrinsic_libfunc (ss, expr);
5720 /* This probably meant someone forgot to add an intrinsic to the above
5721 list(s) when they implemented it, or something's gone horribly
5727 #include "gt-fortran-trans-intrinsic.h"