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_procedure_call (se, sym, expr->value.function.actual, expr,
1710 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1730 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
1739 gfc_actual_arglist *actual;
1746 gfc_conv_intrinsic_funcall (se, expr);
1750 actual = expr->value.function.actual;
1751 type = gfc_typenode_for_spec (&expr->ts);
1752 /* Initialize the result. */
1753 resvar = gfc_create_var (type, "test");
1755 tmp = convert (type, boolean_true_node);
1757 tmp = convert (type, boolean_false_node);
1758 gfc_add_modify (&se->pre, resvar, tmp);
1760 /* Walk the arguments. */
1761 arrayss = gfc_walk_expr (actual->expr);
1762 gcc_assert (arrayss != gfc_ss_terminator);
1764 /* Initialize the scalarizer. */
1765 gfc_init_loopinfo (&loop);
1766 exit_label = gfc_build_label_decl (NULL_TREE);
1767 TREE_USED (exit_label) = 1;
1768 gfc_add_ss_to_loop (&loop, arrayss);
1770 /* Initialize the loop. */
1771 gfc_conv_ss_startstride (&loop);
1772 gfc_conv_loop_setup (&loop, &expr->where);
1774 gfc_mark_ss_chain_used (arrayss, 1);
1775 /* Generate the loop body. */
1776 gfc_start_scalarized_body (&loop, &body);
1778 /* If the condition matches then set the return value. */
1779 gfc_start_block (&block);
1781 tmp = convert (type, boolean_false_node);
1783 tmp = convert (type, boolean_true_node);
1784 gfc_add_modify (&block, resvar, tmp);
1786 /* And break out of the loop. */
1787 tmp = build1_v (GOTO_EXPR, exit_label);
1788 gfc_add_expr_to_block (&block, tmp);
1790 found = gfc_finish_block (&block);
1792 /* Check this element. */
1793 gfc_init_se (&arrayse, NULL);
1794 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1795 arrayse.ss = arrayss;
1796 gfc_conv_expr_val (&arrayse, actual->expr);
1798 gfc_add_block_to_block (&body, &arrayse.pre);
1799 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1800 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1801 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1802 gfc_add_expr_to_block (&body, tmp);
1803 gfc_add_block_to_block (&body, &arrayse.post);
1805 gfc_trans_scalarizing_loops (&loop, &body);
1807 /* Add the exit label. */
1808 tmp = build1_v (LABEL_EXPR, exit_label);
1809 gfc_add_expr_to_block (&loop.pre, tmp);
1811 gfc_add_block_to_block (&se->pre, &loop.pre);
1812 gfc_add_block_to_block (&se->pre, &loop.post);
1813 gfc_cleanup_loop (&loop);
1818 /* COUNT(A) = Number of true elements in A. */
1820 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1827 gfc_actual_arglist *actual;
1833 gfc_conv_intrinsic_funcall (se, expr);
1837 actual = expr->value.function.actual;
1839 type = gfc_typenode_for_spec (&expr->ts);
1840 /* Initialize the result. */
1841 resvar = gfc_create_var (type, "count");
1842 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1844 /* Walk the arguments. */
1845 arrayss = gfc_walk_expr (actual->expr);
1846 gcc_assert (arrayss != gfc_ss_terminator);
1848 /* Initialize the scalarizer. */
1849 gfc_init_loopinfo (&loop);
1850 gfc_add_ss_to_loop (&loop, arrayss);
1852 /* Initialize the loop. */
1853 gfc_conv_ss_startstride (&loop);
1854 gfc_conv_loop_setup (&loop, &expr->where);
1856 gfc_mark_ss_chain_used (arrayss, 1);
1857 /* Generate the loop body. */
1858 gfc_start_scalarized_body (&loop, &body);
1860 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1861 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1862 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1864 gfc_init_se (&arrayse, NULL);
1865 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1866 arrayse.ss = arrayss;
1867 gfc_conv_expr_val (&arrayse, actual->expr);
1868 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1870 gfc_add_block_to_block (&body, &arrayse.pre);
1871 gfc_add_expr_to_block (&body, tmp);
1872 gfc_add_block_to_block (&body, &arrayse.post);
1874 gfc_trans_scalarizing_loops (&loop, &body);
1876 gfc_add_block_to_block (&se->pre, &loop.pre);
1877 gfc_add_block_to_block (&se->pre, &loop.post);
1878 gfc_cleanup_loop (&loop);
1883 /* Inline implementation of the sum and product intrinsics. */
1885 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
1893 gfc_actual_arglist *actual;
1898 gfc_expr *arrayexpr;
1903 gfc_conv_intrinsic_funcall (se, expr);
1907 type = gfc_typenode_for_spec (&expr->ts);
1908 /* Initialize the result. */
1909 resvar = gfc_create_var (type, "val");
1910 if (op == PLUS_EXPR)
1911 tmp = gfc_build_const (type, integer_zero_node);
1913 tmp = gfc_build_const (type, integer_one_node);
1915 gfc_add_modify (&se->pre, resvar, tmp);
1917 /* Walk the arguments. */
1918 actual = expr->value.function.actual;
1919 arrayexpr = actual->expr;
1920 arrayss = gfc_walk_expr (arrayexpr);
1921 gcc_assert (arrayss != gfc_ss_terminator);
1923 actual = actual->next->next;
1924 gcc_assert (actual);
1925 maskexpr = actual->expr;
1926 if (maskexpr && maskexpr->rank != 0)
1928 maskss = gfc_walk_expr (maskexpr);
1929 gcc_assert (maskss != gfc_ss_terminator);
1934 /* Initialize the scalarizer. */
1935 gfc_init_loopinfo (&loop);
1936 gfc_add_ss_to_loop (&loop, arrayss);
1938 gfc_add_ss_to_loop (&loop, maskss);
1940 /* Initialize the loop. */
1941 gfc_conv_ss_startstride (&loop);
1942 gfc_conv_loop_setup (&loop, &expr->where);
1944 gfc_mark_ss_chain_used (arrayss, 1);
1946 gfc_mark_ss_chain_used (maskss, 1);
1947 /* Generate the loop body. */
1948 gfc_start_scalarized_body (&loop, &body);
1950 /* If we have a mask, only add this element if the mask is set. */
1953 gfc_init_se (&maskse, NULL);
1954 gfc_copy_loopinfo_to_se (&maskse, &loop);
1956 gfc_conv_expr_val (&maskse, maskexpr);
1957 gfc_add_block_to_block (&body, &maskse.pre);
1959 gfc_start_block (&block);
1962 gfc_init_block (&block);
1964 /* Do the actual summation/product. */
1965 gfc_init_se (&arrayse, NULL);
1966 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1967 arrayse.ss = arrayss;
1968 gfc_conv_expr_val (&arrayse, arrayexpr);
1969 gfc_add_block_to_block (&block, &arrayse.pre);
1971 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1972 gfc_add_modify (&block, resvar, tmp);
1973 gfc_add_block_to_block (&block, &arrayse.post);
1977 /* We enclose the above in if (mask) {...} . */
1978 tmp = gfc_finish_block (&block);
1980 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1983 tmp = gfc_finish_block (&block);
1984 gfc_add_expr_to_block (&body, tmp);
1986 gfc_trans_scalarizing_loops (&loop, &body);
1988 /* For a scalar mask, enclose the loop in an if statement. */
1989 if (maskexpr && maskss == NULL)
1991 gfc_init_se (&maskse, NULL);
1992 gfc_conv_expr_val (&maskse, maskexpr);
1993 gfc_init_block (&block);
1994 gfc_add_block_to_block (&block, &loop.pre);
1995 gfc_add_block_to_block (&block, &loop.post);
1996 tmp = gfc_finish_block (&block);
1998 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1999 gfc_add_expr_to_block (&block, tmp);
2000 gfc_add_block_to_block (&se->pre, &block);
2004 gfc_add_block_to_block (&se->pre, &loop.pre);
2005 gfc_add_block_to_block (&se->pre, &loop.post);
2008 gfc_cleanup_loop (&loop);
2014 /* Inline implementation of the dot_product intrinsic. This function
2015 is based on gfc_conv_intrinsic_arith (the previous function). */
2017 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
2025 gfc_actual_arglist *actual;
2026 gfc_ss *arrayss1, *arrayss2;
2027 gfc_se arrayse1, arrayse2;
2028 gfc_expr *arrayexpr1, *arrayexpr2;
2030 type = gfc_typenode_for_spec (&expr->ts);
2032 /* Initialize the result. */
2033 resvar = gfc_create_var (type, "val");
2034 if (expr->ts.type == BT_LOGICAL)
2035 tmp = build_int_cst (type, 0);
2037 tmp = gfc_build_const (type, integer_zero_node);
2039 gfc_add_modify (&se->pre, resvar, tmp);
2041 /* Walk argument #1. */
2042 actual = expr->value.function.actual;
2043 arrayexpr1 = actual->expr;
2044 arrayss1 = gfc_walk_expr (arrayexpr1);
2045 gcc_assert (arrayss1 != gfc_ss_terminator);
2047 /* Walk argument #2. */
2048 actual = actual->next;
2049 arrayexpr2 = actual->expr;
2050 arrayss2 = gfc_walk_expr (arrayexpr2);
2051 gcc_assert (arrayss2 != gfc_ss_terminator);
2053 /* Initialize the scalarizer. */
2054 gfc_init_loopinfo (&loop);
2055 gfc_add_ss_to_loop (&loop, arrayss1);
2056 gfc_add_ss_to_loop (&loop, arrayss2);
2058 /* Initialize the loop. */
2059 gfc_conv_ss_startstride (&loop);
2060 gfc_conv_loop_setup (&loop, &expr->where);
2062 gfc_mark_ss_chain_used (arrayss1, 1);
2063 gfc_mark_ss_chain_used (arrayss2, 1);
2065 /* Generate the loop body. */
2066 gfc_start_scalarized_body (&loop, &body);
2067 gfc_init_block (&block);
2069 /* Make the tree expression for [conjg(]array1[)]. */
2070 gfc_init_se (&arrayse1, NULL);
2071 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2072 arrayse1.ss = arrayss1;
2073 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2074 if (expr->ts.type == BT_COMPLEX)
2075 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2076 gfc_add_block_to_block (&block, &arrayse1.pre);
2078 /* Make the tree expression for array2. */
2079 gfc_init_se (&arrayse2, NULL);
2080 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2081 arrayse2.ss = arrayss2;
2082 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2083 gfc_add_block_to_block (&block, &arrayse2.pre);
2085 /* Do the actual product and sum. */
2086 if (expr->ts.type == BT_LOGICAL)
2088 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2089 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2093 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2094 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2096 gfc_add_modify (&block, resvar, tmp);
2098 /* Finish up the loop block and the loop. */
2099 tmp = gfc_finish_block (&block);
2100 gfc_add_expr_to_block (&body, tmp);
2102 gfc_trans_scalarizing_loops (&loop, &body);
2103 gfc_add_block_to_block (&se->pre, &loop.pre);
2104 gfc_add_block_to_block (&se->pre, &loop.post);
2105 gfc_cleanup_loop (&loop);
2112 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
2116 stmtblock_t ifblock;
2117 stmtblock_t elseblock;
2125 gfc_actual_arglist *actual;
2130 gfc_expr *arrayexpr;
2137 gfc_conv_intrinsic_funcall (se, expr);
2141 /* Initialize the result. */
2142 pos = gfc_create_var (gfc_array_index_type, "pos");
2143 offset = gfc_create_var (gfc_array_index_type, "offset");
2144 type = gfc_typenode_for_spec (&expr->ts);
2146 /* Walk the arguments. */
2147 actual = expr->value.function.actual;
2148 arrayexpr = actual->expr;
2149 arrayss = gfc_walk_expr (arrayexpr);
2150 gcc_assert (arrayss != gfc_ss_terminator);
2152 actual = actual->next->next;
2153 gcc_assert (actual);
2154 maskexpr = actual->expr;
2155 if (maskexpr && maskexpr->rank != 0)
2157 maskss = gfc_walk_expr (maskexpr);
2158 gcc_assert (maskss != gfc_ss_terminator);
2163 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2164 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2165 switch (arrayexpr->ts.type)
2168 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2169 arrayexpr->ts.kind, 0);
2173 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2174 arrayexpr->ts.kind);
2181 /* We start with the most negative possible value for MAXLOC, and the most
2182 positive possible value for MINLOC. The most negative possible value is
2183 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2184 possible value is HUGE in both cases. */
2186 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2187 gfc_add_modify (&se->pre, limit, tmp);
2189 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2190 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2191 build_int_cst (type, 1));
2193 /* Initialize the scalarizer. */
2194 gfc_init_loopinfo (&loop);
2195 gfc_add_ss_to_loop (&loop, arrayss);
2197 gfc_add_ss_to_loop (&loop, maskss);
2199 /* Initialize the loop. */
2200 gfc_conv_ss_startstride (&loop);
2201 gfc_conv_loop_setup (&loop, &expr->where);
2203 gcc_assert (loop.dimen == 1);
2205 /* Initialize the position to zero, following Fortran 2003. We are free
2206 to do this because Fortran 95 allows the result of an entirely false
2207 mask to be processor dependent. */
2208 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2210 gfc_mark_ss_chain_used (arrayss, 1);
2212 gfc_mark_ss_chain_used (maskss, 1);
2213 /* Generate the loop body. */
2214 gfc_start_scalarized_body (&loop, &body);
2216 /* If we have a mask, only check this element if the mask is set. */
2219 gfc_init_se (&maskse, NULL);
2220 gfc_copy_loopinfo_to_se (&maskse, &loop);
2222 gfc_conv_expr_val (&maskse, maskexpr);
2223 gfc_add_block_to_block (&body, &maskse.pre);
2225 gfc_start_block (&block);
2228 gfc_init_block (&block);
2230 /* Compare with the current limit. */
2231 gfc_init_se (&arrayse, NULL);
2232 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2233 arrayse.ss = arrayss;
2234 gfc_conv_expr_val (&arrayse, arrayexpr);
2235 gfc_add_block_to_block (&block, &arrayse.pre);
2237 /* We do the following if this is a more extreme value. */
2238 gfc_start_block (&ifblock);
2240 /* Assign the value to the limit... */
2241 gfc_add_modify (&ifblock, limit, arrayse.expr);
2243 /* Remember where we are. An offset must be added to the loop
2244 counter to obtain the required position. */
2246 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2247 gfc_index_one_node, loop.from[0]);
2249 tmp = gfc_index_one_node;
2251 gfc_add_modify (&block, offset, tmp);
2253 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2254 loop.loopvar[0], offset);
2255 gfc_add_modify (&ifblock, pos, tmp);
2257 ifbody = gfc_finish_block (&ifblock);
2259 /* If it is a more extreme value or pos is still zero and the value
2260 equal to the limit. */
2261 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2262 fold_build2 (EQ_EXPR, boolean_type_node,
2263 pos, gfc_index_zero_node),
2264 fold_build2 (EQ_EXPR, boolean_type_node,
2265 arrayse.expr, limit));
2266 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2267 fold_build2 (op, boolean_type_node,
2268 arrayse.expr, limit), tmp);
2269 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2270 gfc_add_expr_to_block (&block, tmp);
2274 /* We enclose the above in if (mask) {...}. */
2275 tmp = gfc_finish_block (&block);
2277 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2280 tmp = gfc_finish_block (&block);
2281 gfc_add_expr_to_block (&body, tmp);
2283 gfc_trans_scalarizing_loops (&loop, &body);
2285 /* For a scalar mask, enclose the loop in an if statement. */
2286 if (maskexpr && maskss == NULL)
2288 gfc_init_se (&maskse, NULL);
2289 gfc_conv_expr_val (&maskse, maskexpr);
2290 gfc_init_block (&block);
2291 gfc_add_block_to_block (&block, &loop.pre);
2292 gfc_add_block_to_block (&block, &loop.post);
2293 tmp = gfc_finish_block (&block);
2295 /* For the else part of the scalar mask, just initialize
2296 the pos variable the same way as above. */
2298 gfc_init_block (&elseblock);
2299 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2300 elsetmp = gfc_finish_block (&elseblock);
2302 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2303 gfc_add_expr_to_block (&block, tmp);
2304 gfc_add_block_to_block (&se->pre, &block);
2308 gfc_add_block_to_block (&se->pre, &loop.pre);
2309 gfc_add_block_to_block (&se->pre, &loop.post);
2311 gfc_cleanup_loop (&loop);
2313 se->expr = convert (type, pos);
2317 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
2326 gfc_actual_arglist *actual;
2331 gfc_expr *arrayexpr;
2337 gfc_conv_intrinsic_funcall (se, expr);
2341 type = gfc_typenode_for_spec (&expr->ts);
2342 /* Initialize the result. */
2343 limit = gfc_create_var (type, "limit");
2344 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2345 switch (expr->ts.type)
2348 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind, 0);
2352 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2359 /* We start with the most negative possible value for MAXVAL, and the most
2360 positive possible value for MINVAL. The most negative possible value is
2361 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2362 possible value is HUGE in both cases. */
2364 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2366 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2367 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2368 tmp, build_int_cst (type, 1));
2370 gfc_add_modify (&se->pre, limit, tmp);
2372 /* Walk the arguments. */
2373 actual = expr->value.function.actual;
2374 arrayexpr = actual->expr;
2375 arrayss = gfc_walk_expr (arrayexpr);
2376 gcc_assert (arrayss != gfc_ss_terminator);
2378 actual = actual->next->next;
2379 gcc_assert (actual);
2380 maskexpr = actual->expr;
2381 if (maskexpr && maskexpr->rank != 0)
2383 maskss = gfc_walk_expr (maskexpr);
2384 gcc_assert (maskss != gfc_ss_terminator);
2389 /* Initialize the scalarizer. */
2390 gfc_init_loopinfo (&loop);
2391 gfc_add_ss_to_loop (&loop, arrayss);
2393 gfc_add_ss_to_loop (&loop, maskss);
2395 /* Initialize the loop. */
2396 gfc_conv_ss_startstride (&loop);
2397 gfc_conv_loop_setup (&loop, &expr->where);
2399 gfc_mark_ss_chain_used (arrayss, 1);
2401 gfc_mark_ss_chain_used (maskss, 1);
2402 /* Generate the loop body. */
2403 gfc_start_scalarized_body (&loop, &body);
2405 /* If we have a mask, only add this element if the mask is set. */
2408 gfc_init_se (&maskse, NULL);
2409 gfc_copy_loopinfo_to_se (&maskse, &loop);
2411 gfc_conv_expr_val (&maskse, maskexpr);
2412 gfc_add_block_to_block (&body, &maskse.pre);
2414 gfc_start_block (&block);
2417 gfc_init_block (&block);
2419 /* Compare with the current limit. */
2420 gfc_init_se (&arrayse, NULL);
2421 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2422 arrayse.ss = arrayss;
2423 gfc_conv_expr_val (&arrayse, arrayexpr);
2424 gfc_add_block_to_block (&block, &arrayse.pre);
2426 /* Assign the value to the limit... */
2427 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2429 /* If it is a more extreme value. */
2430 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2431 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2432 gfc_add_expr_to_block (&block, tmp);
2433 gfc_add_block_to_block (&block, &arrayse.post);
2435 tmp = gfc_finish_block (&block);
2437 /* We enclose the above in if (mask) {...}. */
2438 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2439 gfc_add_expr_to_block (&body, tmp);
2441 gfc_trans_scalarizing_loops (&loop, &body);
2443 /* For a scalar mask, enclose the loop in an if statement. */
2444 if (maskexpr && maskss == NULL)
2446 gfc_init_se (&maskse, NULL);
2447 gfc_conv_expr_val (&maskse, maskexpr);
2448 gfc_init_block (&block);
2449 gfc_add_block_to_block (&block, &loop.pre);
2450 gfc_add_block_to_block (&block, &loop.post);
2451 tmp = gfc_finish_block (&block);
2453 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2454 gfc_add_expr_to_block (&block, tmp);
2455 gfc_add_block_to_block (&se->pre, &block);
2459 gfc_add_block_to_block (&se->pre, &loop.pre);
2460 gfc_add_block_to_block (&se->pre, &loop.post);
2463 gfc_cleanup_loop (&loop);
2468 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2470 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2476 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2477 type = TREE_TYPE (args[0]);
2479 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2480 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2481 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2482 build_int_cst (type, 0));
2483 type = gfc_typenode_for_spec (&expr->ts);
2484 se->expr = convert (type, tmp);
2487 /* Generate code to perform the specified operation. */
2489 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
2493 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2494 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2499 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2503 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2504 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2507 /* Set or clear a single bit. */
2509 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2516 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2517 type = TREE_TYPE (args[0]);
2519 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2525 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2527 se->expr = fold_build2 (op, type, args[0], tmp);
2530 /* Extract a sequence of bits.
2531 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2533 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2540 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2541 type = TREE_TYPE (args[0]);
2543 mask = build_int_cst (type, -1);
2544 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2545 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2547 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2549 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2552 /* RSHIFT (I, SHIFT) = I >> SHIFT
2553 LSHIFT (I, SHIFT) = I << SHIFT */
2555 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2559 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2561 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2562 TREE_TYPE (args[0]), args[0], args[1]);
2565 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2567 : ((shift >= 0) ? i << shift : i >> -shift)
2568 where all shifts are logical shifts. */
2570 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2582 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2583 type = TREE_TYPE (args[0]);
2584 utype = unsigned_type_for (type);
2586 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2588 /* Left shift if positive. */
2589 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2591 /* Right shift if negative.
2592 We convert to an unsigned type because we want a logical shift.
2593 The standard doesn't define the case of shifting negative
2594 numbers, and we try to be compatible with other compilers, most
2595 notably g77, here. */
2596 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2597 convert (utype, args[0]), width));
2599 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2600 build_int_cst (TREE_TYPE (args[1]), 0));
2601 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2603 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2604 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2606 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2607 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2609 se->expr = fold_build3 (COND_EXPR, type, cond,
2610 build_int_cst (type, 0), tmp);
2614 /* Circular shift. AKA rotate or barrel shift. */
2617 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2625 unsigned int num_args;
2627 num_args = gfc_intrinsic_argument_list_length (expr);
2628 args = (tree *) alloca (sizeof (tree) * num_args);
2630 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2634 /* Use a library function for the 3 parameter version. */
2635 tree int4type = gfc_get_int_type (4);
2637 type = TREE_TYPE (args[0]);
2638 /* We convert the first argument to at least 4 bytes, and
2639 convert back afterwards. This removes the need for library
2640 functions for all argument sizes, and function will be
2641 aligned to at least 32 bits, so there's no loss. */
2642 if (expr->ts.kind < 4)
2643 args[0] = convert (int4type, args[0]);
2645 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2646 need loads of library functions. They cannot have values >
2647 BIT_SIZE (I) so the conversion is safe. */
2648 args[1] = convert (int4type, args[1]);
2649 args[2] = convert (int4type, args[2]);
2651 switch (expr->ts.kind)
2656 tmp = gfor_fndecl_math_ishftc4;
2659 tmp = gfor_fndecl_math_ishftc8;
2662 tmp = gfor_fndecl_math_ishftc16;
2667 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2668 /* Convert the result back to the original type, if we extended
2669 the first argument's width above. */
2670 if (expr->ts.kind < 4)
2671 se->expr = convert (type, se->expr);
2675 type = TREE_TYPE (args[0]);
2677 /* Rotate left if positive. */
2678 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2680 /* Rotate right if negative. */
2681 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2682 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2684 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2685 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2686 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2688 /* Do nothing if shift == 0. */
2689 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2690 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2693 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
2694 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
2696 The conditional expression is necessary because the result of LEADZ(0)
2697 is defined, but the result of __builtin_clz(0) is undefined for most
2700 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
2701 difference in bit size between the argument of LEADZ and the C int. */
2704 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
2716 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2718 /* Which variant of __builtin_clz* should we call? */
2719 arg_kind = expr->value.function.actual->expr->ts.kind;
2720 i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
2726 arg_type = unsigned_type_node;
2731 arg_type = long_unsigned_type_node;
2736 arg_type = long_long_unsigned_type_node;
2744 /* Convert the actual argument to the proper argument type for the built-in
2745 function. But the return type is of the default INTEGER kind. */
2746 arg = fold_convert (arg_type, arg);
2747 result_type = gfc_get_int_type (gfc_default_integer_kind);
2749 /* Compute LEADZ for the case i .ne. 0. */
2750 s = TYPE_PRECISION (arg_type) - gfc_integer_kinds[i].bit_size;
2751 tmp = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
2752 leadz = fold_build2 (MINUS_EXPR, result_type,
2753 tmp, build_int_cst (result_type, s));
2755 /* Build BIT_SIZE. */
2756 bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
2758 /* ??? For some combinations of targets and integer kinds, the condition
2759 can be avoided if CLZ_DEFINED_VALUE_AT_ZERO is used. Later. */
2760 cond = fold_build2 (EQ_EXPR, boolean_type_node,
2761 arg, build_int_cst (arg_type, 0));
2762 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
2765 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
2767 The conditional expression is necessary because the result of TRAILZ(0)
2768 is defined, but the result of __builtin_ctz(0) is undefined for most
2772 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
2783 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2785 /* Which variant of __builtin_clz* should we call? */
2786 arg_kind = expr->value.function.actual->expr->ts.kind;
2787 i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
2788 switch (expr->ts.kind)
2793 arg_type = unsigned_type_node;
2798 arg_type = long_unsigned_type_node;
2803 arg_type = long_long_unsigned_type_node;
2811 /* Convert the actual argument to the proper argument type for the built-in
2812 function. But the return type is of the default INTEGER kind. */
2813 arg = fold_convert (arg_type, arg);
2814 result_type = gfc_get_int_type (gfc_default_integer_kind);
2816 /* Compute TRAILZ for the case i .ne. 0. */
2817 trailz = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
2819 /* Build BIT_SIZE. */
2820 bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
2822 /* ??? For some combinations of targets and integer kinds, the condition
2823 can be avoided if CTZ_DEFINED_VALUE_AT_ZERO is used. Later. */
2824 cond = fold_build2 (EQ_EXPR, boolean_type_node,
2825 arg, build_int_cst (arg_type, 0));
2826 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
2829 /* Process an intrinsic with unspecified argument-types that has an optional
2830 argument (which could be of type character), e.g. EOSHIFT. For those, we
2831 need to append the string length of the optional argument if it is not
2832 present and the type is really character.
2833 primary specifies the position (starting at 1) of the non-optional argument
2834 specifying the type and optional gives the position of the optional
2835 argument in the arglist. */
2838 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
2839 unsigned primary, unsigned optional)
2841 gfc_actual_arglist* prim_arg;
2842 gfc_actual_arglist* opt_arg;
2844 gfc_actual_arglist* arg;
2848 /* Find the two arguments given as position. */
2852 for (arg = expr->value.function.actual; arg; arg = arg->next)
2856 if (cur_pos == primary)
2858 if (cur_pos == optional)
2861 if (cur_pos >= primary && cur_pos >= optional)
2864 gcc_assert (prim_arg);
2865 gcc_assert (prim_arg->expr);
2866 gcc_assert (opt_arg);
2868 /* If we do have type CHARACTER and the optional argument is really absent,
2869 append a dummy 0 as string length. */
2870 append_args = NULL_TREE;
2871 if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
2875 dummy = build_int_cst (gfc_charlen_type_node, 0);
2876 append_args = gfc_chainon_list (append_args, dummy);
2879 /* Build the call itself. */
2880 sym = gfc_get_symbol_for_expr (expr);
2881 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
2887 /* The length of a character string. */
2889 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2899 gcc_assert (!se->ss);
2901 arg = expr->value.function.actual->expr;
2903 type = gfc_typenode_for_spec (&expr->ts);
2904 switch (arg->expr_type)
2907 len = build_int_cst (NULL_TREE, arg->value.character.length);
2911 /* Obtain the string length from the function used by
2912 trans-array.c(gfc_trans_array_constructor). */
2914 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2918 if (arg->ref == NULL
2919 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2921 /* This doesn't catch all cases.
2922 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2923 and the surrounding thread. */
2924 sym = arg->symtree->n.sym;
2925 decl = gfc_get_symbol_decl (sym);
2926 if (decl == current_function_decl && sym->attr.function
2927 && (sym->result == sym))
2928 decl = gfc_get_fake_result_decl (sym, 0);
2930 len = sym->ts.cl->backend_decl;
2935 /* Otherwise fall through. */
2938 /* Anybody stupid enough to do this deserves inefficient code. */
2939 ss = gfc_walk_expr (arg);
2940 gfc_init_se (&argse, se);
2941 if (ss == gfc_ss_terminator)
2942 gfc_conv_expr (&argse, arg);
2944 gfc_conv_expr_descriptor (&argse, arg, ss);
2945 gfc_add_block_to_block (&se->pre, &argse.pre);
2946 gfc_add_block_to_block (&se->post, &argse.post);
2947 len = argse.string_length;
2950 se->expr = convert (type, len);
2953 /* The length of a character string not including trailing blanks. */
2955 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2957 int kind = expr->value.function.actual->expr->ts.kind;
2958 tree args[2], type, fndecl;
2960 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2961 type = gfc_typenode_for_spec (&expr->ts);
2964 fndecl = gfor_fndecl_string_len_trim;
2966 fndecl = gfor_fndecl_string_len_trim_char4;
2970 se->expr = build_call_expr (fndecl, 2, args[0], args[1]);
2971 se->expr = convert (type, se->expr);
2975 /* Returns the starting position of a substring within a string. */
2978 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2981 tree logical4_type_node = gfc_get_logical_type (4);
2985 unsigned int num_args;
2987 args = (tree *) alloca (sizeof (tree) * 5);
2989 /* Get number of arguments; characters count double due to the
2990 string length argument. Kind= is not passed to the library
2991 and thus ignored. */
2992 if (expr->value.function.actual->next->next->expr == NULL)
2997 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2998 type = gfc_typenode_for_spec (&expr->ts);
3001 args[4] = build_int_cst (logical4_type_node, 0);
3003 args[4] = convert (logical4_type_node, args[4]);
3005 fndecl = build_addr (function, current_function_decl);
3006 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
3008 se->expr = convert (type, se->expr);
3012 /* The ascii value for a single character. */
3014 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
3016 tree args[2], type, pchartype;
3018 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3019 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
3020 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
3021 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
3022 type = gfc_typenode_for_spec (&expr->ts);
3024 se->expr = build_fold_indirect_ref (args[1]);
3025 se->expr = convert (type, se->expr);
3029 /* Intrinsic ISNAN calls __builtin_isnan. */
3032 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
3036 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3037 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
3038 STRIP_TYPE_NOPS (se->expr);
3039 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3043 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
3044 their argument against a constant integer value. */
3047 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
3051 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3052 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
3053 arg, build_int_cst (TREE_TYPE (arg), value));
3058 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
3061 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
3069 unsigned int num_args;
3071 num_args = gfc_intrinsic_argument_list_length (expr);
3072 args = (tree *) alloca (sizeof (tree) * num_args);
3074 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3075 if (expr->ts.type != BT_CHARACTER)
3083 /* We do the same as in the non-character case, but the argument
3084 list is different because of the string length arguments. We
3085 also have to set the string length for the result. */
3092 gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
3094 se->string_length = len;
3096 type = TREE_TYPE (tsource);
3097 se->expr = fold_build3 (COND_EXPR, type, mask, tsource,
3098 fold_convert (type, fsource));
3102 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
3104 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
3106 tree arg, type, tmp;
3109 switch (expr->ts.kind)
3112 frexp = BUILT_IN_FREXPF;
3115 frexp = BUILT_IN_FREXP;
3119 frexp = BUILT_IN_FREXPL;
3125 type = gfc_typenode_for_spec (&expr->ts);
3126 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3127 tmp = gfc_create_var (integer_type_node, NULL);
3128 se->expr = build_call_expr (built_in_decls[frexp], 2,
3129 fold_convert (type, arg),
3130 gfc_build_addr_expr (NULL_TREE, tmp));
3131 se->expr = fold_convert (type, se->expr);
3135 /* NEAREST (s, dir) is translated into
3136 tmp = copysign (HUGE_VAL, dir);
3137 return nextafter (s, tmp);
3140 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
3142 tree args[2], type, tmp;
3143 int nextafter, copysign, huge_val;
3145 switch (expr->ts.kind)
3148 nextafter = BUILT_IN_NEXTAFTERF;
3149 copysign = BUILT_IN_COPYSIGNF;
3150 huge_val = BUILT_IN_HUGE_VALF;
3153 nextafter = BUILT_IN_NEXTAFTER;
3154 copysign = BUILT_IN_COPYSIGN;
3155 huge_val = BUILT_IN_HUGE_VAL;
3159 nextafter = BUILT_IN_NEXTAFTERL;
3160 copysign = BUILT_IN_COPYSIGNL;
3161 huge_val = BUILT_IN_HUGE_VALL;
3167 type = gfc_typenode_for_spec (&expr->ts);
3168 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3169 tmp = build_call_expr (built_in_decls[copysign], 2,
3170 build_call_expr (built_in_decls[huge_val], 0),
3171 fold_convert (type, args[1]));
3172 se->expr = build_call_expr (built_in_decls[nextafter], 2,
3173 fold_convert (type, args[0]), tmp);
3174 se->expr = fold_convert (type, se->expr);
3178 /* SPACING (s) is translated into
3186 e = MAX_EXPR (e, emin);
3187 res = scalbn (1., e);
3191 where prec is the precision of s, gfc_real_kinds[k].digits,
3192 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
3193 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
3196 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
3198 tree arg, type, prec, emin, tiny, res, e;
3200 int frexp, scalbn, k;
3203 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3204 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
3205 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
3206 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
3208 switch (expr->ts.kind)
3211 frexp = BUILT_IN_FREXPF;
3212 scalbn = BUILT_IN_SCALBNF;
3215 frexp = BUILT_IN_FREXP;
3216 scalbn = BUILT_IN_SCALBN;
3220 frexp = BUILT_IN_FREXPL;
3221 scalbn = BUILT_IN_SCALBNL;
3227 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3228 arg = gfc_evaluate_now (arg, &se->pre);
3230 type = gfc_typenode_for_spec (&expr->ts);
3231 e = gfc_create_var (integer_type_node, NULL);
3232 res = gfc_create_var (type, NULL);
3235 /* Build the block for s /= 0. */
3236 gfc_start_block (&block);
3237 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3238 gfc_build_addr_expr (NULL_TREE, e));
3239 gfc_add_expr_to_block (&block, tmp);
3241 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3242 gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3245 tmp = build_call_expr (built_in_decls[scalbn], 2,
3246 build_real_from_int_cst (type, integer_one_node), e);
3247 gfc_add_modify (&block, res, tmp);
3249 /* Finish by building the IF statement. */
3250 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3251 build_real_from_int_cst (type, integer_zero_node));
3252 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3253 gfc_finish_block (&block));
3255 gfc_add_expr_to_block (&se->pre, tmp);
3260 /* RRSPACING (s) is translated into
3267 x = scalbn (x, precision - e);
3271 where precision is gfc_real_kinds[k].digits. */
3274 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3276 tree arg, type, e, x, cond, stmt, tmp;
3277 int frexp, scalbn, fabs, prec, k;
3280 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3281 prec = gfc_real_kinds[k].digits;
3282 switch (expr->ts.kind)
3285 frexp = BUILT_IN_FREXPF;
3286 scalbn = BUILT_IN_SCALBNF;
3287 fabs = BUILT_IN_FABSF;
3290 frexp = BUILT_IN_FREXP;
3291 scalbn = BUILT_IN_SCALBN;
3292 fabs = BUILT_IN_FABS;
3296 frexp = BUILT_IN_FREXPL;
3297 scalbn = BUILT_IN_SCALBNL;
3298 fabs = BUILT_IN_FABSL;
3304 type = gfc_typenode_for_spec (&expr->ts);
3305 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3306 arg = gfc_evaluate_now (arg, &se->pre);
3308 e = gfc_create_var (integer_type_node, NULL);
3309 x = gfc_create_var (type, NULL);
3310 gfc_add_modify (&se->pre, x,
3311 build_call_expr (built_in_decls[fabs], 1, arg));
3314 gfc_start_block (&block);
3315 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3316 gfc_build_addr_expr (NULL_TREE, e));
3317 gfc_add_expr_to_block (&block, tmp);
3319 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3320 build_int_cst (NULL_TREE, prec), e);
3321 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3322 gfc_add_modify (&block, x, tmp);
3323 stmt = gfc_finish_block (&block);
3325 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3326 build_real_from_int_cst (type, integer_zero_node));
3327 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3328 gfc_add_expr_to_block (&se->pre, tmp);
3330 se->expr = fold_convert (type, x);
3334 /* SCALE (s, i) is translated into scalbn (s, i). */
3336 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3341 switch (expr->ts.kind)
3344 scalbn = BUILT_IN_SCALBNF;
3347 scalbn = BUILT_IN_SCALBN;
3351 scalbn = BUILT_IN_SCALBNL;
3357 type = gfc_typenode_for_spec (&expr->ts);
3358 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3359 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3360 fold_convert (type, args[0]),
3361 fold_convert (integer_type_node, args[1]));
3362 se->expr = fold_convert (type, se->expr);
3366 /* SET_EXPONENT (s, i) is translated into
3367 scalbn (frexp (s, &dummy_int), i). */
3369 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3371 tree args[2], type, tmp;
3374 switch (expr->ts.kind)
3377 frexp = BUILT_IN_FREXPF;
3378 scalbn = BUILT_IN_SCALBNF;
3381 frexp = BUILT_IN_FREXP;
3382 scalbn = BUILT_IN_SCALBN;
3386 frexp = BUILT_IN_FREXPL;
3387 scalbn = BUILT_IN_SCALBNL;
3393 type = gfc_typenode_for_spec (&expr->ts);
3394 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3396 tmp = gfc_create_var (integer_type_node, NULL);
3397 tmp = build_call_expr (built_in_decls[frexp], 2,
3398 fold_convert (type, args[0]),
3399 gfc_build_addr_expr (NULL_TREE, tmp));
3400 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3401 fold_convert (integer_type_node, args[1]));
3402 se->expr = fold_convert (type, se->expr);
3407 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3409 gfc_actual_arglist *actual;
3417 gfc_init_se (&argse, NULL);
3418 actual = expr->value.function.actual;
3420 ss = gfc_walk_expr (actual->expr);
3421 gcc_assert (ss != gfc_ss_terminator);
3422 argse.want_pointer = 1;
3423 argse.data_not_needed = 1;
3424 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3425 gfc_add_block_to_block (&se->pre, &argse.pre);
3426 gfc_add_block_to_block (&se->post, &argse.post);
3427 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3429 /* Build the call to size0. */
3430 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3432 actual = actual->next;
3436 gfc_init_se (&argse, NULL);
3437 gfc_conv_expr_type (&argse, actual->expr,
3438 gfc_array_index_type);
3439 gfc_add_block_to_block (&se->pre, &argse.pre);
3441 /* Unusually, for an intrinsic, size does not exclude
3442 an optional arg2, so we must test for it. */
3443 if (actual->expr->expr_type == EXPR_VARIABLE
3444 && actual->expr->symtree->n.sym->attr.dummy
3445 && actual->expr->symtree->n.sym->attr.optional)
3448 /* Build the call to size1. */
3449 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3452 gfc_init_se (&argse, NULL);
3453 argse.want_pointer = 1;
3454 argse.data_not_needed = 1;
3455 gfc_conv_expr (&argse, actual->expr);
3456 gfc_add_block_to_block (&se->pre, &argse.pre);
3457 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3458 argse.expr, null_pointer_node);
3459 tmp = gfc_evaluate_now (tmp, &se->pre);
3460 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3461 tmp, fncall1, fncall0);
3465 se->expr = NULL_TREE;
3466 argse.expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3467 argse.expr, gfc_index_one_node);
3470 else if (expr->value.function.actual->expr->rank == 1)
3472 argse.expr = gfc_index_zero_node;
3473 se->expr = NULL_TREE;
3478 if (se->expr == NULL_TREE)
3480 tree ubound, lbound;
3482 arg1 = build_fold_indirect_ref (arg1);
3483 ubound = gfc_conv_descriptor_ubound (arg1, argse.expr);
3484 lbound = gfc_conv_descriptor_lbound (arg1, argse.expr);
3485 se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3487 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
3488 gfc_index_one_node);
3489 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
3490 gfc_index_zero_node);
3493 type = gfc_typenode_for_spec (&expr->ts);
3494 se->expr = convert (type, se->expr);
3498 /* Helper function to compute the size of a character variable,
3499 excluding the terminating null characters. The result has
3500 gfc_array_index_type type. */
3503 size_of_string_in_bytes (int kind, tree string_length)
3506 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3508 bytesize = build_int_cst (gfc_array_index_type,
3509 gfc_character_kinds[i].bit_size / 8);
3511 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3512 fold_convert (gfc_array_index_type, string_length));
3517 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3530 arg = expr->value.function.actual->expr;
3532 gfc_init_se (&argse, NULL);
3533 ss = gfc_walk_expr (arg);
3535 if (ss == gfc_ss_terminator)
3537 gfc_conv_expr_reference (&argse, arg);
3538 source = argse.expr;
3540 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3542 /* Obtain the source word length. */
3543 if (arg->ts.type == BT_CHARACTER)
3544 se->expr = size_of_string_in_bytes (arg->ts.kind,
3545 argse.string_length);
3547 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
3551 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3552 argse.want_pointer = 0;
3553 gfc_conv_expr_descriptor (&argse, arg, ss);
3554 source = gfc_conv_descriptor_data_get (argse.expr);
3555 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3557 /* Obtain the argument's word length. */
3558 if (arg->ts.type == BT_CHARACTER)
3559 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3561 tmp = fold_convert (gfc_array_index_type,
3562 size_in_bytes (type));
3563 gfc_add_modify (&argse.pre, source_bytes, tmp);
3565 /* Obtain the size of the array in bytes. */
3566 for (n = 0; n < arg->rank; n++)
3569 idx = gfc_rank_cst[n];
3570 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3571 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3572 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3574 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3575 tmp, gfc_index_one_node);
3576 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3578 gfc_add_modify (&argse.pre, source_bytes, tmp);
3580 se->expr = source_bytes;
3583 gfc_add_block_to_block (&se->pre, &argse.pre);
3587 /* Intrinsic string comparison functions. */
3590 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
3594 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3597 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
3598 expr->value.function.actual->expr->ts.kind);
3599 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3600 build_int_cst (TREE_TYPE (se->expr), 0));
3603 /* Generate a call to the adjustl/adjustr library function. */
3605 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3613 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3616 type = TREE_TYPE (args[2]);
3617 var = gfc_conv_string_tmp (se, type, len);
3620 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3621 gfc_add_expr_to_block (&se->pre, tmp);
3623 se->string_length = len;
3627 /* Generate code for the TRANSFER intrinsic:
3629 DEST = TRANSFER (SOURCE, MOLD)
3631 typeof<DEST> = typeof<MOLD>
3636 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3638 typeof<DEST> = typeof<MOLD>
3640 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3641 sizeof (DEST(0) * SIZE). */
3643 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3660 gfc_actual_arglist *arg;
3670 info = &se->ss->data.info;
3672 /* Convert SOURCE. The output from this stage is:-
3673 source_bytes = length of the source in bytes
3674 source = pointer to the source data. */
3675 arg = expr->value.function.actual;
3677 /* Ensure double transfer through LOGICAL preserves all
3679 if (arg->expr->expr_type == EXPR_FUNCTION
3680 && arg->expr->value.function.esym == NULL
3681 && arg->expr->value.function.isym != NULL
3682 && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
3683 && arg->expr->ts.type == BT_LOGICAL
3684 && expr->ts.type != arg->expr->ts.type)
3685 arg->expr->value.function.name = "__transfer_in_transfer";
3687 gfc_init_se (&argse, NULL);
3688 ss = gfc_walk_expr (arg->expr);
3690 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3692 /* Obtain the pointer to source and the length of source in bytes. */
3693 if (ss == gfc_ss_terminator)
3695 gfc_conv_expr_reference (&argse, arg->expr);
3696 source = argse.expr;
3698 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3700 /* Obtain the source word length. */
3701 if (arg->expr->ts.type == BT_CHARACTER)
3702 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3703 argse.string_length);
3705 tmp = fold_convert (gfc_array_index_type,
3706 size_in_bytes (source_type));
3710 argse.want_pointer = 0;
3711 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3712 source = gfc_conv_descriptor_data_get (argse.expr);
3713 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3715 /* Repack the source if not a full variable array. */
3716 if (arg->expr->expr_type == EXPR_VARIABLE
3717 && arg->expr->ref->u.ar.type != AR_FULL)
3719 tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
3721 if (gfc_option.warn_array_temp)
3722 gfc_warning ("Creating array temporary at %L", &expr->where);
3724 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3725 source = gfc_evaluate_now (source, &argse.pre);
3727 /* Free the temporary. */
3728 gfc_start_block (&block);
3729 tmp = gfc_call_free (convert (pvoid_type_node, source));
3730 gfc_add_expr_to_block (&block, tmp);
3731 stmt = gfc_finish_block (&block);
3733 /* Clean up if it was repacked. */
3734 gfc_init_block (&block);
3735 tmp = gfc_conv_array_data (argse.expr);
3736 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3737 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3738 gfc_add_expr_to_block (&block, tmp);
3739 gfc_add_block_to_block (&block, &se->post);
3740 gfc_init_block (&se->post);
3741 gfc_add_block_to_block (&se->post, &block);
3744 /* Obtain the source word length. */
3745 if (arg->expr->ts.type == BT_CHARACTER)
3746 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3747 argse.string_length);
3749 tmp = fold_convert (gfc_array_index_type,
3750 size_in_bytes (source_type));
3752 /* Obtain the size of the array in bytes. */
3753 extent = gfc_create_var (gfc_array_index_type, NULL);
3754 for (n = 0; n < arg->expr->rank; n++)
3757 idx = gfc_rank_cst[n];
3758 gfc_add_modify (&argse.pre, source_bytes, tmp);
3759 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3760 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3761 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3762 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3764 gfc_add_modify (&argse.pre, extent, tmp);
3765 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3766 extent, gfc_index_one_node);
3767 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3772 gfc_add_modify (&argse.pre, source_bytes, tmp);
3773 gfc_add_block_to_block (&se->pre, &argse.pre);
3774 gfc_add_block_to_block (&se->post, &argse.post);
3776 /* Now convert MOLD. The outputs are:
3777 mold_type = the TREE type of MOLD
3778 dest_word_len = destination word length in bytes. */
3781 gfc_init_se (&argse, NULL);
3782 ss = gfc_walk_expr (arg->expr);
3784 scalar_mold = arg->expr->rank == 0;
3786 if (ss == gfc_ss_terminator)
3788 gfc_conv_expr_reference (&argse, arg->expr);
3789 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3793 gfc_init_se (&argse, NULL);
3794 argse.want_pointer = 0;
3795 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3796 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3799 gfc_add_block_to_block (&se->pre, &argse.pre);
3800 gfc_add_block_to_block (&se->post, &argse.post);
3802 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
3804 /* If this TRANSFER is nested in another TRANSFER, use a type
3805 that preserves all bits. */
3806 if (arg->expr->ts.type == BT_LOGICAL)
3807 mold_type = gfc_get_int_type (arg->expr->ts.kind);
3810 if (arg->expr->ts.type == BT_CHARACTER)
3812 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
3813 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3816 tmp = fold_convert (gfc_array_index_type,
3817 size_in_bytes (mold_type));
3819 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3820 gfc_add_modify (&se->pre, dest_word_len, tmp);
3822 /* Finally convert SIZE, if it is present. */
3824 size_words = gfc_create_var (gfc_array_index_type, NULL);
3828 gfc_init_se (&argse, NULL);
3829 gfc_conv_expr_reference (&argse, arg->expr);
3830 tmp = convert (gfc_array_index_type,
3831 build_fold_indirect_ref (argse.expr));
3832 gfc_add_block_to_block (&se->pre, &argse.pre);
3833 gfc_add_block_to_block (&se->post, &argse.post);
3838 /* Separate array and scalar results. */
3839 if (scalar_mold && tmp == NULL_TREE)
3840 goto scalar_transfer;
3842 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3843 if (tmp != NULL_TREE)
3844 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3845 tmp, dest_word_len);
3849 gfc_add_modify (&se->pre, size_bytes, tmp);
3850 gfc_add_modify (&se->pre, size_words,
3851 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3852 size_bytes, dest_word_len));
3854 /* Evaluate the bounds of the result. If the loop range exists, we have
3855 to check if it is too large. If so, we modify loop->to be consistent
3856 with min(size, size(source)). Otherwise, size is made consistent with
3857 the loop range, so that the right number of bytes is transferred.*/
3858 n = se->loop->order[0];
3859 if (se->loop->to[n] != NULL_TREE)
3861 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3862 se->loop->to[n], se->loop->from[n]);
3863 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3864 tmp, gfc_index_one_node);
3865 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3867 gfc_add_modify (&se->pre, size_words, tmp);
3868 gfc_add_modify (&se->pre, size_bytes,
3869 fold_build2 (MULT_EXPR, gfc_array_index_type,
3870 size_words, dest_word_len));
3871 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3872 size_words, se->loop->from[n]);
3873 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3874 upper, gfc_index_one_node);
3878 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3879 size_words, gfc_index_one_node);
3880 se->loop->from[n] = gfc_index_zero_node;
3883 se->loop->to[n] = upper;
3885 /* Build a destination descriptor, using the pointer, source, as the
3887 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3888 info, mold_type, NULL_TREE, false, true, false,
3891 /* Cast the pointer to the result. */
3892 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3893 tmp = fold_convert (pvoid_type_node, tmp);
3895 /* Use memcpy to do the transfer. */
3896 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3899 fold_convert (pvoid_type_node, source),
3900 fold_build2 (MIN_EXPR, gfc_array_index_type,
3901 size_bytes, source_bytes));
3902 gfc_add_expr_to_block (&se->pre, tmp);
3904 se->expr = info->descriptor;
3905 if (expr->ts.type == BT_CHARACTER)
3906 se->string_length = dest_word_len;
3910 /* Deal with scalar results. */
3912 extent = fold_build2 (MIN_EXPR, gfc_array_index_type,
3913 dest_word_len, source_bytes);
3915 if (expr->ts.type == BT_CHARACTER)
3920 ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
3921 tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
3924 /* If source is longer than the destination, use a pointer to
3925 the source directly. */
3926 gfc_init_block (&block);
3927 gfc_add_modify (&block, tmpdecl, ptr);
3928 direct = gfc_finish_block (&block);
3930 /* Otherwise, allocate a string with the length of the destination
3931 and copy the source into it. */
3932 gfc_init_block (&block);
3933 tmp = gfc_get_pchar_type (expr->ts.kind);
3934 tmp = gfc_call_malloc (&block, tmp, dest_word_len);
3935 gfc_add_modify (&block, tmpdecl,
3936 fold_convert (TREE_TYPE (ptr), tmp));
3937 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3938 fold_convert (pvoid_type_node, tmpdecl),
3939 fold_convert (pvoid_type_node, ptr),
3941 gfc_add_expr_to_block (&block, tmp);
3942 indirect = gfc_finish_block (&block);
3944 /* Wrap it up with the condition. */
3945 tmp = fold_build2 (LE_EXPR, boolean_type_node,
3946 dest_word_len, source_bytes);
3947 tmp = build3_v (COND_EXPR, tmp, direct, indirect);
3948 gfc_add_expr_to_block (&se->pre, tmp);
3951 se->string_length = dest_word_len;
3955 tmpdecl = gfc_create_var (mold_type, "transfer");
3957 ptr = convert (build_pointer_type (mold_type), source);
3959 /* Use memcpy to do the transfer. */
3960 tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
3961 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3962 fold_convert (pvoid_type_node, tmp),
3963 fold_convert (pvoid_type_node, ptr),
3965 gfc_add_expr_to_block (&se->pre, tmp);
3972 /* Generate code for the ALLOCATED intrinsic.
3973 Generate inline code that directly check the address of the argument. */
3976 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3978 gfc_actual_arglist *arg1;
3983 gfc_init_se (&arg1se, NULL);
3984 arg1 = expr->value.function.actual;
3985 ss1 = gfc_walk_expr (arg1->expr);
3986 arg1se.descriptor_only = 1;
3987 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3989 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3990 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3991 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3992 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3996 /* Generate code for the ASSOCIATED intrinsic.
3997 If both POINTER and TARGET are arrays, generate a call to library function
3998 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3999 In other cases, generate inline code that directly compare the address of
4000 POINTER with the address of TARGET. */
4003 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
4005 gfc_actual_arglist *arg1;
4006 gfc_actual_arglist *arg2;
4011 tree nonzero_charlen;
4012 tree nonzero_arraylen;
4015 gfc_init_se (&arg1se, NULL);
4016 gfc_init_se (&arg2se, NULL);
4017 arg1 = expr->value.function.actual;
4019 ss1 = gfc_walk_expr (arg1->expr);
4023 /* No optional target. */
4024 if (ss1 == gfc_ss_terminator)
4026 /* A pointer to a scalar. */
4027 arg1se.want_pointer = 1;
4028 gfc_conv_expr (&arg1se, arg1->expr);
4033 /* A pointer to an array. */
4034 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4035 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
4037 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4038 gfc_add_block_to_block (&se->post, &arg1se.post);
4039 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
4040 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
4045 /* An optional target. */
4046 ss2 = gfc_walk_expr (arg2->expr);
4048 nonzero_charlen = NULL_TREE;
4049 if (arg1->expr->ts.type == BT_CHARACTER)
4050 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
4051 arg1->expr->ts.cl->backend_decl,
4054 if (ss1 == gfc_ss_terminator)
4056 /* A pointer to a scalar. */
4057 gcc_assert (ss2 == gfc_ss_terminator);
4058 arg1se.want_pointer = 1;
4059 gfc_conv_expr (&arg1se, arg1->expr);
4060 arg2se.want_pointer = 1;
4061 gfc_conv_expr (&arg2se, arg2->expr);
4062 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4063 gfc_add_block_to_block (&se->post, &arg1se.post);
4064 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4065 arg1se.expr, arg2se.expr);
4066 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
4067 arg1se.expr, null_pointer_node);
4068 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4073 /* An array pointer of zero length is not associated if target is
4075 arg1se.descriptor_only = 1;
4076 gfc_conv_expr_lhs (&arg1se, arg1->expr);
4077 tmp = gfc_conv_descriptor_stride (arg1se.expr,
4078 gfc_rank_cst[arg1->expr->rank - 1]);
4079 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
4080 build_int_cst (TREE_TYPE (tmp), 0));
4082 /* A pointer to an array, call library function _gfor_associated. */
4083 gcc_assert (ss2 != gfc_ss_terminator);
4084 arg1se.want_pointer = 1;
4085 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4087 arg2se.want_pointer = 1;
4088 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
4089 gfc_add_block_to_block (&se->pre, &arg2se.pre);
4090 gfc_add_block_to_block (&se->post, &arg2se.post);
4091 se->expr = build_call_expr (gfor_fndecl_associated, 2,
4092 arg1se.expr, arg2se.expr);
4093 se->expr = convert (boolean_type_node, se->expr);
4094 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4095 se->expr, nonzero_arraylen);
4098 /* If target is present zero character length pointers cannot
4100 if (nonzero_charlen != NULL_TREE)
4101 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4102 se->expr, nonzero_charlen);
4105 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4109 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
4112 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
4116 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4117 se->expr = build_call_expr (gfor_fndecl_sc_kind, 2, args[0], args[1]);
4118 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4122 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
4125 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
4129 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4131 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
4132 type = gfc_get_int_type (4);
4133 arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
4135 /* Convert it to the required type. */
4136 type = gfc_typenode_for_spec (&expr->ts);
4137 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
4138 se->expr = fold_convert (type, se->expr);
4142 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
4145 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
4147 gfc_actual_arglist *actual;
4152 for (actual = expr->value.function.actual; actual; actual = actual->next)
4154 gfc_init_se (&argse, se);
4156 /* Pass a NULL pointer for an absent arg. */
4157 if (actual->expr == NULL)
4158 argse.expr = null_pointer_node;
4164 if (actual->expr->ts.kind != gfc_c_int_kind)
4166 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
4167 ts.type = BT_INTEGER;
4168 ts.kind = gfc_c_int_kind;
4169 gfc_convert_type (actual->expr, &ts, 2);
4171 gfc_conv_expr_reference (&argse, actual->expr);
4174 gfc_add_block_to_block (&se->pre, &argse.pre);
4175 gfc_add_block_to_block (&se->post, &argse.post);
4176 args = gfc_chainon_list (args, argse.expr);
4179 /* Convert it to the required type. */
4180 type = gfc_typenode_for_spec (&expr->ts);
4181 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
4182 se->expr = fold_convert (type, se->expr);
4186 /* Generate code for TRIM (A) intrinsic function. */
4189 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
4199 unsigned int num_args;
4201 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
4202 args = (tree *) alloca (sizeof (tree) * num_args);
4204 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
4205 addr = gfc_build_addr_expr (ppvoid_type_node, var);
4206 len = gfc_create_var (gfc_get_int_type (4), "len");
4208 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
4209 args[0] = gfc_build_addr_expr (NULL_TREE, len);
4212 if (expr->ts.kind == 1)
4213 function = gfor_fndecl_string_trim;
4214 else if (expr->ts.kind == 4)
4215 function = gfor_fndecl_string_trim_char4;
4219 fndecl = build_addr (function, current_function_decl);
4220 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
4222 gfc_add_expr_to_block (&se->pre, tmp);
4224 /* Free the temporary afterwards, if necessary. */
4225 cond = fold_build2 (GT_EXPR, boolean_type_node,
4226 len, build_int_cst (TREE_TYPE (len), 0));
4227 tmp = gfc_call_free (var);
4228 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
4229 gfc_add_expr_to_block (&se->post, tmp);
4232 se->string_length = len;
4236 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
4239 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
4241 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
4242 tree type, cond, tmp, count, exit_label, n, max, largest;
4244 stmtblock_t block, body;
4247 /* We store in charsize the size of a character. */
4248 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
4249 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
4251 /* Get the arguments. */
4252 gfc_conv_intrinsic_function_args (se, expr, args, 3);
4253 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
4255 ncopies = gfc_evaluate_now (args[2], &se->pre);
4256 ncopies_type = TREE_TYPE (ncopies);
4258 /* Check that NCOPIES is not negative. */
4259 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
4260 build_int_cst (ncopies_type, 0));
4261 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4262 "Argument NCOPIES of REPEAT intrinsic is negative "
4263 "(its value is %lld)",
4264 fold_convert (long_integer_type_node, ncopies));
4266 /* If the source length is zero, any non negative value of NCOPIES
4267 is valid, and nothing happens. */
4268 n = gfc_create_var (ncopies_type, "ncopies");
4269 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4270 build_int_cst (size_type_node, 0));
4271 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
4272 build_int_cst (ncopies_type, 0), ncopies);
4273 gfc_add_modify (&se->pre, n, tmp);
4276 /* Check that ncopies is not too large: ncopies should be less than
4277 (or equal to) MAX / slen, where MAX is the maximal integer of
4278 the gfc_charlen_type_node type. If slen == 0, we need a special
4279 case to avoid the division by zero. */
4280 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
4281 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
4282 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
4283 fold_convert (size_type_node, max), slen);
4284 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
4285 ? size_type_node : ncopies_type;
4286 cond = fold_build2 (GT_EXPR, boolean_type_node,
4287 fold_convert (largest, ncopies),
4288 fold_convert (largest, max));
4289 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4290 build_int_cst (size_type_node, 0));
4291 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
4293 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4294 "Argument NCOPIES of REPEAT intrinsic is too large");
4296 /* Compute the destination length. */
4297 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4298 fold_convert (gfc_charlen_type_node, slen),
4299 fold_convert (gfc_charlen_type_node, ncopies));
4300 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
4301 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4303 /* Generate the code to do the repeat operation:
4304 for (i = 0; i < ncopies; i++)
4305 memmove (dest + (i * slen * size), src, slen*size); */
4306 gfc_start_block (&block);
4307 count = gfc_create_var (ncopies_type, "count");
4308 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4309 exit_label = gfc_build_label_decl (NULL_TREE);
4311 /* Start the loop body. */
4312 gfc_start_block (&body);
4314 /* Exit the loop if count >= ncopies. */
4315 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4316 tmp = build1_v (GOTO_EXPR, exit_label);
4317 TREE_USED (exit_label) = 1;
4318 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4319 build_empty_stmt ());
4320 gfc_add_expr_to_block (&body, tmp);
4322 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4323 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4324 fold_convert (gfc_charlen_type_node, slen),
4325 fold_convert (gfc_charlen_type_node, count));
4326 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4327 tmp, fold_convert (gfc_charlen_type_node, size));
4328 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4329 fold_convert (pvoid_type_node, dest),
4330 fold_convert (sizetype, tmp));
4331 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4332 fold_build2 (MULT_EXPR, size_type_node, slen,
4333 fold_convert (size_type_node, size)));
4334 gfc_add_expr_to_block (&body, tmp);
4336 /* Increment count. */
4337 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4338 count, build_int_cst (TREE_TYPE (count), 1));
4339 gfc_add_modify (&body, count, tmp);
4341 /* Build the loop. */
4342 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4343 gfc_add_expr_to_block (&block, tmp);
4345 /* Add the exit label. */
4346 tmp = build1_v (LABEL_EXPR, exit_label);
4347 gfc_add_expr_to_block (&block, tmp);
4349 /* Finish the block. */
4350 tmp = gfc_finish_block (&block);
4351 gfc_add_expr_to_block (&se->pre, tmp);
4353 /* Set the result value. */
4355 se->string_length = dlen;
4359 /* Generate code for the IARGC intrinsic. */
4362 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4368 /* Call the library function. This always returns an INTEGER(4). */
4369 fndecl = gfor_fndecl_iargc;
4370 tmp = build_call_expr (fndecl, 0);
4372 /* Convert it to the required type. */
4373 type = gfc_typenode_for_spec (&expr->ts);
4374 tmp = fold_convert (type, tmp);
4380 /* The loc intrinsic returns the address of its argument as
4381 gfc_index_integer_kind integer. */
4384 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4390 gcc_assert (!se->ss);
4392 arg_expr = expr->value.function.actual->expr;
4393 ss = gfc_walk_expr (arg_expr);
4394 if (ss == gfc_ss_terminator)
4395 gfc_conv_expr_reference (se, arg_expr);
4397 gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL, NULL);
4398 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4400 /* Create a temporary variable for loc return value. Without this,
4401 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4402 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4403 gfc_add_modify (&se->pre, temp_var, se->expr);
4404 se->expr = temp_var;
4407 /* Generate code for an intrinsic function. Some map directly to library
4408 calls, others get special handling. In some cases the name of the function
4409 used depends on the type specifiers. */
4412 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4414 gfc_intrinsic_sym *isym;
4419 isym = expr->value.function.isym;
4421 name = &expr->value.function.name[2];
4423 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4425 lib = gfc_is_intrinsic_libcall (expr);
4429 se->ignore_optional = 1;
4431 switch (expr->value.function.isym->id)
4433 case GFC_ISYM_EOSHIFT:
4435 case GFC_ISYM_RESHAPE:
4436 /* For all of those the first argument specifies the type and the
4437 third is optional. */
4438 conv_generic_with_optional_char_arg (se, expr, 1, 3);
4442 gfc_conv_intrinsic_funcall (se, expr);
4450 switch (expr->value.function.isym->id)
4455 case GFC_ISYM_REPEAT:
4456 gfc_conv_intrinsic_repeat (se, expr);
4460 gfc_conv_intrinsic_trim (se, expr);
4463 case GFC_ISYM_SC_KIND:
4464 gfc_conv_intrinsic_sc_kind (se, expr);
4467 case GFC_ISYM_SI_KIND:
4468 gfc_conv_intrinsic_si_kind (se, expr);
4471 case GFC_ISYM_SR_KIND:
4472 gfc_conv_intrinsic_sr_kind (se, expr);
4475 case GFC_ISYM_EXPONENT:
4476 gfc_conv_intrinsic_exponent (se, expr);
4480 kind = expr->value.function.actual->expr->ts.kind;
4482 fndecl = gfor_fndecl_string_scan;
4484 fndecl = gfor_fndecl_string_scan_char4;
4488 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4491 case GFC_ISYM_VERIFY:
4492 kind = expr->value.function.actual->expr->ts.kind;
4494 fndecl = gfor_fndecl_string_verify;
4496 fndecl = gfor_fndecl_string_verify_char4;
4500 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4503 case GFC_ISYM_ALLOCATED:
4504 gfc_conv_allocated (se, expr);
4507 case GFC_ISYM_ASSOCIATED:
4508 gfc_conv_associated(se, expr);
4512 gfc_conv_intrinsic_abs (se, expr);
4515 case GFC_ISYM_ADJUSTL:
4516 if (expr->ts.kind == 1)
4517 fndecl = gfor_fndecl_adjustl;
4518 else if (expr->ts.kind == 4)
4519 fndecl = gfor_fndecl_adjustl_char4;
4523 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4526 case GFC_ISYM_ADJUSTR:
4527 if (expr->ts.kind == 1)
4528 fndecl = gfor_fndecl_adjustr;
4529 else if (expr->ts.kind == 4)
4530 fndecl = gfor_fndecl_adjustr_char4;
4534 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4537 case GFC_ISYM_AIMAG:
4538 gfc_conv_intrinsic_imagpart (se, expr);
4542 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4546 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4549 case GFC_ISYM_ANINT:
4550 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4554 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4558 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4561 case GFC_ISYM_BTEST:
4562 gfc_conv_intrinsic_btest (se, expr);
4565 case GFC_ISYM_ACHAR:
4567 gfc_conv_intrinsic_char (se, expr);
4570 case GFC_ISYM_CONVERSION:
4572 case GFC_ISYM_LOGICAL:
4574 gfc_conv_intrinsic_conversion (se, expr);
4577 /* Integer conversions are handled separately to make sure we get the
4578 correct rounding mode. */
4583 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4587 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4590 case GFC_ISYM_CEILING:
4591 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4594 case GFC_ISYM_FLOOR:
4595 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4599 gfc_conv_intrinsic_mod (se, expr, 0);
4602 case GFC_ISYM_MODULO:
4603 gfc_conv_intrinsic_mod (se, expr, 1);
4606 case GFC_ISYM_CMPLX:
4607 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4610 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4611 gfc_conv_intrinsic_iargc (se, expr);
4614 case GFC_ISYM_COMPLEX:
4615 gfc_conv_intrinsic_cmplx (se, expr, 1);
4618 case GFC_ISYM_CONJG:
4619 gfc_conv_intrinsic_conjg (se, expr);
4622 case GFC_ISYM_COUNT:
4623 gfc_conv_intrinsic_count (se, expr);
4626 case GFC_ISYM_CTIME:
4627 gfc_conv_intrinsic_ctime (se, expr);
4631 gfc_conv_intrinsic_dim (se, expr);
4634 case GFC_ISYM_DOT_PRODUCT:
4635 gfc_conv_intrinsic_dot_product (se, expr);
4638 case GFC_ISYM_DPROD:
4639 gfc_conv_intrinsic_dprod (se, expr);
4642 case GFC_ISYM_FDATE:
4643 gfc_conv_intrinsic_fdate (se, expr);
4646 case GFC_ISYM_FRACTION:
4647 gfc_conv_intrinsic_fraction (se, expr);
4651 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4654 case GFC_ISYM_IBCLR:
4655 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4658 case GFC_ISYM_IBITS:
4659 gfc_conv_intrinsic_ibits (se, expr);
4662 case GFC_ISYM_IBSET:
4663 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4666 case GFC_ISYM_IACHAR:
4667 case GFC_ISYM_ICHAR:
4668 /* We assume ASCII character sequence. */
4669 gfc_conv_intrinsic_ichar (se, expr);
4672 case GFC_ISYM_IARGC:
4673 gfc_conv_intrinsic_iargc (se, expr);
4677 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4680 case GFC_ISYM_INDEX:
4681 kind = expr->value.function.actual->expr->ts.kind;
4683 fndecl = gfor_fndecl_string_index;
4685 fndecl = gfor_fndecl_string_index_char4;
4689 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4693 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4696 case GFC_ISYM_IS_IOSTAT_END:
4697 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4700 case GFC_ISYM_IS_IOSTAT_EOR:
4701 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4704 case GFC_ISYM_ISNAN:
4705 gfc_conv_intrinsic_isnan (se, expr);
4708 case GFC_ISYM_LSHIFT:
4709 gfc_conv_intrinsic_rlshift (se, expr, 0);
4712 case GFC_ISYM_RSHIFT:
4713 gfc_conv_intrinsic_rlshift (se, expr, 1);
4716 case GFC_ISYM_ISHFT:
4717 gfc_conv_intrinsic_ishft (se, expr);
4720 case GFC_ISYM_ISHFTC:
4721 gfc_conv_intrinsic_ishftc (se, expr);
4724 case GFC_ISYM_LEADZ:
4725 gfc_conv_intrinsic_leadz (se, expr);
4728 case GFC_ISYM_TRAILZ:
4729 gfc_conv_intrinsic_trailz (se, expr);
4732 case GFC_ISYM_LBOUND:
4733 gfc_conv_intrinsic_bound (se, expr, 0);
4736 case GFC_ISYM_TRANSPOSE:
4737 if (se->ss && se->ss->useflags)
4739 gfc_conv_tmp_array_ref (se);
4740 gfc_advance_se_ss_chain (se);
4743 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4747 gfc_conv_intrinsic_len (se, expr);
4750 case GFC_ISYM_LEN_TRIM:
4751 gfc_conv_intrinsic_len_trim (se, expr);
4755 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4759 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4763 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4767 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4771 if (expr->ts.type == BT_CHARACTER)
4772 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4774 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4777 case GFC_ISYM_MAXLOC:
4778 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4781 case GFC_ISYM_MAXVAL:
4782 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4785 case GFC_ISYM_MERGE:
4786 gfc_conv_intrinsic_merge (se, expr);
4790 if (expr->ts.type == BT_CHARACTER)
4791 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4793 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4796 case GFC_ISYM_MINLOC:
4797 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4800 case GFC_ISYM_MINVAL:
4801 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4804 case GFC_ISYM_NEAREST:
4805 gfc_conv_intrinsic_nearest (se, expr);
4809 gfc_conv_intrinsic_not (se, expr);
4813 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4816 case GFC_ISYM_PRESENT:
4817 gfc_conv_intrinsic_present (se, expr);
4820 case GFC_ISYM_PRODUCT:
4821 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4824 case GFC_ISYM_RRSPACING:
4825 gfc_conv_intrinsic_rrspacing (se, expr);
4828 case GFC_ISYM_SET_EXPONENT:
4829 gfc_conv_intrinsic_set_exponent (se, expr);
4832 case GFC_ISYM_SCALE:
4833 gfc_conv_intrinsic_scale (se, expr);
4837 gfc_conv_intrinsic_sign (se, expr);
4841 gfc_conv_intrinsic_size (se, expr);
4844 case GFC_ISYM_SIZEOF:
4845 gfc_conv_intrinsic_sizeof (se, expr);
4848 case GFC_ISYM_SPACING:
4849 gfc_conv_intrinsic_spacing (se, expr);
4853 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4856 case GFC_ISYM_TRANSFER:
4857 if (se->ss && se->ss->useflags)
4859 /* Access the previously obtained result. */
4860 gfc_conv_tmp_array_ref (se);
4861 gfc_advance_se_ss_chain (se);
4864 gfc_conv_intrinsic_transfer (se, expr);
4867 case GFC_ISYM_TTYNAM:
4868 gfc_conv_intrinsic_ttynam (se, expr);
4871 case GFC_ISYM_UBOUND:
4872 gfc_conv_intrinsic_bound (se, expr, 1);
4876 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4880 gfc_conv_intrinsic_loc (se, expr);
4883 case GFC_ISYM_ACCESS:
4884 case GFC_ISYM_CHDIR:
4885 case GFC_ISYM_CHMOD:
4886 case GFC_ISYM_DTIME:
4887 case GFC_ISYM_ETIME:
4889 case GFC_ISYM_FGETC:
4892 case GFC_ISYM_FPUTC:
4893 case GFC_ISYM_FSTAT:
4894 case GFC_ISYM_FTELL:
4895 case GFC_ISYM_GETCWD:
4896 case GFC_ISYM_GETGID:
4897 case GFC_ISYM_GETPID:
4898 case GFC_ISYM_GETUID:
4899 case GFC_ISYM_HOSTNM:
4901 case GFC_ISYM_IERRNO:
4902 case GFC_ISYM_IRAND:
4903 case GFC_ISYM_ISATTY:
4905 case GFC_ISYM_LSTAT:
4906 case GFC_ISYM_MALLOC:
4907 case GFC_ISYM_MATMUL:
4908 case GFC_ISYM_MCLOCK:
4909 case GFC_ISYM_MCLOCK8:
4911 case GFC_ISYM_RENAME:
4912 case GFC_ISYM_SECOND:
4913 case GFC_ISYM_SECNDS:
4914 case GFC_ISYM_SIGNAL:
4916 case GFC_ISYM_SYMLNK:
4917 case GFC_ISYM_SYSTEM:
4919 case GFC_ISYM_TIME8:
4920 case GFC_ISYM_UMASK:
4921 case GFC_ISYM_UNLINK:
4922 gfc_conv_intrinsic_funcall (se, expr);
4925 case GFC_ISYM_EOSHIFT:
4927 case GFC_ISYM_RESHAPE:
4928 /* For those, expr->rank should always be >0 and thus the if above the
4929 switch should have matched. */
4934 gfc_conv_intrinsic_lib_function (se, expr);
4940 /* This generates code to execute before entering the scalarization loop.
4941 Currently does nothing. */
4944 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4946 switch (ss->expr->value.function.isym->id)
4948 case GFC_ISYM_UBOUND:
4949 case GFC_ISYM_LBOUND:
4958 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4959 inside the scalarization loop. */
4962 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4966 /* The two argument version returns a scalar. */
4967 if (expr->value.function.actual->next->expr)
4970 newss = gfc_get_ss ();
4971 newss->type = GFC_SS_INTRINSIC;
4974 newss->data.info.dimen = 1;
4980 /* Walk an intrinsic array libcall. */
4983 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4987 gcc_assert (expr->rank > 0);
4989 newss = gfc_get_ss ();
4990 newss->type = GFC_SS_FUNCTION;
4993 newss->data.info.dimen = expr->rank;
4999 /* Returns nonzero if the specified intrinsic function call maps directly to
5000 an external library call. Should only be used for functions that return
5004 gfc_is_intrinsic_libcall (gfc_expr * expr)
5006 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
5007 gcc_assert (expr->rank > 0);
5009 switch (expr->value.function.isym->id)
5013 case GFC_ISYM_COUNT:
5014 case GFC_ISYM_MATMUL:
5015 case GFC_ISYM_MAXLOC:
5016 case GFC_ISYM_MAXVAL:
5017 case GFC_ISYM_MINLOC:
5018 case GFC_ISYM_MINVAL:
5019 case GFC_ISYM_PRODUCT:
5021 case GFC_ISYM_SHAPE:
5022 case GFC_ISYM_SPREAD:
5023 case GFC_ISYM_TRANSPOSE:
5024 /* Ignore absent optional parameters. */
5027 case GFC_ISYM_RESHAPE:
5028 case GFC_ISYM_CSHIFT:
5029 case GFC_ISYM_EOSHIFT:
5031 case GFC_ISYM_UNPACK:
5032 /* Pass absent optional parameters. */
5040 /* Walk an intrinsic function. */
5042 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
5043 gfc_intrinsic_sym * isym)
5047 if (isym->elemental)
5048 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
5050 if (expr->rank == 0)
5053 if (gfc_is_intrinsic_libcall (expr))
5054 return gfc_walk_intrinsic_libfunc (ss, expr);
5056 /* Special cases. */
5059 case GFC_ISYM_LBOUND:
5060 case GFC_ISYM_UBOUND:
5061 return gfc_walk_intrinsic_bound (ss, expr);
5063 case GFC_ISYM_TRANSFER:
5064 return gfc_walk_intrinsic_libfunc (ss, expr);
5067 /* This probably meant someone forgot to add an intrinsic to the above
5068 list(s) when they implemented it, or something's gone horribly
5074 #include "gt-fortran-trans-intrinsic.h"