1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
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 gfc_intrinsic_map_t GTY(())
50 /* The explicit enum is required to work around inadequacies in the
51 garbage collection/gengtype parsing mechanism. */
54 /* Enum value from the "language-independent", aka C-centric, part
55 of gcc, or END_BUILTINS of no such value set. */
56 enum built_in_function code_r4;
57 enum built_in_function code_r8;
58 enum built_in_function code_r10;
59 enum built_in_function code_r16;
60 enum built_in_function code_c4;
61 enum built_in_function code_c8;
62 enum built_in_function code_c10;
63 enum built_in_function code_c16;
65 /* True if the naming pattern is to prepend "c" for complex and
66 append "f" for kind=4. False if the naming pattern is to
67 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
70 /* True if a complex version of the function exists. */
71 bool complex_available;
73 /* True if the function should be marked const. */
76 /* The base library name of this function. */
79 /* Cache decls created for the various operand types. */
91 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
92 defines complex variants of all of the entries in mathbuiltins.def
94 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
95 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
96 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, 0, 0, 0, 0, true, \
97 false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
98 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
100 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
101 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
102 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
103 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
104 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
105 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
107 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
108 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
111 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
113 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
115 /* Functions built into gcc itself. */
116 #include "mathbuiltins.def"
118 /* Functions in libgfortran. */
119 LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
122 LIB_FUNCTION (NONE, NULL, false)
126 #undef DEFINE_MATH_BUILTIN
127 #undef DEFINE_MATH_BUILTIN_C
129 /* Structure for storing components of a floating number to be used by
130 elemental functions to manipulate reals. */
133 tree arg; /* Variable tree to view convert to integer. */
134 tree expn; /* Variable tree to save exponent. */
135 tree frac; /* Variable tree to save fraction. */
136 tree smask; /* Constant tree of sign's mask. */
137 tree emask; /* Constant tree of exponent's mask. */
138 tree fmask; /* Constant tree of fraction's mask. */
139 tree edigits; /* Constant tree of the number of exponent bits. */
140 tree fdigits; /* Constant tree of the number of fraction bits. */
141 tree f1; /* Constant tree of the f1 defined in the real model. */
142 tree bias; /* Constant tree of the bias of exponent in the memory. */
143 tree type; /* Type tree of arg1. */
144 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
148 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
150 /* Evaluate the arguments to an intrinsic function. The value
151 of NARGS may be less than the actual number of arguments in EXPR
152 to allow optional "KIND" arguments that are not included in the
153 generated code to be ignored. */
156 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
157 tree *argarray, int nargs)
159 gfc_actual_arglist *actual;
161 gfc_intrinsic_arg *formal;
165 formal = expr->value.function.isym->formal;
166 actual = expr->value.function.actual;
168 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
169 actual = actual->next,
170 formal = formal ? formal->next : NULL)
174 /* Skip omitted optional arguments. */
181 /* Evaluate the parameter. This will substitute scalarized
182 references automatically. */
183 gfc_init_se (&argse, se);
185 if (e->ts.type == BT_CHARACTER)
187 gfc_conv_expr (&argse, e);
188 gfc_conv_string_parameter (&argse);
189 argarray[curr_arg++] = argse.string_length;
190 gcc_assert (curr_arg < nargs);
193 gfc_conv_expr_val (&argse, e);
195 /* If an optional argument is itself an optional dummy argument,
196 check its presence and substitute a null if absent. */
197 if (e->expr_type == EXPR_VARIABLE
198 && e->symtree->n.sym->attr.optional
201 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
203 gfc_add_block_to_block (&se->pre, &argse.pre);
204 gfc_add_block_to_block (&se->post, &argse.post);
205 argarray[curr_arg] = argse.expr;
209 /* Count the number of actual arguments to the intrinsic function EXPR
210 including any "hidden" string length arguments. */
213 gfc_intrinsic_argument_list_length (gfc_expr *expr)
216 gfc_actual_arglist *actual;
218 for (actual = expr->value.function.actual; actual; actual = actual->next)
223 if (actual->expr->ts.type == BT_CHARACTER)
233 /* Conversions between different types are output by the frontend as
234 intrinsic functions. We implement these directly with inline code. */
237 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
243 nargs = gfc_intrinsic_argument_list_length (expr);
244 args = (tree *) alloca (sizeof (tree) * nargs);
246 /* Evaluate all the arguments passed. Whilst we're only interested in the
247 first one here, there are other parts of the front-end that assume this
248 and will trigger an ICE if it's not the case. */
249 type = gfc_typenode_for_spec (&expr->ts);
250 gcc_assert (expr->value.function.actual->expr);
251 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
253 /* Conversion between character kinds involves a call to a library
255 if (expr->ts.type == BT_CHARACTER)
257 tree fndecl, var, addr, tmp;
259 if (expr->ts.kind == 1
260 && expr->value.function.actual->expr->ts.kind == 4)
261 fndecl = gfor_fndecl_convert_char4_to_char1;
262 else if (expr->ts.kind == 4
263 && expr->value.function.actual->expr->ts.kind == 1)
264 fndecl = gfor_fndecl_convert_char1_to_char4;
268 /* Create the variable storing the converted value. */
269 type = gfc_get_pchar_type (expr->ts.kind);
270 var = gfc_create_var (type, "str");
271 addr = gfc_build_addr_expr (build_pointer_type (type), var);
273 /* Call the library function that will perform the conversion. */
274 gcc_assert (nargs >= 2);
275 tmp = build_call_expr (fndecl, 3, addr, args[0], args[1]);
276 gfc_add_expr_to_block (&se->pre, tmp);
278 /* Free the temporary afterwards. */
279 tmp = gfc_call_free (var);
280 gfc_add_expr_to_block (&se->post, tmp);
283 se->string_length = args[0];
288 /* Conversion from complex to non-complex involves taking the real
289 component of the value. */
290 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
291 && expr->ts.type != BT_COMPLEX)
295 artype = TREE_TYPE (TREE_TYPE (args[0]));
296 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
299 se->expr = convert (type, args[0]);
302 /* This is needed because the gcc backend only implements
303 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
304 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
305 Similarly for CEILING. */
308 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
315 argtype = TREE_TYPE (arg);
316 arg = gfc_evaluate_now (arg, pblock);
318 intval = convert (type, arg);
319 intval = gfc_evaluate_now (intval, pblock);
321 tmp = convert (argtype, intval);
322 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
324 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
325 build_int_cst (type, 1));
326 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
331 /* Round to nearest integer, away from zero. */
334 build_round_expr (tree arg, tree restype)
339 int argprec, resprec;
341 argtype = TREE_TYPE (arg);
342 argprec = TYPE_PRECISION (argtype);
343 resprec = TYPE_PRECISION (restype);
345 /* Depending on the type of the result, choose the long int intrinsic
346 (lround family) or long long intrinsic (llround). We might also
347 need to convert the result afterwards. */
348 if (resprec <= LONG_TYPE_SIZE)
350 else if (resprec <= LONG_LONG_TYPE_SIZE)
355 /* Now, depending on the argument type, we choose between intrinsics. */
356 if (argprec == TYPE_PRECISION (float_type_node))
357 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
358 else if (argprec == TYPE_PRECISION (double_type_node))
359 fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
360 else if (argprec == TYPE_PRECISION (long_double_type_node))
361 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
365 return fold_convert (restype, build_call_expr (fn, 1, arg));
369 /* Convert a real to an integer using a specific rounding mode.
370 Ideally we would just build the corresponding GENERIC node,
371 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
374 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
375 enum rounding_mode op)
380 return build_fixbound_expr (pblock, arg, type, 0);
384 return build_fixbound_expr (pblock, arg, type, 1);
388 return build_round_expr (arg, type);
392 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
401 /* Round a real value using the specified rounding mode.
402 We use a temporary integer of that same kind size as the result.
403 Values larger than those that can be represented by this kind are
404 unchanged, as they will not be accurate enough to represent the
406 huge = HUGE (KIND (a))
407 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
411 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
422 kind = expr->ts.kind;
423 nargs = gfc_intrinsic_argument_list_length (expr);
426 /* We have builtin functions for some cases. */
469 /* Evaluate the argument. */
470 gcc_assert (expr->value.function.actual->expr);
471 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
473 /* Use a builtin function if one exists. */
474 if (n != END_BUILTINS)
476 tmp = built_in_decls[n];
477 se->expr = build_call_expr (tmp, 1, arg[0]);
481 /* This code is probably redundant, but we'll keep it lying around just
483 type = gfc_typenode_for_spec (&expr->ts);
484 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
486 /* Test if the value is too large to handle sensibly. */
487 gfc_set_model_kind (kind);
489 n = gfc_validate_kind (BT_INTEGER, kind, false);
490 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
491 tmp = gfc_conv_mpfr_to_tree (huge, kind);
492 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
494 mpfr_neg (huge, huge, GFC_RND_MODE);
495 tmp = gfc_conv_mpfr_to_tree (huge, kind);
496 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
497 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
498 itype = gfc_get_int_type (kind);
500 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
501 tmp = convert (type, tmp);
502 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
507 /* Convert to an integer using the specified rounding mode. */
510 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
516 nargs = gfc_intrinsic_argument_list_length (expr);
517 args = (tree *) alloca (sizeof (tree) * nargs);
519 /* Evaluate the argument, we process all arguments even though we only
520 use the first one for code generation purposes. */
521 type = gfc_typenode_for_spec (&expr->ts);
522 gcc_assert (expr->value.function.actual->expr);
523 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
525 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
527 /* Conversion to a different integer kind. */
528 se->expr = convert (type, args[0]);
532 /* Conversion from complex to non-complex involves taking the real
533 component of the value. */
534 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
535 && expr->ts.type != BT_COMPLEX)
539 artype = TREE_TYPE (TREE_TYPE (args[0]));
540 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
543 se->expr = build_fix_expr (&se->pre, args[0], type, op);
548 /* Get the imaginary component of a value. */
551 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
555 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
556 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
560 /* Get the complex conjugate of a value. */
563 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
567 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
568 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
572 /* Initialize function decls for library functions. The external functions
573 are created as required. Builtin functions are added here. */
576 gfc_build_intrinsic_lib_fndecls (void)
578 gfc_intrinsic_map_t *m;
580 /* Add GCC builtin functions. */
581 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
583 if (m->code_r4 != END_BUILTINS)
584 m->real4_decl = built_in_decls[m->code_r4];
585 if (m->code_r8 != END_BUILTINS)
586 m->real8_decl = built_in_decls[m->code_r8];
587 if (m->code_r10 != END_BUILTINS)
588 m->real10_decl = built_in_decls[m->code_r10];
589 if (m->code_r16 != END_BUILTINS)
590 m->real16_decl = built_in_decls[m->code_r16];
591 if (m->code_c4 != END_BUILTINS)
592 m->complex4_decl = built_in_decls[m->code_c4];
593 if (m->code_c8 != END_BUILTINS)
594 m->complex8_decl = built_in_decls[m->code_c8];
595 if (m->code_c10 != END_BUILTINS)
596 m->complex10_decl = built_in_decls[m->code_c10];
597 if (m->code_c16 != END_BUILTINS)
598 m->complex16_decl = built_in_decls[m->code_c16];
603 /* Create a fndecl for a simple intrinsic library function. */
606 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
611 gfc_actual_arglist *actual;
614 char name[GFC_MAX_SYMBOL_LEN + 3];
617 if (ts->type == BT_REAL)
622 pdecl = &m->real4_decl;
625 pdecl = &m->real8_decl;
628 pdecl = &m->real10_decl;
631 pdecl = &m->real16_decl;
637 else if (ts->type == BT_COMPLEX)
639 gcc_assert (m->complex_available);
644 pdecl = &m->complex4_decl;
647 pdecl = &m->complex8_decl;
650 pdecl = &m->complex10_decl;
653 pdecl = &m->complex16_decl;
668 snprintf (name, sizeof (name), "%s%s%s",
669 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
670 else if (ts->kind == 8)
671 snprintf (name, sizeof (name), "%s%s",
672 ts->type == BT_COMPLEX ? "c" : "", m->name);
675 gcc_assert (ts->kind == 10 || ts->kind == 16);
676 snprintf (name, sizeof (name), "%s%s%s",
677 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
682 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
683 ts->type == BT_COMPLEX ? 'c' : 'r',
687 argtypes = NULL_TREE;
688 for (actual = expr->value.function.actual; actual; actual = actual->next)
690 type = gfc_typenode_for_spec (&actual->expr->ts);
691 argtypes = gfc_chainon_list (argtypes, type);
693 argtypes = gfc_chainon_list (argtypes, void_type_node);
694 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
695 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
697 /* Mark the decl as external. */
698 DECL_EXTERNAL (fndecl) = 1;
699 TREE_PUBLIC (fndecl) = 1;
701 /* Mark it __attribute__((const)), if possible. */
702 TREE_READONLY (fndecl) = m->is_constant;
704 rest_of_decl_compilation (fndecl, 1, 0);
711 /* Convert an intrinsic function into an external or builtin call. */
714 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
716 gfc_intrinsic_map_t *m;
720 unsigned int num_args;
723 id = expr->value.function.isym->id;
724 /* Find the entry for this function. */
725 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
731 if (m->id == GFC_ISYM_NONE)
733 internal_error ("Intrinsic function %s(%d) not recognized",
734 expr->value.function.name, id);
737 /* Get the decl and generate the call. */
738 num_args = gfc_intrinsic_argument_list_length (expr);
739 args = (tree *) alloca (sizeof (tree) * num_args);
741 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
742 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
743 rettype = TREE_TYPE (TREE_TYPE (fndecl));
745 fndecl = build_addr (fndecl, current_function_decl);
746 se->expr = build_call_array (rettype, fndecl, num_args, args);
750 /* If bounds-checking is enabled, create code to verify at runtime that the
751 string lengths for both expressions are the same (needed for e.g. MERGE).
752 If bounds-checking is not enabled, does nothing. */
755 conv_same_strlen_check (const char* intr_name, locus* where, tree a, tree b,
761 /* If bounds-checking is disabled, do nothing. */
762 if (!flag_bounds_check)
765 /* Compare the two string lengths. */
766 cond = fold_build2 (NE_EXPR, boolean_type_node, a, b);
768 /* Output the runtime-check. */
769 name = gfc_build_cstring_const (intr_name);
770 name = gfc_build_addr_expr (pchar_type_node, name);
771 gfc_trans_runtime_check (true, false, cond, target, where,
772 "Unequal character lengths (%ld/%ld) for arguments"
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 build_fold_addr_expr (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 (flag_bounds_check)
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);
976 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
980 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
982 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
983 ubound, gfc_index_zero_node);
987 if (as->type == AS_ASSUMED_SIZE)
988 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
989 build_int_cst (TREE_TYPE (bound),
990 arg->expr->rank - 1));
992 cond = boolean_false_node;
994 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
995 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
997 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
998 lbound, gfc_index_one_node);
1005 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
1006 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
1007 gfc_index_one_node);
1008 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
1009 gfc_index_zero_node);
1012 se->expr = gfc_index_one_node;
1015 type = gfc_typenode_for_spec (&expr->ts);
1016 se->expr = convert (type, se->expr);
1021 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
1026 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1028 switch (expr->value.function.actual->expr->ts.type)
1032 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
1036 switch (expr->ts.kind)
1051 se->expr = build_call_expr (built_in_decls[n], 1, arg);
1060 /* Create a complex value from one or two real components. */
1063 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1069 unsigned int num_args;
1071 num_args = gfc_intrinsic_argument_list_length (expr);
1072 args = (tree *) alloca (sizeof (tree) * num_args);
1074 type = gfc_typenode_for_spec (&expr->ts);
1075 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1076 real = convert (TREE_TYPE (type), args[0]);
1078 imag = convert (TREE_TYPE (type), args[1]);
1079 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1081 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1083 imag = convert (TREE_TYPE (type), imag);
1086 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1088 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1091 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1092 MODULO(A, P) = A - FLOOR (A / P) * P */
1093 /* TODO: MOD(x, 0) */
1096 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1107 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1109 switch (expr->ts.type)
1112 /* Integer case is easy, we've got a builtin op. */
1113 type = TREE_TYPE (args[0]);
1116 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1118 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1123 /* Check if we have a builtin fmod. */
1124 switch (expr->ts.kind)
1143 /* Use it if it exists. */
1144 if (n != END_BUILTINS)
1146 tmp = build_addr (built_in_decls[n], current_function_decl);
1147 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1153 type = TREE_TYPE (args[0]);
1155 args[0] = gfc_evaluate_now (args[0], &se->pre);
1156 args[1] = gfc_evaluate_now (args[1], &se->pre);
1159 modulo = arg - floor (arg/arg2) * arg2, so
1160 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1162 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1163 thereby avoiding another division and retaining the accuracy
1164 of the builtin function. */
1165 if (n != END_BUILTINS && modulo)
1167 tree zero = gfc_build_const (type, integer_zero_node);
1168 tmp = gfc_evaluate_now (se->expr, &se->pre);
1169 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1170 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1171 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1172 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1173 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1174 test = gfc_evaluate_now (test, &se->pre);
1175 se->expr = fold_build3 (COND_EXPR, type, test,
1176 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1181 /* If we do not have a built_in fmod, the calculation is going to
1182 have to be done longhand. */
1183 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1185 /* Test if the value is too large to handle sensibly. */
1186 gfc_set_model_kind (expr->ts.kind);
1188 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1189 ikind = expr->ts.kind;
1192 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1193 ikind = gfc_max_integer_kind;
1195 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1196 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1197 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1199 mpfr_neg (huge, huge, GFC_RND_MODE);
1200 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1201 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1202 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1204 itype = gfc_get_int_type (ikind);
1206 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1208 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1209 tmp = convert (type, tmp);
1210 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1211 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1212 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1221 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1224 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1232 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1233 type = TREE_TYPE (args[0]);
1235 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1236 val = gfc_evaluate_now (val, &se->pre);
1238 zero = gfc_build_const (type, integer_zero_node);
1239 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1240 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1244 /* SIGN(A, B) is absolute value of A times sign of B.
1245 The real value versions use library functions to ensure the correct
1246 handling of negative zero. Integer case implemented as:
1247 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1251 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1257 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1258 if (expr->ts.type == BT_REAL)
1260 switch (expr->ts.kind)
1263 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1266 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1270 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1275 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1279 /* Having excluded floating point types, we know we are now dealing
1280 with signed integer types. */
1281 type = TREE_TYPE (args[0]);
1283 /* Args[0] is used multiple times below. */
1284 args[0] = gfc_evaluate_now (args[0], &se->pre);
1286 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1287 the signs of A and B are the same, and of all ones if they differ. */
1288 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1289 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1290 build_int_cst (type, TYPE_PRECISION (type) - 1));
1291 tmp = gfc_evaluate_now (tmp, &se->pre);
1293 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1294 is all ones (i.e. -1). */
1295 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1296 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1301 /* Test for the presence of an optional argument. */
1304 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1308 arg = expr->value.function.actual->expr;
1309 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1310 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1311 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1315 /* Calculate the double precision product of two single precision values. */
1318 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1323 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1325 /* Convert the args to double precision before multiplying. */
1326 type = gfc_typenode_for_spec (&expr->ts);
1327 args[0] = convert (type, args[0]);
1328 args[1] = convert (type, args[1]);
1329 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1333 /* Return a length one character string containing an ascii character. */
1336 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1341 unsigned int num_args;
1343 num_args = gfc_intrinsic_argument_list_length (expr);
1344 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1346 type = gfc_get_char_type (expr->ts.kind);
1347 var = gfc_create_var (type, "char");
1349 arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1350 gfc_add_modify (&se->pre, var, arg[0]);
1351 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1352 se->string_length = integer_one_node;
1357 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1365 unsigned int num_args;
1367 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1368 args = (tree *) alloca (sizeof (tree) * num_args);
1370 var = gfc_create_var (pchar_type_node, "pstr");
1371 len = gfc_create_var (gfc_get_int_type (8), "len");
1373 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1374 args[0] = build_fold_addr_expr (var);
1375 args[1] = build_fold_addr_expr (len);
1377 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1378 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1379 fndecl, num_args, args);
1380 gfc_add_expr_to_block (&se->pre, tmp);
1382 /* Free the temporary afterwards, if necessary. */
1383 cond = fold_build2 (GT_EXPR, boolean_type_node,
1384 len, build_int_cst (TREE_TYPE (len), 0));
1385 tmp = gfc_call_free (var);
1386 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1387 gfc_add_expr_to_block (&se->post, tmp);
1390 se->string_length = len;
1395 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1403 unsigned int num_args;
1405 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1406 args = (tree *) alloca (sizeof (tree) * num_args);
1408 var = gfc_create_var (pchar_type_node, "pstr");
1409 len = gfc_create_var (gfc_get_int_type (4), "len");
1411 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1412 args[0] = build_fold_addr_expr (var);
1413 args[1] = build_fold_addr_expr (len);
1415 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1416 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1417 fndecl, num_args, args);
1418 gfc_add_expr_to_block (&se->pre, tmp);
1420 /* Free the temporary afterwards, if necessary. */
1421 cond = fold_build2 (GT_EXPR, boolean_type_node,
1422 len, build_int_cst (TREE_TYPE (len), 0));
1423 tmp = gfc_call_free (var);
1424 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1425 gfc_add_expr_to_block (&se->post, tmp);
1428 se->string_length = len;
1432 /* Return a character string containing the tty name. */
1435 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1443 unsigned int num_args;
1445 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1446 args = (tree *) alloca (sizeof (tree) * num_args);
1448 var = gfc_create_var (pchar_type_node, "pstr");
1449 len = gfc_create_var (gfc_get_int_type (4), "len");
1451 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1452 args[0] = build_fold_addr_expr (var);
1453 args[1] = build_fold_addr_expr (len);
1455 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1456 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1457 fndecl, num_args, args);
1458 gfc_add_expr_to_block (&se->pre, tmp);
1460 /* Free the temporary afterwards, if necessary. */
1461 cond = fold_build2 (GT_EXPR, boolean_type_node,
1462 len, build_int_cst (TREE_TYPE (len), 0));
1463 tmp = gfc_call_free (var);
1464 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1465 gfc_add_expr_to_block (&se->post, tmp);
1468 se->string_length = len;
1472 /* Get the minimum/maximum value of all the parameters.
1473 minmax (a1, a2, a3, ...)
1476 if (a2 .op. mvar || isnan(mvar))
1478 if (a3 .op. mvar || isnan(mvar))
1485 /* TODO: Mismatching types can occur when specific names are used.
1486 These should be handled during resolution. */
1488 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1496 gfc_actual_arglist *argexpr;
1497 unsigned int i, nargs;
1499 nargs = gfc_intrinsic_argument_list_length (expr);
1500 args = (tree *) alloca (sizeof (tree) * nargs);
1502 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1503 type = gfc_typenode_for_spec (&expr->ts);
1505 argexpr = expr->value.function.actual;
1506 if (TREE_TYPE (args[0]) != type)
1507 args[0] = convert (type, args[0]);
1508 /* Only evaluate the argument once. */
1509 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1510 args[0] = gfc_evaluate_now (args[0], &se->pre);
1512 mvar = gfc_create_var (type, "M");
1513 gfc_add_modify (&se->pre, mvar, args[0]);
1514 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1520 /* Handle absent optional arguments by ignoring the comparison. */
1521 if (argexpr->expr->expr_type == EXPR_VARIABLE
1522 && argexpr->expr->symtree->n.sym->attr.optional
1523 && TREE_CODE (val) == INDIRECT_REF)
1525 (NE_EXPR, boolean_type_node, TREE_OPERAND (val, 0),
1526 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1531 /* Only evaluate the argument once. */
1532 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1533 val = gfc_evaluate_now (val, &se->pre);
1536 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1538 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1540 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1541 __builtin_isnan might be made dependent on that module being loaded,
1542 to help performance of programs that don't rely on IEEE semantics. */
1543 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1545 isnan = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1546 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1547 fold_convert (boolean_type_node, isnan));
1549 tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
1551 if (cond != NULL_TREE)
1552 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1554 gfc_add_expr_to_block (&se->pre, tmp);
1555 argexpr = argexpr->next;
1561 /* Generate library calls for MIN and MAX intrinsics for character
1564 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1567 tree var, len, fndecl, tmp, cond, function;
1570 nargs = gfc_intrinsic_argument_list_length (expr);
1571 args = (tree *) alloca (sizeof (tree) * (nargs + 4));
1572 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1574 /* Create the result variables. */
1575 len = gfc_create_var (gfc_charlen_type_node, "len");
1576 args[0] = build_fold_addr_expr (len);
1577 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1578 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1579 args[2] = build_int_cst (NULL_TREE, op);
1580 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1582 if (expr->ts.kind == 1)
1583 function = gfor_fndecl_string_minmax;
1584 else if (expr->ts.kind == 4)
1585 function = gfor_fndecl_string_minmax_char4;
1589 /* Make the function call. */
1590 fndecl = build_addr (function, current_function_decl);
1591 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
1593 gfc_add_expr_to_block (&se->pre, tmp);
1595 /* Free the temporary afterwards, if necessary. */
1596 cond = fold_build2 (GT_EXPR, boolean_type_node,
1597 len, build_int_cst (TREE_TYPE (len), 0));
1598 tmp = gfc_call_free (var);
1599 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1600 gfc_add_expr_to_block (&se->post, tmp);
1603 se->string_length = len;
1607 /* Create a symbol node for this intrinsic. The symbol from the frontend
1608 has the generic name. */
1611 gfc_get_symbol_for_expr (gfc_expr * expr)
1615 /* TODO: Add symbols for intrinsic function to the global namespace. */
1616 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1617 sym = gfc_new_symbol (expr->value.function.name, NULL);
1620 sym->attr.external = 1;
1621 sym->attr.function = 1;
1622 sym->attr.always_explicit = 1;
1623 sym->attr.proc = PROC_INTRINSIC;
1624 sym->attr.flavor = FL_PROCEDURE;
1628 sym->attr.dimension = 1;
1629 sym->as = gfc_get_array_spec ();
1630 sym->as->type = AS_ASSUMED_SHAPE;
1631 sym->as->rank = expr->rank;
1634 /* TODO: proper argument lists for external intrinsics. */
1638 /* Generate a call to an external intrinsic function. */
1640 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1645 gcc_assert (!se->ss || se->ss->expr == expr);
1648 gcc_assert (expr->rank > 0);
1650 gcc_assert (expr->rank == 0);
1652 sym = gfc_get_symbol_for_expr (expr);
1654 /* Calls to libgfortran_matmul need to be appended special arguments,
1655 to be able to call the BLAS ?gemm functions if required and possible. */
1656 append_args = NULL_TREE;
1657 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1658 && sym->ts.type != BT_LOGICAL)
1660 tree cint = gfc_get_int_type (gfc_c_int_kind);
1662 if (gfc_option.flag_external_blas
1663 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1664 && (sym->ts.kind == gfc_default_real_kind
1665 || sym->ts.kind == gfc_default_double_kind))
1669 if (sym->ts.type == BT_REAL)
1671 if (sym->ts.kind == gfc_default_real_kind)
1672 gemm_fndecl = gfor_fndecl_sgemm;
1674 gemm_fndecl = gfor_fndecl_dgemm;
1678 if (sym->ts.kind == gfc_default_real_kind)
1679 gemm_fndecl = gfor_fndecl_cgemm;
1681 gemm_fndecl = gfor_fndecl_zgemm;
1684 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1685 append_args = gfc_chainon_list
1686 (append_args, build_int_cst
1687 (cint, gfc_option.blas_matmul_limit));
1688 append_args = gfc_chainon_list (append_args,
1689 gfc_build_addr_expr (NULL_TREE,
1694 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1695 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1696 append_args = gfc_chainon_list (append_args, null_pointer_node);
1700 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1704 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1724 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1733 gfc_actual_arglist *actual;
1740 gfc_conv_intrinsic_funcall (se, expr);
1744 actual = expr->value.function.actual;
1745 type = gfc_typenode_for_spec (&expr->ts);
1746 /* Initialize the result. */
1747 resvar = gfc_create_var (type, "test");
1749 tmp = convert (type, boolean_true_node);
1751 tmp = convert (type, boolean_false_node);
1752 gfc_add_modify (&se->pre, resvar, tmp);
1754 /* Walk the arguments. */
1755 arrayss = gfc_walk_expr (actual->expr);
1756 gcc_assert (arrayss != gfc_ss_terminator);
1758 /* Initialize the scalarizer. */
1759 gfc_init_loopinfo (&loop);
1760 exit_label = gfc_build_label_decl (NULL_TREE);
1761 TREE_USED (exit_label) = 1;
1762 gfc_add_ss_to_loop (&loop, arrayss);
1764 /* Initialize the loop. */
1765 gfc_conv_ss_startstride (&loop);
1766 gfc_conv_loop_setup (&loop, &expr->where);
1768 gfc_mark_ss_chain_used (arrayss, 1);
1769 /* Generate the loop body. */
1770 gfc_start_scalarized_body (&loop, &body);
1772 /* If the condition matches then set the return value. */
1773 gfc_start_block (&block);
1775 tmp = convert (type, boolean_false_node);
1777 tmp = convert (type, boolean_true_node);
1778 gfc_add_modify (&block, resvar, tmp);
1780 /* And break out of the loop. */
1781 tmp = build1_v (GOTO_EXPR, exit_label);
1782 gfc_add_expr_to_block (&block, tmp);
1784 found = gfc_finish_block (&block);
1786 /* Check this element. */
1787 gfc_init_se (&arrayse, NULL);
1788 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1789 arrayse.ss = arrayss;
1790 gfc_conv_expr_val (&arrayse, actual->expr);
1792 gfc_add_block_to_block (&body, &arrayse.pre);
1793 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1794 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1795 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1796 gfc_add_expr_to_block (&body, tmp);
1797 gfc_add_block_to_block (&body, &arrayse.post);
1799 gfc_trans_scalarizing_loops (&loop, &body);
1801 /* Add the exit label. */
1802 tmp = build1_v (LABEL_EXPR, exit_label);
1803 gfc_add_expr_to_block (&loop.pre, tmp);
1805 gfc_add_block_to_block (&se->pre, &loop.pre);
1806 gfc_add_block_to_block (&se->pre, &loop.post);
1807 gfc_cleanup_loop (&loop);
1812 /* COUNT(A) = Number of true elements in A. */
1814 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1821 gfc_actual_arglist *actual;
1827 gfc_conv_intrinsic_funcall (se, expr);
1831 actual = expr->value.function.actual;
1833 type = gfc_typenode_for_spec (&expr->ts);
1834 /* Initialize the result. */
1835 resvar = gfc_create_var (type, "count");
1836 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1838 /* Walk the arguments. */
1839 arrayss = gfc_walk_expr (actual->expr);
1840 gcc_assert (arrayss != gfc_ss_terminator);
1842 /* Initialize the scalarizer. */
1843 gfc_init_loopinfo (&loop);
1844 gfc_add_ss_to_loop (&loop, arrayss);
1846 /* Initialize the loop. */
1847 gfc_conv_ss_startstride (&loop);
1848 gfc_conv_loop_setup (&loop, &expr->where);
1850 gfc_mark_ss_chain_used (arrayss, 1);
1851 /* Generate the loop body. */
1852 gfc_start_scalarized_body (&loop, &body);
1854 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1855 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1856 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1858 gfc_init_se (&arrayse, NULL);
1859 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1860 arrayse.ss = arrayss;
1861 gfc_conv_expr_val (&arrayse, actual->expr);
1862 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1864 gfc_add_block_to_block (&body, &arrayse.pre);
1865 gfc_add_expr_to_block (&body, tmp);
1866 gfc_add_block_to_block (&body, &arrayse.post);
1868 gfc_trans_scalarizing_loops (&loop, &body);
1870 gfc_add_block_to_block (&se->pre, &loop.pre);
1871 gfc_add_block_to_block (&se->pre, &loop.post);
1872 gfc_cleanup_loop (&loop);
1877 /* Inline implementation of the sum and product intrinsics. */
1879 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1887 gfc_actual_arglist *actual;
1892 gfc_expr *arrayexpr;
1897 gfc_conv_intrinsic_funcall (se, expr);
1901 type = gfc_typenode_for_spec (&expr->ts);
1902 /* Initialize the result. */
1903 resvar = gfc_create_var (type, "val");
1904 if (op == PLUS_EXPR)
1905 tmp = gfc_build_const (type, integer_zero_node);
1907 tmp = gfc_build_const (type, integer_one_node);
1909 gfc_add_modify (&se->pre, resvar, tmp);
1911 /* Walk the arguments. */
1912 actual = expr->value.function.actual;
1913 arrayexpr = actual->expr;
1914 arrayss = gfc_walk_expr (arrayexpr);
1915 gcc_assert (arrayss != gfc_ss_terminator);
1917 actual = actual->next->next;
1918 gcc_assert (actual);
1919 maskexpr = actual->expr;
1920 if (maskexpr && maskexpr->rank != 0)
1922 maskss = gfc_walk_expr (maskexpr);
1923 gcc_assert (maskss != gfc_ss_terminator);
1928 /* Initialize the scalarizer. */
1929 gfc_init_loopinfo (&loop);
1930 gfc_add_ss_to_loop (&loop, arrayss);
1932 gfc_add_ss_to_loop (&loop, maskss);
1934 /* Initialize the loop. */
1935 gfc_conv_ss_startstride (&loop);
1936 gfc_conv_loop_setup (&loop, &expr->where);
1938 gfc_mark_ss_chain_used (arrayss, 1);
1940 gfc_mark_ss_chain_used (maskss, 1);
1941 /* Generate the loop body. */
1942 gfc_start_scalarized_body (&loop, &body);
1944 /* If we have a mask, only add this element if the mask is set. */
1947 gfc_init_se (&maskse, NULL);
1948 gfc_copy_loopinfo_to_se (&maskse, &loop);
1950 gfc_conv_expr_val (&maskse, maskexpr);
1951 gfc_add_block_to_block (&body, &maskse.pre);
1953 gfc_start_block (&block);
1956 gfc_init_block (&block);
1958 /* Do the actual summation/product. */
1959 gfc_init_se (&arrayse, NULL);
1960 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1961 arrayse.ss = arrayss;
1962 gfc_conv_expr_val (&arrayse, arrayexpr);
1963 gfc_add_block_to_block (&block, &arrayse.pre);
1965 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1966 gfc_add_modify (&block, resvar, tmp);
1967 gfc_add_block_to_block (&block, &arrayse.post);
1971 /* We enclose the above in if (mask) {...} . */
1972 tmp = gfc_finish_block (&block);
1974 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1977 tmp = gfc_finish_block (&block);
1978 gfc_add_expr_to_block (&body, tmp);
1980 gfc_trans_scalarizing_loops (&loop, &body);
1982 /* For a scalar mask, enclose the loop in an if statement. */
1983 if (maskexpr && maskss == NULL)
1985 gfc_init_se (&maskse, NULL);
1986 gfc_conv_expr_val (&maskse, maskexpr);
1987 gfc_init_block (&block);
1988 gfc_add_block_to_block (&block, &loop.pre);
1989 gfc_add_block_to_block (&block, &loop.post);
1990 tmp = gfc_finish_block (&block);
1992 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1993 gfc_add_expr_to_block (&block, tmp);
1994 gfc_add_block_to_block (&se->pre, &block);
1998 gfc_add_block_to_block (&se->pre, &loop.pre);
1999 gfc_add_block_to_block (&se->pre, &loop.post);
2002 gfc_cleanup_loop (&loop);
2008 /* Inline implementation of the dot_product intrinsic. This function
2009 is based on gfc_conv_intrinsic_arith (the previous function). */
2011 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
2019 gfc_actual_arglist *actual;
2020 gfc_ss *arrayss1, *arrayss2;
2021 gfc_se arrayse1, arrayse2;
2022 gfc_expr *arrayexpr1, *arrayexpr2;
2024 type = gfc_typenode_for_spec (&expr->ts);
2026 /* Initialize the result. */
2027 resvar = gfc_create_var (type, "val");
2028 if (expr->ts.type == BT_LOGICAL)
2029 tmp = build_int_cst (type, 0);
2031 tmp = gfc_build_const (type, integer_zero_node);
2033 gfc_add_modify (&se->pre, resvar, tmp);
2035 /* Walk argument #1. */
2036 actual = expr->value.function.actual;
2037 arrayexpr1 = actual->expr;
2038 arrayss1 = gfc_walk_expr (arrayexpr1);
2039 gcc_assert (arrayss1 != gfc_ss_terminator);
2041 /* Walk argument #2. */
2042 actual = actual->next;
2043 arrayexpr2 = actual->expr;
2044 arrayss2 = gfc_walk_expr (arrayexpr2);
2045 gcc_assert (arrayss2 != gfc_ss_terminator);
2047 /* Initialize the scalarizer. */
2048 gfc_init_loopinfo (&loop);
2049 gfc_add_ss_to_loop (&loop, arrayss1);
2050 gfc_add_ss_to_loop (&loop, arrayss2);
2052 /* Initialize the loop. */
2053 gfc_conv_ss_startstride (&loop);
2054 gfc_conv_loop_setup (&loop, &expr->where);
2056 gfc_mark_ss_chain_used (arrayss1, 1);
2057 gfc_mark_ss_chain_used (arrayss2, 1);
2059 /* Generate the loop body. */
2060 gfc_start_scalarized_body (&loop, &body);
2061 gfc_init_block (&block);
2063 /* Make the tree expression for [conjg(]array1[)]. */
2064 gfc_init_se (&arrayse1, NULL);
2065 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2066 arrayse1.ss = arrayss1;
2067 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2068 if (expr->ts.type == BT_COMPLEX)
2069 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2070 gfc_add_block_to_block (&block, &arrayse1.pre);
2072 /* Make the tree expression for array2. */
2073 gfc_init_se (&arrayse2, NULL);
2074 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2075 arrayse2.ss = arrayss2;
2076 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2077 gfc_add_block_to_block (&block, &arrayse2.pre);
2079 /* Do the actual product and sum. */
2080 if (expr->ts.type == BT_LOGICAL)
2082 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2083 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2087 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2088 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2090 gfc_add_modify (&block, resvar, tmp);
2092 /* Finish up the loop block and the loop. */
2093 tmp = gfc_finish_block (&block);
2094 gfc_add_expr_to_block (&body, tmp);
2096 gfc_trans_scalarizing_loops (&loop, &body);
2097 gfc_add_block_to_block (&se->pre, &loop.pre);
2098 gfc_add_block_to_block (&se->pre, &loop.post);
2099 gfc_cleanup_loop (&loop);
2106 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
2110 stmtblock_t ifblock;
2111 stmtblock_t elseblock;
2119 gfc_actual_arglist *actual;
2124 gfc_expr *arrayexpr;
2131 gfc_conv_intrinsic_funcall (se, expr);
2135 /* Initialize the result. */
2136 pos = gfc_create_var (gfc_array_index_type, "pos");
2137 offset = gfc_create_var (gfc_array_index_type, "offset");
2138 type = gfc_typenode_for_spec (&expr->ts);
2140 /* Walk the arguments. */
2141 actual = expr->value.function.actual;
2142 arrayexpr = actual->expr;
2143 arrayss = gfc_walk_expr (arrayexpr);
2144 gcc_assert (arrayss != gfc_ss_terminator);
2146 actual = actual->next->next;
2147 gcc_assert (actual);
2148 maskexpr = actual->expr;
2149 if (maskexpr && maskexpr->rank != 0)
2151 maskss = gfc_walk_expr (maskexpr);
2152 gcc_assert (maskss != gfc_ss_terminator);
2157 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2158 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2159 switch (arrayexpr->ts.type)
2162 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
2166 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2167 arrayexpr->ts.kind);
2174 /* We start with the most negative possible value for MAXLOC, and the most
2175 positive possible value for MINLOC. The most negative possible value is
2176 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2177 possible value is HUGE in both cases. */
2179 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2180 gfc_add_modify (&se->pre, limit, tmp);
2182 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2183 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2184 build_int_cst (type, 1));
2186 /* Initialize the scalarizer. */
2187 gfc_init_loopinfo (&loop);
2188 gfc_add_ss_to_loop (&loop, arrayss);
2190 gfc_add_ss_to_loop (&loop, maskss);
2192 /* Initialize the loop. */
2193 gfc_conv_ss_startstride (&loop);
2194 gfc_conv_loop_setup (&loop, &expr->where);
2196 gcc_assert (loop.dimen == 1);
2198 /* Initialize the position to zero, following Fortran 2003. We are free
2199 to do this because Fortran 95 allows the result of an entirely false
2200 mask to be processor dependent. */
2201 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2203 gfc_mark_ss_chain_used (arrayss, 1);
2205 gfc_mark_ss_chain_used (maskss, 1);
2206 /* Generate the loop body. */
2207 gfc_start_scalarized_body (&loop, &body);
2209 /* If we have a mask, only check this element if the mask is set. */
2212 gfc_init_se (&maskse, NULL);
2213 gfc_copy_loopinfo_to_se (&maskse, &loop);
2215 gfc_conv_expr_val (&maskse, maskexpr);
2216 gfc_add_block_to_block (&body, &maskse.pre);
2218 gfc_start_block (&block);
2221 gfc_init_block (&block);
2223 /* Compare with the current limit. */
2224 gfc_init_se (&arrayse, NULL);
2225 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2226 arrayse.ss = arrayss;
2227 gfc_conv_expr_val (&arrayse, arrayexpr);
2228 gfc_add_block_to_block (&block, &arrayse.pre);
2230 /* We do the following if this is a more extreme value. */
2231 gfc_start_block (&ifblock);
2233 /* Assign the value to the limit... */
2234 gfc_add_modify (&ifblock, limit, arrayse.expr);
2236 /* Remember where we are. An offset must be added to the loop
2237 counter to obtain the required position. */
2239 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2240 gfc_index_one_node, loop.from[0]);
2242 tmp = gfc_index_one_node;
2244 gfc_add_modify (&block, offset, tmp);
2246 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2247 loop.loopvar[0], offset);
2248 gfc_add_modify (&ifblock, pos, tmp);
2250 ifbody = gfc_finish_block (&ifblock);
2252 /* If it is a more extreme value or pos is still zero and the value
2253 equal to the limit. */
2254 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2255 fold_build2 (EQ_EXPR, boolean_type_node,
2256 pos, gfc_index_zero_node),
2257 fold_build2 (EQ_EXPR, boolean_type_node,
2258 arrayse.expr, limit));
2259 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2260 fold_build2 (op, boolean_type_node,
2261 arrayse.expr, limit), tmp);
2262 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2263 gfc_add_expr_to_block (&block, tmp);
2267 /* We enclose the above in if (mask) {...}. */
2268 tmp = gfc_finish_block (&block);
2270 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2273 tmp = gfc_finish_block (&block);
2274 gfc_add_expr_to_block (&body, tmp);
2276 gfc_trans_scalarizing_loops (&loop, &body);
2278 /* For a scalar mask, enclose the loop in an if statement. */
2279 if (maskexpr && maskss == NULL)
2281 gfc_init_se (&maskse, NULL);
2282 gfc_conv_expr_val (&maskse, maskexpr);
2283 gfc_init_block (&block);
2284 gfc_add_block_to_block (&block, &loop.pre);
2285 gfc_add_block_to_block (&block, &loop.post);
2286 tmp = gfc_finish_block (&block);
2288 /* For the else part of the scalar mask, just initialize
2289 the pos variable the same way as above. */
2291 gfc_init_block (&elseblock);
2292 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2293 elsetmp = gfc_finish_block (&elseblock);
2295 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2296 gfc_add_expr_to_block (&block, tmp);
2297 gfc_add_block_to_block (&se->pre, &block);
2301 gfc_add_block_to_block (&se->pre, &loop.pre);
2302 gfc_add_block_to_block (&se->pre, &loop.post);
2304 gfc_cleanup_loop (&loop);
2306 se->expr = convert (type, pos);
2310 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2319 gfc_actual_arglist *actual;
2324 gfc_expr *arrayexpr;
2330 gfc_conv_intrinsic_funcall (se, expr);
2334 type = gfc_typenode_for_spec (&expr->ts);
2335 /* Initialize the result. */
2336 limit = gfc_create_var (type, "limit");
2337 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2338 switch (expr->ts.type)
2341 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2345 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2352 /* We start with the most negative possible value for MAXVAL, and the most
2353 positive possible value for MINVAL. The most negative possible value is
2354 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2355 possible value is HUGE in both cases. */
2357 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2359 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2360 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2361 tmp, build_int_cst (type, 1));
2363 gfc_add_modify (&se->pre, limit, tmp);
2365 /* Walk the arguments. */
2366 actual = expr->value.function.actual;
2367 arrayexpr = actual->expr;
2368 arrayss = gfc_walk_expr (arrayexpr);
2369 gcc_assert (arrayss != gfc_ss_terminator);
2371 actual = actual->next->next;
2372 gcc_assert (actual);
2373 maskexpr = actual->expr;
2374 if (maskexpr && maskexpr->rank != 0)
2376 maskss = gfc_walk_expr (maskexpr);
2377 gcc_assert (maskss != gfc_ss_terminator);
2382 /* Initialize the scalarizer. */
2383 gfc_init_loopinfo (&loop);
2384 gfc_add_ss_to_loop (&loop, arrayss);
2386 gfc_add_ss_to_loop (&loop, maskss);
2388 /* Initialize the loop. */
2389 gfc_conv_ss_startstride (&loop);
2390 gfc_conv_loop_setup (&loop, &expr->where);
2392 gfc_mark_ss_chain_used (arrayss, 1);
2394 gfc_mark_ss_chain_used (maskss, 1);
2395 /* Generate the loop body. */
2396 gfc_start_scalarized_body (&loop, &body);
2398 /* If we have a mask, only add this element if the mask is set. */
2401 gfc_init_se (&maskse, NULL);
2402 gfc_copy_loopinfo_to_se (&maskse, &loop);
2404 gfc_conv_expr_val (&maskse, maskexpr);
2405 gfc_add_block_to_block (&body, &maskse.pre);
2407 gfc_start_block (&block);
2410 gfc_init_block (&block);
2412 /* Compare with the current limit. */
2413 gfc_init_se (&arrayse, NULL);
2414 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2415 arrayse.ss = arrayss;
2416 gfc_conv_expr_val (&arrayse, arrayexpr);
2417 gfc_add_block_to_block (&block, &arrayse.pre);
2419 /* Assign the value to the limit... */
2420 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2422 /* If it is a more extreme value. */
2423 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2424 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2425 gfc_add_expr_to_block (&block, tmp);
2426 gfc_add_block_to_block (&block, &arrayse.post);
2428 tmp = gfc_finish_block (&block);
2430 /* We enclose the above in if (mask) {...}. */
2431 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2432 gfc_add_expr_to_block (&body, tmp);
2434 gfc_trans_scalarizing_loops (&loop, &body);
2436 /* For a scalar mask, enclose the loop in an if statement. */
2437 if (maskexpr && maskss == NULL)
2439 gfc_init_se (&maskse, NULL);
2440 gfc_conv_expr_val (&maskse, maskexpr);
2441 gfc_init_block (&block);
2442 gfc_add_block_to_block (&block, &loop.pre);
2443 gfc_add_block_to_block (&block, &loop.post);
2444 tmp = gfc_finish_block (&block);
2446 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2447 gfc_add_expr_to_block (&block, tmp);
2448 gfc_add_block_to_block (&se->pre, &block);
2452 gfc_add_block_to_block (&se->pre, &loop.pre);
2453 gfc_add_block_to_block (&se->pre, &loop.post);
2456 gfc_cleanup_loop (&loop);
2461 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2463 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2469 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2470 type = TREE_TYPE (args[0]);
2472 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2473 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2474 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2475 build_int_cst (type, 0));
2476 type = gfc_typenode_for_spec (&expr->ts);
2477 se->expr = convert (type, tmp);
2480 /* Generate code to perform the specified operation. */
2482 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2486 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2487 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2492 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2496 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2497 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2500 /* Set or clear a single bit. */
2502 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2509 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2510 type = TREE_TYPE (args[0]);
2512 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2518 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2520 se->expr = fold_build2 (op, type, args[0], tmp);
2523 /* Extract a sequence of bits.
2524 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2526 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2533 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2534 type = TREE_TYPE (args[0]);
2536 mask = build_int_cst (type, -1);
2537 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2538 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2540 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2542 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2545 /* RSHIFT (I, SHIFT) = I >> SHIFT
2546 LSHIFT (I, SHIFT) = I << SHIFT */
2548 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2552 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2554 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2555 TREE_TYPE (args[0]), args[0], args[1]);
2558 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2560 : ((shift >= 0) ? i << shift : i >> -shift)
2561 where all shifts are logical shifts. */
2563 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2575 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2576 type = TREE_TYPE (args[0]);
2577 utype = unsigned_type_for (type);
2579 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2581 /* Left shift if positive. */
2582 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2584 /* Right shift if negative.
2585 We convert to an unsigned type because we want a logical shift.
2586 The standard doesn't define the case of shifting negative
2587 numbers, and we try to be compatible with other compilers, most
2588 notably g77, here. */
2589 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2590 convert (utype, args[0]), width));
2592 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2593 build_int_cst (TREE_TYPE (args[1]), 0));
2594 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2596 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2597 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2599 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2600 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2602 se->expr = fold_build3 (COND_EXPR, type, cond,
2603 build_int_cst (type, 0), tmp);
2607 /* Circular shift. AKA rotate or barrel shift. */
2610 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2618 unsigned int num_args;
2620 num_args = gfc_intrinsic_argument_list_length (expr);
2621 args = (tree *) alloca (sizeof (tree) * num_args);
2623 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2627 /* Use a library function for the 3 parameter version. */
2628 tree int4type = gfc_get_int_type (4);
2630 type = TREE_TYPE (args[0]);
2631 /* We convert the first argument to at least 4 bytes, and
2632 convert back afterwards. This removes the need for library
2633 functions for all argument sizes, and function will be
2634 aligned to at least 32 bits, so there's no loss. */
2635 if (expr->ts.kind < 4)
2636 args[0] = convert (int4type, args[0]);
2638 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2639 need loads of library functions. They cannot have values >
2640 BIT_SIZE (I) so the conversion is safe. */
2641 args[1] = convert (int4type, args[1]);
2642 args[2] = convert (int4type, args[2]);
2644 switch (expr->ts.kind)
2649 tmp = gfor_fndecl_math_ishftc4;
2652 tmp = gfor_fndecl_math_ishftc8;
2655 tmp = gfor_fndecl_math_ishftc16;
2660 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2661 /* Convert the result back to the original type, if we extended
2662 the first argument's width above. */
2663 if (expr->ts.kind < 4)
2664 se->expr = convert (type, se->expr);
2668 type = TREE_TYPE (args[0]);
2670 /* Rotate left if positive. */
2671 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2673 /* Rotate right if negative. */
2674 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2675 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2677 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2678 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2679 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2681 /* Do nothing if shift == 0. */
2682 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2683 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2686 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
2687 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
2689 The conditional expression is necessary because the result of LEADZ(0)
2690 is defined, but the result of __builtin_clz(0) is undefined for most
2693 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
2694 difference in bit size between the argument of LEADZ and the C int. */
2697 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
2709 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2711 /* Which variant of __builtin_clz* should we call? */
2712 arg_kind = expr->value.function.actual->expr->ts.kind;
2713 i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
2719 arg_type = unsigned_type_node;
2724 arg_type = long_unsigned_type_node;
2729 arg_type = long_long_unsigned_type_node;
2737 /* Convert the actual argument to the proper argument type for the built-in
2738 function. But the return type is of the default INTEGER kind. */
2739 arg = fold_convert (arg_type, arg);
2740 result_type = gfc_get_int_type (gfc_default_integer_kind);
2742 /* Compute LEADZ for the case i .ne. 0. */
2743 s = TYPE_PRECISION (arg_type) - gfc_integer_kinds[i].bit_size;
2744 tmp = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
2745 leadz = fold_build2 (MINUS_EXPR, result_type,
2746 tmp, build_int_cst (result_type, s));
2748 /* Build BIT_SIZE. */
2749 bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
2751 /* ??? For some combinations of targets and integer kinds, the condition
2752 can be avoided if CLZ_DEFINED_VALUE_AT_ZERO is used. Later. */
2753 cond = fold_build2 (EQ_EXPR, boolean_type_node,
2754 arg, build_int_cst (arg_type, 0));
2755 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
2758 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
2760 The conditional expression is necessary because the result of TRAILZ(0)
2761 is defined, but the result of __builtin_ctz(0) is undefined for most
2765 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
2776 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2778 /* Which variant of __builtin_clz* should we call? */
2779 arg_kind = expr->value.function.actual->expr->ts.kind;
2780 i = gfc_validate_kind (BT_INTEGER, arg_kind, false);
2781 switch (expr->ts.kind)
2786 arg_type = unsigned_type_node;
2791 arg_type = long_unsigned_type_node;
2796 arg_type = long_long_unsigned_type_node;
2804 /* Convert the actual argument to the proper argument type for the built-in
2805 function. But the return type is of the default INTEGER kind. */
2806 arg = fold_convert (arg_type, arg);
2807 result_type = gfc_get_int_type (gfc_default_integer_kind);
2809 /* Compute TRAILZ for the case i .ne. 0. */
2810 trailz = fold_convert (result_type, build_call_expr (built_in_decls[n], 1, arg));
2812 /* Build BIT_SIZE. */
2813 bit_size = build_int_cst (result_type, gfc_integer_kinds[i].bit_size);
2815 /* ??? For some combinations of targets and integer kinds, the condition
2816 can be avoided if CTZ_DEFINED_VALUE_AT_ZERO is used. Later. */
2817 cond = fold_build2 (EQ_EXPR, boolean_type_node,
2818 arg, build_int_cst (arg_type, 0));
2819 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
2822 /* Process an intrinsic with unspecified argument-types that has an optional
2823 argument (which could be of type character), e.g. EOSHIFT. For those, we
2824 need to append the string length of the optional argument if it is not
2825 present and the type is really character.
2826 primary specifies the position (starting at 1) of the non-optional argument
2827 specifying the type and optional gives the position of the optional
2828 argument in the arglist. */
2831 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
2832 unsigned primary, unsigned optional)
2834 gfc_actual_arglist* prim_arg;
2835 gfc_actual_arglist* opt_arg;
2837 gfc_actual_arglist* arg;
2841 /* Find the two arguments given as position. */
2845 for (arg = expr->value.function.actual; arg; arg = arg->next)
2849 if (cur_pos == primary)
2851 if (cur_pos == optional)
2854 if (cur_pos >= primary && cur_pos >= optional)
2857 gcc_assert (prim_arg);
2858 gcc_assert (prim_arg->expr);
2859 gcc_assert (opt_arg);
2861 /* If we do have type CHARACTER and the optional argument is really absent,
2862 append a dummy 0 as string length. */
2863 append_args = NULL_TREE;
2864 if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
2868 dummy = build_int_cst (gfc_charlen_type_node, 0);
2869 append_args = gfc_chainon_list (append_args, dummy);
2872 /* Build the call itself. */
2873 sym = gfc_get_symbol_for_expr (expr);
2874 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
2879 /* The length of a character string. */
2881 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2891 gcc_assert (!se->ss);
2893 arg = expr->value.function.actual->expr;
2895 type = gfc_typenode_for_spec (&expr->ts);
2896 switch (arg->expr_type)
2899 len = build_int_cst (NULL_TREE, arg->value.character.length);
2903 /* Obtain the string length from the function used by
2904 trans-array.c(gfc_trans_array_constructor). */
2906 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2910 if (arg->ref == NULL
2911 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2913 /* This doesn't catch all cases.
2914 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2915 and the surrounding thread. */
2916 sym = arg->symtree->n.sym;
2917 decl = gfc_get_symbol_decl (sym);
2918 if (decl == current_function_decl && sym->attr.function
2919 && (sym->result == sym))
2920 decl = gfc_get_fake_result_decl (sym, 0);
2922 len = sym->ts.cl->backend_decl;
2927 /* Otherwise fall through. */
2930 /* Anybody stupid enough to do this deserves inefficient code. */
2931 ss = gfc_walk_expr (arg);
2932 gfc_init_se (&argse, se);
2933 if (ss == gfc_ss_terminator)
2934 gfc_conv_expr (&argse, arg);
2936 gfc_conv_expr_descriptor (&argse, arg, ss);
2937 gfc_add_block_to_block (&se->pre, &argse.pre);
2938 gfc_add_block_to_block (&se->post, &argse.post);
2939 len = argse.string_length;
2942 se->expr = convert (type, len);
2945 /* The length of a character string not including trailing blanks. */
2947 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2949 int kind = expr->value.function.actual->expr->ts.kind;
2950 tree args[2], type, fndecl;
2952 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2953 type = gfc_typenode_for_spec (&expr->ts);
2956 fndecl = gfor_fndecl_string_len_trim;
2958 fndecl = gfor_fndecl_string_len_trim_char4;
2962 se->expr = build_call_expr (fndecl, 2, args[0], args[1]);
2963 se->expr = convert (type, se->expr);
2967 /* Returns the starting position of a substring within a string. */
2970 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2973 tree logical4_type_node = gfc_get_logical_type (4);
2977 unsigned int num_args;
2979 args = (tree *) alloca (sizeof (tree) * 5);
2981 /* Get number of arguments; characters count double due to the
2982 string length argument. Kind= is not passed to the library
2983 and thus ignored. */
2984 if (expr->value.function.actual->next->next->expr == NULL)
2989 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2990 type = gfc_typenode_for_spec (&expr->ts);
2993 args[4] = build_int_cst (logical4_type_node, 0);
2995 args[4] = convert (logical4_type_node, args[4]);
2997 fndecl = build_addr (function, current_function_decl);
2998 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
3000 se->expr = convert (type, se->expr);
3004 /* The ascii value for a single character. */
3006 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
3008 tree args[2], type, pchartype;
3010 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3011 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
3012 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
3013 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
3014 type = gfc_typenode_for_spec (&expr->ts);
3016 se->expr = build_fold_indirect_ref (args[1]);
3017 se->expr = convert (type, se->expr);
3021 /* Intrinsic ISNAN calls __builtin_isnan. */
3024 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
3028 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3029 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
3030 STRIP_TYPE_NOPS (se->expr);
3031 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3035 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
3036 their argument against a constant integer value. */
3039 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
3043 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3044 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
3045 arg, build_int_cst (TREE_TYPE (arg), value));
3050 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
3053 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
3061 unsigned int num_args;
3063 num_args = gfc_intrinsic_argument_list_length (expr);
3064 args = (tree *) alloca (sizeof (tree) * num_args);
3066 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3067 if (expr->ts.type != BT_CHARACTER)
3075 /* We do the same as in the non-character case, but the argument
3076 list is different because of the string length arguments. We
3077 also have to set the string length for the result. */
3084 conv_same_strlen_check ("MERGE", &expr->where, len, len2, &se->post);
3086 se->string_length = len;
3088 type = TREE_TYPE (tsource);
3089 se->expr = fold_build3 (COND_EXPR, type, mask, tsource,
3090 fold_convert (type, fsource));
3094 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
3096 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
3098 tree arg, type, tmp;
3101 switch (expr->ts.kind)
3104 frexp = BUILT_IN_FREXPF;
3107 frexp = BUILT_IN_FREXP;
3111 frexp = BUILT_IN_FREXPL;
3117 type = gfc_typenode_for_spec (&expr->ts);
3118 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3119 tmp = gfc_create_var (integer_type_node, NULL);
3120 se->expr = build_call_expr (built_in_decls[frexp], 2,
3121 fold_convert (type, arg),
3122 build_fold_addr_expr (tmp));
3123 se->expr = fold_convert (type, se->expr);
3127 /* NEAREST (s, dir) is translated into
3128 tmp = copysign (INF, dir);
3129 return nextafter (s, tmp);
3132 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
3134 tree args[2], type, tmp;
3135 int nextafter, copysign, inf;
3137 switch (expr->ts.kind)
3140 nextafter = BUILT_IN_NEXTAFTERF;
3141 copysign = BUILT_IN_COPYSIGNF;
3142 inf = BUILT_IN_INFF;
3145 nextafter = BUILT_IN_NEXTAFTER;
3146 copysign = BUILT_IN_COPYSIGN;
3151 nextafter = BUILT_IN_NEXTAFTERL;
3152 copysign = BUILT_IN_COPYSIGNL;
3153 inf = BUILT_IN_INFL;
3159 type = gfc_typenode_for_spec (&expr->ts);
3160 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3161 tmp = build_call_expr (built_in_decls[copysign], 2,
3162 build_call_expr (built_in_decls[inf], 0),
3163 fold_convert (type, args[1]));
3164 se->expr = build_call_expr (built_in_decls[nextafter], 2,
3165 fold_convert (type, args[0]), tmp);
3166 se->expr = fold_convert (type, se->expr);
3170 /* SPACING (s) is translated into
3178 e = MAX_EXPR (e, emin);
3179 res = scalbn (1., e);
3183 where prec is the precision of s, gfc_real_kinds[k].digits,
3184 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
3185 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
3188 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
3190 tree arg, type, prec, emin, tiny, res, e;
3192 int frexp, scalbn, k;
3195 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3196 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
3197 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
3198 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind);
3200 switch (expr->ts.kind)
3203 frexp = BUILT_IN_FREXPF;
3204 scalbn = BUILT_IN_SCALBNF;
3207 frexp = BUILT_IN_FREXP;
3208 scalbn = BUILT_IN_SCALBN;
3212 frexp = BUILT_IN_FREXPL;
3213 scalbn = BUILT_IN_SCALBNL;
3219 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3220 arg = gfc_evaluate_now (arg, &se->pre);
3222 type = gfc_typenode_for_spec (&expr->ts);
3223 e = gfc_create_var (integer_type_node, NULL);
3224 res = gfc_create_var (type, NULL);
3227 /* Build the block for s /= 0. */
3228 gfc_start_block (&block);
3229 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3230 build_fold_addr_expr (e));
3231 gfc_add_expr_to_block (&block, tmp);
3233 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3234 gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3237 tmp = build_call_expr (built_in_decls[scalbn], 2,
3238 build_real_from_int_cst (type, integer_one_node), e);
3239 gfc_add_modify (&block, res, tmp);
3241 /* Finish by building the IF statement. */
3242 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3243 build_real_from_int_cst (type, integer_zero_node));
3244 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3245 gfc_finish_block (&block));
3247 gfc_add_expr_to_block (&se->pre, tmp);
3252 /* RRSPACING (s) is translated into
3259 x = scalbn (x, precision - e);
3263 where precision is gfc_real_kinds[k].digits. */
3266 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3268 tree arg, type, e, x, cond, stmt, tmp;
3269 int frexp, scalbn, fabs, prec, k;
3272 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3273 prec = gfc_real_kinds[k].digits;
3274 switch (expr->ts.kind)
3277 frexp = BUILT_IN_FREXPF;
3278 scalbn = BUILT_IN_SCALBNF;
3279 fabs = BUILT_IN_FABSF;
3282 frexp = BUILT_IN_FREXP;
3283 scalbn = BUILT_IN_SCALBN;
3284 fabs = BUILT_IN_FABS;
3288 frexp = BUILT_IN_FREXPL;
3289 scalbn = BUILT_IN_SCALBNL;
3290 fabs = BUILT_IN_FABSL;
3296 type = gfc_typenode_for_spec (&expr->ts);
3297 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3298 arg = gfc_evaluate_now (arg, &se->pre);
3300 e = gfc_create_var (integer_type_node, NULL);
3301 x = gfc_create_var (type, NULL);
3302 gfc_add_modify (&se->pre, x,
3303 build_call_expr (built_in_decls[fabs], 1, arg));
3306 gfc_start_block (&block);
3307 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3308 build_fold_addr_expr (e));
3309 gfc_add_expr_to_block (&block, tmp);
3311 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3312 build_int_cst (NULL_TREE, prec), e);
3313 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3314 gfc_add_modify (&block, x, tmp);
3315 stmt = gfc_finish_block (&block);
3317 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3318 build_real_from_int_cst (type, integer_zero_node));
3319 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3320 gfc_add_expr_to_block (&se->pre, tmp);
3322 se->expr = fold_convert (type, x);
3326 /* SCALE (s, i) is translated into scalbn (s, i). */
3328 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3333 switch (expr->ts.kind)
3336 scalbn = BUILT_IN_SCALBNF;
3339 scalbn = BUILT_IN_SCALBN;
3343 scalbn = BUILT_IN_SCALBNL;
3349 type = gfc_typenode_for_spec (&expr->ts);
3350 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3351 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3352 fold_convert (type, args[0]),
3353 fold_convert (integer_type_node, args[1]));
3354 se->expr = fold_convert (type, se->expr);
3358 /* SET_EXPONENT (s, i) is translated into
3359 scalbn (frexp (s, &dummy_int), i). */
3361 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3363 tree args[2], type, tmp;
3366 switch (expr->ts.kind)
3369 frexp = BUILT_IN_FREXPF;
3370 scalbn = BUILT_IN_SCALBNF;
3373 frexp = BUILT_IN_FREXP;
3374 scalbn = BUILT_IN_SCALBN;
3378 frexp = BUILT_IN_FREXPL;
3379 scalbn = BUILT_IN_SCALBNL;
3385 type = gfc_typenode_for_spec (&expr->ts);
3386 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3388 tmp = gfc_create_var (integer_type_node, NULL);
3389 tmp = build_call_expr (built_in_decls[frexp], 2,
3390 fold_convert (type, args[0]),
3391 build_fold_addr_expr (tmp));
3392 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3393 fold_convert (integer_type_node, args[1]));
3394 se->expr = fold_convert (type, se->expr);
3399 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3401 gfc_actual_arglist *actual;
3409 gfc_init_se (&argse, NULL);
3410 actual = expr->value.function.actual;
3412 ss = gfc_walk_expr (actual->expr);
3413 gcc_assert (ss != gfc_ss_terminator);
3414 argse.want_pointer = 1;
3415 argse.data_not_needed = 1;
3416 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3417 gfc_add_block_to_block (&se->pre, &argse.pre);
3418 gfc_add_block_to_block (&se->post, &argse.post);
3419 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3421 /* Build the call to size0. */
3422 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3424 actual = actual->next;
3428 gfc_init_se (&argse, NULL);
3429 gfc_conv_expr_type (&argse, actual->expr,
3430 gfc_array_index_type);
3431 gfc_add_block_to_block (&se->pre, &argse.pre);
3433 /* Unusually, for an intrinsic, size does not exclude
3434 an optional arg2, so we must test for it. */
3435 if (actual->expr->expr_type == EXPR_VARIABLE
3436 && actual->expr->symtree->n.sym->attr.dummy
3437 && actual->expr->symtree->n.sym->attr.optional)
3440 /* Build the call to size1. */
3441 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3444 gfc_init_se (&argse, NULL);
3445 argse.want_pointer = 1;
3446 argse.data_not_needed = 1;
3447 gfc_conv_expr (&argse, actual->expr);
3448 gfc_add_block_to_block (&se->pre, &argse.pre);
3449 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3450 argse.expr, null_pointer_node);
3451 tmp = gfc_evaluate_now (tmp, &se->pre);
3452 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3453 tmp, fncall1, fncall0);
3457 se->expr = NULL_TREE;
3458 argse.expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3459 argse.expr, gfc_index_one_node);
3462 else if (expr->value.function.actual->expr->rank == 1)
3464 argse.expr = gfc_index_zero_node;
3465 se->expr = NULL_TREE;
3470 if (se->expr == NULL_TREE)
3472 tree ubound, lbound;
3474 arg1 = build_fold_indirect_ref (arg1);
3475 ubound = gfc_conv_descriptor_ubound (arg1, argse.expr);
3476 lbound = gfc_conv_descriptor_lbound (arg1, argse.expr);
3477 se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3479 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
3480 gfc_index_one_node);
3481 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
3482 gfc_index_zero_node);
3485 type = gfc_typenode_for_spec (&expr->ts);
3486 se->expr = convert (type, se->expr);
3490 /* Helper function to compute the size of a character variable,
3491 excluding the terminating null characters. The result has
3492 gfc_array_index_type type. */
3495 size_of_string_in_bytes (int kind, tree string_length)
3498 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3500 bytesize = build_int_cst (gfc_array_index_type,
3501 gfc_character_kinds[i].bit_size / 8);
3503 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3504 fold_convert (gfc_array_index_type, string_length));
3509 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3522 arg = expr->value.function.actual->expr;
3524 gfc_init_se (&argse, NULL);
3525 ss = gfc_walk_expr (arg);
3527 if (ss == gfc_ss_terminator)
3529 gfc_conv_expr_reference (&argse, arg);
3530 source = argse.expr;
3532 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3534 /* Obtain the source word length. */
3535 if (arg->ts.type == BT_CHARACTER)
3536 se->expr = size_of_string_in_bytes (arg->ts.kind,
3537 argse.string_length);
3539 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
3543 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3544 argse.want_pointer = 0;
3545 gfc_conv_expr_descriptor (&argse, arg, ss);
3546 source = gfc_conv_descriptor_data_get (argse.expr);
3547 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3549 /* Obtain the argument's word length. */
3550 if (arg->ts.type == BT_CHARACTER)
3551 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3553 tmp = fold_convert (gfc_array_index_type,
3554 size_in_bytes (type));
3555 gfc_add_modify (&argse.pre, source_bytes, tmp);
3557 /* Obtain the size of the array in bytes. */
3558 for (n = 0; n < arg->rank; n++)
3561 idx = gfc_rank_cst[n];
3562 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3563 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3564 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3566 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3567 tmp, gfc_index_one_node);
3568 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3570 gfc_add_modify (&argse.pre, source_bytes, tmp);
3572 se->expr = source_bytes;
3575 gfc_add_block_to_block (&se->pre, &argse.pre);
3579 /* Intrinsic string comparison functions. */
3582 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
3586 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3589 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
3590 expr->value.function.actual->expr->ts.kind);
3591 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3592 build_int_cst (TREE_TYPE (se->expr), 0));
3595 /* Generate a call to the adjustl/adjustr library function. */
3597 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3605 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3608 type = TREE_TYPE (args[2]);
3609 var = gfc_conv_string_tmp (se, type, len);
3612 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3613 gfc_add_expr_to_block (&se->pre, tmp);
3615 se->string_length = len;
3619 /* Array transfer statement.
3620 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3622 typeof<DEST> = typeof<MOLD>
3624 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3625 sizeof (DEST(0) * SIZE). */
3628 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
3643 gfc_actual_arglist *arg;
3650 gcc_assert (se->loop);
3651 info = &se->ss->data.info;
3653 /* Convert SOURCE. The output from this stage is:-
3654 source_bytes = length of the source in bytes
3655 source = pointer to the source data. */
3656 arg = expr->value.function.actual;
3657 gfc_init_se (&argse, NULL);
3658 ss = gfc_walk_expr (arg->expr);
3660 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3662 /* Obtain the pointer to source and the length of source in bytes. */
3663 if (ss == gfc_ss_terminator)
3665 gfc_conv_expr_reference (&argse, arg->expr);
3666 source = argse.expr;
3668 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3670 /* Obtain the source word length. */
3671 if (arg->expr->ts.type == BT_CHARACTER)
3672 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3673 argse.string_length);
3675 tmp = fold_convert (gfc_array_index_type,
3676 size_in_bytes (source_type));
3680 argse.want_pointer = 0;
3681 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3682 source = gfc_conv_descriptor_data_get (argse.expr);
3683 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3685 /* Repack the source if not a full variable array. */
3686 if (!(arg->expr->expr_type == EXPR_VARIABLE
3687 && arg->expr->ref->u.ar.type == AR_FULL))
3689 tmp = build_fold_addr_expr (argse.expr);
3691 if (gfc_option.warn_array_temp)
3692 gfc_warning ("Creating array temporary at %L", &expr->where);
3694 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3695 source = gfc_evaluate_now (source, &argse.pre);
3697 /* Free the temporary. */
3698 gfc_start_block (&block);
3699 tmp = gfc_call_free (convert (pvoid_type_node, source));
3700 gfc_add_expr_to_block (&block, tmp);
3701 stmt = gfc_finish_block (&block);
3703 /* Clean up if it was repacked. */
3704 gfc_init_block (&block);
3705 tmp = gfc_conv_array_data (argse.expr);
3706 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3707 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3708 gfc_add_expr_to_block (&block, tmp);
3709 gfc_add_block_to_block (&block, &se->post);
3710 gfc_init_block (&se->post);
3711 gfc_add_block_to_block (&se->post, &block);
3714 /* Obtain the source word length. */
3715 if (arg->expr->ts.type == BT_CHARACTER)
3716 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3717 argse.string_length);
3719 tmp = fold_convert (gfc_array_index_type,
3720 size_in_bytes (source_type));
3722 /* Obtain the size of the array in bytes. */
3723 extent = gfc_create_var (gfc_array_index_type, NULL);
3724 for (n = 0; n < arg->expr->rank; n++)
3727 idx = gfc_rank_cst[n];
3728 gfc_add_modify (&argse.pre, source_bytes, tmp);
3729 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3730 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3731 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3732 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3734 gfc_add_modify (&argse.pre, extent, tmp);
3735 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3736 extent, gfc_index_one_node);
3737 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3742 gfc_add_modify (&argse.pre, source_bytes, tmp);
3743 gfc_add_block_to_block (&se->pre, &argse.pre);
3744 gfc_add_block_to_block (&se->post, &argse.post);
3746 /* Now convert MOLD. The outputs are:
3747 mold_type = the TREE type of MOLD
3748 dest_word_len = destination word length in bytes. */
3751 gfc_init_se (&argse, NULL);
3752 ss = gfc_walk_expr (arg->expr);
3754 if (ss == gfc_ss_terminator)
3756 gfc_conv_expr_reference (&argse, arg->expr);
3757 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3761 gfc_init_se (&argse, NULL);
3762 argse.want_pointer = 0;
3763 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3764 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3767 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
3769 /* If this TRANSFER is nested in another TRANSFER, use a type
3770 that preserves all bits. */
3771 if (arg->expr->ts.type == BT_LOGICAL)
3772 mold_type = gfc_get_int_type (arg->expr->ts.kind);
3775 if (arg->expr->ts.type == BT_CHARACTER)
3777 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
3778 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3781 tmp = fold_convert (gfc_array_index_type,
3782 size_in_bytes (mold_type));
3784 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3785 gfc_add_modify (&se->pre, dest_word_len, tmp);
3787 /* Finally convert SIZE, if it is present. */
3789 size_words = gfc_create_var (gfc_array_index_type, NULL);
3793 gfc_init_se (&argse, NULL);
3794 gfc_conv_expr_reference (&argse, arg->expr);
3795 tmp = convert (gfc_array_index_type,
3796 build_fold_indirect_ref (argse.expr));
3797 gfc_add_block_to_block (&se->pre, &argse.pre);
3798 gfc_add_block_to_block (&se->post, &argse.post);
3803 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3804 if (tmp != NULL_TREE)
3806 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3807 tmp, dest_word_len);
3808 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3814 gfc_add_modify (&se->pre, size_bytes, tmp);
3815 gfc_add_modify (&se->pre, size_words,
3816 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3817 size_bytes, dest_word_len));
3819 /* Evaluate the bounds of the result. If the loop range exists, we have
3820 to check if it is too large. If so, we modify loop->to be consistent
3821 with min(size, size(source)). Otherwise, size is made consistent with
3822 the loop range, so that the right number of bytes is transferred.*/
3823 n = se->loop->order[0];
3824 if (se->loop->to[n] != NULL_TREE)
3826 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3827 se->loop->to[n], se->loop->from[n]);
3828 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3829 tmp, gfc_index_one_node);
3830 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3832 gfc_add_modify (&se->pre, size_words, tmp);
3833 gfc_add_modify (&se->pre, size_bytes,
3834 fold_build2 (MULT_EXPR, gfc_array_index_type,
3835 size_words, dest_word_len));
3836 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3837 size_words, se->loop->from[n]);
3838 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3839 upper, gfc_index_one_node);
3843 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3844 size_words, gfc_index_one_node);
3845 se->loop->from[n] = gfc_index_zero_node;
3848 se->loop->to[n] = upper;
3850 /* Build a destination descriptor, using the pointer, source, as the
3851 data field. This is already allocated so set callee_alloc.
3852 FIXME callee_alloc is not set! */
3854 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3855 info, mold_type, NULL_TREE, false, true, false,
3858 /* Cast the pointer to the result. */
3859 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3860 tmp = fold_convert (pvoid_type_node, tmp);
3862 /* Use memcpy to do the transfer. */
3863 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3866 fold_convert (pvoid_type_node, source),
3868 gfc_add_expr_to_block (&se->pre, tmp);
3870 se->expr = info->descriptor;
3871 if (expr->ts.type == BT_CHARACTER)
3872 se->string_length = dest_word_len;
3876 /* Scalar transfer statement.
3877 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3880 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3882 gfc_actual_arglist *arg;
3889 /* Get a pointer to the source. */
3890 arg = expr->value.function.actual;
3891 ss = gfc_walk_expr (arg->expr);
3892 gfc_init_se (&argse, NULL);
3893 if (ss == gfc_ss_terminator)
3894 gfc_conv_expr_reference (&argse, arg->expr);
3896 gfc_conv_array_parameter (&argse, arg->expr, ss, 1, NULL, NULL);
3897 gfc_add_block_to_block (&se->pre, &argse.pre);
3898 gfc_add_block_to_block (&se->post, &argse.post);
3902 type = gfc_typenode_for_spec (&expr->ts);
3903 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
3905 /* If this TRANSFER is nested in another TRANSFER, use a type
3906 that preserves all bits. */
3907 if (expr->ts.type == BT_LOGICAL)
3908 type = gfc_get_int_type (expr->ts.kind);
3911 if (expr->ts.type == BT_CHARACTER)
3913 ptr = convert (build_pointer_type (type), ptr);
3914 gfc_init_se (&argse, NULL);
3915 gfc_conv_expr (&argse, arg->expr);
3916 gfc_add_block_to_block (&se->pre, &argse.pre);
3917 gfc_add_block_to_block (&se->post, &argse.post);
3919 se->string_length = argse.string_length;
3924 tmpdecl = gfc_create_var (type, "transfer");
3925 moldsize = size_in_bytes (type);
3927 /* Use memcpy to do the transfer. */
3928 tmp = build_fold_addr_expr (tmpdecl);
3929 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3930 fold_convert (pvoid_type_node, tmp),
3931 fold_convert (pvoid_type_node, ptr),
3933 gfc_add_expr_to_block (&se->pre, tmp);
3940 /* Generate code for the ALLOCATED intrinsic.
3941 Generate inline code that directly check the address of the argument. */
3944 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3946 gfc_actual_arglist *arg1;
3951 gfc_init_se (&arg1se, NULL);
3952 arg1 = expr->value.function.actual;
3953 ss1 = gfc_walk_expr (arg1->expr);
3954 arg1se.descriptor_only = 1;
3955 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3957 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3958 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3959 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3960 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3964 /* Generate code for the ASSOCIATED intrinsic.
3965 If both POINTER and TARGET are arrays, generate a call to library function
3966 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3967 In other cases, generate inline code that directly compare the address of
3968 POINTER with the address of TARGET. */
3971 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3973 gfc_actual_arglist *arg1;
3974 gfc_actual_arglist *arg2;
3979 tree nonzero_charlen;
3980 tree nonzero_arraylen;
3983 gfc_init_se (&arg1se, NULL);
3984 gfc_init_se (&arg2se, NULL);
3985 arg1 = expr->value.function.actual;
3987 ss1 = gfc_walk_expr (arg1->expr);
3991 /* No optional target. */
3992 if (ss1 == gfc_ss_terminator)
3994 /* A pointer to a scalar. */
3995 arg1se.want_pointer = 1;
3996 gfc_conv_expr (&arg1se, arg1->expr);
4001 /* A pointer to an array. */
4002 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4003 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
4005 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4006 gfc_add_block_to_block (&se->post, &arg1se.post);
4007 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
4008 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
4013 /* An optional target. */
4014 ss2 = gfc_walk_expr (arg2->expr);
4016 nonzero_charlen = NULL_TREE;
4017 if (arg1->expr->ts.type == BT_CHARACTER)
4018 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
4019 arg1->expr->ts.cl->backend_decl,
4022 if (ss1 == gfc_ss_terminator)
4024 /* A pointer to a scalar. */
4025 gcc_assert (ss2 == gfc_ss_terminator);
4026 arg1se.want_pointer = 1;
4027 gfc_conv_expr (&arg1se, arg1->expr);
4028 arg2se.want_pointer = 1;
4029 gfc_conv_expr (&arg2se, arg2->expr);
4030 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4031 gfc_add_block_to_block (&se->post, &arg1se.post);
4032 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4033 arg1se.expr, arg2se.expr);
4034 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
4035 arg1se.expr, null_pointer_node);
4036 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4041 /* An array pointer of zero length is not associated if target is
4043 arg1se.descriptor_only = 1;
4044 gfc_conv_expr_lhs (&arg1se, arg1->expr);
4045 tmp = gfc_conv_descriptor_stride (arg1se.expr,
4046 gfc_rank_cst[arg1->expr->rank - 1]);
4047 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
4048 build_int_cst (TREE_TYPE (tmp), 0));
4050 /* A pointer to an array, call library function _gfor_associated. */
4051 gcc_assert (ss2 != gfc_ss_terminator);
4052 arg1se.want_pointer = 1;
4053 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4055 arg2se.want_pointer = 1;
4056 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
4057 gfc_add_block_to_block (&se->pre, &arg2se.pre);
4058 gfc_add_block_to_block (&se->post, &arg2se.post);
4059 se->expr = build_call_expr (gfor_fndecl_associated, 2,
4060 arg1se.expr, arg2se.expr);
4061 se->expr = convert (boolean_type_node, se->expr);
4062 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4063 se->expr, nonzero_arraylen);
4066 /* If target is present zero character length pointers cannot
4068 if (nonzero_charlen != NULL_TREE)
4069 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4070 se->expr, nonzero_charlen);
4073 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4077 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
4080 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
4084 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4085 se->expr = build_call_expr (gfor_fndecl_sc_kind, 2, args[0], args[1]);
4086 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4090 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
4093 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
4097 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4099 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
4100 type = gfc_get_int_type (4);
4101 arg = build_fold_addr_expr (fold_convert (type, arg));
4103 /* Convert it to the required type. */
4104 type = gfc_typenode_for_spec (&expr->ts);
4105 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
4106 se->expr = fold_convert (type, se->expr);
4110 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
4113 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
4115 gfc_actual_arglist *actual;
4120 for (actual = expr->value.function.actual; actual; actual = actual->next)
4122 gfc_init_se (&argse, se);
4124 /* Pass a NULL pointer for an absent arg. */
4125 if (actual->expr == NULL)
4126 argse.expr = null_pointer_node;
4132 if (actual->expr->ts.kind != gfc_c_int_kind)
4134 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
4135 ts.type = BT_INTEGER;
4136 ts.kind = gfc_c_int_kind;
4137 gfc_convert_type (actual->expr, &ts, 2);
4139 gfc_conv_expr_reference (&argse, actual->expr);
4142 gfc_add_block_to_block (&se->pre, &argse.pre);
4143 gfc_add_block_to_block (&se->post, &argse.post);
4144 args = gfc_chainon_list (args, argse.expr);
4147 /* Convert it to the required type. */
4148 type = gfc_typenode_for_spec (&expr->ts);
4149 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
4150 se->expr = fold_convert (type, se->expr);
4154 /* Generate code for TRIM (A) intrinsic function. */
4157 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
4167 unsigned int num_args;
4169 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
4170 args = (tree *) alloca (sizeof (tree) * num_args);
4172 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
4173 addr = gfc_build_addr_expr (ppvoid_type_node, var);
4174 len = gfc_create_var (gfc_get_int_type (4), "len");
4176 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
4177 args[0] = build_fold_addr_expr (len);
4180 if (expr->ts.kind == 1)
4181 function = gfor_fndecl_string_trim;
4182 else if (expr->ts.kind == 4)
4183 function = gfor_fndecl_string_trim_char4;
4187 fndecl = build_addr (function, current_function_decl);
4188 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
4190 gfc_add_expr_to_block (&se->pre, tmp);
4192 /* Free the temporary afterwards, if necessary. */
4193 cond = fold_build2 (GT_EXPR, boolean_type_node,
4194 len, build_int_cst (TREE_TYPE (len), 0));
4195 tmp = gfc_call_free (var);
4196 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
4197 gfc_add_expr_to_block (&se->post, tmp);
4200 se->string_length = len;
4204 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
4207 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
4209 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
4210 tree type, cond, tmp, count, exit_label, n, max, largest;
4212 stmtblock_t block, body;
4215 /* We store in charsize the size of a character. */
4216 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
4217 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
4219 /* Get the arguments. */
4220 gfc_conv_intrinsic_function_args (se, expr, args, 3);
4221 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
4223 ncopies = gfc_evaluate_now (args[2], &se->pre);
4224 ncopies_type = TREE_TYPE (ncopies);
4226 /* Check that NCOPIES is not negative. */
4227 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
4228 build_int_cst (ncopies_type, 0));
4229 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4230 "Argument NCOPIES of REPEAT intrinsic is negative "
4231 "(its value is %lld)",
4232 fold_convert (long_integer_type_node, ncopies));
4234 /* If the source length is zero, any non negative value of NCOPIES
4235 is valid, and nothing happens. */
4236 n = gfc_create_var (ncopies_type, "ncopies");
4237 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4238 build_int_cst (size_type_node, 0));
4239 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
4240 build_int_cst (ncopies_type, 0), ncopies);
4241 gfc_add_modify (&se->pre, n, tmp);
4244 /* Check that ncopies is not too large: ncopies should be less than
4245 (or equal to) MAX / slen, where MAX is the maximal integer of
4246 the gfc_charlen_type_node type. If slen == 0, we need a special
4247 case to avoid the division by zero. */
4248 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
4249 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
4250 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
4251 fold_convert (size_type_node, max), slen);
4252 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
4253 ? size_type_node : ncopies_type;
4254 cond = fold_build2 (GT_EXPR, boolean_type_node,
4255 fold_convert (largest, ncopies),
4256 fold_convert (largest, max));
4257 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4258 build_int_cst (size_type_node, 0));
4259 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
4261 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4262 "Argument NCOPIES of REPEAT intrinsic is too large");
4264 /* Compute the destination length. */
4265 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4266 fold_convert (gfc_charlen_type_node, slen),
4267 fold_convert (gfc_charlen_type_node, ncopies));
4268 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
4269 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4271 /* Generate the code to do the repeat operation:
4272 for (i = 0; i < ncopies; i++)
4273 memmove (dest + (i * slen * size), src, slen*size); */
4274 gfc_start_block (&block);
4275 count = gfc_create_var (ncopies_type, "count");
4276 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4277 exit_label = gfc_build_label_decl (NULL_TREE);
4279 /* Start the loop body. */
4280 gfc_start_block (&body);
4282 /* Exit the loop if count >= ncopies. */
4283 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4284 tmp = build1_v (GOTO_EXPR, exit_label);
4285 TREE_USED (exit_label) = 1;
4286 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4287 build_empty_stmt ());
4288 gfc_add_expr_to_block (&body, tmp);
4290 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4291 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4292 fold_convert (gfc_charlen_type_node, slen),
4293 fold_convert (gfc_charlen_type_node, count));
4294 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4295 tmp, fold_convert (gfc_charlen_type_node, size));
4296 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4297 fold_convert (pvoid_type_node, dest),
4298 fold_convert (sizetype, tmp));
4299 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4300 fold_build2 (MULT_EXPR, size_type_node, slen,
4301 fold_convert (size_type_node, size)));
4302 gfc_add_expr_to_block (&body, tmp);
4304 /* Increment count. */
4305 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4306 count, build_int_cst (TREE_TYPE (count), 1));
4307 gfc_add_modify (&body, count, tmp);
4309 /* Build the loop. */
4310 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4311 gfc_add_expr_to_block (&block, tmp);
4313 /* Add the exit label. */
4314 tmp = build1_v (LABEL_EXPR, exit_label);
4315 gfc_add_expr_to_block (&block, tmp);
4317 /* Finish the block. */
4318 tmp = gfc_finish_block (&block);
4319 gfc_add_expr_to_block (&se->pre, tmp);
4321 /* Set the result value. */
4323 se->string_length = dlen;
4327 /* Generate code for the IARGC intrinsic. */
4330 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4336 /* Call the library function. This always returns an INTEGER(4). */
4337 fndecl = gfor_fndecl_iargc;
4338 tmp = build_call_expr (fndecl, 0);
4340 /* Convert it to the required type. */
4341 type = gfc_typenode_for_spec (&expr->ts);
4342 tmp = fold_convert (type, tmp);
4348 /* The loc intrinsic returns the address of its argument as
4349 gfc_index_integer_kind integer. */
4352 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4358 gcc_assert (!se->ss);
4360 arg_expr = expr->value.function.actual->expr;
4361 ss = gfc_walk_expr (arg_expr);
4362 if (ss == gfc_ss_terminator)
4363 gfc_conv_expr_reference (se, arg_expr);
4365 gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL);
4366 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4368 /* Create a temporary variable for loc return value. Without this,
4369 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4370 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4371 gfc_add_modify (&se->pre, temp_var, se->expr);
4372 se->expr = temp_var;
4375 /* Generate code for an intrinsic function. Some map directly to library
4376 calls, others get special handling. In some cases the name of the function
4377 used depends on the type specifiers. */
4380 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4382 gfc_intrinsic_sym *isym;
4387 isym = expr->value.function.isym;
4389 name = &expr->value.function.name[2];
4391 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4393 lib = gfc_is_intrinsic_libcall (expr);
4397 se->ignore_optional = 1;
4399 switch (expr->value.function.isym->id)
4401 case GFC_ISYM_EOSHIFT:
4403 case GFC_ISYM_RESHAPE:
4404 /* For all of those the first argument specifies the type and the
4405 third is optional. */
4406 conv_generic_with_optional_char_arg (se, expr, 1, 3);
4410 gfc_conv_intrinsic_funcall (se, expr);
4418 switch (expr->value.function.isym->id)
4423 case GFC_ISYM_REPEAT:
4424 gfc_conv_intrinsic_repeat (se, expr);
4428 gfc_conv_intrinsic_trim (se, expr);
4431 case GFC_ISYM_SC_KIND:
4432 gfc_conv_intrinsic_sc_kind (se, expr);
4435 case GFC_ISYM_SI_KIND:
4436 gfc_conv_intrinsic_si_kind (se, expr);
4439 case GFC_ISYM_SR_KIND:
4440 gfc_conv_intrinsic_sr_kind (se, expr);
4443 case GFC_ISYM_EXPONENT:
4444 gfc_conv_intrinsic_exponent (se, expr);
4448 kind = expr->value.function.actual->expr->ts.kind;
4450 fndecl = gfor_fndecl_string_scan;
4452 fndecl = gfor_fndecl_string_scan_char4;
4456 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4459 case GFC_ISYM_VERIFY:
4460 kind = expr->value.function.actual->expr->ts.kind;
4462 fndecl = gfor_fndecl_string_verify;
4464 fndecl = gfor_fndecl_string_verify_char4;
4468 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4471 case GFC_ISYM_ALLOCATED:
4472 gfc_conv_allocated (se, expr);
4475 case GFC_ISYM_ASSOCIATED:
4476 gfc_conv_associated(se, expr);
4480 gfc_conv_intrinsic_abs (se, expr);
4483 case GFC_ISYM_ADJUSTL:
4484 if (expr->ts.kind == 1)
4485 fndecl = gfor_fndecl_adjustl;
4486 else if (expr->ts.kind == 4)
4487 fndecl = gfor_fndecl_adjustl_char4;
4491 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4494 case GFC_ISYM_ADJUSTR:
4495 if (expr->ts.kind == 1)
4496 fndecl = gfor_fndecl_adjustr;
4497 else if (expr->ts.kind == 4)
4498 fndecl = gfor_fndecl_adjustr_char4;
4502 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4505 case GFC_ISYM_AIMAG:
4506 gfc_conv_intrinsic_imagpart (se, expr);
4510 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4514 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4517 case GFC_ISYM_ANINT:
4518 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4522 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4526 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4529 case GFC_ISYM_BTEST:
4530 gfc_conv_intrinsic_btest (se, expr);
4533 case GFC_ISYM_ACHAR:
4535 gfc_conv_intrinsic_char (se, expr);
4538 case GFC_ISYM_CONVERSION:
4540 case GFC_ISYM_LOGICAL:
4542 gfc_conv_intrinsic_conversion (se, expr);
4545 /* Integer conversions are handled separately to make sure we get the
4546 correct rounding mode. */
4551 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4555 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4558 case GFC_ISYM_CEILING:
4559 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4562 case GFC_ISYM_FLOOR:
4563 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4567 gfc_conv_intrinsic_mod (se, expr, 0);
4570 case GFC_ISYM_MODULO:
4571 gfc_conv_intrinsic_mod (se, expr, 1);
4574 case GFC_ISYM_CMPLX:
4575 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4578 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4579 gfc_conv_intrinsic_iargc (se, expr);
4582 case GFC_ISYM_COMPLEX:
4583 gfc_conv_intrinsic_cmplx (se, expr, 1);
4586 case GFC_ISYM_CONJG:
4587 gfc_conv_intrinsic_conjg (se, expr);
4590 case GFC_ISYM_COUNT:
4591 gfc_conv_intrinsic_count (se, expr);
4594 case GFC_ISYM_CTIME:
4595 gfc_conv_intrinsic_ctime (se, expr);
4599 gfc_conv_intrinsic_dim (se, expr);
4602 case GFC_ISYM_DOT_PRODUCT:
4603 gfc_conv_intrinsic_dot_product (se, expr);
4606 case GFC_ISYM_DPROD:
4607 gfc_conv_intrinsic_dprod (se, expr);
4610 case GFC_ISYM_FDATE:
4611 gfc_conv_intrinsic_fdate (se, expr);
4614 case GFC_ISYM_FRACTION:
4615 gfc_conv_intrinsic_fraction (se, expr);
4619 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4622 case GFC_ISYM_IBCLR:
4623 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4626 case GFC_ISYM_IBITS:
4627 gfc_conv_intrinsic_ibits (se, expr);
4630 case GFC_ISYM_IBSET:
4631 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4634 case GFC_ISYM_IACHAR:
4635 case GFC_ISYM_ICHAR:
4636 /* We assume ASCII character sequence. */
4637 gfc_conv_intrinsic_ichar (se, expr);
4640 case GFC_ISYM_IARGC:
4641 gfc_conv_intrinsic_iargc (se, expr);
4645 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4648 case GFC_ISYM_INDEX:
4649 kind = expr->value.function.actual->expr->ts.kind;
4651 fndecl = gfor_fndecl_string_index;
4653 fndecl = gfor_fndecl_string_index_char4;
4657 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4661 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4664 case GFC_ISYM_IS_IOSTAT_END:
4665 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4668 case GFC_ISYM_IS_IOSTAT_EOR:
4669 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4672 case GFC_ISYM_ISNAN:
4673 gfc_conv_intrinsic_isnan (se, expr);
4676 case GFC_ISYM_LSHIFT:
4677 gfc_conv_intrinsic_rlshift (se, expr, 0);
4680 case GFC_ISYM_RSHIFT:
4681 gfc_conv_intrinsic_rlshift (se, expr, 1);
4684 case GFC_ISYM_ISHFT:
4685 gfc_conv_intrinsic_ishft (se, expr);
4688 case GFC_ISYM_ISHFTC:
4689 gfc_conv_intrinsic_ishftc (se, expr);
4692 case GFC_ISYM_LEADZ:
4693 gfc_conv_intrinsic_leadz (se, expr);
4696 case GFC_ISYM_TRAILZ:
4697 gfc_conv_intrinsic_trailz (se, expr);
4700 case GFC_ISYM_LBOUND:
4701 gfc_conv_intrinsic_bound (se, expr, 0);
4704 case GFC_ISYM_TRANSPOSE:
4705 if (se->ss && se->ss->useflags)
4707 gfc_conv_tmp_array_ref (se);
4708 gfc_advance_se_ss_chain (se);
4711 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4715 gfc_conv_intrinsic_len (se, expr);
4718 case GFC_ISYM_LEN_TRIM:
4719 gfc_conv_intrinsic_len_trim (se, expr);
4723 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4727 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4731 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4735 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4739 if (expr->ts.type == BT_CHARACTER)
4740 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4742 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4745 case GFC_ISYM_MAXLOC:
4746 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4749 case GFC_ISYM_MAXVAL:
4750 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4753 case GFC_ISYM_MERGE:
4754 gfc_conv_intrinsic_merge (se, expr);
4758 if (expr->ts.type == BT_CHARACTER)
4759 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4761 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4764 case GFC_ISYM_MINLOC:
4765 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4768 case GFC_ISYM_MINVAL:
4769 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4772 case GFC_ISYM_NEAREST:
4773 gfc_conv_intrinsic_nearest (se, expr);
4777 gfc_conv_intrinsic_not (se, expr);
4781 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4784 case GFC_ISYM_PRESENT:
4785 gfc_conv_intrinsic_present (se, expr);
4788 case GFC_ISYM_PRODUCT:
4789 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4792 case GFC_ISYM_RRSPACING:
4793 gfc_conv_intrinsic_rrspacing (se, expr);
4796 case GFC_ISYM_SET_EXPONENT:
4797 gfc_conv_intrinsic_set_exponent (se, expr);
4800 case GFC_ISYM_SCALE:
4801 gfc_conv_intrinsic_scale (se, expr);
4805 gfc_conv_intrinsic_sign (se, expr);
4809 gfc_conv_intrinsic_size (se, expr);
4812 case GFC_ISYM_SIZEOF:
4813 gfc_conv_intrinsic_sizeof (se, expr);
4816 case GFC_ISYM_SPACING:
4817 gfc_conv_intrinsic_spacing (se, expr);
4821 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4824 case GFC_ISYM_TRANSFER:
4825 if (se->ss && se->ss->useflags)
4827 /* Access the previously obtained result. */
4828 gfc_conv_tmp_array_ref (se);
4829 gfc_advance_se_ss_chain (se);
4833 /* Ensure double transfer through LOGICAL preserves all
4835 gfc_expr *source = expr->value.function.actual->expr;
4836 if (source->expr_type == EXPR_FUNCTION
4837 && source->value.function.esym == NULL
4838 && source->value.function.isym != NULL
4839 && source->value.function.isym->id == GFC_ISYM_TRANSFER
4840 && source->ts.type == BT_LOGICAL
4841 && expr->ts.type != source->ts.type)
4842 source->value.function.name = "__transfer_in_transfer";
4845 gfc_conv_intrinsic_array_transfer (se, expr);
4847 gfc_conv_intrinsic_transfer (se, expr);
4851 case GFC_ISYM_TTYNAM:
4852 gfc_conv_intrinsic_ttynam (se, expr);
4855 case GFC_ISYM_UBOUND:
4856 gfc_conv_intrinsic_bound (se, expr, 1);
4860 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4864 gfc_conv_intrinsic_loc (se, expr);
4867 case GFC_ISYM_ACCESS:
4868 case GFC_ISYM_CHDIR:
4869 case GFC_ISYM_CHMOD:
4870 case GFC_ISYM_DTIME:
4871 case GFC_ISYM_ETIME:
4873 case GFC_ISYM_FGETC:
4876 case GFC_ISYM_FPUTC:
4877 case GFC_ISYM_FSTAT:
4878 case GFC_ISYM_FTELL:
4879 case GFC_ISYM_GETCWD:
4880 case GFC_ISYM_GETGID:
4881 case GFC_ISYM_GETPID:
4882 case GFC_ISYM_GETUID:
4883 case GFC_ISYM_HOSTNM:
4885 case GFC_ISYM_IERRNO:
4886 case GFC_ISYM_IRAND:
4887 case GFC_ISYM_ISATTY:
4889 case GFC_ISYM_LSTAT:
4890 case GFC_ISYM_MALLOC:
4891 case GFC_ISYM_MATMUL:
4892 case GFC_ISYM_MCLOCK:
4893 case GFC_ISYM_MCLOCK8:
4895 case GFC_ISYM_RENAME:
4896 case GFC_ISYM_SECOND:
4897 case GFC_ISYM_SECNDS:
4898 case GFC_ISYM_SIGNAL:
4900 case GFC_ISYM_SYMLNK:
4901 case GFC_ISYM_SYSTEM:
4903 case GFC_ISYM_TIME8:
4904 case GFC_ISYM_UMASK:
4905 case GFC_ISYM_UNLINK:
4906 gfc_conv_intrinsic_funcall (se, expr);
4909 case GFC_ISYM_EOSHIFT:
4911 case GFC_ISYM_RESHAPE:
4912 /* For those, expr->rank should always be >0 and thus the if above the
4913 switch should have matched. */
4918 gfc_conv_intrinsic_lib_function (se, expr);
4924 /* This generates code to execute before entering the scalarization loop.
4925 Currently does nothing. */
4928 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4930 switch (ss->expr->value.function.isym->id)
4932 case GFC_ISYM_UBOUND:
4933 case GFC_ISYM_LBOUND:
4942 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4943 inside the scalarization loop. */
4946 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4950 /* The two argument version returns a scalar. */
4951 if (expr->value.function.actual->next->expr)
4954 newss = gfc_get_ss ();
4955 newss->type = GFC_SS_INTRINSIC;
4958 newss->data.info.dimen = 1;
4964 /* Walk an intrinsic array libcall. */
4967 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4971 gcc_assert (expr->rank > 0);
4973 newss = gfc_get_ss ();
4974 newss->type = GFC_SS_FUNCTION;
4977 newss->data.info.dimen = expr->rank;
4983 /* Returns nonzero if the specified intrinsic function call maps directly to
4984 an external library call. Should only be used for functions that return
4988 gfc_is_intrinsic_libcall (gfc_expr * expr)
4990 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4991 gcc_assert (expr->rank > 0);
4993 switch (expr->value.function.isym->id)
4997 case GFC_ISYM_COUNT:
4998 case GFC_ISYM_MATMUL:
4999 case GFC_ISYM_MAXLOC:
5000 case GFC_ISYM_MAXVAL:
5001 case GFC_ISYM_MINLOC:
5002 case GFC_ISYM_MINVAL:
5003 case GFC_ISYM_PRODUCT:
5005 case GFC_ISYM_SHAPE:
5006 case GFC_ISYM_SPREAD:
5007 case GFC_ISYM_TRANSPOSE:
5008 /* Ignore absent optional parameters. */
5011 case GFC_ISYM_RESHAPE:
5012 case GFC_ISYM_CSHIFT:
5013 case GFC_ISYM_EOSHIFT:
5015 case GFC_ISYM_UNPACK:
5016 /* Pass absent optional parameters. */
5024 /* Walk an intrinsic function. */
5026 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
5027 gfc_intrinsic_sym * isym)
5031 if (isym->elemental)
5032 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
5034 if (expr->rank == 0)
5037 if (gfc_is_intrinsic_libcall (expr))
5038 return gfc_walk_intrinsic_libfunc (ss, expr);
5040 /* Special cases. */
5043 case GFC_ISYM_LBOUND:
5044 case GFC_ISYM_UBOUND:
5045 return gfc_walk_intrinsic_bound (ss, expr);
5047 case GFC_ISYM_TRANSFER:
5048 return gfc_walk_intrinsic_libfunc (ss, expr);
5051 /* This probably meant someone forgot to add an intrinsic to the above
5052 list(s) when they implemented it, or something's gone horribly
5058 #include "gt-fortran-trans-intrinsic.h"