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 (fndecl, 3, addr, args[0], args[1]);
277 gfc_add_expr_to_block (&se->pre, tmp);
279 /* Free the temporary afterwards. */
280 tmp = gfc_call_free (var);
281 gfc_add_expr_to_block (&se->post, tmp);
284 se->string_length = args[0];
289 /* Conversion from complex to non-complex involves taking the real
290 component of the value. */
291 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
292 && expr->ts.type != BT_COMPLEX)
296 artype = TREE_TYPE (TREE_TYPE (args[0]));
297 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
300 se->expr = convert (type, args[0]);
303 /* This is needed because the gcc backend only implements
304 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
305 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
306 Similarly for CEILING. */
309 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
316 argtype = TREE_TYPE (arg);
317 arg = gfc_evaluate_now (arg, pblock);
319 intval = convert (type, arg);
320 intval = gfc_evaluate_now (intval, pblock);
322 tmp = convert (argtype, intval);
323 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
325 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
326 build_int_cst (type, 1));
327 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
332 /* Round to nearest integer, away from zero. */
335 build_round_expr (tree arg, tree restype)
340 int argprec, resprec;
342 argtype = TREE_TYPE (arg);
343 argprec = TYPE_PRECISION (argtype);
344 resprec = TYPE_PRECISION (restype);
346 /* Depending on the type of the result, choose the long int intrinsic
347 (lround family) or long long intrinsic (llround). We might also
348 need to convert the result afterwards. */
349 if (resprec <= LONG_TYPE_SIZE)
351 else if (resprec <= LONG_LONG_TYPE_SIZE)
356 /* Now, depending on the argument type, we choose between intrinsics. */
357 if (argprec == TYPE_PRECISION (float_type_node))
358 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
359 else if (argprec == TYPE_PRECISION (double_type_node))
360 fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
361 else if (argprec == TYPE_PRECISION (long_double_type_node))
362 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
366 return fold_convert (restype, build_call_expr (fn, 1, arg));
370 /* Convert a real to an integer using a specific rounding mode.
371 Ideally we would just build the corresponding GENERIC node,
372 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
375 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
376 enum rounding_mode op)
381 return build_fixbound_expr (pblock, arg, type, 0);
385 return build_fixbound_expr (pblock, arg, type, 1);
389 return build_round_expr (arg, type);
393 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
402 /* Round a real value using the specified rounding mode.
403 We use a temporary integer of that same kind size as the result.
404 Values larger than those that can be represented by this kind are
405 unchanged, as they will not be accurate enough to represent the
407 huge = HUGE (KIND (a))
408 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
412 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
423 kind = expr->ts.kind;
424 nargs = gfc_intrinsic_argument_list_length (expr);
427 /* We have builtin functions for some cases. */
470 /* Evaluate the argument. */
471 gcc_assert (expr->value.function.actual->expr);
472 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
474 /* Use a builtin function if one exists. */
475 if (n != END_BUILTINS)
477 tmp = built_in_decls[n];
478 se->expr = build_call_expr (tmp, 1, arg[0]);
482 /* This code is probably redundant, but we'll keep it lying around just
484 type = gfc_typenode_for_spec (&expr->ts);
485 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
487 /* Test if the value is too large to handle sensibly. */
488 gfc_set_model_kind (kind);
490 n = gfc_validate_kind (BT_INTEGER, kind, false);
491 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
492 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
493 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
495 mpfr_neg (huge, huge, GFC_RND_MODE);
496 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
497 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
498 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
499 itype = gfc_get_int_type (kind);
501 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
502 tmp = convert (type, tmp);
503 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
508 /* Convert to an integer using the specified rounding mode. */
511 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
517 nargs = gfc_intrinsic_argument_list_length (expr);
518 args = (tree *) alloca (sizeof (tree) * nargs);
520 /* Evaluate the argument, we process all arguments even though we only
521 use the first one for code generation purposes. */
522 type = gfc_typenode_for_spec (&expr->ts);
523 gcc_assert (expr->value.function.actual->expr);
524 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
526 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
528 /* Conversion to a different integer kind. */
529 se->expr = convert (type, args[0]);
533 /* Conversion from complex to non-complex involves taking the real
534 component of the value. */
535 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
536 && expr->ts.type != BT_COMPLEX)
540 artype = TREE_TYPE (TREE_TYPE (args[0]));
541 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
544 se->expr = build_fix_expr (&se->pre, args[0], type, op);
549 /* Get the imaginary component of a value. */
552 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
556 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
557 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
561 /* Get the complex conjugate of a value. */
564 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
568 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
569 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
573 /* Initialize function decls for library functions. The external functions
574 are created as required. Builtin functions are added here. */
577 gfc_build_intrinsic_lib_fndecls (void)
579 gfc_intrinsic_map_t *m;
581 /* Add GCC builtin functions. */
582 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
584 if (m->code_r4 != END_BUILTINS)
585 m->real4_decl = built_in_decls[m->code_r4];
586 if (m->code_r8 != END_BUILTINS)
587 m->real8_decl = built_in_decls[m->code_r8];
588 if (m->code_r10 != END_BUILTINS)
589 m->real10_decl = built_in_decls[m->code_r10];
590 if (m->code_r16 != END_BUILTINS)
591 m->real16_decl = built_in_decls[m->code_r16];
592 if (m->code_c4 != END_BUILTINS)
593 m->complex4_decl = built_in_decls[m->code_c4];
594 if (m->code_c8 != END_BUILTINS)
595 m->complex8_decl = built_in_decls[m->code_c8];
596 if (m->code_c10 != END_BUILTINS)
597 m->complex10_decl = built_in_decls[m->code_c10];
598 if (m->code_c16 != END_BUILTINS)
599 m->complex16_decl = built_in_decls[m->code_c16];
604 /* Create a fndecl for a simple intrinsic library function. */
607 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
612 gfc_actual_arglist *actual;
615 char name[GFC_MAX_SYMBOL_LEN + 3];
618 if (ts->type == BT_REAL)
623 pdecl = &m->real4_decl;
626 pdecl = &m->real8_decl;
629 pdecl = &m->real10_decl;
632 pdecl = &m->real16_decl;
638 else if (ts->type == BT_COMPLEX)
640 gcc_assert (m->complex_available);
645 pdecl = &m->complex4_decl;
648 pdecl = &m->complex8_decl;
651 pdecl = &m->complex10_decl;
654 pdecl = &m->complex16_decl;
669 snprintf (name, sizeof (name), "%s%s%s",
670 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
671 else if (ts->kind == 8)
672 snprintf (name, sizeof (name), "%s%s",
673 ts->type == BT_COMPLEX ? "c" : "", m->name);
676 gcc_assert (ts->kind == 10 || ts->kind == 16);
677 snprintf (name, sizeof (name), "%s%s%s",
678 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
683 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
684 ts->type == BT_COMPLEX ? 'c' : 'r',
688 argtypes = NULL_TREE;
689 for (actual = expr->value.function.actual; actual; actual = actual->next)
691 type = gfc_typenode_for_spec (&actual->expr->ts);
692 argtypes = gfc_chainon_list (argtypes, type);
694 argtypes = gfc_chainon_list (argtypes, void_type_node);
695 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
696 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
698 /* Mark the decl as external. */
699 DECL_EXTERNAL (fndecl) = 1;
700 TREE_PUBLIC (fndecl) = 1;
702 /* Mark it __attribute__((const)), if possible. */
703 TREE_READONLY (fndecl) = m->is_constant;
705 rest_of_decl_compilation (fndecl, 1, 0);
712 /* Convert an intrinsic function into an external or builtin call. */
715 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
717 gfc_intrinsic_map_t *m;
721 unsigned int num_args;
724 id = expr->value.function.isym->id;
725 /* Find the entry for this function. */
726 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
732 if (m->id == GFC_ISYM_NONE)
734 internal_error ("Intrinsic function %s(%d) not recognized",
735 expr->value.function.name, id);
738 /* Get the decl and generate the call. */
739 num_args = gfc_intrinsic_argument_list_length (expr);
740 args = (tree *) alloca (sizeof (tree) * num_args);
742 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
743 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
744 rettype = TREE_TYPE (TREE_TYPE (fndecl));
746 fndecl = build_addr (fndecl, current_function_decl);
747 se->expr = build_call_array (rettype, fndecl, num_args, args);
751 /* If bounds-checking is enabled, create code to verify at runtime that the
752 string lengths for both expressions are the same (needed for e.g. MERGE).
753 If bounds-checking is not enabled, does nothing. */
756 gfc_trans_same_strlen_check (const char* intr_name, locus* where,
757 tree a, tree b, stmtblock_t* target)
762 /* If bounds-checking is disabled, do nothing. */
763 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
766 /* Compare the two string lengths. */
767 cond = fold_build2 (NE_EXPR, boolean_type_node, a, b);
769 /* Output the runtime-check. */
770 name = gfc_build_cstring_const (intr_name);
771 name = gfc_build_addr_expr (pchar_type_node, name);
772 gfc_trans_runtime_check (true, false, cond, target, where,
773 "Unequal character lengths (%ld/%ld) in %s",
774 fold_convert (long_integer_type_node, a),
775 fold_convert (long_integer_type_node, b), name);
779 /* The EXPONENT(s) intrinsic function is translated into
786 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
788 tree arg, type, res, tmp;
791 switch (expr->value.function.actual->expr->ts.kind)
794 frexp = BUILT_IN_FREXPF;
797 frexp = BUILT_IN_FREXP;
801 frexp = BUILT_IN_FREXPL;
807 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
809 res = gfc_create_var (integer_type_node, NULL);
810 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
811 gfc_build_addr_expr (NULL_TREE, res));
812 gfc_add_expr_to_block (&se->pre, tmp);
814 type = gfc_typenode_for_spec (&expr->ts);
815 se->expr = fold_convert (type, res);
818 /* Evaluate a single upper or lower bound. */
819 /* TODO: bound intrinsic generates way too much unnecessary code. */
822 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
824 gfc_actual_arglist *arg;
825 gfc_actual_arglist *arg2;
830 tree cond, cond1, cond2, cond3, cond4, size;
838 arg = expr->value.function.actual;
843 /* Create an implicit second parameter from the loop variable. */
844 gcc_assert (!arg2->expr);
845 gcc_assert (se->loop->dimen == 1);
846 gcc_assert (se->ss->expr == expr);
847 gfc_advance_se_ss_chain (se);
848 bound = se->loop->loopvar[0];
849 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
854 /* use the passed argument. */
855 gcc_assert (arg->next->expr);
856 gfc_init_se (&argse, NULL);
857 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
858 gfc_add_block_to_block (&se->pre, &argse.pre);
860 /* Convert from one based to zero based. */
861 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
865 /* TODO: don't re-evaluate the descriptor on each iteration. */
866 /* Get a descriptor for the first parameter. */
867 ss = gfc_walk_expr (arg->expr);
868 gcc_assert (ss != gfc_ss_terminator);
869 gfc_init_se (&argse, NULL);
870 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
871 gfc_add_block_to_block (&se->pre, &argse.pre);
872 gfc_add_block_to_block (&se->post, &argse.post);
876 if (INTEGER_CST_P (bound))
880 hi = TREE_INT_CST_HIGH (bound);
881 low = TREE_INT_CST_LOW (bound);
882 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
883 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
884 "dimension index", upper ? "UBOUND" : "LBOUND",
889 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
891 bound = gfc_evaluate_now (bound, &se->pre);
892 cond = fold_build2 (LT_EXPR, boolean_type_node,
893 bound, build_int_cst (TREE_TYPE (bound), 0));
894 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
895 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
896 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
897 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
902 ubound = gfc_conv_descriptor_ubound (desc, bound);
903 lbound = gfc_conv_descriptor_lbound (desc, bound);
905 /* Follow any component references. */
906 if (arg->expr->expr_type == EXPR_VARIABLE
907 || arg->expr->expr_type == EXPR_CONSTANT)
909 as = arg->expr->symtree->n.sym->as;
910 for (ref = arg->expr->ref; ref; ref = ref->next)
915 as = ref->u.c.component->as;
923 switch (ref->u.ar.type)
942 /* 13.14.53: Result value for LBOUND
944 Case (i): For an array section or for an array expression other than a
945 whole array or array structure component, LBOUND(ARRAY, DIM)
946 has the value 1. For a whole array or array structure
947 component, LBOUND(ARRAY, DIM) has the value:
948 (a) equal to the lower bound for subscript DIM of ARRAY if
949 dimension DIM of ARRAY does not have extent zero
950 or if ARRAY is an assumed-size array of rank DIM,
953 13.14.113: Result value for UBOUND
955 Case (i): For an array section or for an array expression other than a
956 whole array or array structure component, UBOUND(ARRAY, DIM)
957 has the value equal to the number of elements in the given
958 dimension; otherwise, it has a value equal to the upper bound
959 for subscript DIM of ARRAY if dimension DIM of ARRAY does
960 not have size zero and has value zero if dimension DIM has
965 tree stride = gfc_conv_descriptor_stride (desc, bound);
967 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
968 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
970 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
971 gfc_index_zero_node);
972 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
974 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
975 gfc_index_zero_node);
980 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
982 cond5 = fold_build2 (EQ_EXPR, boolean_type_node, gfc_index_one_node, lbound);
983 cond5 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond5);
985 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond5);
987 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
988 ubound, gfc_index_zero_node);
992 if (as->type == AS_ASSUMED_SIZE)
993 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
994 build_int_cst (TREE_TYPE (bound),
995 arg->expr->rank - 1));
997 cond = boolean_false_node;
999 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
1000 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
1002 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
1003 lbound, gfc_index_one_node);
1010 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
1011 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
1012 gfc_index_one_node);
1013 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
1014 gfc_index_zero_node);
1017 se->expr = gfc_index_one_node;
1020 type = gfc_typenode_for_spec (&expr->ts);
1021 se->expr = convert (type, se->expr);
1026 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
1031 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1033 switch (expr->value.function.actual->expr->ts.type)
1037 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
1041 switch (expr->ts.kind)
1056 se->expr = build_call_expr (built_in_decls[n], 1, arg);
1065 /* Create a complex value from one or two real components. */
1068 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1074 unsigned int num_args;
1076 num_args = gfc_intrinsic_argument_list_length (expr);
1077 args = (tree *) alloca (sizeof (tree) * num_args);
1079 type = gfc_typenode_for_spec (&expr->ts);
1080 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1081 real = convert (TREE_TYPE (type), args[0]);
1083 imag = convert (TREE_TYPE (type), args[1]);
1084 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1086 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1088 imag = convert (TREE_TYPE (type), imag);
1091 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1093 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1096 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1097 MODULO(A, P) = A - FLOOR (A / P) * P */
1098 /* TODO: MOD(x, 0) */
1101 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1112 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1114 switch (expr->ts.type)
1117 /* Integer case is easy, we've got a builtin op. */
1118 type = TREE_TYPE (args[0]);
1121 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1123 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1128 /* Check if we have a builtin fmod. */
1129 switch (expr->ts.kind)
1148 /* Use it if it exists. */
1149 if (n != END_BUILTINS)
1151 tmp = build_addr (built_in_decls[n], current_function_decl);
1152 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1158 type = TREE_TYPE (args[0]);
1160 args[0] = gfc_evaluate_now (args[0], &se->pre);
1161 args[1] = gfc_evaluate_now (args[1], &se->pre);
1164 modulo = arg - floor (arg/arg2) * arg2, so
1165 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1167 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1168 thereby avoiding another division and retaining the accuracy
1169 of the builtin function. */
1170 if (n != END_BUILTINS && modulo)
1172 tree zero = gfc_build_const (type, integer_zero_node);
1173 tmp = gfc_evaluate_now (se->expr, &se->pre);
1174 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1175 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1176 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1177 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1178 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1179 test = gfc_evaluate_now (test, &se->pre);
1180 se->expr = fold_build3 (COND_EXPR, type, test,
1181 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1186 /* If we do not have a built_in fmod, the calculation is going to
1187 have to be done longhand. */
1188 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1190 /* Test if the value is too large to handle sensibly. */
1191 gfc_set_model_kind (expr->ts.kind);
1193 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1194 ikind = expr->ts.kind;
1197 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1198 ikind = gfc_max_integer_kind;
1200 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1201 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1202 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1204 mpfr_neg (huge, huge, GFC_RND_MODE);
1205 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1206 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1207 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1209 itype = gfc_get_int_type (ikind);
1211 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1213 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1214 tmp = convert (type, tmp);
1215 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1216 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1217 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1226 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1229 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1237 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1238 type = TREE_TYPE (args[0]);
1240 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1241 val = gfc_evaluate_now (val, &se->pre);
1243 zero = gfc_build_const (type, integer_zero_node);
1244 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1245 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1249 /* SIGN(A, B) is absolute value of A times sign of B.
1250 The real value versions use library functions to ensure the correct
1251 handling of negative zero. Integer case implemented as:
1252 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1256 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1262 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1263 if (expr->ts.type == BT_REAL)
1265 switch (expr->ts.kind)
1268 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1271 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1275 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1280 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1284 /* Having excluded floating point types, we know we are now dealing
1285 with signed integer types. */
1286 type = TREE_TYPE (args[0]);
1288 /* Args[0] is used multiple times below. */
1289 args[0] = gfc_evaluate_now (args[0], &se->pre);
1291 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1292 the signs of A and B are the same, and of all ones if they differ. */
1293 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1294 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1295 build_int_cst (type, TYPE_PRECISION (type) - 1));
1296 tmp = gfc_evaluate_now (tmp, &se->pre);
1298 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1299 is all ones (i.e. -1). */
1300 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1301 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1306 /* Test for the presence of an optional argument. */
1309 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1313 arg = expr->value.function.actual->expr;
1314 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1315 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1316 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1320 /* Calculate the double precision product of two single precision values. */
1323 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1328 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1330 /* Convert the args to double precision before multiplying. */
1331 type = gfc_typenode_for_spec (&expr->ts);
1332 args[0] = convert (type, args[0]);
1333 args[1] = convert (type, args[1]);
1334 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1338 /* Return a length one character string containing an ascii character. */
1341 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1346 unsigned int num_args;
1348 num_args = gfc_intrinsic_argument_list_length (expr);
1349 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1351 type = gfc_get_char_type (expr->ts.kind);
1352 var = gfc_create_var (type, "char");
1354 arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1355 gfc_add_modify (&se->pre, var, arg[0]);
1356 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1357 se->string_length = integer_one_node;
1362 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1370 unsigned int num_args;
1372 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1373 args = (tree *) alloca (sizeof (tree) * num_args);
1375 var = gfc_create_var (pchar_type_node, "pstr");
1376 len = gfc_create_var (gfc_get_int_type (8), "len");
1378 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1379 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1380 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1382 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1383 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1384 fndecl, num_args, args);
1385 gfc_add_expr_to_block (&se->pre, tmp);
1387 /* Free the temporary afterwards, if necessary. */
1388 cond = fold_build2 (GT_EXPR, boolean_type_node,
1389 len, build_int_cst (TREE_TYPE (len), 0));
1390 tmp = gfc_call_free (var);
1391 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1392 gfc_add_expr_to_block (&se->post, tmp);
1395 se->string_length = len;
1400 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1408 unsigned int num_args;
1410 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1411 args = (tree *) alloca (sizeof (tree) * num_args);
1413 var = gfc_create_var (pchar_type_node, "pstr");
1414 len = gfc_create_var (gfc_get_int_type (4), "len");
1416 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1417 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1418 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1420 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1421 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1422 fndecl, num_args, args);
1423 gfc_add_expr_to_block (&se->pre, tmp);
1425 /* Free the temporary afterwards, if necessary. */
1426 cond = fold_build2 (GT_EXPR, boolean_type_node,
1427 len, build_int_cst (TREE_TYPE (len), 0));
1428 tmp = gfc_call_free (var);
1429 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1430 gfc_add_expr_to_block (&se->post, tmp);
1433 se->string_length = len;
1437 /* Return a character string containing the tty name. */
1440 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1448 unsigned int num_args;
1450 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1451 args = (tree *) alloca (sizeof (tree) * num_args);
1453 var = gfc_create_var (pchar_type_node, "pstr");
1454 len = gfc_create_var (gfc_get_int_type (4), "len");
1456 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1457 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1458 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1460 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1461 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1462 fndecl, num_args, args);
1463 gfc_add_expr_to_block (&se->pre, tmp);
1465 /* Free the temporary afterwards, if necessary. */
1466 cond = fold_build2 (GT_EXPR, boolean_type_node,
1467 len, build_int_cst (TREE_TYPE (len), 0));
1468 tmp = gfc_call_free (var);
1469 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1470 gfc_add_expr_to_block (&se->post, tmp);
1473 se->string_length = len;
1477 /* Get the minimum/maximum value of all the parameters.
1478 minmax (a1, a2, a3, ...)
1481 if (a2 .op. mvar || isnan(mvar))
1483 if (a3 .op. mvar || isnan(mvar))
1490 /* TODO: Mismatching types can occur when specific names are used.
1491 These should be handled during resolution. */
1493 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
1501 gfc_actual_arglist *argexpr;
1502 unsigned int i, nargs;
1504 nargs = gfc_intrinsic_argument_list_length (expr);
1505 args = (tree *) alloca (sizeof (tree) * nargs);
1507 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1508 type = gfc_typenode_for_spec (&expr->ts);
1510 argexpr = expr->value.function.actual;
1511 if (TREE_TYPE (args[0]) != type)
1512 args[0] = convert (type, args[0]);
1513 /* Only evaluate the argument once. */
1514 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1515 args[0] = gfc_evaluate_now (args[0], &se->pre);
1517 mvar = gfc_create_var (type, "M");
1518 gfc_add_modify (&se->pre, mvar, args[0]);
1519 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1525 /* Handle absent optional arguments by ignoring the comparison. */
1526 if (argexpr->expr->expr_type == EXPR_VARIABLE
1527 && argexpr->expr->symtree->n.sym->attr.optional
1528 && TREE_CODE (val) == INDIRECT_REF)
1530 (NE_EXPR, boolean_type_node, TREE_OPERAND (val, 0),
1531 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1536 /* Only evaluate the argument once. */
1537 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1538 val = gfc_evaluate_now (val, &se->pre);
1541 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1543 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1545 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1546 __builtin_isnan might be made dependent on that module being loaded,
1547 to help performance of programs that don't rely on IEEE semantics. */
1548 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1550 isnan = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1551 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1552 fold_convert (boolean_type_node, isnan));
1554 tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
1556 if (cond != NULL_TREE)
1557 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1559 gfc_add_expr_to_block (&se->pre, tmp);
1560 argexpr = argexpr->next;
1566 /* Generate library calls for MIN and MAX intrinsics for character
1569 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1572 tree var, len, fndecl, tmp, cond, function;
1575 nargs = gfc_intrinsic_argument_list_length (expr);
1576 args = (tree *) alloca (sizeof (tree) * (nargs + 4));
1577 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1579 /* Create the result variables. */
1580 len = gfc_create_var (gfc_charlen_type_node, "len");
1581 args[0] = gfc_build_addr_expr (NULL_TREE, len);
1582 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1583 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1584 args[2] = build_int_cst (NULL_TREE, op);
1585 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1587 if (expr->ts.kind == 1)
1588 function = gfor_fndecl_string_minmax;
1589 else if (expr->ts.kind == 4)
1590 function = gfor_fndecl_string_minmax_char4;
1594 /* Make the function call. */
1595 fndecl = build_addr (function, current_function_decl);
1596 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
1598 gfc_add_expr_to_block (&se->pre, tmp);
1600 /* Free the temporary afterwards, if necessary. */
1601 cond = fold_build2 (GT_EXPR, boolean_type_node,
1602 len, build_int_cst (TREE_TYPE (len), 0));
1603 tmp = gfc_call_free (var);
1604 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1605 gfc_add_expr_to_block (&se->post, tmp);
1608 se->string_length = len;
1612 /* Create a symbol node for this intrinsic. The symbol from the frontend
1613 has the generic name. */
1616 gfc_get_symbol_for_expr (gfc_expr * expr)
1620 /* TODO: Add symbols for intrinsic function to the global namespace. */
1621 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1622 sym = gfc_new_symbol (expr->value.function.name, NULL);
1625 sym->attr.external = 1;
1626 sym->attr.function = 1;
1627 sym->attr.always_explicit = 1;
1628 sym->attr.proc = PROC_INTRINSIC;
1629 sym->attr.flavor = FL_PROCEDURE;
1633 sym->attr.dimension = 1;
1634 sym->as = gfc_get_array_spec ();
1635 sym->as->type = AS_ASSUMED_SHAPE;
1636 sym->as->rank = expr->rank;
1639 /* TODO: proper argument lists for external intrinsics. */
1643 /* Generate a call to an external intrinsic function. */
1645 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1650 gcc_assert (!se->ss || se->ss->expr == expr);
1653 gcc_assert (expr->rank > 0);
1655 gcc_assert (expr->rank == 0);
1657 sym = gfc_get_symbol_for_expr (expr);
1659 /* Calls to libgfortran_matmul need to be appended special arguments,
1660 to be able to call the BLAS ?gemm functions if required and possible. */
1661 append_args = NULL_TREE;
1662 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1663 && sym->ts.type != BT_LOGICAL)
1665 tree cint = gfc_get_int_type (gfc_c_int_kind);
1667 if (gfc_option.flag_external_blas
1668 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1669 && (sym->ts.kind == gfc_default_real_kind
1670 || sym->ts.kind == gfc_default_double_kind))
1674 if (sym->ts.type == BT_REAL)
1676 if (sym->ts.kind == gfc_default_real_kind)
1677 gemm_fndecl = gfor_fndecl_sgemm;
1679 gemm_fndecl = gfor_fndecl_dgemm;
1683 if (sym->ts.kind == gfc_default_real_kind)
1684 gemm_fndecl = gfor_fndecl_cgemm;
1686 gemm_fndecl = gfor_fndecl_zgemm;
1689 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1690 append_args = gfc_chainon_list
1691 (append_args, build_int_cst
1692 (cint, gfc_option.blas_matmul_limit));
1693 append_args = gfc_chainon_list (append_args,
1694 gfc_build_addr_expr (NULL_TREE,
1699 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1700 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1701 append_args = gfc_chainon_list (append_args, null_pointer_node);
1705 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1709 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1729 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
1738 gfc_actual_arglist *actual;
1745 gfc_conv_intrinsic_funcall (se, expr);
1749 actual = expr->value.function.actual;
1750 type = gfc_typenode_for_spec (&expr->ts);
1751 /* Initialize the result. */
1752 resvar = gfc_create_var (type, "test");
1754 tmp = convert (type, boolean_true_node);
1756 tmp = convert (type, boolean_false_node);
1757 gfc_add_modify (&se->pre, resvar, tmp);
1759 /* Walk the arguments. */
1760 arrayss = gfc_walk_expr (actual->expr);
1761 gcc_assert (arrayss != gfc_ss_terminator);
1763 /* Initialize the scalarizer. */
1764 gfc_init_loopinfo (&loop);
1765 exit_label = gfc_build_label_decl (NULL_TREE);
1766 TREE_USED (exit_label) = 1;
1767 gfc_add_ss_to_loop (&loop, arrayss);
1769 /* Initialize the loop. */
1770 gfc_conv_ss_startstride (&loop);
1771 gfc_conv_loop_setup (&loop, &expr->where);
1773 gfc_mark_ss_chain_used (arrayss, 1);
1774 /* Generate the loop body. */
1775 gfc_start_scalarized_body (&loop, &body);
1777 /* If the condition matches then set the return value. */
1778 gfc_start_block (&block);
1780 tmp = convert (type, boolean_false_node);
1782 tmp = convert (type, boolean_true_node);
1783 gfc_add_modify (&block, resvar, tmp);
1785 /* And break out of the loop. */
1786 tmp = build1_v (GOTO_EXPR, exit_label);
1787 gfc_add_expr_to_block (&block, tmp);
1789 found = gfc_finish_block (&block);
1791 /* Check this element. */
1792 gfc_init_se (&arrayse, NULL);
1793 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1794 arrayse.ss = arrayss;
1795 gfc_conv_expr_val (&arrayse, actual->expr);
1797 gfc_add_block_to_block (&body, &arrayse.pre);
1798 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1799 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1800 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1801 gfc_add_expr_to_block (&body, tmp);
1802 gfc_add_block_to_block (&body, &arrayse.post);
1804 gfc_trans_scalarizing_loops (&loop, &body);
1806 /* Add the exit label. */
1807 tmp = build1_v (LABEL_EXPR, exit_label);
1808 gfc_add_expr_to_block (&loop.pre, tmp);
1810 gfc_add_block_to_block (&se->pre, &loop.pre);
1811 gfc_add_block_to_block (&se->pre, &loop.post);
1812 gfc_cleanup_loop (&loop);
1817 /* COUNT(A) = Number of true elements in A. */
1819 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1826 gfc_actual_arglist *actual;
1832 gfc_conv_intrinsic_funcall (se, expr);
1836 actual = expr->value.function.actual;
1838 type = gfc_typenode_for_spec (&expr->ts);
1839 /* Initialize the result. */
1840 resvar = gfc_create_var (type, "count");
1841 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1843 /* Walk the arguments. */
1844 arrayss = gfc_walk_expr (actual->expr);
1845 gcc_assert (arrayss != gfc_ss_terminator);
1847 /* Initialize the scalarizer. */
1848 gfc_init_loopinfo (&loop);
1849 gfc_add_ss_to_loop (&loop, arrayss);
1851 /* Initialize the loop. */
1852 gfc_conv_ss_startstride (&loop);
1853 gfc_conv_loop_setup (&loop, &expr->where);
1855 gfc_mark_ss_chain_used (arrayss, 1);
1856 /* Generate the loop body. */
1857 gfc_start_scalarized_body (&loop, &body);
1859 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1860 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1861 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1863 gfc_init_se (&arrayse, NULL);
1864 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1865 arrayse.ss = arrayss;
1866 gfc_conv_expr_val (&arrayse, actual->expr);
1867 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1869 gfc_add_block_to_block (&body, &arrayse.pre);
1870 gfc_add_expr_to_block (&body, tmp);
1871 gfc_add_block_to_block (&body, &arrayse.post);
1873 gfc_trans_scalarizing_loops (&loop, &body);
1875 gfc_add_block_to_block (&se->pre, &loop.pre);
1876 gfc_add_block_to_block (&se->pre, &loop.post);
1877 gfc_cleanup_loop (&loop);
1882 /* Inline implementation of the sum and product intrinsics. */
1884 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
1892 gfc_actual_arglist *actual;
1897 gfc_expr *arrayexpr;
1902 gfc_conv_intrinsic_funcall (se, expr);
1906 type = gfc_typenode_for_spec (&expr->ts);
1907 /* Initialize the result. */
1908 resvar = gfc_create_var (type, "val");
1909 if (op == PLUS_EXPR)
1910 tmp = gfc_build_const (type, integer_zero_node);
1912 tmp = gfc_build_const (type, integer_one_node);
1914 gfc_add_modify (&se->pre, resvar, tmp);
1916 /* Walk the arguments. */
1917 actual = expr->value.function.actual;
1918 arrayexpr = actual->expr;
1919 arrayss = gfc_walk_expr (arrayexpr);
1920 gcc_assert (arrayss != gfc_ss_terminator);
1922 actual = actual->next->next;
1923 gcc_assert (actual);
1924 maskexpr = actual->expr;
1925 if (maskexpr && maskexpr->rank != 0)
1927 maskss = gfc_walk_expr (maskexpr);
1928 gcc_assert (maskss != gfc_ss_terminator);
1933 /* Initialize the scalarizer. */
1934 gfc_init_loopinfo (&loop);
1935 gfc_add_ss_to_loop (&loop, arrayss);
1937 gfc_add_ss_to_loop (&loop, maskss);
1939 /* Initialize the loop. */
1940 gfc_conv_ss_startstride (&loop);
1941 gfc_conv_loop_setup (&loop, &expr->where);
1943 gfc_mark_ss_chain_used (arrayss, 1);
1945 gfc_mark_ss_chain_used (maskss, 1);
1946 /* Generate the loop body. */
1947 gfc_start_scalarized_body (&loop, &body);
1949 /* If we have a mask, only add this element if the mask is set. */
1952 gfc_init_se (&maskse, NULL);
1953 gfc_copy_loopinfo_to_se (&maskse, &loop);
1955 gfc_conv_expr_val (&maskse, maskexpr);
1956 gfc_add_block_to_block (&body, &maskse.pre);
1958 gfc_start_block (&block);
1961 gfc_init_block (&block);
1963 /* Do the actual summation/product. */
1964 gfc_init_se (&arrayse, NULL);
1965 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1966 arrayse.ss = arrayss;
1967 gfc_conv_expr_val (&arrayse, arrayexpr);
1968 gfc_add_block_to_block (&block, &arrayse.pre);
1970 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1971 gfc_add_modify (&block, resvar, tmp);
1972 gfc_add_block_to_block (&block, &arrayse.post);
1976 /* We enclose the above in if (mask) {...} . */
1977 tmp = gfc_finish_block (&block);
1979 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1982 tmp = gfc_finish_block (&block);
1983 gfc_add_expr_to_block (&body, tmp);
1985 gfc_trans_scalarizing_loops (&loop, &body);
1987 /* For a scalar mask, enclose the loop in an if statement. */
1988 if (maskexpr && maskss == NULL)
1990 gfc_init_se (&maskse, NULL);
1991 gfc_conv_expr_val (&maskse, maskexpr);
1992 gfc_init_block (&block);
1993 gfc_add_block_to_block (&block, &loop.pre);
1994 gfc_add_block_to_block (&block, &loop.post);
1995 tmp = gfc_finish_block (&block);
1997 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1998 gfc_add_expr_to_block (&block, tmp);
1999 gfc_add_block_to_block (&se->pre, &block);
2003 gfc_add_block_to_block (&se->pre, &loop.pre);
2004 gfc_add_block_to_block (&se->pre, &loop.post);
2007 gfc_cleanup_loop (&loop);
2013 /* Inline implementation of the dot_product intrinsic. This function
2014 is based on gfc_conv_intrinsic_arith (the previous function). */
2016 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
2024 gfc_actual_arglist *actual;
2025 gfc_ss *arrayss1, *arrayss2;
2026 gfc_se arrayse1, arrayse2;
2027 gfc_expr *arrayexpr1, *arrayexpr2;
2029 type = gfc_typenode_for_spec (&expr->ts);
2031 /* Initialize the result. */
2032 resvar = gfc_create_var (type, "val");
2033 if (expr->ts.type == BT_LOGICAL)
2034 tmp = build_int_cst (type, 0);
2036 tmp = gfc_build_const (type, integer_zero_node);
2038 gfc_add_modify (&se->pre, resvar, tmp);
2040 /* Walk argument #1. */
2041 actual = expr->value.function.actual;
2042 arrayexpr1 = actual->expr;
2043 arrayss1 = gfc_walk_expr (arrayexpr1);
2044 gcc_assert (arrayss1 != gfc_ss_terminator);
2046 /* Walk argument #2. */
2047 actual = actual->next;
2048 arrayexpr2 = actual->expr;
2049 arrayss2 = gfc_walk_expr (arrayexpr2);
2050 gcc_assert (arrayss2 != gfc_ss_terminator);
2052 /* Initialize the scalarizer. */
2053 gfc_init_loopinfo (&loop);
2054 gfc_add_ss_to_loop (&loop, arrayss1);
2055 gfc_add_ss_to_loop (&loop, arrayss2);
2057 /* Initialize the loop. */
2058 gfc_conv_ss_startstride (&loop);
2059 gfc_conv_loop_setup (&loop, &expr->where);
2061 gfc_mark_ss_chain_used (arrayss1, 1);
2062 gfc_mark_ss_chain_used (arrayss2, 1);
2064 /* Generate the loop body. */
2065 gfc_start_scalarized_body (&loop, &body);
2066 gfc_init_block (&block);
2068 /* Make the tree expression for [conjg(]array1[)]. */
2069 gfc_init_se (&arrayse1, NULL);
2070 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2071 arrayse1.ss = arrayss1;
2072 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2073 if (expr->ts.type == BT_COMPLEX)
2074 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2075 gfc_add_block_to_block (&block, &arrayse1.pre);
2077 /* Make the tree expression for array2. */
2078 gfc_init_se (&arrayse2, NULL);
2079 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2080 arrayse2.ss = arrayss2;
2081 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2082 gfc_add_block_to_block (&block, &arrayse2.pre);
2084 /* Do the actual product and sum. */
2085 if (expr->ts.type == BT_LOGICAL)
2087 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2088 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2092 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2093 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2095 gfc_add_modify (&block, resvar, tmp);
2097 /* Finish up the loop block and the loop. */
2098 tmp = gfc_finish_block (&block);
2099 gfc_add_expr_to_block (&body, tmp);
2101 gfc_trans_scalarizing_loops (&loop, &body);
2102 gfc_add_block_to_block (&se->pre, &loop.pre);
2103 gfc_add_block_to_block (&se->pre, &loop.post);
2104 gfc_cleanup_loop (&loop);
2111 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
2115 stmtblock_t ifblock;
2116 stmtblock_t elseblock;
2124 gfc_actual_arglist *actual;
2129 gfc_expr *arrayexpr;
2136 gfc_conv_intrinsic_funcall (se, expr);
2140 /* Initialize the result. */
2141 pos = gfc_create_var (gfc_array_index_type, "pos");
2142 offset = gfc_create_var (gfc_array_index_type, "offset");
2143 type = gfc_typenode_for_spec (&expr->ts);
2145 /* Walk the arguments. */
2146 actual = expr->value.function.actual;
2147 arrayexpr = actual->expr;
2148 arrayss = gfc_walk_expr (arrayexpr);
2149 gcc_assert (arrayss != gfc_ss_terminator);
2151 actual = actual->next->next;
2152 gcc_assert (actual);
2153 maskexpr = actual->expr;
2154 if (maskexpr && maskexpr->rank != 0)
2156 maskss = gfc_walk_expr (maskexpr);
2157 gcc_assert (maskss != gfc_ss_terminator);
2162 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2163 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2164 switch (arrayexpr->ts.type)
2167 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2168 arrayexpr->ts.kind, 0);
2172 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2173 arrayexpr->ts.kind);
2180 /* We start with the most negative possible value for MAXLOC, and the most
2181 positive possible value for MINLOC. The most negative possible value is
2182 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2183 possible value is HUGE in both cases. */
2185 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2186 gfc_add_modify (&se->pre, limit, tmp);
2188 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2189 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2190 build_int_cst (type, 1));
2192 /* Initialize the scalarizer. */
2193 gfc_init_loopinfo (&loop);
2194 gfc_add_ss_to_loop (&loop, arrayss);
2196 gfc_add_ss_to_loop (&loop, maskss);
2198 /* Initialize the loop. */
2199 gfc_conv_ss_startstride (&loop);
2200 gfc_conv_loop_setup (&loop, &expr->where);
2202 gcc_assert (loop.dimen == 1);
2204 /* Initialize the position to zero, following Fortran 2003. We are free
2205 to do this because Fortran 95 allows the result of an entirely false
2206 mask to be processor dependent. */
2207 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2209 gfc_mark_ss_chain_used (arrayss, 1);
2211 gfc_mark_ss_chain_used (maskss, 1);
2212 /* Generate the loop body. */
2213 gfc_start_scalarized_body (&loop, &body);
2215 /* If we have a mask, only check this element if the mask is set. */
2218 gfc_init_se (&maskse, NULL);
2219 gfc_copy_loopinfo_to_se (&maskse, &loop);
2221 gfc_conv_expr_val (&maskse, maskexpr);
2222 gfc_add_block_to_block (&body, &maskse.pre);
2224 gfc_start_block (&block);
2227 gfc_init_block (&block);
2229 /* Compare with the current limit. */
2230 gfc_init_se (&arrayse, NULL);
2231 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2232 arrayse.ss = arrayss;
2233 gfc_conv_expr_val (&arrayse, arrayexpr);
2234 gfc_add_block_to_block (&block, &arrayse.pre);
2236 /* We do the following if this is a more extreme value. */
2237 gfc_start_block (&ifblock);
2239 /* Assign the value to the limit... */
2240 gfc_add_modify (&ifblock, limit, arrayse.expr);
2242 /* Remember where we are. An offset must be added to the loop
2243 counter to obtain the required position. */
2245 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2246 gfc_index_one_node, loop.from[0]);
2248 tmp = gfc_index_one_node;
2250 gfc_add_modify (&block, offset, tmp);
2252 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2253 loop.loopvar[0], offset);
2254 gfc_add_modify (&ifblock, pos, tmp);
2256 ifbody = gfc_finish_block (&ifblock);
2258 /* If it is a more extreme value or pos is still zero and the value
2259 equal to the limit. */
2260 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2261 fold_build2 (EQ_EXPR, boolean_type_node,
2262 pos, gfc_index_zero_node),
2263 fold_build2 (EQ_EXPR, boolean_type_node,
2264 arrayse.expr, limit));
2265 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2266 fold_build2 (op, boolean_type_node,
2267 arrayse.expr, limit), tmp);
2268 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2269 gfc_add_expr_to_block (&block, tmp);
2273 /* We enclose the above in if (mask) {...}. */
2274 tmp = gfc_finish_block (&block);
2276 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2279 tmp = gfc_finish_block (&block);
2280 gfc_add_expr_to_block (&body, tmp);
2282 gfc_trans_scalarizing_loops (&loop, &body);
2284 /* For a scalar mask, enclose the loop in an if statement. */
2285 if (maskexpr && maskss == NULL)
2287 gfc_init_se (&maskse, NULL);
2288 gfc_conv_expr_val (&maskse, maskexpr);
2289 gfc_init_block (&block);
2290 gfc_add_block_to_block (&block, &loop.pre);
2291 gfc_add_block_to_block (&block, &loop.post);
2292 tmp = gfc_finish_block (&block);
2294 /* For the else part of the scalar mask, just initialize
2295 the pos variable the same way as above. */
2297 gfc_init_block (&elseblock);
2298 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2299 elsetmp = gfc_finish_block (&elseblock);
2301 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2302 gfc_add_expr_to_block (&block, tmp);
2303 gfc_add_block_to_block (&se->pre, &block);
2307 gfc_add_block_to_block (&se->pre, &loop.pre);
2308 gfc_add_block_to_block (&se->pre, &loop.post);
2310 gfc_cleanup_loop (&loop);
2312 se->expr = convert (type, pos);
2316 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
2325 gfc_actual_arglist *actual;
2330 gfc_expr *arrayexpr;
2336 gfc_conv_intrinsic_funcall (se, expr);
2340 type = gfc_typenode_for_spec (&expr->ts);
2341 /* Initialize the result. */
2342 limit = gfc_create_var (type, "limit");
2343 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2344 switch (expr->ts.type)
2347 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind, 0);
2351 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2358 /* We start with the most negative possible value for MAXVAL, and the most
2359 positive possible value for MINVAL. The most negative possible value is
2360 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2361 possible value is HUGE in both cases. */
2363 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2365 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2366 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2367 tmp, build_int_cst (type, 1));
2369 gfc_add_modify (&se->pre, limit, tmp);
2371 /* Walk the arguments. */
2372 actual = expr->value.function.actual;
2373 arrayexpr = actual->expr;
2374 arrayss = gfc_walk_expr (arrayexpr);
2375 gcc_assert (arrayss != gfc_ss_terminator);
2377 actual = actual->next->next;
2378 gcc_assert (actual);
2379 maskexpr = actual->expr;
2380 if (maskexpr && maskexpr->rank != 0)
2382 maskss = gfc_walk_expr (maskexpr);
2383 gcc_assert (maskss != gfc_ss_terminator);
2388 /* Initialize the scalarizer. */
2389 gfc_init_loopinfo (&loop);
2390 gfc_add_ss_to_loop (&loop, arrayss);
2392 gfc_add_ss_to_loop (&loop, maskss);
2394 /* Initialize the loop. */
2395 gfc_conv_ss_startstride (&loop);
2396 gfc_conv_loop_setup (&loop, &expr->where);
2398 gfc_mark_ss_chain_used (arrayss, 1);
2400 gfc_mark_ss_chain_used (maskss, 1);
2401 /* Generate the loop body. */
2402 gfc_start_scalarized_body (&loop, &body);
2404 /* If we have a mask, only add this element if the mask is set. */
2407 gfc_init_se (&maskse, NULL);
2408 gfc_copy_loopinfo_to_se (&maskse, &loop);
2410 gfc_conv_expr_val (&maskse, maskexpr);
2411 gfc_add_block_to_block (&body, &maskse.pre);
2413 gfc_start_block (&block);
2416 gfc_init_block (&block);
2418 /* Compare with the current limit. */
2419 gfc_init_se (&arrayse, NULL);
2420 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2421 arrayse.ss = arrayss;
2422 gfc_conv_expr_val (&arrayse, arrayexpr);
2423 gfc_add_block_to_block (&block, &arrayse.pre);
2425 /* Assign the value to the limit... */
2426 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2428 /* If it is a more extreme value. */
2429 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2430 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2431 gfc_add_expr_to_block (&block, tmp);
2432 gfc_add_block_to_block (&block, &arrayse.post);
2434 tmp = gfc_finish_block (&block);
2436 /* We enclose the above in if (mask) {...}. */
2437 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2438 gfc_add_expr_to_block (&body, tmp);
2440 gfc_trans_scalarizing_loops (&loop, &body);
2442 /* For a scalar mask, enclose the loop in an if statement. */
2443 if (maskexpr && maskss == NULL)
2445 gfc_init_se (&maskse, NULL);
2446 gfc_conv_expr_val (&maskse, maskexpr);
2447 gfc_init_block (&block);
2448 gfc_add_block_to_block (&block, &loop.pre);
2449 gfc_add_block_to_block (&block, &loop.post);
2450 tmp = gfc_finish_block (&block);
2452 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2453 gfc_add_expr_to_block (&block, tmp);
2454 gfc_add_block_to_block (&se->pre, &block);
2458 gfc_add_block_to_block (&se->pre, &loop.pre);
2459 gfc_add_block_to_block (&se->pre, &loop.post);
2462 gfc_cleanup_loop (&loop);
2467 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2469 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2475 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2476 type = TREE_TYPE (args[0]);
2478 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2479 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2480 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2481 build_int_cst (type, 0));
2482 type = gfc_typenode_for_spec (&expr->ts);
2483 se->expr = convert (type, tmp);
2486 /* Generate code to perform the specified operation. */
2488 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
2492 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2493 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2498 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2502 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2503 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2506 /* Set or clear a single bit. */
2508 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2515 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2516 type = TREE_TYPE (args[0]);
2518 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2524 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2526 se->expr = fold_build2 (op, type, args[0], tmp);
2529 /* Extract a sequence of bits.
2530 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2532 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2539 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2540 type = TREE_TYPE (args[0]);
2542 mask = build_int_cst (type, -1);
2543 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2544 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2546 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2548 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2551 /* RSHIFT (I, SHIFT) = I >> SHIFT
2552 LSHIFT (I, SHIFT) = I << SHIFT */
2554 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2558 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2560 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2561 TREE_TYPE (args[0]), args[0], args[1]);
2564 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2566 : ((shift >= 0) ? i << shift : i >> -shift)
2567 where all shifts are logical shifts. */
2569 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2581 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2582 type = TREE_TYPE (args[0]);
2583 utype = unsigned_type_for (type);
2585 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2587 /* Left shift if positive. */
2588 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2590 /* Right shift if negative.
2591 We convert to an unsigned type because we want a logical shift.
2592 The standard doesn't define the case of shifting negative
2593 numbers, and we try to be compatible with other compilers, most
2594 notably g77, here. */
2595 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2596 convert (utype, args[0]), width));
2598 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2599 build_int_cst (TREE_TYPE (args[1]), 0));
2600 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2602 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2603 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2605 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2606 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2608 se->expr = fold_build3 (COND_EXPR, type, cond,
2609 build_int_cst (type, 0), tmp);
2613 /* Circular shift. AKA rotate or barrel shift. */
2616 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2624 unsigned int num_args;
2626 num_args = gfc_intrinsic_argument_list_length (expr);
2627 args = (tree *) alloca (sizeof (tree) * num_args);
2629 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2633 /* Use a library function for the 3 parameter version. */
2634 tree int4type = gfc_get_int_type (4);
2636 type = TREE_TYPE (args[0]);
2637 /* We convert the first argument to at least 4 bytes, and
2638 convert back afterwards. This removes the need for library
2639 functions for all argument sizes, and function will be
2640 aligned to at least 32 bits, so there's no loss. */
2641 if (expr->ts.kind < 4)
2642 args[0] = convert (int4type, args[0]);
2644 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2645 need loads of library functions. They cannot have values >
2646 BIT_SIZE (I) so the conversion is safe. */
2647 args[1] = convert (int4type, args[1]);
2648 args[2] = convert (int4type, args[2]);
2650 switch (expr->ts.kind)
2655 tmp = gfor_fndecl_math_ishftc4;
2658 tmp = gfor_fndecl_math_ishftc8;
2661 tmp = gfor_fndecl_math_ishftc16;
2666 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2667 /* Convert the result back to the original type, if we extended
2668 the first argument's width above. */
2669 if (expr->ts.kind < 4)
2670 se->expr = convert (type, se->expr);
2674 type = TREE_TYPE (args[0]);
2676 /* Rotate left if positive. */
2677 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2679 /* Rotate right if negative. */
2680 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2681 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2683 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2684 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2685 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2687 /* Do nothing if shift == 0. */
2688 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2689 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2692 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
2693 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
2695 The conditional expression is necessary because the result of LEADZ(0)
2696 is defined, but the result of __builtin_clz(0) is undefined for most
2699 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
2700 difference in bit size between the argument of LEADZ and the C int. */
2703 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
2715 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2717 /* Which variant of __builtin_clz* should we call? */
2718 arg_kind = expr->value.function.actual->expr->ts.kind;
2719 i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
2725 arg_type = unsigned_type_node;
2730 arg_type = long_unsigned_type_node;
2735 arg_type = long_long_unsigned_type_node;
2743 /* Convert the actual argument to the proper argument type for the built-in
2744 function. But the return type is of the default INTEGER kind. */
2745 arg = fold_convert (arg_type, arg);
2746 result_type = gfc_get_int_type (gfc_default_integer_kind);
2748 /* Compute LEADZ for the case i .ne. 0. */
2749 s = TYPE_PRECISION (arg_type) - gfc_integer_kinds[i].bit_size;
2750 tmp = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
2751 leadz = fold_build2 (MINUS_EXPR, result_type,
2752 tmp, build_int_cst (result_type, s));
2754 /* Build BIT_SIZE. */
2755 bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
2757 /* ??? For some combinations of targets and integer kinds, the condition
2758 can be avoided if CLZ_DEFINED_VALUE_AT_ZERO is used. Later. */
2759 cond = fold_build2 (EQ_EXPR, boolean_type_node,
2760 arg, build_int_cst (arg_type, 0));
2761 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
2764 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
2766 The conditional expression is necessary because the result of TRAILZ(0)
2767 is defined, but the result of __builtin_ctz(0) is undefined for most
2771 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
2782 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2784 /* Which variant of __builtin_clz* should we call? */
2785 arg_kind = expr->value.function.actual->expr->ts.kind;
2786 i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
2787 switch (expr->ts.kind)
2792 arg_type = unsigned_type_node;
2797 arg_type = long_unsigned_type_node;
2802 arg_type = long_long_unsigned_type_node;
2810 /* Convert the actual argument to the proper argument type for the built-in
2811 function. But the return type is of the default INTEGER kind. */
2812 arg = fold_convert (arg_type, arg);
2813 result_type = gfc_get_int_type (gfc_default_integer_kind);
2815 /* Compute TRAILZ for the case i .ne. 0. */
2816 trailz = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
2818 /* Build BIT_SIZE. */
2819 bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
2821 /* ??? For some combinations of targets and integer kinds, the condition
2822 can be avoided if CTZ_DEFINED_VALUE_AT_ZERO is used. Later. */
2823 cond = fold_build2 (EQ_EXPR, boolean_type_node,
2824 arg, build_int_cst (arg_type, 0));
2825 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
2828 /* Process an intrinsic with unspecified argument-types that has an optional
2829 argument (which could be of type character), e.g. EOSHIFT. For those, we
2830 need to append the string length of the optional argument if it is not
2831 present and the type is really character.
2832 primary specifies the position (starting at 1) of the non-optional argument
2833 specifying the type and optional gives the position of the optional
2834 argument in the arglist. */
2837 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
2838 unsigned primary, unsigned optional)
2840 gfc_actual_arglist* prim_arg;
2841 gfc_actual_arglist* opt_arg;
2843 gfc_actual_arglist* arg;
2847 /* Find the two arguments given as position. */
2851 for (arg = expr->value.function.actual; arg; arg = arg->next)
2855 if (cur_pos == primary)
2857 if (cur_pos == optional)
2860 if (cur_pos >= primary && cur_pos >= optional)
2863 gcc_assert (prim_arg);
2864 gcc_assert (prim_arg->expr);
2865 gcc_assert (opt_arg);
2867 /* If we do have type CHARACTER and the optional argument is really absent,
2868 append a dummy 0 as string length. */
2869 append_args = NULL_TREE;
2870 if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
2874 dummy = build_int_cst (gfc_charlen_type_node, 0);
2875 append_args = gfc_chainon_list (append_args, dummy);
2878 /* Build the call itself. */
2879 sym = gfc_get_symbol_for_expr (expr);
2880 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
2885 /* The length of a character string. */
2887 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2897 gcc_assert (!se->ss);
2899 arg = expr->value.function.actual->expr;
2901 type = gfc_typenode_for_spec (&expr->ts);
2902 switch (arg->expr_type)
2905 len = build_int_cst (NULL_TREE, arg->value.character.length);
2909 /* Obtain the string length from the function used by
2910 trans-array.c(gfc_trans_array_constructor). */
2912 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2916 if (arg->ref == NULL
2917 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2919 /* This doesn't catch all cases.
2920 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2921 and the surrounding thread. */
2922 sym = arg->symtree->n.sym;
2923 decl = gfc_get_symbol_decl (sym);
2924 if (decl == current_function_decl && sym->attr.function
2925 && (sym->result == sym))
2926 decl = gfc_get_fake_result_decl (sym, 0);
2928 len = sym->ts.cl->backend_decl;
2933 /* Otherwise fall through. */
2936 /* Anybody stupid enough to do this deserves inefficient code. */
2937 ss = gfc_walk_expr (arg);
2938 gfc_init_se (&argse, se);
2939 if (ss == gfc_ss_terminator)
2940 gfc_conv_expr (&argse, arg);
2942 gfc_conv_expr_descriptor (&argse, arg, ss);
2943 gfc_add_block_to_block (&se->pre, &argse.pre);
2944 gfc_add_block_to_block (&se->post, &argse.post);
2945 len = argse.string_length;
2948 se->expr = convert (type, len);
2951 /* The length of a character string not including trailing blanks. */
2953 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2955 int kind = expr->value.function.actual->expr->ts.kind;
2956 tree args[2], type, fndecl;
2958 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2959 type = gfc_typenode_for_spec (&expr->ts);
2962 fndecl = gfor_fndecl_string_len_trim;
2964 fndecl = gfor_fndecl_string_len_trim_char4;
2968 se->expr = build_call_expr (fndecl, 2, args[0], args[1]);
2969 se->expr = convert (type, se->expr);
2973 /* Returns the starting position of a substring within a string. */
2976 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2979 tree logical4_type_node = gfc_get_logical_type (4);
2983 unsigned int num_args;
2985 args = (tree *) alloca (sizeof (tree) * 5);
2987 /* Get number of arguments; characters count double due to the
2988 string length argument. Kind= is not passed to the library
2989 and thus ignored. */
2990 if (expr->value.function.actual->next->next->expr == NULL)
2995 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2996 type = gfc_typenode_for_spec (&expr->ts);
2999 args[4] = build_int_cst (logical4_type_node, 0);
3001 args[4] = convert (logical4_type_node, args[4]);
3003 fndecl = build_addr (function, current_function_decl);
3004 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
3006 se->expr = convert (type, se->expr);
3010 /* The ascii value for a single character. */
3012 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
3014 tree args[2], type, pchartype;
3016 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3017 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
3018 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
3019 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
3020 type = gfc_typenode_for_spec (&expr->ts);
3022 se->expr = build_fold_indirect_ref (args[1]);
3023 se->expr = convert (type, se->expr);
3027 /* Intrinsic ISNAN calls __builtin_isnan. */
3030 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
3034 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3035 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
3036 STRIP_TYPE_NOPS (se->expr);
3037 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3041 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
3042 their argument against a constant integer value. */
3045 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
3049 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3050 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
3051 arg, build_int_cst (TREE_TYPE (arg), value));
3056 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
3059 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
3067 unsigned int num_args;
3069 num_args = gfc_intrinsic_argument_list_length (expr);
3070 args = (tree *) alloca (sizeof (tree) * num_args);
3072 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3073 if (expr->ts.type != BT_CHARACTER)
3081 /* We do the same as in the non-character case, but the argument
3082 list is different because of the string length arguments. We
3083 also have to set the string length for the result. */
3090 gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
3092 se->string_length = len;
3094 type = TREE_TYPE (tsource);
3095 se->expr = fold_build3 (COND_EXPR, type, mask, tsource,
3096 fold_convert (type, fsource));
3100 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
3102 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
3104 tree arg, type, tmp;
3107 switch (expr->ts.kind)
3110 frexp = BUILT_IN_FREXPF;
3113 frexp = BUILT_IN_FREXP;
3117 frexp = BUILT_IN_FREXPL;
3123 type = gfc_typenode_for_spec (&expr->ts);
3124 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3125 tmp = gfc_create_var (integer_type_node, NULL);
3126 se->expr = build_call_expr (built_in_decls[frexp], 2,
3127 fold_convert (type, arg),
3128 gfc_build_addr_expr (NULL_TREE, tmp));
3129 se->expr = fold_convert (type, se->expr);
3133 /* NEAREST (s, dir) is translated into
3134 tmp = copysign (HUGE_VAL, dir);
3135 return nextafter (s, tmp);
3138 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
3140 tree args[2], type, tmp;
3141 int nextafter, copysign, huge_val;
3143 switch (expr->ts.kind)
3146 nextafter = BUILT_IN_NEXTAFTERF;
3147 copysign = BUILT_IN_COPYSIGNF;
3148 huge_val = BUILT_IN_HUGE_VALF;
3151 nextafter = BUILT_IN_NEXTAFTER;
3152 copysign = BUILT_IN_COPYSIGN;
3153 huge_val = BUILT_IN_HUGE_VAL;
3157 nextafter = BUILT_IN_NEXTAFTERL;
3158 copysign = BUILT_IN_COPYSIGNL;
3159 huge_val = BUILT_IN_HUGE_VALL;
3165 type = gfc_typenode_for_spec (&expr->ts);
3166 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3167 tmp = build_call_expr (built_in_decls[copysign], 2,
3168 build_call_expr (built_in_decls[huge_val], 0),
3169 fold_convert (type, args[1]));
3170 se->expr = build_call_expr (built_in_decls[nextafter], 2,
3171 fold_convert (type, args[0]), tmp);
3172 se->expr = fold_convert (type, se->expr);
3176 /* SPACING (s) is translated into
3184 e = MAX_EXPR (e, emin);
3185 res = scalbn (1., e);
3189 where prec is the precision of s, gfc_real_kinds[k].digits,
3190 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
3191 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
3194 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
3196 tree arg, type, prec, emin, tiny, res, e;
3198 int frexp, scalbn, k;
3201 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3202 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
3203 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
3204 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
3206 switch (expr->ts.kind)
3209 frexp = BUILT_IN_FREXPF;
3210 scalbn = BUILT_IN_SCALBNF;
3213 frexp = BUILT_IN_FREXP;
3214 scalbn = BUILT_IN_SCALBN;
3218 frexp = BUILT_IN_FREXPL;
3219 scalbn = BUILT_IN_SCALBNL;
3225 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3226 arg = gfc_evaluate_now (arg, &se->pre);
3228 type = gfc_typenode_for_spec (&expr->ts);
3229 e = gfc_create_var (integer_type_node, NULL);
3230 res = gfc_create_var (type, NULL);
3233 /* Build the block for s /= 0. */
3234 gfc_start_block (&block);
3235 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3236 gfc_build_addr_expr (NULL_TREE, e));
3237 gfc_add_expr_to_block (&block, tmp);
3239 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3240 gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3243 tmp = build_call_expr (built_in_decls[scalbn], 2,
3244 build_real_from_int_cst (type, integer_one_node), e);
3245 gfc_add_modify (&block, res, tmp);
3247 /* Finish by building the IF statement. */
3248 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3249 build_real_from_int_cst (type, integer_zero_node));
3250 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3251 gfc_finish_block (&block));
3253 gfc_add_expr_to_block (&se->pre, tmp);
3258 /* RRSPACING (s) is translated into
3265 x = scalbn (x, precision - e);
3269 where precision is gfc_real_kinds[k].digits. */
3272 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3274 tree arg, type, e, x, cond, stmt, tmp;
3275 int frexp, scalbn, fabs, prec, k;
3278 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3279 prec = gfc_real_kinds[k].digits;
3280 switch (expr->ts.kind)
3283 frexp = BUILT_IN_FREXPF;
3284 scalbn = BUILT_IN_SCALBNF;
3285 fabs = BUILT_IN_FABSF;
3288 frexp = BUILT_IN_FREXP;
3289 scalbn = BUILT_IN_SCALBN;
3290 fabs = BUILT_IN_FABS;
3294 frexp = BUILT_IN_FREXPL;
3295 scalbn = BUILT_IN_SCALBNL;
3296 fabs = BUILT_IN_FABSL;
3302 type = gfc_typenode_for_spec (&expr->ts);
3303 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3304 arg = gfc_evaluate_now (arg, &se->pre);
3306 e = gfc_create_var (integer_type_node, NULL);
3307 x = gfc_create_var (type, NULL);
3308 gfc_add_modify (&se->pre, x,
3309 build_call_expr (built_in_decls[fabs], 1, arg));
3312 gfc_start_block (&block);
3313 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3314 gfc_build_addr_expr (NULL_TREE, e));
3315 gfc_add_expr_to_block (&block, tmp);
3317 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3318 build_int_cst (NULL_TREE, prec), e);
3319 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3320 gfc_add_modify (&block, x, tmp);
3321 stmt = gfc_finish_block (&block);
3323 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3324 build_real_from_int_cst (type, integer_zero_node));
3325 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3326 gfc_add_expr_to_block (&se->pre, tmp);
3328 se->expr = fold_convert (type, x);
3332 /* SCALE (s, i) is translated into scalbn (s, i). */
3334 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3339 switch (expr->ts.kind)
3342 scalbn = BUILT_IN_SCALBNF;
3345 scalbn = BUILT_IN_SCALBN;
3349 scalbn = BUILT_IN_SCALBNL;
3355 type = gfc_typenode_for_spec (&expr->ts);
3356 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3357 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3358 fold_convert (type, args[0]),
3359 fold_convert (integer_type_node, args[1]));
3360 se->expr = fold_convert (type, se->expr);
3364 /* SET_EXPONENT (s, i) is translated into
3365 scalbn (frexp (s, &dummy_int), i). */
3367 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3369 tree args[2], type, tmp;
3372 switch (expr->ts.kind)
3375 frexp = BUILT_IN_FREXPF;
3376 scalbn = BUILT_IN_SCALBNF;
3379 frexp = BUILT_IN_FREXP;
3380 scalbn = BUILT_IN_SCALBN;
3384 frexp = BUILT_IN_FREXPL;
3385 scalbn = BUILT_IN_SCALBNL;
3391 type = gfc_typenode_for_spec (&expr->ts);
3392 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3394 tmp = gfc_create_var (integer_type_node, NULL);
3395 tmp = build_call_expr (built_in_decls[frexp], 2,
3396 fold_convert (type, args[0]),
3397 gfc_build_addr_expr (NULL_TREE, tmp));
3398 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3399 fold_convert (integer_type_node, args[1]));
3400 se->expr = fold_convert (type, se->expr);
3405 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3407 gfc_actual_arglist *actual;
3415 gfc_init_se (&argse, NULL);
3416 actual = expr->value.function.actual;
3418 ss = gfc_walk_expr (actual->expr);
3419 gcc_assert (ss != gfc_ss_terminator);
3420 argse.want_pointer = 1;
3421 argse.data_not_needed = 1;
3422 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3423 gfc_add_block_to_block (&se->pre, &argse.pre);
3424 gfc_add_block_to_block (&se->post, &argse.post);
3425 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3427 /* Build the call to size0. */
3428 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3430 actual = actual->next;
3434 gfc_init_se (&argse, NULL);
3435 gfc_conv_expr_type (&argse, actual->expr,
3436 gfc_array_index_type);
3437 gfc_add_block_to_block (&se->pre, &argse.pre);
3439 /* Unusually, for an intrinsic, size does not exclude
3440 an optional arg2, so we must test for it. */
3441 if (actual->expr->expr_type == EXPR_VARIABLE
3442 && actual->expr->symtree->n.sym->attr.dummy
3443 && actual->expr->symtree->n.sym->attr.optional)
3446 /* Build the call to size1. */
3447 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3450 gfc_init_se (&argse, NULL);
3451 argse.want_pointer = 1;
3452 argse.data_not_needed = 1;
3453 gfc_conv_expr (&argse, actual->expr);
3454 gfc_add_block_to_block (&se->pre, &argse.pre);
3455 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3456 argse.expr, null_pointer_node);
3457 tmp = gfc_evaluate_now (tmp, &se->pre);
3458 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3459 tmp, fncall1, fncall0);
3463 se->expr = NULL_TREE;
3464 argse.expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3465 argse.expr, gfc_index_one_node);
3468 else if (expr->value.function.actual->expr->rank == 1)
3470 argse.expr = gfc_index_zero_node;
3471 se->expr = NULL_TREE;
3476 if (se->expr == NULL_TREE)
3478 tree ubound, lbound;
3480 arg1 = build_fold_indirect_ref (arg1);
3481 ubound = gfc_conv_descriptor_ubound (arg1, argse.expr);
3482 lbound = gfc_conv_descriptor_lbound (arg1, argse.expr);
3483 se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3485 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
3486 gfc_index_one_node);
3487 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
3488 gfc_index_zero_node);
3491 type = gfc_typenode_for_spec (&expr->ts);
3492 se->expr = convert (type, se->expr);
3496 /* Helper function to compute the size of a character variable,
3497 excluding the terminating null characters. The result has
3498 gfc_array_index_type type. */
3501 size_of_string_in_bytes (int kind, tree string_length)
3504 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3506 bytesize = build_int_cst (gfc_array_index_type,
3507 gfc_character_kinds[i].bit_size / 8);
3509 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3510 fold_convert (gfc_array_index_type, string_length));
3515 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3528 arg = expr->value.function.actual->expr;
3530 gfc_init_se (&argse, NULL);
3531 ss = gfc_walk_expr (arg);
3533 if (ss == gfc_ss_terminator)
3535 gfc_conv_expr_reference (&argse, arg);
3536 source = argse.expr;
3538 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3540 /* Obtain the source word length. */
3541 if (arg->ts.type == BT_CHARACTER)
3542 se->expr = size_of_string_in_bytes (arg->ts.kind,
3543 argse.string_length);
3545 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
3549 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3550 argse.want_pointer = 0;
3551 gfc_conv_expr_descriptor (&argse, arg, ss);
3552 source = gfc_conv_descriptor_data_get (argse.expr);
3553 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3555 /* Obtain the argument's word length. */
3556 if (arg->ts.type == BT_CHARACTER)
3557 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3559 tmp = fold_convert (gfc_array_index_type,
3560 size_in_bytes (type));
3561 gfc_add_modify (&argse.pre, source_bytes, tmp);
3563 /* Obtain the size of the array in bytes. */
3564 for (n = 0; n < arg->rank; n++)
3567 idx = gfc_rank_cst[n];
3568 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3569 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3570 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3572 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3573 tmp, gfc_index_one_node);
3574 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3576 gfc_add_modify (&argse.pre, source_bytes, tmp);
3578 se->expr = source_bytes;
3581 gfc_add_block_to_block (&se->pre, &argse.pre);
3585 /* Intrinsic string comparison functions. */
3588 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
3592 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3595 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
3596 expr->value.function.actual->expr->ts.kind);
3597 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3598 build_int_cst (TREE_TYPE (se->expr), 0));
3601 /* Generate a call to the adjustl/adjustr library function. */
3603 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3611 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3614 type = TREE_TYPE (args[2]);
3615 var = gfc_conv_string_tmp (se, type, len);
3618 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3619 gfc_add_expr_to_block (&se->pre, tmp);
3621 se->string_length = len;
3625 /* Generate code for the TRANSFER intrinsic:
3627 DEST = TRANSFER (SOURCE, MOLD)
3629 typeof<DEST> = typeof<MOLD>
3634 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3636 typeof<DEST> = typeof<MOLD>
3638 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3639 sizeof (DEST(0) * SIZE). */
3641 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3658 gfc_actual_arglist *arg;
3668 info = &se->ss->data.info;
3670 /* Convert SOURCE. The output from this stage is:-
3671 source_bytes = length of the source in bytes
3672 source = pointer to the source data. */
3673 arg = expr->value.function.actual;
3675 /* Ensure double transfer through LOGICAL preserves all
3677 if (arg->expr->expr_type == EXPR_FUNCTION
3678 && arg->expr->value.function.esym == NULL
3679 && arg->expr->value.function.isym != NULL
3680 && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
3681 && arg->expr->ts.type == BT_LOGICAL
3682 && expr->ts.type != arg->expr->ts.type)
3683 arg->expr->value.function.name = "__transfer_in_transfer";
3685 gfc_init_se (&argse, NULL);
3686 ss = gfc_walk_expr (arg->expr);
3688 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3690 /* Obtain the pointer to source and the length of source in bytes. */
3691 if (ss == gfc_ss_terminator)
3693 gfc_conv_expr_reference (&argse, arg->expr);
3694 source = argse.expr;
3696 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3698 /* Obtain the source word length. */
3699 if (arg->expr->ts.type == BT_CHARACTER)
3700 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3701 argse.string_length);
3703 tmp = fold_convert (gfc_array_index_type,
3704 size_in_bytes (source_type));
3708 argse.want_pointer = 0;
3709 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3710 source = gfc_conv_descriptor_data_get (argse.expr);
3711 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3713 /* Repack the source if not a full variable array. */
3714 if (arg->expr->expr_type == EXPR_VARIABLE
3715 && arg->expr->ref->u.ar.type != AR_FULL)
3717 tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
3719 if (gfc_option.warn_array_temp)
3720 gfc_warning ("Creating array temporary at %L", &expr->where);
3722 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3723 source = gfc_evaluate_now (source, &argse.pre);
3725 /* Free the temporary. */
3726 gfc_start_block (&block);
3727 tmp = gfc_call_free (convert (pvoid_type_node, source));
3728 gfc_add_expr_to_block (&block, tmp);
3729 stmt = gfc_finish_block (&block);
3731 /* Clean up if it was repacked. */
3732 gfc_init_block (&block);
3733 tmp = gfc_conv_array_data (argse.expr);
3734 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3735 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3736 gfc_add_expr_to_block (&block, tmp);
3737 gfc_add_block_to_block (&block, &se->post);
3738 gfc_init_block (&se->post);
3739 gfc_add_block_to_block (&se->post, &block);
3742 /* Obtain the source word length. */
3743 if (arg->expr->ts.type == BT_CHARACTER)
3744 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3745 argse.string_length);
3747 tmp = fold_convert (gfc_array_index_type,
3748 size_in_bytes (source_type));
3750 /* Obtain the size of the array in bytes. */
3751 extent = gfc_create_var (gfc_array_index_type, NULL);
3752 for (n = 0; n < arg->expr->rank; n++)
3755 idx = gfc_rank_cst[n];
3756 gfc_add_modify (&argse.pre, source_bytes, tmp);
3757 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3758 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3759 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3760 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3762 gfc_add_modify (&argse.pre, extent, tmp);
3763 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3764 extent, gfc_index_one_node);
3765 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3770 gfc_add_modify (&argse.pre, source_bytes, tmp);
3771 gfc_add_block_to_block (&se->pre, &argse.pre);
3772 gfc_add_block_to_block (&se->post, &argse.post);
3774 /* Now convert MOLD. The outputs are:
3775 mold_type = the TREE type of MOLD
3776 dest_word_len = destination word length in bytes. */
3779 gfc_init_se (&argse, NULL);
3780 ss = gfc_walk_expr (arg->expr);
3782 scalar_mold = arg->expr->rank == 0;
3784 if (ss == gfc_ss_terminator)
3786 gfc_conv_expr_reference (&argse, arg->expr);
3787 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3791 gfc_init_se (&argse, NULL);
3792 argse.want_pointer = 0;
3793 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3794 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3797 gfc_add_block_to_block (&se->pre, &argse.pre);
3798 gfc_add_block_to_block (&se->post, &argse.post);
3800 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
3802 /* If this TRANSFER is nested in another TRANSFER, use a type
3803 that preserves all bits. */
3804 if (arg->expr->ts.type == BT_LOGICAL)
3805 mold_type = gfc_get_int_type (arg->expr->ts.kind);
3808 if (arg->expr->ts.type == BT_CHARACTER)
3810 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
3811 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3814 tmp = fold_convert (gfc_array_index_type,
3815 size_in_bytes (mold_type));
3817 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3818 gfc_add_modify (&se->pre, dest_word_len, tmp);
3820 /* Finally convert SIZE, if it is present. */
3822 size_words = gfc_create_var (gfc_array_index_type, NULL);
3826 gfc_init_se (&argse, NULL);
3827 gfc_conv_expr_reference (&argse, arg->expr);
3828 tmp = convert (gfc_array_index_type,
3829 build_fold_indirect_ref (argse.expr));
3830 gfc_add_block_to_block (&se->pre, &argse.pre);
3831 gfc_add_block_to_block (&se->post, &argse.post);
3836 /* Separate array and scalar results. */
3837 if (scalar_mold && tmp == NULL_TREE)
3838 goto scalar_transfer;
3840 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3841 if (tmp != NULL_TREE)
3842 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3843 tmp, dest_word_len);
3847 gfc_add_modify (&se->pre, size_bytes, tmp);
3848 gfc_add_modify (&se->pre, size_words,
3849 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3850 size_bytes, dest_word_len));
3852 /* Evaluate the bounds of the result. If the loop range exists, we have
3853 to check if it is too large. If so, we modify loop->to be consistent
3854 with min(size, size(source)). Otherwise, size is made consistent with
3855 the loop range, so that the right number of bytes is transferred.*/
3856 n = se->loop->order[0];
3857 if (se->loop->to[n] != NULL_TREE)
3859 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3860 se->loop->to[n], se->loop->from[n]);
3861 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3862 tmp, gfc_index_one_node);
3863 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3865 gfc_add_modify (&se->pre, size_words, tmp);
3866 gfc_add_modify (&se->pre, size_bytes,
3867 fold_build2 (MULT_EXPR, gfc_array_index_type,
3868 size_words, dest_word_len));
3869 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3870 size_words, se->loop->from[n]);
3871 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3872 upper, gfc_index_one_node);
3876 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3877 size_words, gfc_index_one_node);
3878 se->loop->from[n] = gfc_index_zero_node;
3881 se->loop->to[n] = upper;
3883 /* Build a destination descriptor, using the pointer, source, as the
3885 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3886 info, mold_type, NULL_TREE, false, true, false,
3889 /* Cast the pointer to the result. */
3890 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3891 tmp = fold_convert (pvoid_type_node, tmp);
3893 /* Use memcpy to do the transfer. */
3894 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3897 fold_convert (pvoid_type_node, source),
3898 fold_build2 (MIN_EXPR, gfc_array_index_type,
3899 size_bytes, source_bytes));
3900 gfc_add_expr_to_block (&se->pre, tmp);
3902 se->expr = info->descriptor;
3903 if (expr->ts.type == BT_CHARACTER)
3904 se->string_length = dest_word_len;
3908 /* Deal with scalar results. */
3910 extent = fold_build2 (MIN_EXPR, gfc_array_index_type,
3911 dest_word_len, source_bytes);
3913 if (expr->ts.type == BT_CHARACTER)
3918 ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
3919 tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
3922 /* If source is longer than the destination, use a pointer to
3923 the source directly. */
3924 gfc_init_block (&block);
3925 gfc_add_modify (&block, tmpdecl, ptr);
3926 direct = gfc_finish_block (&block);
3928 /* Otherwise, allocate a string with the length of the destination
3929 and copy the source into it. */
3930 gfc_init_block (&block);
3931 tmp = gfc_get_pchar_type (expr->ts.kind);
3932 tmp = gfc_call_malloc (&block, tmp, dest_word_len);
3933 gfc_add_modify (&block, tmpdecl,
3934 fold_convert (TREE_TYPE (ptr), tmp));
3935 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3936 fold_convert (pvoid_type_node, tmpdecl),
3937 fold_convert (pvoid_type_node, ptr),
3939 gfc_add_expr_to_block (&block, tmp);
3940 indirect = gfc_finish_block (&block);
3942 /* Wrap it up with the condition. */
3943 tmp = fold_build2 (LE_EXPR, boolean_type_node,
3944 dest_word_len, source_bytes);
3945 tmp = build3_v (COND_EXPR, tmp, direct, indirect);
3946 gfc_add_expr_to_block (&se->pre, tmp);
3949 se->string_length = dest_word_len;
3953 tmpdecl = gfc_create_var (mold_type, "transfer");
3955 ptr = convert (build_pointer_type (mold_type), source);
3957 /* Use memcpy to do the transfer. */
3958 tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
3959 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3960 fold_convert (pvoid_type_node, tmp),
3961 fold_convert (pvoid_type_node, ptr),
3963 gfc_add_expr_to_block (&se->pre, tmp);
3970 /* Generate code for the ALLOCATED intrinsic.
3971 Generate inline code that directly check the address of the argument. */
3974 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3976 gfc_actual_arglist *arg1;
3981 gfc_init_se (&arg1se, NULL);
3982 arg1 = expr->value.function.actual;
3983 ss1 = gfc_walk_expr (arg1->expr);
3984 arg1se.descriptor_only = 1;
3985 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3987 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3988 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3989 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3990 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3994 /* Generate code for the ASSOCIATED intrinsic.
3995 If both POINTER and TARGET are arrays, generate a call to library function
3996 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3997 In other cases, generate inline code that directly compare the address of
3998 POINTER with the address of TARGET. */
4001 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
4003 gfc_actual_arglist *arg1;
4004 gfc_actual_arglist *arg2;
4009 tree nonzero_charlen;
4010 tree nonzero_arraylen;
4013 gfc_init_se (&arg1se, NULL);
4014 gfc_init_se (&arg2se, NULL);
4015 arg1 = expr->value.function.actual;
4017 ss1 = gfc_walk_expr (arg1->expr);
4021 /* No optional target. */
4022 if (ss1 == gfc_ss_terminator)
4024 /* A pointer to a scalar. */
4025 arg1se.want_pointer = 1;
4026 gfc_conv_expr (&arg1se, arg1->expr);
4031 /* A pointer to an array. */
4032 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4033 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
4035 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4036 gfc_add_block_to_block (&se->post, &arg1se.post);
4037 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
4038 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
4043 /* An optional target. */
4044 ss2 = gfc_walk_expr (arg2->expr);
4046 nonzero_charlen = NULL_TREE;
4047 if (arg1->expr->ts.type == BT_CHARACTER)
4048 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
4049 arg1->expr->ts.cl->backend_decl,
4052 if (ss1 == gfc_ss_terminator)
4054 /* A pointer to a scalar. */
4055 gcc_assert (ss2 == gfc_ss_terminator);
4056 arg1se.want_pointer = 1;
4057 gfc_conv_expr (&arg1se, arg1->expr);
4058 arg2se.want_pointer = 1;
4059 gfc_conv_expr (&arg2se, arg2->expr);
4060 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4061 gfc_add_block_to_block (&se->post, &arg1se.post);
4062 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4063 arg1se.expr, arg2se.expr);
4064 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
4065 arg1se.expr, null_pointer_node);
4066 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4071 /* An array pointer of zero length is not associated if target is
4073 arg1se.descriptor_only = 1;
4074 gfc_conv_expr_lhs (&arg1se, arg1->expr);
4075 tmp = gfc_conv_descriptor_stride (arg1se.expr,
4076 gfc_rank_cst[arg1->expr->rank - 1]);
4077 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
4078 build_int_cst (TREE_TYPE (tmp), 0));
4080 /* A pointer to an array, call library function _gfor_associated. */
4081 gcc_assert (ss2 != gfc_ss_terminator);
4082 arg1se.want_pointer = 1;
4083 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4085 arg2se.want_pointer = 1;
4086 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
4087 gfc_add_block_to_block (&se->pre, &arg2se.pre);
4088 gfc_add_block_to_block (&se->post, &arg2se.post);
4089 se->expr = build_call_expr (gfor_fndecl_associated, 2,
4090 arg1se.expr, arg2se.expr);
4091 se->expr = convert (boolean_type_node, se->expr);
4092 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4093 se->expr, nonzero_arraylen);
4096 /* If target is present zero character length pointers cannot
4098 if (nonzero_charlen != NULL_TREE)
4099 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4100 se->expr, nonzero_charlen);
4103 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4107 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
4110 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
4114 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4115 se->expr = build_call_expr (gfor_fndecl_sc_kind, 2, args[0], args[1]);
4116 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4120 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
4123 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
4127 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4129 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
4130 type = gfc_get_int_type (4);
4131 arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
4133 /* Convert it to the required type. */
4134 type = gfc_typenode_for_spec (&expr->ts);
4135 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
4136 se->expr = fold_convert (type, se->expr);
4140 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
4143 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
4145 gfc_actual_arglist *actual;
4150 for (actual = expr->value.function.actual; actual; actual = actual->next)
4152 gfc_init_se (&argse, se);
4154 /* Pass a NULL pointer for an absent arg. */
4155 if (actual->expr == NULL)
4156 argse.expr = null_pointer_node;
4162 if (actual->expr->ts.kind != gfc_c_int_kind)
4164 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
4165 ts.type = BT_INTEGER;
4166 ts.kind = gfc_c_int_kind;
4167 gfc_convert_type (actual->expr, &ts, 2);
4169 gfc_conv_expr_reference (&argse, actual->expr);
4172 gfc_add_block_to_block (&se->pre, &argse.pre);
4173 gfc_add_block_to_block (&se->post, &argse.post);
4174 args = gfc_chainon_list (args, argse.expr);
4177 /* Convert it to the required type. */
4178 type = gfc_typenode_for_spec (&expr->ts);
4179 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
4180 se->expr = fold_convert (type, se->expr);
4184 /* Generate code for TRIM (A) intrinsic function. */
4187 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
4197 unsigned int num_args;
4199 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
4200 args = (tree *) alloca (sizeof (tree) * num_args);
4202 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
4203 addr = gfc_build_addr_expr (ppvoid_type_node, var);
4204 len = gfc_create_var (gfc_get_int_type (4), "len");
4206 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
4207 args[0] = gfc_build_addr_expr (NULL_TREE, len);
4210 if (expr->ts.kind == 1)
4211 function = gfor_fndecl_string_trim;
4212 else if (expr->ts.kind == 4)
4213 function = gfor_fndecl_string_trim_char4;
4217 fndecl = build_addr (function, current_function_decl);
4218 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
4220 gfc_add_expr_to_block (&se->pre, tmp);
4222 /* Free the temporary afterwards, if necessary. */
4223 cond = fold_build2 (GT_EXPR, boolean_type_node,
4224 len, build_int_cst (TREE_TYPE (len), 0));
4225 tmp = gfc_call_free (var);
4226 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
4227 gfc_add_expr_to_block (&se->post, tmp);
4230 se->string_length = len;
4234 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
4237 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
4239 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
4240 tree type, cond, tmp, count, exit_label, n, max, largest;
4242 stmtblock_t block, body;
4245 /* We store in charsize the size of a character. */
4246 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
4247 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
4249 /* Get the arguments. */
4250 gfc_conv_intrinsic_function_args (se, expr, args, 3);
4251 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
4253 ncopies = gfc_evaluate_now (args[2], &se->pre);
4254 ncopies_type = TREE_TYPE (ncopies);
4256 /* Check that NCOPIES is not negative. */
4257 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
4258 build_int_cst (ncopies_type, 0));
4259 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4260 "Argument NCOPIES of REPEAT intrinsic is negative "
4261 "(its value is %lld)",
4262 fold_convert (long_integer_type_node, ncopies));
4264 /* If the source length is zero, any non negative value of NCOPIES
4265 is valid, and nothing happens. */
4266 n = gfc_create_var (ncopies_type, "ncopies");
4267 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4268 build_int_cst (size_type_node, 0));
4269 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
4270 build_int_cst (ncopies_type, 0), ncopies);
4271 gfc_add_modify (&se->pre, n, tmp);
4274 /* Check that ncopies is not too large: ncopies should be less than
4275 (or equal to) MAX / slen, where MAX is the maximal integer of
4276 the gfc_charlen_type_node type. If slen == 0, we need a special
4277 case to avoid the division by zero. */
4278 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
4279 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
4280 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
4281 fold_convert (size_type_node, max), slen);
4282 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
4283 ? size_type_node : ncopies_type;
4284 cond = fold_build2 (GT_EXPR, boolean_type_node,
4285 fold_convert (largest, ncopies),
4286 fold_convert (largest, max));
4287 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4288 build_int_cst (size_type_node, 0));
4289 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
4291 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4292 "Argument NCOPIES of REPEAT intrinsic is too large");
4294 /* Compute the destination length. */
4295 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4296 fold_convert (gfc_charlen_type_node, slen),
4297 fold_convert (gfc_charlen_type_node, ncopies));
4298 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
4299 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4301 /* Generate the code to do the repeat operation:
4302 for (i = 0; i < ncopies; i++)
4303 memmove (dest + (i * slen * size), src, slen*size); */
4304 gfc_start_block (&block);
4305 count = gfc_create_var (ncopies_type, "count");
4306 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4307 exit_label = gfc_build_label_decl (NULL_TREE);
4309 /* Start the loop body. */
4310 gfc_start_block (&body);
4312 /* Exit the loop if count >= ncopies. */
4313 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4314 tmp = build1_v (GOTO_EXPR, exit_label);
4315 TREE_USED (exit_label) = 1;
4316 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4317 build_empty_stmt ());
4318 gfc_add_expr_to_block (&body, tmp);
4320 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4321 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4322 fold_convert (gfc_charlen_type_node, slen),
4323 fold_convert (gfc_charlen_type_node, count));
4324 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4325 tmp, fold_convert (gfc_charlen_type_node, size));
4326 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4327 fold_convert (pvoid_type_node, dest),
4328 fold_convert (sizetype, tmp));
4329 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4330 fold_build2 (MULT_EXPR, size_type_node, slen,
4331 fold_convert (size_type_node, size)));
4332 gfc_add_expr_to_block (&body, tmp);
4334 /* Increment count. */
4335 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4336 count, build_int_cst (TREE_TYPE (count), 1));
4337 gfc_add_modify (&body, count, tmp);
4339 /* Build the loop. */
4340 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4341 gfc_add_expr_to_block (&block, tmp);
4343 /* Add the exit label. */
4344 tmp = build1_v (LABEL_EXPR, exit_label);
4345 gfc_add_expr_to_block (&block, tmp);
4347 /* Finish the block. */
4348 tmp = gfc_finish_block (&block);
4349 gfc_add_expr_to_block (&se->pre, tmp);
4351 /* Set the result value. */
4353 se->string_length = dlen;
4357 /* Generate code for the IARGC intrinsic. */
4360 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4366 /* Call the library function. This always returns an INTEGER(4). */
4367 fndecl = gfor_fndecl_iargc;
4368 tmp = build_call_expr (fndecl, 0);
4370 /* Convert it to the required type. */
4371 type = gfc_typenode_for_spec (&expr->ts);
4372 tmp = fold_convert (type, tmp);
4378 /* The loc intrinsic returns the address of its argument as
4379 gfc_index_integer_kind integer. */
4382 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4388 gcc_assert (!se->ss);
4390 arg_expr = expr->value.function.actual->expr;
4391 ss = gfc_walk_expr (arg_expr);
4392 if (ss == gfc_ss_terminator)
4393 gfc_conv_expr_reference (se, arg_expr);
4395 gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL);
4396 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4398 /* Create a temporary variable for loc return value. Without this,
4399 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4400 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4401 gfc_add_modify (&se->pre, temp_var, se->expr);
4402 se->expr = temp_var;
4405 /* Generate code for an intrinsic function. Some map directly to library
4406 calls, others get special handling. In some cases the name of the function
4407 used depends on the type specifiers. */
4410 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4412 gfc_intrinsic_sym *isym;
4417 isym = expr->value.function.isym;
4419 name = &expr->value.function.name[2];
4421 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4423 lib = gfc_is_intrinsic_libcall (expr);
4427 se->ignore_optional = 1;
4429 switch (expr->value.function.isym->id)
4431 case GFC_ISYM_EOSHIFT:
4433 case GFC_ISYM_RESHAPE:
4434 /* For all of those the first argument specifies the type and the
4435 third is optional. */
4436 conv_generic_with_optional_char_arg (se, expr, 1, 3);
4440 gfc_conv_intrinsic_funcall (se, expr);
4448 switch (expr->value.function.isym->id)
4453 case GFC_ISYM_REPEAT:
4454 gfc_conv_intrinsic_repeat (se, expr);
4458 gfc_conv_intrinsic_trim (se, expr);
4461 case GFC_ISYM_SC_KIND:
4462 gfc_conv_intrinsic_sc_kind (se, expr);
4465 case GFC_ISYM_SI_KIND:
4466 gfc_conv_intrinsic_si_kind (se, expr);
4469 case GFC_ISYM_SR_KIND:
4470 gfc_conv_intrinsic_sr_kind (se, expr);
4473 case GFC_ISYM_EXPONENT:
4474 gfc_conv_intrinsic_exponent (se, expr);
4478 kind = expr->value.function.actual->expr->ts.kind;
4480 fndecl = gfor_fndecl_string_scan;
4482 fndecl = gfor_fndecl_string_scan_char4;
4486 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4489 case GFC_ISYM_VERIFY:
4490 kind = expr->value.function.actual->expr->ts.kind;
4492 fndecl = gfor_fndecl_string_verify;
4494 fndecl = gfor_fndecl_string_verify_char4;
4498 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4501 case GFC_ISYM_ALLOCATED:
4502 gfc_conv_allocated (se, expr);
4505 case GFC_ISYM_ASSOCIATED:
4506 gfc_conv_associated(se, expr);
4510 gfc_conv_intrinsic_abs (se, expr);
4513 case GFC_ISYM_ADJUSTL:
4514 if (expr->ts.kind == 1)
4515 fndecl = gfor_fndecl_adjustl;
4516 else if (expr->ts.kind == 4)
4517 fndecl = gfor_fndecl_adjustl_char4;
4521 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4524 case GFC_ISYM_ADJUSTR:
4525 if (expr->ts.kind == 1)
4526 fndecl = gfor_fndecl_adjustr;
4527 else if (expr->ts.kind == 4)
4528 fndecl = gfor_fndecl_adjustr_char4;
4532 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4535 case GFC_ISYM_AIMAG:
4536 gfc_conv_intrinsic_imagpart (se, expr);
4540 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4544 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4547 case GFC_ISYM_ANINT:
4548 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4552 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4556 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4559 case GFC_ISYM_BTEST:
4560 gfc_conv_intrinsic_btest (se, expr);
4563 case GFC_ISYM_ACHAR:
4565 gfc_conv_intrinsic_char (se, expr);
4568 case GFC_ISYM_CONVERSION:
4570 case GFC_ISYM_LOGICAL:
4572 gfc_conv_intrinsic_conversion (se, expr);
4575 /* Integer conversions are handled separately to make sure we get the
4576 correct rounding mode. */
4581 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4585 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4588 case GFC_ISYM_CEILING:
4589 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4592 case GFC_ISYM_FLOOR:
4593 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4597 gfc_conv_intrinsic_mod (se, expr, 0);
4600 case GFC_ISYM_MODULO:
4601 gfc_conv_intrinsic_mod (se, expr, 1);
4604 case GFC_ISYM_CMPLX:
4605 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4608 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4609 gfc_conv_intrinsic_iargc (se, expr);
4612 case GFC_ISYM_COMPLEX:
4613 gfc_conv_intrinsic_cmplx (se, expr, 1);
4616 case GFC_ISYM_CONJG:
4617 gfc_conv_intrinsic_conjg (se, expr);
4620 case GFC_ISYM_COUNT:
4621 gfc_conv_intrinsic_count (se, expr);
4624 case GFC_ISYM_CTIME:
4625 gfc_conv_intrinsic_ctime (se, expr);
4629 gfc_conv_intrinsic_dim (se, expr);
4632 case GFC_ISYM_DOT_PRODUCT:
4633 gfc_conv_intrinsic_dot_product (se, expr);
4636 case GFC_ISYM_DPROD:
4637 gfc_conv_intrinsic_dprod (se, expr);
4640 case GFC_ISYM_FDATE:
4641 gfc_conv_intrinsic_fdate (se, expr);
4644 case GFC_ISYM_FRACTION:
4645 gfc_conv_intrinsic_fraction (se, expr);
4649 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4652 case GFC_ISYM_IBCLR:
4653 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4656 case GFC_ISYM_IBITS:
4657 gfc_conv_intrinsic_ibits (se, expr);
4660 case GFC_ISYM_IBSET:
4661 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4664 case GFC_ISYM_IACHAR:
4665 case GFC_ISYM_ICHAR:
4666 /* We assume ASCII character sequence. */
4667 gfc_conv_intrinsic_ichar (se, expr);
4670 case GFC_ISYM_IARGC:
4671 gfc_conv_intrinsic_iargc (se, expr);
4675 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4678 case GFC_ISYM_INDEX:
4679 kind = expr->value.function.actual->expr->ts.kind;
4681 fndecl = gfor_fndecl_string_index;
4683 fndecl = gfor_fndecl_string_index_char4;
4687 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4691 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4694 case GFC_ISYM_IS_IOSTAT_END:
4695 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4698 case GFC_ISYM_IS_IOSTAT_EOR:
4699 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4702 case GFC_ISYM_ISNAN:
4703 gfc_conv_intrinsic_isnan (se, expr);
4706 case GFC_ISYM_LSHIFT:
4707 gfc_conv_intrinsic_rlshift (se, expr, 0);
4710 case GFC_ISYM_RSHIFT:
4711 gfc_conv_intrinsic_rlshift (se, expr, 1);
4714 case GFC_ISYM_ISHFT:
4715 gfc_conv_intrinsic_ishft (se, expr);
4718 case GFC_ISYM_ISHFTC:
4719 gfc_conv_intrinsic_ishftc (se, expr);
4722 case GFC_ISYM_LEADZ:
4723 gfc_conv_intrinsic_leadz (se, expr);
4726 case GFC_ISYM_TRAILZ:
4727 gfc_conv_intrinsic_trailz (se, expr);
4730 case GFC_ISYM_LBOUND:
4731 gfc_conv_intrinsic_bound (se, expr, 0);
4734 case GFC_ISYM_TRANSPOSE:
4735 if (se->ss && se->ss->useflags)
4737 gfc_conv_tmp_array_ref (se);
4738 gfc_advance_se_ss_chain (se);
4741 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4745 gfc_conv_intrinsic_len (se, expr);
4748 case GFC_ISYM_LEN_TRIM:
4749 gfc_conv_intrinsic_len_trim (se, expr);
4753 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4757 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4761 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4765 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4769 if (expr->ts.type == BT_CHARACTER)
4770 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4772 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4775 case GFC_ISYM_MAXLOC:
4776 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4779 case GFC_ISYM_MAXVAL:
4780 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4783 case GFC_ISYM_MERGE:
4784 gfc_conv_intrinsic_merge (se, expr);
4788 if (expr->ts.type == BT_CHARACTER)
4789 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4791 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4794 case GFC_ISYM_MINLOC:
4795 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4798 case GFC_ISYM_MINVAL:
4799 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4802 case GFC_ISYM_NEAREST:
4803 gfc_conv_intrinsic_nearest (se, expr);
4807 gfc_conv_intrinsic_not (se, expr);
4811 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4814 case GFC_ISYM_PRESENT:
4815 gfc_conv_intrinsic_present (se, expr);
4818 case GFC_ISYM_PRODUCT:
4819 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4822 case GFC_ISYM_RRSPACING:
4823 gfc_conv_intrinsic_rrspacing (se, expr);
4826 case GFC_ISYM_SET_EXPONENT:
4827 gfc_conv_intrinsic_set_exponent (se, expr);
4830 case GFC_ISYM_SCALE:
4831 gfc_conv_intrinsic_scale (se, expr);
4835 gfc_conv_intrinsic_sign (se, expr);
4839 gfc_conv_intrinsic_size (se, expr);
4842 case GFC_ISYM_SIZEOF:
4843 gfc_conv_intrinsic_sizeof (se, expr);
4846 case GFC_ISYM_SPACING:
4847 gfc_conv_intrinsic_spacing (se, expr);
4851 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4854 case GFC_ISYM_TRANSFER:
4855 if (se->ss && se->ss->useflags)
4857 /* Access the previously obtained result. */
4858 gfc_conv_tmp_array_ref (se);
4859 gfc_advance_se_ss_chain (se);
4862 gfc_conv_intrinsic_transfer (se, expr);
4865 case GFC_ISYM_TTYNAM:
4866 gfc_conv_intrinsic_ttynam (se, expr);
4869 case GFC_ISYM_UBOUND:
4870 gfc_conv_intrinsic_bound (se, expr, 1);
4874 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4878 gfc_conv_intrinsic_loc (se, expr);
4881 case GFC_ISYM_ACCESS:
4882 case GFC_ISYM_CHDIR:
4883 case GFC_ISYM_CHMOD:
4884 case GFC_ISYM_DTIME:
4885 case GFC_ISYM_ETIME:
4887 case GFC_ISYM_FGETC:
4890 case GFC_ISYM_FPUTC:
4891 case GFC_ISYM_FSTAT:
4892 case GFC_ISYM_FTELL:
4893 case GFC_ISYM_GETCWD:
4894 case GFC_ISYM_GETGID:
4895 case GFC_ISYM_GETPID:
4896 case GFC_ISYM_GETUID:
4897 case GFC_ISYM_HOSTNM:
4899 case GFC_ISYM_IERRNO:
4900 case GFC_ISYM_IRAND:
4901 case GFC_ISYM_ISATTY:
4903 case GFC_ISYM_LSTAT:
4904 case GFC_ISYM_MALLOC:
4905 case GFC_ISYM_MATMUL:
4906 case GFC_ISYM_MCLOCK:
4907 case GFC_ISYM_MCLOCK8:
4909 case GFC_ISYM_RENAME:
4910 case GFC_ISYM_SECOND:
4911 case GFC_ISYM_SECNDS:
4912 case GFC_ISYM_SIGNAL:
4914 case GFC_ISYM_SYMLNK:
4915 case GFC_ISYM_SYSTEM:
4917 case GFC_ISYM_TIME8:
4918 case GFC_ISYM_UMASK:
4919 case GFC_ISYM_UNLINK:
4920 gfc_conv_intrinsic_funcall (se, expr);
4923 case GFC_ISYM_EOSHIFT:
4925 case GFC_ISYM_RESHAPE:
4926 /* For those, expr->rank should always be >0 and thus the if above the
4927 switch should have matched. */
4932 gfc_conv_intrinsic_lib_function (se, expr);
4938 /* This generates code to execute before entering the scalarization loop.
4939 Currently does nothing. */
4942 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4944 switch (ss->expr->value.function.isym->id)
4946 case GFC_ISYM_UBOUND:
4947 case GFC_ISYM_LBOUND:
4956 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4957 inside the scalarization loop. */
4960 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4964 /* The two argument version returns a scalar. */
4965 if (expr->value.function.actual->next->expr)
4968 newss = gfc_get_ss ();
4969 newss->type = GFC_SS_INTRINSIC;
4972 newss->data.info.dimen = 1;
4978 /* Walk an intrinsic array libcall. */
4981 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4985 gcc_assert (expr->rank > 0);
4987 newss = gfc_get_ss ();
4988 newss->type = GFC_SS_FUNCTION;
4991 newss->data.info.dimen = expr->rank;
4997 /* Returns nonzero if the specified intrinsic function call maps directly to
4998 an external library call. Should only be used for functions that return
5002 gfc_is_intrinsic_libcall (gfc_expr * expr)
5004 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
5005 gcc_assert (expr->rank > 0);
5007 switch (expr->value.function.isym->id)
5011 case GFC_ISYM_COUNT:
5012 case GFC_ISYM_MATMUL:
5013 case GFC_ISYM_MAXLOC:
5014 case GFC_ISYM_MAXVAL:
5015 case GFC_ISYM_MINLOC:
5016 case GFC_ISYM_MINVAL:
5017 case GFC_ISYM_PRODUCT:
5019 case GFC_ISYM_SHAPE:
5020 case GFC_ISYM_SPREAD:
5021 case GFC_ISYM_TRANSPOSE:
5022 /* Ignore absent optional parameters. */
5025 case GFC_ISYM_RESHAPE:
5026 case GFC_ISYM_CSHIFT:
5027 case GFC_ISYM_EOSHIFT:
5029 case GFC_ISYM_UNPACK:
5030 /* Pass absent optional parameters. */
5038 /* Walk an intrinsic function. */
5040 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
5041 gfc_intrinsic_sym * isym)
5045 if (isym->elemental)
5046 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
5048 if (expr->rank == 0)
5051 if (gfc_is_intrinsic_libcall (expr))
5052 return gfc_walk_intrinsic_libfunc (ss, expr);
5054 /* Special cases. */
5057 case GFC_ISYM_LBOUND:
5058 case GFC_ISYM_UBOUND:
5059 return gfc_walk_intrinsic_bound (ss, expr);
5061 case GFC_ISYM_TRANSFER:
5062 return gfc_walk_intrinsic_libfunc (ss, expr);
5065 /* This probably meant someone forgot to add an intrinsic to the above
5066 list(s) when they implemented it, or something's gone horribly
5072 #include "gt-fortran-trans-intrinsic.h"