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"
33 #include "tree-gimple.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 = 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 = 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 = 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);
749 /* The EXPONENT(s) intrinsic function is translated into
756 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
758 tree arg, type, res, tmp;
761 switch (expr->value.function.actual->expr->ts.kind)
764 frexp = BUILT_IN_FREXPF;
767 frexp = BUILT_IN_FREXP;
771 frexp = BUILT_IN_FREXPL;
777 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
779 res = gfc_create_var (integer_type_node, NULL);
780 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
781 build_fold_addr_expr (res));
782 gfc_add_expr_to_block (&se->pre, tmp);
784 type = gfc_typenode_for_spec (&expr->ts);
785 se->expr = fold_convert (type, res);
788 /* Evaluate a single upper or lower bound. */
789 /* TODO: bound intrinsic generates way too much unnecessary code. */
792 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
794 gfc_actual_arglist *arg;
795 gfc_actual_arglist *arg2;
800 tree cond, cond1, cond2, cond3, cond4, size;
808 arg = expr->value.function.actual;
813 /* Create an implicit second parameter from the loop variable. */
814 gcc_assert (!arg2->expr);
815 gcc_assert (se->loop->dimen == 1);
816 gcc_assert (se->ss->expr == expr);
817 gfc_advance_se_ss_chain (se);
818 bound = se->loop->loopvar[0];
819 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
824 /* use the passed argument. */
825 gcc_assert (arg->next->expr);
826 gfc_init_se (&argse, NULL);
827 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
828 gfc_add_block_to_block (&se->pre, &argse.pre);
830 /* Convert from one based to zero based. */
831 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
835 /* TODO: don't re-evaluate the descriptor on each iteration. */
836 /* Get a descriptor for the first parameter. */
837 ss = gfc_walk_expr (arg->expr);
838 gcc_assert (ss != gfc_ss_terminator);
839 gfc_init_se (&argse, NULL);
840 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
841 gfc_add_block_to_block (&se->pre, &argse.pre);
842 gfc_add_block_to_block (&se->post, &argse.post);
846 if (INTEGER_CST_P (bound))
850 hi = TREE_INT_CST_HIGH (bound);
851 low = TREE_INT_CST_LOW (bound);
852 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
853 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
854 "dimension index", upper ? "UBOUND" : "LBOUND",
859 if (flag_bounds_check)
861 bound = gfc_evaluate_now (bound, &se->pre);
862 cond = fold_build2 (LT_EXPR, boolean_type_node,
863 bound, build_int_cst (TREE_TYPE (bound), 0));
864 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
865 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
866 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
867 gfc_trans_runtime_check (cond, &se->pre, &expr->where, gfc_msg_fault);
871 ubound = gfc_conv_descriptor_ubound (desc, bound);
872 lbound = gfc_conv_descriptor_lbound (desc, bound);
874 /* Follow any component references. */
875 if (arg->expr->expr_type == EXPR_VARIABLE
876 || arg->expr->expr_type == EXPR_CONSTANT)
878 as = arg->expr->symtree->n.sym->as;
879 for (ref = arg->expr->ref; ref; ref = ref->next)
884 as = ref->u.c.component->as;
892 switch (ref->u.ar.type)
910 /* 13.14.53: Result value for LBOUND
912 Case (i): For an array section or for an array expression other than a
913 whole array or array structure component, LBOUND(ARRAY, DIM)
914 has the value 1. For a whole array or array structure
915 component, LBOUND(ARRAY, DIM) has the value:
916 (a) equal to the lower bound for subscript DIM of ARRAY if
917 dimension DIM of ARRAY does not have extent zero
918 or if ARRAY is an assumed-size array of rank DIM,
921 13.14.113: Result value for UBOUND
923 Case (i): For an array section or for an array expression other than a
924 whole array or array structure component, UBOUND(ARRAY, DIM)
925 has the value equal to the number of elements in the given
926 dimension; otherwise, it has a value equal to the upper bound
927 for subscript DIM of ARRAY if dimension DIM of ARRAY does
928 not have size zero and has value zero if dimension DIM has
933 tree stride = gfc_conv_descriptor_stride (desc, bound);
935 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
936 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
938 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
939 gfc_index_zero_node);
940 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
942 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
943 gfc_index_zero_node);
944 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
948 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
950 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
951 ubound, gfc_index_zero_node);
955 if (as->type == AS_ASSUMED_SIZE)
956 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
957 build_int_cst (TREE_TYPE (bound),
958 arg->expr->rank - 1));
960 cond = boolean_false_node;
962 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
963 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
965 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
966 lbound, gfc_index_one_node);
973 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
974 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
976 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
977 gfc_index_zero_node);
980 se->expr = gfc_index_one_node;
983 type = gfc_typenode_for_spec (&expr->ts);
984 se->expr = convert (type, se->expr);
989 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
994 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
996 switch (expr->value.function.actual->expr->ts.type)
1000 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
1004 switch (expr->ts.kind)
1019 se->expr = build_call_expr (built_in_decls[n], 1, arg);
1028 /* Create a complex value from one or two real components. */
1031 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1037 unsigned int num_args;
1039 num_args = gfc_intrinsic_argument_list_length (expr);
1040 args = alloca (sizeof (tree) * num_args);
1042 type = gfc_typenode_for_spec (&expr->ts);
1043 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1044 real = convert (TREE_TYPE (type), args[0]);
1046 imag = convert (TREE_TYPE (type), args[1]);
1047 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1049 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1051 imag = convert (TREE_TYPE (type), imag);
1054 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1056 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1059 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1060 MODULO(A, P) = A - FLOOR (A / P) * P */
1061 /* TODO: MOD(x, 0) */
1064 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1075 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1077 switch (expr->ts.type)
1080 /* Integer case is easy, we've got a builtin op. */
1081 type = TREE_TYPE (args[0]);
1084 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1086 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1091 /* Check if we have a builtin fmod. */
1092 switch (expr->ts.kind)
1111 /* Use it if it exists. */
1112 if (n != END_BUILTINS)
1114 tmp = build_addr (built_in_decls[n], current_function_decl);
1115 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1121 type = TREE_TYPE (args[0]);
1123 args[0] = gfc_evaluate_now (args[0], &se->pre);
1124 args[1] = gfc_evaluate_now (args[1], &se->pre);
1127 modulo = arg - floor (arg/arg2) * arg2, so
1128 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1130 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1131 thereby avoiding another division and retaining the accuracy
1132 of the builtin function. */
1133 if (n != END_BUILTINS && modulo)
1135 tree zero = gfc_build_const (type, integer_zero_node);
1136 tmp = gfc_evaluate_now (se->expr, &se->pre);
1137 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1138 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1139 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1140 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1141 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1142 test = gfc_evaluate_now (test, &se->pre);
1143 se->expr = fold_build3 (COND_EXPR, type, test,
1144 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1149 /* If we do not have a built_in fmod, the calculation is going to
1150 have to be done longhand. */
1151 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1153 /* Test if the value is too large to handle sensibly. */
1154 gfc_set_model_kind (expr->ts.kind);
1156 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1157 ikind = expr->ts.kind;
1160 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1161 ikind = gfc_max_integer_kind;
1163 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1164 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1165 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1167 mpfr_neg (huge, huge, GFC_RND_MODE);
1168 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1169 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1170 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1172 itype = gfc_get_int_type (ikind);
1174 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1176 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1177 tmp = convert (type, tmp);
1178 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1179 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1180 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1189 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1192 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1200 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1201 type = TREE_TYPE (args[0]);
1203 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1204 val = gfc_evaluate_now (val, &se->pre);
1206 zero = gfc_build_const (type, integer_zero_node);
1207 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1208 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1212 /* SIGN(A, B) is absolute value of A times sign of B.
1213 The real value versions use library functions to ensure the correct
1214 handling of negative zero. Integer case implemented as:
1215 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1219 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1225 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1226 if (expr->ts.type == BT_REAL)
1228 switch (expr->ts.kind)
1231 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1234 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1238 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1243 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1247 /* Having excluded floating point types, we know we are now dealing
1248 with signed integer types. */
1249 type = TREE_TYPE (args[0]);
1251 /* Args[0] is used multiple times below. */
1252 args[0] = gfc_evaluate_now (args[0], &se->pre);
1254 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1255 the signs of A and B are the same, and of all ones if they differ. */
1256 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1257 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1258 build_int_cst (type, TYPE_PRECISION (type) - 1));
1259 tmp = gfc_evaluate_now (tmp, &se->pre);
1261 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1262 is all ones (i.e. -1). */
1263 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1264 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1269 /* Test for the presence of an optional argument. */
1272 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1276 arg = expr->value.function.actual->expr;
1277 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1278 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1279 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1283 /* Calculate the double precision product of two single precision values. */
1286 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1291 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1293 /* Convert the args to double precision before multiplying. */
1294 type = gfc_typenode_for_spec (&expr->ts);
1295 args[0] = convert (type, args[0]);
1296 args[1] = convert (type, args[1]);
1297 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1301 /* Return a length one character string containing an ascii character. */
1304 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1309 unsigned int num_args;
1311 num_args = gfc_intrinsic_argument_list_length (expr);
1312 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1314 type = gfc_get_char_type (expr->ts.kind);
1315 var = gfc_create_var (type, "char");
1317 arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1318 gfc_add_modify_expr (&se->pre, var, arg[0]);
1319 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1320 se->string_length = integer_one_node;
1325 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1333 unsigned int num_args;
1335 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1336 args = alloca (sizeof (tree) * num_args);
1338 var = gfc_create_var (pchar_type_node, "pstr");
1339 len = gfc_create_var (gfc_get_int_type (8), "len");
1341 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1342 args[0] = build_fold_addr_expr (var);
1343 args[1] = build_fold_addr_expr (len);
1345 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1346 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1347 fndecl, num_args, args);
1348 gfc_add_expr_to_block (&se->pre, tmp);
1350 /* Free the temporary afterwards, if necessary. */
1351 cond = fold_build2 (GT_EXPR, boolean_type_node,
1352 len, build_int_cst (TREE_TYPE (len), 0));
1353 tmp = gfc_call_free (var);
1354 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1355 gfc_add_expr_to_block (&se->post, tmp);
1358 se->string_length = len;
1363 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1371 unsigned int num_args;
1373 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1374 args = alloca (sizeof (tree) * num_args);
1376 var = gfc_create_var (pchar_type_node, "pstr");
1377 len = gfc_create_var (gfc_get_int_type (4), "len");
1379 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1380 args[0] = build_fold_addr_expr (var);
1381 args[1] = build_fold_addr_expr (len);
1383 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1384 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1385 fndecl, num_args, args);
1386 gfc_add_expr_to_block (&se->pre, tmp);
1388 /* Free the temporary afterwards, if necessary. */
1389 cond = fold_build2 (GT_EXPR, boolean_type_node,
1390 len, build_int_cst (TREE_TYPE (len), 0));
1391 tmp = gfc_call_free (var);
1392 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1393 gfc_add_expr_to_block (&se->post, tmp);
1396 se->string_length = len;
1400 /* Return a character string containing the tty name. */
1403 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1411 unsigned int num_args;
1413 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1414 args = alloca (sizeof (tree) * num_args);
1416 var = gfc_create_var (pchar_type_node, "pstr");
1417 len = gfc_create_var (gfc_get_int_type (4), "len");
1419 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1420 args[0] = build_fold_addr_expr (var);
1421 args[1] = build_fold_addr_expr (len);
1423 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1424 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1425 fndecl, num_args, args);
1426 gfc_add_expr_to_block (&se->pre, tmp);
1428 /* Free the temporary afterwards, if necessary. */
1429 cond = fold_build2 (GT_EXPR, boolean_type_node,
1430 len, build_int_cst (TREE_TYPE (len), 0));
1431 tmp = gfc_call_free (var);
1432 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1433 gfc_add_expr_to_block (&se->post, tmp);
1436 se->string_length = len;
1440 /* Get the minimum/maximum value of all the parameters.
1441 minmax (a1, a2, a3, ...)
1444 if (a2 .op. mvar || isnan(mvar))
1446 if (a3 .op. mvar || isnan(mvar))
1453 /* TODO: Mismatching types can occur when specific names are used.
1454 These should be handled during resolution. */
1456 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1464 gfc_actual_arglist *argexpr;
1465 unsigned int i, nargs;
1467 nargs = gfc_intrinsic_argument_list_length (expr);
1468 args = alloca (sizeof (tree) * nargs);
1470 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1471 type = gfc_typenode_for_spec (&expr->ts);
1473 argexpr = expr->value.function.actual;
1474 if (TREE_TYPE (args[0]) != type)
1475 args[0] = convert (type, args[0]);
1476 /* Only evaluate the argument once. */
1477 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1478 args[0] = gfc_evaluate_now (args[0], &se->pre);
1480 mvar = gfc_create_var (type, "M");
1481 gfc_add_modify_expr (&se->pre, mvar, args[0]);
1482 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1488 /* Handle absent optional arguments by ignoring the comparison. */
1489 if (argexpr->expr->expr_type == EXPR_VARIABLE
1490 && argexpr->expr->symtree->n.sym->attr.optional
1491 && TREE_CODE (val) == INDIRECT_REF)
1493 (NE_EXPR, boolean_type_node, TREE_OPERAND (val, 0),
1494 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1499 /* Only evaluate the argument once. */
1500 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1501 val = gfc_evaluate_now (val, &se->pre);
1504 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1506 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1508 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1509 __builtin_isnan might be made dependent on that module being loaded,
1510 to help performance of programs that don't rely on IEEE semantics. */
1511 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1513 isnan = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1514 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1515 fold_convert (boolean_type_node, isnan));
1517 tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
1519 if (cond != NULL_TREE)
1520 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1522 gfc_add_expr_to_block (&se->pre, tmp);
1523 argexpr = argexpr->next;
1529 /* Generate library calls for MIN and MAX intrinsics for character
1532 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1535 tree var, len, fndecl, tmp, cond, function;
1538 nargs = gfc_intrinsic_argument_list_length (expr);
1539 args = alloca (sizeof (tree) * (nargs + 4));
1540 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1542 /* Create the result variables. */
1543 len = gfc_create_var (gfc_charlen_type_node, "len");
1544 args[0] = build_fold_addr_expr (len);
1545 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1546 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1547 args[2] = build_int_cst (NULL_TREE, op);
1548 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1550 if (expr->ts.kind == 1)
1551 function = gfor_fndecl_string_minmax;
1552 else if (expr->ts.kind == 4)
1553 function = gfor_fndecl_string_minmax_char4;
1557 /* Make the function call. */
1558 fndecl = build_addr (function, current_function_decl);
1559 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
1561 gfc_add_expr_to_block (&se->pre, tmp);
1563 /* Free the temporary afterwards, if necessary. */
1564 cond = fold_build2 (GT_EXPR, boolean_type_node,
1565 len, build_int_cst (TREE_TYPE (len), 0));
1566 tmp = gfc_call_free (var);
1567 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1568 gfc_add_expr_to_block (&se->post, tmp);
1571 se->string_length = len;
1575 /* Create a symbol node for this intrinsic. The symbol from the frontend
1576 has the generic name. */
1579 gfc_get_symbol_for_expr (gfc_expr * expr)
1583 /* TODO: Add symbols for intrinsic function to the global namespace. */
1584 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1585 sym = gfc_new_symbol (expr->value.function.name, NULL);
1588 sym->attr.external = 1;
1589 sym->attr.function = 1;
1590 sym->attr.always_explicit = 1;
1591 sym->attr.proc = PROC_INTRINSIC;
1592 sym->attr.flavor = FL_PROCEDURE;
1596 sym->attr.dimension = 1;
1597 sym->as = gfc_get_array_spec ();
1598 sym->as->type = AS_ASSUMED_SHAPE;
1599 sym->as->rank = expr->rank;
1602 /* TODO: proper argument lists for external intrinsics. */
1606 /* Generate a call to an external intrinsic function. */
1608 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1613 gcc_assert (!se->ss || se->ss->expr == expr);
1616 gcc_assert (expr->rank > 0);
1618 gcc_assert (expr->rank == 0);
1620 sym = gfc_get_symbol_for_expr (expr);
1622 /* Calls to libgfortran_matmul need to be appended special arguments,
1623 to be able to call the BLAS ?gemm functions if required and possible. */
1624 append_args = NULL_TREE;
1625 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1626 && sym->ts.type != BT_LOGICAL)
1628 tree cint = gfc_get_int_type (gfc_c_int_kind);
1630 if (gfc_option.flag_external_blas
1631 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1632 && (sym->ts.kind == gfc_default_real_kind
1633 || sym->ts.kind == gfc_default_double_kind))
1637 if (sym->ts.type == BT_REAL)
1639 if (sym->ts.kind == gfc_default_real_kind)
1640 gemm_fndecl = gfor_fndecl_sgemm;
1642 gemm_fndecl = gfor_fndecl_dgemm;
1646 if (sym->ts.kind == gfc_default_real_kind)
1647 gemm_fndecl = gfor_fndecl_cgemm;
1649 gemm_fndecl = gfor_fndecl_zgemm;
1652 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1653 append_args = gfc_chainon_list
1654 (append_args, build_int_cst
1655 (cint, gfc_option.blas_matmul_limit));
1656 append_args = gfc_chainon_list (append_args,
1657 gfc_build_addr_expr (NULL_TREE,
1662 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1663 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1664 append_args = gfc_chainon_list (append_args, null_pointer_node);
1668 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1672 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1692 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1701 gfc_actual_arglist *actual;
1708 gfc_conv_intrinsic_funcall (se, expr);
1712 actual = expr->value.function.actual;
1713 type = gfc_typenode_for_spec (&expr->ts);
1714 /* Initialize the result. */
1715 resvar = gfc_create_var (type, "test");
1717 tmp = convert (type, boolean_true_node);
1719 tmp = convert (type, boolean_false_node);
1720 gfc_add_modify_expr (&se->pre, resvar, tmp);
1722 /* Walk the arguments. */
1723 arrayss = gfc_walk_expr (actual->expr);
1724 gcc_assert (arrayss != gfc_ss_terminator);
1726 /* Initialize the scalarizer. */
1727 gfc_init_loopinfo (&loop);
1728 exit_label = gfc_build_label_decl (NULL_TREE);
1729 TREE_USED (exit_label) = 1;
1730 gfc_add_ss_to_loop (&loop, arrayss);
1732 /* Initialize the loop. */
1733 gfc_conv_ss_startstride (&loop);
1734 gfc_conv_loop_setup (&loop);
1736 gfc_mark_ss_chain_used (arrayss, 1);
1737 /* Generate the loop body. */
1738 gfc_start_scalarized_body (&loop, &body);
1740 /* If the condition matches then set the return value. */
1741 gfc_start_block (&block);
1743 tmp = convert (type, boolean_false_node);
1745 tmp = convert (type, boolean_true_node);
1746 gfc_add_modify_expr (&block, resvar, tmp);
1748 /* And break out of the loop. */
1749 tmp = build1_v (GOTO_EXPR, exit_label);
1750 gfc_add_expr_to_block (&block, tmp);
1752 found = gfc_finish_block (&block);
1754 /* Check this element. */
1755 gfc_init_se (&arrayse, NULL);
1756 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1757 arrayse.ss = arrayss;
1758 gfc_conv_expr_val (&arrayse, actual->expr);
1760 gfc_add_block_to_block (&body, &arrayse.pre);
1761 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1762 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1763 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1764 gfc_add_expr_to_block (&body, tmp);
1765 gfc_add_block_to_block (&body, &arrayse.post);
1767 gfc_trans_scalarizing_loops (&loop, &body);
1769 /* Add the exit label. */
1770 tmp = build1_v (LABEL_EXPR, exit_label);
1771 gfc_add_expr_to_block (&loop.pre, tmp);
1773 gfc_add_block_to_block (&se->pre, &loop.pre);
1774 gfc_add_block_to_block (&se->pre, &loop.post);
1775 gfc_cleanup_loop (&loop);
1780 /* COUNT(A) = Number of true elements in A. */
1782 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1789 gfc_actual_arglist *actual;
1795 gfc_conv_intrinsic_funcall (se, expr);
1799 actual = expr->value.function.actual;
1801 type = gfc_typenode_for_spec (&expr->ts);
1802 /* Initialize the result. */
1803 resvar = gfc_create_var (type, "count");
1804 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1806 /* Walk the arguments. */
1807 arrayss = gfc_walk_expr (actual->expr);
1808 gcc_assert (arrayss != gfc_ss_terminator);
1810 /* Initialize the scalarizer. */
1811 gfc_init_loopinfo (&loop);
1812 gfc_add_ss_to_loop (&loop, arrayss);
1814 /* Initialize the loop. */
1815 gfc_conv_ss_startstride (&loop);
1816 gfc_conv_loop_setup (&loop);
1818 gfc_mark_ss_chain_used (arrayss, 1);
1819 /* Generate the loop body. */
1820 gfc_start_scalarized_body (&loop, &body);
1822 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1823 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1824 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1826 gfc_init_se (&arrayse, NULL);
1827 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1828 arrayse.ss = arrayss;
1829 gfc_conv_expr_val (&arrayse, actual->expr);
1830 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1832 gfc_add_block_to_block (&body, &arrayse.pre);
1833 gfc_add_expr_to_block (&body, tmp);
1834 gfc_add_block_to_block (&body, &arrayse.post);
1836 gfc_trans_scalarizing_loops (&loop, &body);
1838 gfc_add_block_to_block (&se->pre, &loop.pre);
1839 gfc_add_block_to_block (&se->pre, &loop.post);
1840 gfc_cleanup_loop (&loop);
1845 /* Inline implementation of the sum and product intrinsics. */
1847 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1855 gfc_actual_arglist *actual;
1860 gfc_expr *arrayexpr;
1865 gfc_conv_intrinsic_funcall (se, expr);
1869 type = gfc_typenode_for_spec (&expr->ts);
1870 /* Initialize the result. */
1871 resvar = gfc_create_var (type, "val");
1872 if (op == PLUS_EXPR)
1873 tmp = gfc_build_const (type, integer_zero_node);
1875 tmp = gfc_build_const (type, integer_one_node);
1877 gfc_add_modify_expr (&se->pre, resvar, tmp);
1879 /* Walk the arguments. */
1880 actual = expr->value.function.actual;
1881 arrayexpr = actual->expr;
1882 arrayss = gfc_walk_expr (arrayexpr);
1883 gcc_assert (arrayss != gfc_ss_terminator);
1885 actual = actual->next->next;
1886 gcc_assert (actual);
1887 maskexpr = actual->expr;
1888 if (maskexpr && maskexpr->rank != 0)
1890 maskss = gfc_walk_expr (maskexpr);
1891 gcc_assert (maskss != gfc_ss_terminator);
1896 /* Initialize the scalarizer. */
1897 gfc_init_loopinfo (&loop);
1898 gfc_add_ss_to_loop (&loop, arrayss);
1900 gfc_add_ss_to_loop (&loop, maskss);
1902 /* Initialize the loop. */
1903 gfc_conv_ss_startstride (&loop);
1904 gfc_conv_loop_setup (&loop);
1906 gfc_mark_ss_chain_used (arrayss, 1);
1908 gfc_mark_ss_chain_used (maskss, 1);
1909 /* Generate the loop body. */
1910 gfc_start_scalarized_body (&loop, &body);
1912 /* If we have a mask, only add this element if the mask is set. */
1915 gfc_init_se (&maskse, NULL);
1916 gfc_copy_loopinfo_to_se (&maskse, &loop);
1918 gfc_conv_expr_val (&maskse, maskexpr);
1919 gfc_add_block_to_block (&body, &maskse.pre);
1921 gfc_start_block (&block);
1924 gfc_init_block (&block);
1926 /* Do the actual summation/product. */
1927 gfc_init_se (&arrayse, NULL);
1928 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1929 arrayse.ss = arrayss;
1930 gfc_conv_expr_val (&arrayse, arrayexpr);
1931 gfc_add_block_to_block (&block, &arrayse.pre);
1933 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1934 gfc_add_modify_expr (&block, resvar, tmp);
1935 gfc_add_block_to_block (&block, &arrayse.post);
1939 /* We enclose the above in if (mask) {...} . */
1940 tmp = gfc_finish_block (&block);
1942 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1945 tmp = gfc_finish_block (&block);
1946 gfc_add_expr_to_block (&body, tmp);
1948 gfc_trans_scalarizing_loops (&loop, &body);
1950 /* For a scalar mask, enclose the loop in an if statement. */
1951 if (maskexpr && maskss == NULL)
1953 gfc_init_se (&maskse, NULL);
1954 gfc_conv_expr_val (&maskse, maskexpr);
1955 gfc_init_block (&block);
1956 gfc_add_block_to_block (&block, &loop.pre);
1957 gfc_add_block_to_block (&block, &loop.post);
1958 tmp = gfc_finish_block (&block);
1960 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1961 gfc_add_expr_to_block (&block, tmp);
1962 gfc_add_block_to_block (&se->pre, &block);
1966 gfc_add_block_to_block (&se->pre, &loop.pre);
1967 gfc_add_block_to_block (&se->pre, &loop.post);
1970 gfc_cleanup_loop (&loop);
1976 /* Inline implementation of the dot_product intrinsic. This function
1977 is based on gfc_conv_intrinsic_arith (the previous function). */
1979 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1987 gfc_actual_arglist *actual;
1988 gfc_ss *arrayss1, *arrayss2;
1989 gfc_se arrayse1, arrayse2;
1990 gfc_expr *arrayexpr1, *arrayexpr2;
1992 type = gfc_typenode_for_spec (&expr->ts);
1994 /* Initialize the result. */
1995 resvar = gfc_create_var (type, "val");
1996 if (expr->ts.type == BT_LOGICAL)
1997 tmp = build_int_cst (type, 0);
1999 tmp = gfc_build_const (type, integer_zero_node);
2001 gfc_add_modify_expr (&se->pre, resvar, tmp);
2003 /* Walk argument #1. */
2004 actual = expr->value.function.actual;
2005 arrayexpr1 = actual->expr;
2006 arrayss1 = gfc_walk_expr (arrayexpr1);
2007 gcc_assert (arrayss1 != gfc_ss_terminator);
2009 /* Walk argument #2. */
2010 actual = actual->next;
2011 arrayexpr2 = actual->expr;
2012 arrayss2 = gfc_walk_expr (arrayexpr2);
2013 gcc_assert (arrayss2 != gfc_ss_terminator);
2015 /* Initialize the scalarizer. */
2016 gfc_init_loopinfo (&loop);
2017 gfc_add_ss_to_loop (&loop, arrayss1);
2018 gfc_add_ss_to_loop (&loop, arrayss2);
2020 /* Initialize the loop. */
2021 gfc_conv_ss_startstride (&loop);
2022 gfc_conv_loop_setup (&loop);
2024 gfc_mark_ss_chain_used (arrayss1, 1);
2025 gfc_mark_ss_chain_used (arrayss2, 1);
2027 /* Generate the loop body. */
2028 gfc_start_scalarized_body (&loop, &body);
2029 gfc_init_block (&block);
2031 /* Make the tree expression for [conjg(]array1[)]. */
2032 gfc_init_se (&arrayse1, NULL);
2033 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2034 arrayse1.ss = arrayss1;
2035 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2036 if (expr->ts.type == BT_COMPLEX)
2037 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2038 gfc_add_block_to_block (&block, &arrayse1.pre);
2040 /* Make the tree expression for array2. */
2041 gfc_init_se (&arrayse2, NULL);
2042 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2043 arrayse2.ss = arrayss2;
2044 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2045 gfc_add_block_to_block (&block, &arrayse2.pre);
2047 /* Do the actual product and sum. */
2048 if (expr->ts.type == BT_LOGICAL)
2050 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2051 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2055 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2056 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2058 gfc_add_modify_expr (&block, resvar, tmp);
2060 /* Finish up the loop block and the loop. */
2061 tmp = gfc_finish_block (&block);
2062 gfc_add_expr_to_block (&body, tmp);
2064 gfc_trans_scalarizing_loops (&loop, &body);
2065 gfc_add_block_to_block (&se->pre, &loop.pre);
2066 gfc_add_block_to_block (&se->pre, &loop.post);
2067 gfc_cleanup_loop (&loop);
2074 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
2078 stmtblock_t ifblock;
2079 stmtblock_t elseblock;
2087 gfc_actual_arglist *actual;
2092 gfc_expr *arrayexpr;
2099 gfc_conv_intrinsic_funcall (se, expr);
2103 /* Initialize the result. */
2104 pos = gfc_create_var (gfc_array_index_type, "pos");
2105 offset = gfc_create_var (gfc_array_index_type, "offset");
2106 type = gfc_typenode_for_spec (&expr->ts);
2108 /* Walk the arguments. */
2109 actual = expr->value.function.actual;
2110 arrayexpr = actual->expr;
2111 arrayss = gfc_walk_expr (arrayexpr);
2112 gcc_assert (arrayss != gfc_ss_terminator);
2114 actual = actual->next->next;
2115 gcc_assert (actual);
2116 maskexpr = actual->expr;
2117 if (maskexpr && maskexpr->rank != 0)
2119 maskss = gfc_walk_expr (maskexpr);
2120 gcc_assert (maskss != gfc_ss_terminator);
2125 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2126 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2127 switch (arrayexpr->ts.type)
2130 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
2134 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2135 arrayexpr->ts.kind);
2142 /* We start with the most negative possible value for MAXLOC, and the most
2143 positive possible value for MINLOC. The most negative possible value is
2144 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2145 possible value is HUGE in both cases. */
2147 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2148 gfc_add_modify_expr (&se->pre, limit, tmp);
2150 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2151 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2152 build_int_cst (type, 1));
2154 /* Initialize the scalarizer. */
2155 gfc_init_loopinfo (&loop);
2156 gfc_add_ss_to_loop (&loop, arrayss);
2158 gfc_add_ss_to_loop (&loop, maskss);
2160 /* Initialize the loop. */
2161 gfc_conv_ss_startstride (&loop);
2162 gfc_conv_loop_setup (&loop);
2164 gcc_assert (loop.dimen == 1);
2166 /* Initialize the position to zero, following Fortran 2003. We are free
2167 to do this because Fortran 95 allows the result of an entirely false
2168 mask to be processor dependent. */
2169 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2171 gfc_mark_ss_chain_used (arrayss, 1);
2173 gfc_mark_ss_chain_used (maskss, 1);
2174 /* Generate the loop body. */
2175 gfc_start_scalarized_body (&loop, &body);
2177 /* If we have a mask, only check this element if the mask is set. */
2180 gfc_init_se (&maskse, NULL);
2181 gfc_copy_loopinfo_to_se (&maskse, &loop);
2183 gfc_conv_expr_val (&maskse, maskexpr);
2184 gfc_add_block_to_block (&body, &maskse.pre);
2186 gfc_start_block (&block);
2189 gfc_init_block (&block);
2191 /* Compare with the current limit. */
2192 gfc_init_se (&arrayse, NULL);
2193 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2194 arrayse.ss = arrayss;
2195 gfc_conv_expr_val (&arrayse, arrayexpr);
2196 gfc_add_block_to_block (&block, &arrayse.pre);
2198 /* We do the following if this is a more extreme value. */
2199 gfc_start_block (&ifblock);
2201 /* Assign the value to the limit... */
2202 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2204 /* Remember where we are. An offset must be added to the loop
2205 counter to obtain the required position. */
2207 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2208 gfc_index_one_node, loop.from[0]);
2210 tmp = build_int_cst (gfc_array_index_type, 1);
2212 gfc_add_modify_expr (&block, offset, tmp);
2214 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2215 loop.loopvar[0], offset);
2216 gfc_add_modify_expr (&ifblock, pos, tmp);
2218 ifbody = gfc_finish_block (&ifblock);
2220 /* If it is a more extreme value or pos is still zero and the value
2221 equal to the limit. */
2222 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2223 fold_build2 (EQ_EXPR, boolean_type_node,
2224 pos, gfc_index_zero_node),
2225 fold_build2 (EQ_EXPR, boolean_type_node,
2226 arrayse.expr, limit));
2227 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2228 fold_build2 (op, boolean_type_node,
2229 arrayse.expr, limit), tmp);
2230 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2231 gfc_add_expr_to_block (&block, tmp);
2235 /* We enclose the above in if (mask) {...}. */
2236 tmp = gfc_finish_block (&block);
2238 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2241 tmp = gfc_finish_block (&block);
2242 gfc_add_expr_to_block (&body, tmp);
2244 gfc_trans_scalarizing_loops (&loop, &body);
2246 /* For a scalar mask, enclose the loop in an if statement. */
2247 if (maskexpr && maskss == NULL)
2249 gfc_init_se (&maskse, NULL);
2250 gfc_conv_expr_val (&maskse, maskexpr);
2251 gfc_init_block (&block);
2252 gfc_add_block_to_block (&block, &loop.pre);
2253 gfc_add_block_to_block (&block, &loop.post);
2254 tmp = gfc_finish_block (&block);
2256 /* For the else part of the scalar mask, just initialize
2257 the pos variable the same way as above. */
2259 gfc_init_block (&elseblock);
2260 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2261 elsetmp = gfc_finish_block (&elseblock);
2263 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2264 gfc_add_expr_to_block (&block, tmp);
2265 gfc_add_block_to_block (&se->pre, &block);
2269 gfc_add_block_to_block (&se->pre, &loop.pre);
2270 gfc_add_block_to_block (&se->pre, &loop.post);
2272 gfc_cleanup_loop (&loop);
2274 se->expr = convert (type, pos);
2278 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2287 gfc_actual_arglist *actual;
2292 gfc_expr *arrayexpr;
2298 gfc_conv_intrinsic_funcall (se, expr);
2302 type = gfc_typenode_for_spec (&expr->ts);
2303 /* Initialize the result. */
2304 limit = gfc_create_var (type, "limit");
2305 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2306 switch (expr->ts.type)
2309 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2313 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2320 /* We start with the most negative possible value for MAXVAL, and the most
2321 positive possible value for MINVAL. The most negative possible value is
2322 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2323 possible value is HUGE in both cases. */
2325 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2327 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2328 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2329 tmp, build_int_cst (type, 1));
2331 gfc_add_modify_expr (&se->pre, limit, tmp);
2333 /* Walk the arguments. */
2334 actual = expr->value.function.actual;
2335 arrayexpr = actual->expr;
2336 arrayss = gfc_walk_expr (arrayexpr);
2337 gcc_assert (arrayss != gfc_ss_terminator);
2339 actual = actual->next->next;
2340 gcc_assert (actual);
2341 maskexpr = actual->expr;
2342 if (maskexpr && maskexpr->rank != 0)
2344 maskss = gfc_walk_expr (maskexpr);
2345 gcc_assert (maskss != gfc_ss_terminator);
2350 /* Initialize the scalarizer. */
2351 gfc_init_loopinfo (&loop);
2352 gfc_add_ss_to_loop (&loop, arrayss);
2354 gfc_add_ss_to_loop (&loop, maskss);
2356 /* Initialize the loop. */
2357 gfc_conv_ss_startstride (&loop);
2358 gfc_conv_loop_setup (&loop);
2360 gfc_mark_ss_chain_used (arrayss, 1);
2362 gfc_mark_ss_chain_used (maskss, 1);
2363 /* Generate the loop body. */
2364 gfc_start_scalarized_body (&loop, &body);
2366 /* If we have a mask, only add this element if the mask is set. */
2369 gfc_init_se (&maskse, NULL);
2370 gfc_copy_loopinfo_to_se (&maskse, &loop);
2372 gfc_conv_expr_val (&maskse, maskexpr);
2373 gfc_add_block_to_block (&body, &maskse.pre);
2375 gfc_start_block (&block);
2378 gfc_init_block (&block);
2380 /* Compare with the current limit. */
2381 gfc_init_se (&arrayse, NULL);
2382 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2383 arrayse.ss = arrayss;
2384 gfc_conv_expr_val (&arrayse, arrayexpr);
2385 gfc_add_block_to_block (&block, &arrayse.pre);
2387 /* Assign the value to the limit... */
2388 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2390 /* If it is a more extreme value. */
2391 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2392 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2393 gfc_add_expr_to_block (&block, tmp);
2394 gfc_add_block_to_block (&block, &arrayse.post);
2396 tmp = gfc_finish_block (&block);
2398 /* We enclose the above in if (mask) {...}. */
2399 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2400 gfc_add_expr_to_block (&body, tmp);
2402 gfc_trans_scalarizing_loops (&loop, &body);
2404 /* For a scalar mask, enclose the loop in an if statement. */
2405 if (maskexpr && maskss == NULL)
2407 gfc_init_se (&maskse, NULL);
2408 gfc_conv_expr_val (&maskse, maskexpr);
2409 gfc_init_block (&block);
2410 gfc_add_block_to_block (&block, &loop.pre);
2411 gfc_add_block_to_block (&block, &loop.post);
2412 tmp = gfc_finish_block (&block);
2414 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2415 gfc_add_expr_to_block (&block, tmp);
2416 gfc_add_block_to_block (&se->pre, &block);
2420 gfc_add_block_to_block (&se->pre, &loop.pre);
2421 gfc_add_block_to_block (&se->pre, &loop.post);
2424 gfc_cleanup_loop (&loop);
2429 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2431 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2437 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2438 type = TREE_TYPE (args[0]);
2440 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2441 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2442 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2443 build_int_cst (type, 0));
2444 type = gfc_typenode_for_spec (&expr->ts);
2445 se->expr = convert (type, tmp);
2448 /* Generate code to perform the specified operation. */
2450 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2454 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2455 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2460 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2464 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2465 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2468 /* Set or clear a single bit. */
2470 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2477 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2478 type = TREE_TYPE (args[0]);
2480 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2486 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2488 se->expr = fold_build2 (op, type, args[0], tmp);
2491 /* Extract a sequence of bits.
2492 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2494 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2501 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2502 type = TREE_TYPE (args[0]);
2504 mask = build_int_cst (type, -1);
2505 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2506 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2508 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2510 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2513 /* RSHIFT (I, SHIFT) = I >> SHIFT
2514 LSHIFT (I, SHIFT) = I << SHIFT */
2516 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2520 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2522 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2523 TREE_TYPE (args[0]), args[0], args[1]);
2526 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2528 : ((shift >= 0) ? i << shift : i >> -shift)
2529 where all shifts are logical shifts. */
2531 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2543 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2544 type = TREE_TYPE (args[0]);
2545 utype = unsigned_type_for (type);
2547 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2549 /* Left shift if positive. */
2550 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2552 /* Right shift if negative.
2553 We convert to an unsigned type because we want a logical shift.
2554 The standard doesn't define the case of shifting negative
2555 numbers, and we try to be compatible with other compilers, most
2556 notably g77, here. */
2557 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2558 convert (utype, args[0]), width));
2560 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2561 build_int_cst (TREE_TYPE (args[1]), 0));
2562 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2564 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2565 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2567 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2568 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2570 se->expr = fold_build3 (COND_EXPR, type, cond,
2571 build_int_cst (type, 0), tmp);
2575 /* Circular shift. AKA rotate or barrel shift. */
2578 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2586 unsigned int num_args;
2588 num_args = gfc_intrinsic_argument_list_length (expr);
2589 args = alloca (sizeof (tree) * num_args);
2591 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2595 /* Use a library function for the 3 parameter version. */
2596 tree int4type = gfc_get_int_type (4);
2598 type = TREE_TYPE (args[0]);
2599 /* We convert the first argument to at least 4 bytes, and
2600 convert back afterwards. This removes the need for library
2601 functions for all argument sizes, and function will be
2602 aligned to at least 32 bits, so there's no loss. */
2603 if (expr->ts.kind < 4)
2604 args[0] = convert (int4type, args[0]);
2606 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2607 need loads of library functions. They cannot have values >
2608 BIT_SIZE (I) so the conversion is safe. */
2609 args[1] = convert (int4type, args[1]);
2610 args[2] = convert (int4type, args[2]);
2612 switch (expr->ts.kind)
2617 tmp = gfor_fndecl_math_ishftc4;
2620 tmp = gfor_fndecl_math_ishftc8;
2623 tmp = gfor_fndecl_math_ishftc16;
2628 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2629 /* Convert the result back to the original type, if we extended
2630 the first argument's width above. */
2631 if (expr->ts.kind < 4)
2632 se->expr = convert (type, se->expr);
2636 type = TREE_TYPE (args[0]);
2638 /* Rotate left if positive. */
2639 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2641 /* Rotate right if negative. */
2642 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2643 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2645 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2646 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2647 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2649 /* Do nothing if shift == 0. */
2650 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2651 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2654 /* The length of a character string. */
2656 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2666 gcc_assert (!se->ss);
2668 arg = expr->value.function.actual->expr;
2670 type = gfc_typenode_for_spec (&expr->ts);
2671 switch (arg->expr_type)
2674 len = build_int_cst (NULL_TREE, arg->value.character.length);
2678 /* Obtain the string length from the function used by
2679 trans-array.c(gfc_trans_array_constructor). */
2681 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2685 if (arg->ref == NULL
2686 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2688 /* This doesn't catch all cases.
2689 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2690 and the surrounding thread. */
2691 sym = arg->symtree->n.sym;
2692 decl = gfc_get_symbol_decl (sym);
2693 if (decl == current_function_decl && sym->attr.function
2694 && (sym->result == sym))
2695 decl = gfc_get_fake_result_decl (sym, 0);
2697 len = sym->ts.cl->backend_decl;
2702 /* Otherwise fall through. */
2705 /* Anybody stupid enough to do this deserves inefficient code. */
2706 ss = gfc_walk_expr (arg);
2707 gfc_init_se (&argse, se);
2708 if (ss == gfc_ss_terminator)
2709 gfc_conv_expr (&argse, arg);
2711 gfc_conv_expr_descriptor (&argse, arg, ss);
2712 gfc_add_block_to_block (&se->pre, &argse.pre);
2713 gfc_add_block_to_block (&se->post, &argse.post);
2714 len = argse.string_length;
2717 se->expr = convert (type, len);
2720 /* The length of a character string not including trailing blanks. */
2722 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2724 int kind = expr->value.function.actual->expr->ts.kind;
2725 tree args[2], type, fndecl;
2727 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2728 type = gfc_typenode_for_spec (&expr->ts);
2731 fndecl = gfor_fndecl_string_len_trim;
2733 fndecl = gfor_fndecl_string_len_trim_char4;
2737 se->expr = build_call_expr (fndecl, 2, args[0], args[1]);
2738 se->expr = convert (type, se->expr);
2742 /* Returns the starting position of a substring within a string. */
2745 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2748 tree logical4_type_node = gfc_get_logical_type (4);
2752 unsigned int num_args;
2754 num_args = gfc_intrinsic_argument_list_length (expr);
2755 args = alloca (sizeof (tree) * 5);
2757 gfc_conv_intrinsic_function_args (se, expr, args,
2758 num_args >= 5 ? 5 : num_args);
2759 type = gfc_typenode_for_spec (&expr->ts);
2762 args[4] = build_int_cst (logical4_type_node, 0);
2764 args[4] = convert (logical4_type_node, args[4]);
2766 fndecl = build_addr (function, current_function_decl);
2767 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
2769 se->expr = convert (type, se->expr);
2773 /* The ascii value for a single character. */
2775 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2777 tree args[2], type, pchartype;
2779 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2780 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
2781 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
2782 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
2783 type = gfc_typenode_for_spec (&expr->ts);
2785 se->expr = build_fold_indirect_ref (args[1]);
2786 se->expr = convert (type, se->expr);
2790 /* Intrinsic ISNAN calls __builtin_isnan. */
2793 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
2797 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2798 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
2799 STRIP_TYPE_NOPS (se->expr);
2800 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2804 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
2805 their argument against a constant integer value. */
2808 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
2812 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2813 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
2814 arg, build_int_cst (TREE_TYPE (arg), value));
2819 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2822 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2830 unsigned int num_args;
2832 num_args = gfc_intrinsic_argument_list_length (expr);
2833 args = alloca (sizeof (tree) * num_args);
2835 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2836 if (expr->ts.type != BT_CHARACTER)
2844 /* We do the same as in the non-character case, but the argument
2845 list is different because of the string length arguments. We
2846 also have to set the string length for the result. */
2852 se->string_length = len;
2854 type = TREE_TYPE (tsource);
2855 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2859 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
2861 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
2863 tree arg, type, tmp;
2866 switch (expr->ts.kind)
2869 frexp = BUILT_IN_FREXPF;
2872 frexp = BUILT_IN_FREXP;
2876 frexp = BUILT_IN_FREXPL;
2882 type = gfc_typenode_for_spec (&expr->ts);
2883 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2884 tmp = gfc_create_var (integer_type_node, NULL);
2885 se->expr = build_call_expr (built_in_decls[frexp], 2,
2886 fold_convert (type, arg),
2887 build_fold_addr_expr (tmp));
2888 se->expr = fold_convert (type, se->expr);
2892 /* NEAREST (s, dir) is translated into
2893 tmp = copysign (INF, dir);
2894 return nextafter (s, tmp);
2897 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
2899 tree args[2], type, tmp;
2900 int nextafter, copysign, inf;
2902 switch (expr->ts.kind)
2905 nextafter = BUILT_IN_NEXTAFTERF;
2906 copysign = BUILT_IN_COPYSIGNF;
2907 inf = BUILT_IN_INFF;
2910 nextafter = BUILT_IN_NEXTAFTER;
2911 copysign = BUILT_IN_COPYSIGN;
2916 nextafter = BUILT_IN_NEXTAFTERL;
2917 copysign = BUILT_IN_COPYSIGNL;
2918 inf = BUILT_IN_INFL;
2924 type = gfc_typenode_for_spec (&expr->ts);
2925 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2926 tmp = build_call_expr (built_in_decls[copysign], 2,
2927 build_call_expr (built_in_decls[inf], 0),
2928 fold_convert (type, args[1]));
2929 se->expr = build_call_expr (built_in_decls[nextafter], 2,
2930 fold_convert (type, args[0]), tmp);
2931 se->expr = fold_convert (type, se->expr);
2935 /* SPACING (s) is translated into
2943 e = MAX_EXPR (e, emin);
2944 res = scalbn (1., e);
2948 where prec is the precision of s, gfc_real_kinds[k].digits,
2949 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
2950 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
2953 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2955 tree arg, type, prec, emin, tiny, res, e;
2957 int frexp, scalbn, k;
2960 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
2961 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
2962 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
2963 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind);
2965 switch (expr->ts.kind)
2968 frexp = BUILT_IN_FREXPF;
2969 scalbn = BUILT_IN_SCALBNF;
2972 frexp = BUILT_IN_FREXP;
2973 scalbn = BUILT_IN_SCALBN;
2977 frexp = BUILT_IN_FREXPL;
2978 scalbn = BUILT_IN_SCALBNL;
2984 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2985 arg = gfc_evaluate_now (arg, &se->pre);
2987 type = gfc_typenode_for_spec (&expr->ts);
2988 e = gfc_create_var (integer_type_node, NULL);
2989 res = gfc_create_var (type, NULL);
2992 /* Build the block for s /= 0. */
2993 gfc_start_block (&block);
2994 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
2995 build_fold_addr_expr (e));
2996 gfc_add_expr_to_block (&block, tmp);
2998 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
2999 gfc_add_modify_expr (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3002 tmp = build_call_expr (built_in_decls[scalbn], 2,
3003 build_real_from_int_cst (type, integer_one_node), e);
3004 gfc_add_modify_expr (&block, res, tmp);
3006 /* Finish by building the IF statement. */
3007 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3008 build_real_from_int_cst (type, integer_zero_node));
3009 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3010 gfc_finish_block (&block));
3012 gfc_add_expr_to_block (&se->pre, tmp);
3017 /* RRSPACING (s) is translated into
3024 x = scalbn (x, precision - e);
3028 where precision is gfc_real_kinds[k].digits. */
3031 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3033 tree arg, type, e, x, cond, stmt, tmp;
3034 int frexp, scalbn, fabs, prec, k;
3037 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3038 prec = gfc_real_kinds[k].digits;
3039 switch (expr->ts.kind)
3042 frexp = BUILT_IN_FREXPF;
3043 scalbn = BUILT_IN_SCALBNF;
3044 fabs = BUILT_IN_FABSF;
3047 frexp = BUILT_IN_FREXP;
3048 scalbn = BUILT_IN_SCALBN;
3049 fabs = BUILT_IN_FABS;
3053 frexp = BUILT_IN_FREXPL;
3054 scalbn = BUILT_IN_SCALBNL;
3055 fabs = BUILT_IN_FABSL;
3061 type = gfc_typenode_for_spec (&expr->ts);
3062 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3063 arg = gfc_evaluate_now (arg, &se->pre);
3065 e = gfc_create_var (integer_type_node, NULL);
3066 x = gfc_create_var (type, NULL);
3067 gfc_add_modify_expr (&se->pre, x,
3068 build_call_expr (built_in_decls[fabs], 1, arg));
3071 gfc_start_block (&block);
3072 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3073 build_fold_addr_expr (e));
3074 gfc_add_expr_to_block (&block, tmp);
3076 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3077 build_int_cst (NULL_TREE, prec), e);
3078 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3079 gfc_add_modify_expr (&block, x, tmp);
3080 stmt = gfc_finish_block (&block);
3082 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3083 build_real_from_int_cst (type, integer_zero_node));
3084 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3085 gfc_add_expr_to_block (&se->pre, tmp);
3087 se->expr = fold_convert (type, x);
3091 /* SCALE (s, i) is translated into scalbn (s, i). */
3093 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3098 switch (expr->ts.kind)
3101 scalbn = BUILT_IN_SCALBNF;
3104 scalbn = BUILT_IN_SCALBN;
3108 scalbn = BUILT_IN_SCALBNL;
3114 type = gfc_typenode_for_spec (&expr->ts);
3115 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3116 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3117 fold_convert (type, args[0]),
3118 fold_convert (integer_type_node, args[1]));
3119 se->expr = fold_convert (type, se->expr);
3123 /* SET_EXPONENT (s, i) is translated into
3124 scalbn (frexp (s, &dummy_int), i). */
3126 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3128 tree args[2], type, tmp;
3131 switch (expr->ts.kind)
3134 frexp = BUILT_IN_FREXPF;
3135 scalbn = BUILT_IN_SCALBNF;
3138 frexp = BUILT_IN_FREXP;
3139 scalbn = BUILT_IN_SCALBN;
3143 frexp = BUILT_IN_FREXPL;
3144 scalbn = BUILT_IN_SCALBNL;
3150 type = gfc_typenode_for_spec (&expr->ts);
3151 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3153 tmp = gfc_create_var (integer_type_node, NULL);
3154 tmp = build_call_expr (built_in_decls[frexp], 2,
3155 fold_convert (type, args[0]),
3156 build_fold_addr_expr (tmp));
3157 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3158 fold_convert (integer_type_node, args[1]));
3159 se->expr = fold_convert (type, se->expr);
3164 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3166 gfc_actual_arglist *actual;
3174 gfc_init_se (&argse, NULL);
3175 actual = expr->value.function.actual;
3177 ss = gfc_walk_expr (actual->expr);
3178 gcc_assert (ss != gfc_ss_terminator);
3179 argse.want_pointer = 1;
3180 argse.data_not_needed = 1;
3181 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3182 gfc_add_block_to_block (&se->pre, &argse.pre);
3183 gfc_add_block_to_block (&se->post, &argse.post);
3184 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3186 /* Build the call to size0. */
3187 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3189 actual = actual->next;
3193 gfc_init_se (&argse, NULL);
3194 gfc_conv_expr_type (&argse, actual->expr,
3195 gfc_array_index_type);
3196 gfc_add_block_to_block (&se->pre, &argse.pre);
3198 /* Build the call to size1. */
3199 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3202 /* Unusually, for an intrinsic, size does not exclude
3203 an optional arg2, so we must test for it. */
3204 if (actual->expr->expr_type == EXPR_VARIABLE
3205 && actual->expr->symtree->n.sym->attr.dummy
3206 && actual->expr->symtree->n.sym->attr.optional)
3209 gfc_init_se (&argse, NULL);
3210 argse.want_pointer = 1;
3211 argse.data_not_needed = 1;
3212 gfc_conv_expr (&argse, actual->expr);
3213 gfc_add_block_to_block (&se->pre, &argse.pre);
3214 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3215 argse.expr, null_pointer_node);
3216 tmp = gfc_evaluate_now (tmp, &se->pre);
3217 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3218 tmp, fncall1, fncall0);
3226 type = gfc_typenode_for_spec (&expr->ts);
3227 se->expr = convert (type, se->expr);
3231 /* Helper function to compute the size of a character variable,
3232 excluding the terminating null characters. The result has
3233 gfc_array_index_type type. */
3236 size_of_string_in_bytes (int kind, tree string_length)
3239 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3241 bytesize = build_int_cst (gfc_array_index_type,
3242 gfc_character_kinds[i].bit_size / 8);
3244 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3245 fold_convert (gfc_array_index_type, string_length));
3250 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3263 arg = expr->value.function.actual->expr;
3265 gfc_init_se (&argse, NULL);
3266 ss = gfc_walk_expr (arg);
3268 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3270 if (ss == gfc_ss_terminator)
3272 gfc_conv_expr_reference (&argse, arg);
3273 source = argse.expr;
3275 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3277 /* Obtain the source word length. */
3278 if (arg->ts.type == BT_CHARACTER)
3279 source_bytes = size_of_string_in_bytes (arg->ts.kind,
3280 argse.string_length);
3282 source_bytes = fold_convert (gfc_array_index_type,
3283 size_in_bytes (type));
3287 argse.want_pointer = 0;
3288 gfc_conv_expr_descriptor (&argse, arg, ss);
3289 source = gfc_conv_descriptor_data_get (argse.expr);
3290 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3292 /* Obtain the argument's word length. */
3293 if (arg->ts.type == BT_CHARACTER)
3294 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3296 tmp = fold_convert (gfc_array_index_type,
3297 size_in_bytes (type));
3298 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3300 /* Obtain the size of the array in bytes. */
3301 for (n = 0; n < arg->rank; n++)
3304 idx = gfc_rank_cst[n];
3305 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3306 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3307 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3309 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3310 tmp, gfc_index_one_node);
3311 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3313 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3317 gfc_add_block_to_block (&se->pre, &argse.pre);
3318 se->expr = source_bytes;
3322 /* Intrinsic string comparison functions. */
3325 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
3329 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3332 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
3333 expr->value.function.actual->expr->ts.kind);
3334 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3335 build_int_cst (TREE_TYPE (se->expr), 0));
3338 /* Generate a call to the adjustl/adjustr library function. */
3340 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3348 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3351 type = TREE_TYPE (args[2]);
3352 var = gfc_conv_string_tmp (se, type, len);
3355 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3356 gfc_add_expr_to_block (&se->pre, tmp);
3358 se->string_length = len;
3362 /* Array transfer statement.
3363 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3365 typeof<DEST> = typeof<MOLD>
3367 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3368 sizeof (DEST(0) * SIZE). */
3371 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
3386 gfc_actual_arglist *arg;
3393 gcc_assert (se->loop);
3394 info = &se->ss->data.info;
3396 /* Convert SOURCE. The output from this stage is:-
3397 source_bytes = length of the source in bytes
3398 source = pointer to the source data. */
3399 arg = expr->value.function.actual;
3400 gfc_init_se (&argse, NULL);
3401 ss = gfc_walk_expr (arg->expr);
3403 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3405 /* Obtain the pointer to source and the length of source in bytes. */
3406 if (ss == gfc_ss_terminator)
3408 gfc_conv_expr_reference (&argse, arg->expr);
3409 source = argse.expr;
3411 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3413 /* Obtain the source word length. */
3414 if (arg->expr->ts.type == BT_CHARACTER)
3415 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3416 argse.string_length);
3418 tmp = fold_convert (gfc_array_index_type,
3419 size_in_bytes (source_type));
3423 argse.want_pointer = 0;
3424 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3425 source = gfc_conv_descriptor_data_get (argse.expr);
3426 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3428 /* Repack the source if not a full variable array. */
3429 if (!(arg->expr->expr_type == EXPR_VARIABLE
3430 && arg->expr->ref->u.ar.type == AR_FULL))
3432 tmp = build_fold_addr_expr (argse.expr);
3433 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3434 source = gfc_evaluate_now (source, &argse.pre);
3436 /* Free the temporary. */
3437 gfc_start_block (&block);
3438 tmp = gfc_call_free (convert (pvoid_type_node, source));
3439 gfc_add_expr_to_block (&block, tmp);
3440 stmt = gfc_finish_block (&block);
3442 /* Clean up if it was repacked. */
3443 gfc_init_block (&block);
3444 tmp = gfc_conv_array_data (argse.expr);
3445 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3446 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3447 gfc_add_expr_to_block (&block, tmp);
3448 gfc_add_block_to_block (&block, &se->post);
3449 gfc_init_block (&se->post);
3450 gfc_add_block_to_block (&se->post, &block);
3453 /* Obtain the source word length. */
3454 if (arg->expr->ts.type == BT_CHARACTER)
3455 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3456 argse.string_length);
3458 tmp = fold_convert (gfc_array_index_type,
3459 size_in_bytes (source_type));
3461 /* Obtain the size of the array in bytes. */
3462 extent = gfc_create_var (gfc_array_index_type, NULL);
3463 for (n = 0; n < arg->expr->rank; n++)
3466 idx = gfc_rank_cst[n];
3467 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3468 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3469 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3470 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3471 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3473 gfc_add_modify_expr (&argse.pre, extent, tmp);
3474 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3475 extent, gfc_index_one_node);
3476 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3481 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3482 gfc_add_block_to_block (&se->pre, &argse.pre);
3483 gfc_add_block_to_block (&se->post, &argse.post);
3485 /* Now convert MOLD. The outputs are:
3486 mold_type = the TREE type of MOLD
3487 dest_word_len = destination word length in bytes. */
3490 gfc_init_se (&argse, NULL);
3491 ss = gfc_walk_expr (arg->expr);
3493 if (ss == gfc_ss_terminator)
3495 gfc_conv_expr_reference (&argse, arg->expr);
3496 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3500 gfc_init_se (&argse, NULL);
3501 argse.want_pointer = 0;
3502 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3503 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3506 if (arg->expr->ts.type == BT_CHARACTER)
3508 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
3509 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3512 tmp = fold_convert (gfc_array_index_type,
3513 size_in_bytes (mold_type));
3515 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3516 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
3518 /* Finally convert SIZE, if it is present. */
3520 size_words = gfc_create_var (gfc_array_index_type, NULL);
3524 gfc_init_se (&argse, NULL);
3525 gfc_conv_expr_reference (&argse, arg->expr);
3526 tmp = convert (gfc_array_index_type,
3527 build_fold_indirect_ref (argse.expr));
3528 gfc_add_block_to_block (&se->pre, &argse.pre);
3529 gfc_add_block_to_block (&se->post, &argse.post);
3534 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3535 if (tmp != NULL_TREE)
3537 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3538 tmp, dest_word_len);
3539 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3545 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
3546 gfc_add_modify_expr (&se->pre, size_words,
3547 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3548 size_bytes, dest_word_len));
3550 /* Evaluate the bounds of the result. If the loop range exists, we have
3551 to check if it is too large. If so, we modify loop->to be consistent
3552 with min(size, size(source)). Otherwise, size is made consistent with
3553 the loop range, so that the right number of bytes is transferred.*/
3554 n = se->loop->order[0];
3555 if (se->loop->to[n] != NULL_TREE)
3557 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3558 se->loop->to[n], se->loop->from[n]);
3559 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3560 tmp, gfc_index_one_node);
3561 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3563 gfc_add_modify_expr (&se->pre, size_words, tmp);
3564 gfc_add_modify_expr (&se->pre, size_bytes,
3565 fold_build2 (MULT_EXPR, gfc_array_index_type,
3566 size_words, dest_word_len));
3567 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3568 size_words, se->loop->from[n]);
3569 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3570 upper, gfc_index_one_node);
3574 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3575 size_words, gfc_index_one_node);
3576 se->loop->from[n] = gfc_index_zero_node;
3579 se->loop->to[n] = upper;
3581 /* Build a destination descriptor, using the pointer, source, as the
3582 data field. This is already allocated so set callee_alloc.
3583 FIXME callee_alloc is not set! */
3585 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3586 info, mold_type, false, true, false);
3588 /* Cast the pointer to the result. */
3589 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3590 tmp = fold_convert (pvoid_type_node, tmp);
3592 /* Use memcpy to do the transfer. */
3593 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3596 fold_convert (pvoid_type_node, source),
3598 gfc_add_expr_to_block (&se->pre, tmp);
3600 se->expr = info->descriptor;
3601 if (expr->ts.type == BT_CHARACTER)
3602 se->string_length = dest_word_len;
3606 /* Scalar transfer statement.
3607 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3610 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3612 gfc_actual_arglist *arg;
3619 /* Get a pointer to the source. */
3620 arg = expr->value.function.actual;
3621 ss = gfc_walk_expr (arg->expr);
3622 gfc_init_se (&argse, NULL);
3623 if (ss == gfc_ss_terminator)
3624 gfc_conv_expr_reference (&argse, arg->expr);
3626 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3627 gfc_add_block_to_block (&se->pre, &argse.pre);
3628 gfc_add_block_to_block (&se->post, &argse.post);
3632 type = gfc_typenode_for_spec (&expr->ts);
3634 if (expr->ts.type == BT_CHARACTER)
3636 ptr = convert (build_pointer_type (type), ptr);
3637 gfc_init_se (&argse, NULL);
3638 gfc_conv_expr (&argse, arg->expr);
3639 gfc_add_block_to_block (&se->pre, &argse.pre);
3640 gfc_add_block_to_block (&se->post, &argse.post);
3642 se->string_length = argse.string_length;
3647 tmpdecl = gfc_create_var (type, "transfer");
3648 moldsize = size_in_bytes (type);
3650 /* Use memcpy to do the transfer. */
3651 tmp = fold_build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3652 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3653 fold_convert (pvoid_type_node, tmp),
3654 fold_convert (pvoid_type_node, ptr),
3656 gfc_add_expr_to_block (&se->pre, tmp);
3663 /* Generate code for the ALLOCATED intrinsic.
3664 Generate inline code that directly check the address of the argument. */
3667 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3669 gfc_actual_arglist *arg1;
3674 gfc_init_se (&arg1se, NULL);
3675 arg1 = expr->value.function.actual;
3676 ss1 = gfc_walk_expr (arg1->expr);
3677 arg1se.descriptor_only = 1;
3678 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3680 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3681 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3682 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3683 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3687 /* Generate code for the ASSOCIATED intrinsic.
3688 If both POINTER and TARGET are arrays, generate a call to library function
3689 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3690 In other cases, generate inline code that directly compare the address of
3691 POINTER with the address of TARGET. */
3694 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3696 gfc_actual_arglist *arg1;
3697 gfc_actual_arglist *arg2;
3702 tree nonzero_charlen;
3703 tree nonzero_arraylen;
3706 gfc_init_se (&arg1se, NULL);
3707 gfc_init_se (&arg2se, NULL);
3708 arg1 = expr->value.function.actual;
3710 ss1 = gfc_walk_expr (arg1->expr);
3714 /* No optional target. */
3715 if (ss1 == gfc_ss_terminator)
3717 /* A pointer to a scalar. */
3718 arg1se.want_pointer = 1;
3719 gfc_conv_expr (&arg1se, arg1->expr);
3724 /* A pointer to an array. */
3725 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3726 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3728 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3729 gfc_add_block_to_block (&se->post, &arg1se.post);
3730 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
3731 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3736 /* An optional target. */
3737 ss2 = gfc_walk_expr (arg2->expr);
3739 nonzero_charlen = NULL_TREE;
3740 if (arg1->expr->ts.type == BT_CHARACTER)
3741 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
3742 arg1->expr->ts.cl->backend_decl,
3745 if (ss1 == gfc_ss_terminator)
3747 /* A pointer to a scalar. */
3748 gcc_assert (ss2 == gfc_ss_terminator);
3749 arg1se.want_pointer = 1;
3750 gfc_conv_expr (&arg1se, arg1->expr);
3751 arg2se.want_pointer = 1;
3752 gfc_conv_expr (&arg2se, arg2->expr);
3753 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3754 gfc_add_block_to_block (&se->post, &arg1se.post);
3755 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
3756 arg1se.expr, arg2se.expr);
3757 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
3758 arg1se.expr, null_pointer_node);
3759 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3764 /* An array pointer of zero length is not associated if target is
3766 arg1se.descriptor_only = 1;
3767 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3768 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3769 gfc_rank_cst[arg1->expr->rank - 1]);
3770 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
3771 build_int_cst (TREE_TYPE (tmp), 0));
3773 /* A pointer to an array, call library function _gfor_associated. */
3774 gcc_assert (ss2 != gfc_ss_terminator);
3775 arg1se.want_pointer = 1;
3776 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3778 arg2se.want_pointer = 1;
3779 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3780 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3781 gfc_add_block_to_block (&se->post, &arg2se.post);
3782 se->expr = build_call_expr (gfor_fndecl_associated, 2,
3783 arg1se.expr, arg2se.expr);
3784 se->expr = convert (boolean_type_node, se->expr);
3785 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3786 se->expr, nonzero_arraylen);
3789 /* If target is present zero character length pointers cannot
3791 if (nonzero_charlen != NULL_TREE)
3792 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3793 se->expr, nonzero_charlen);
3796 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3800 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
3803 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
3807 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3808 se->expr = build_call_expr (gfor_fndecl_sc_kind, 2, args[0], args[1]);
3809 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3813 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3816 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
3820 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3822 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
3823 type = gfc_get_int_type (4);
3824 arg = build_fold_addr_expr (fold_convert (type, arg));
3826 /* Convert it to the required type. */
3827 type = gfc_typenode_for_spec (&expr->ts);
3828 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
3829 se->expr = fold_convert (type, se->expr);
3833 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3836 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
3838 gfc_actual_arglist *actual;
3843 for (actual = expr->value.function.actual; actual; actual = actual->next)
3845 gfc_init_se (&argse, se);
3847 /* Pass a NULL pointer for an absent arg. */
3848 if (actual->expr == NULL)
3849 argse.expr = null_pointer_node;
3855 if (actual->expr->ts.kind != gfc_c_int_kind)
3857 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
3858 ts.type = BT_INTEGER;
3859 ts.kind = gfc_c_int_kind;
3860 gfc_convert_type (actual->expr, &ts, 2);
3862 gfc_conv_expr_reference (&argse, actual->expr);
3865 gfc_add_block_to_block (&se->pre, &argse.pre);
3866 gfc_add_block_to_block (&se->post, &argse.post);
3867 args = gfc_chainon_list (args, argse.expr);
3870 /* Convert it to the required type. */
3871 type = gfc_typenode_for_spec (&expr->ts);
3872 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3873 se->expr = fold_convert (type, se->expr);
3877 /* Generate code for TRIM (A) intrinsic function. */
3880 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3890 unsigned int num_args;
3892 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
3893 args = alloca (sizeof (tree) * num_args);
3895 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
3896 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3897 len = gfc_create_var (gfc_get_int_type (4), "len");
3899 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
3900 args[0] = build_fold_addr_expr (len);
3903 if (expr->ts.kind == 1)
3904 function = gfor_fndecl_string_trim;
3905 else if (expr->ts.kind == 4)
3906 function = gfor_fndecl_string_trim_char4;
3910 fndecl = build_addr (function, current_function_decl);
3911 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
3913 gfc_add_expr_to_block (&se->pre, tmp);
3915 /* Free the temporary afterwards, if necessary. */
3916 cond = fold_build2 (GT_EXPR, boolean_type_node,
3917 len, build_int_cst (TREE_TYPE (len), 0));
3918 tmp = gfc_call_free (var);
3919 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3920 gfc_add_expr_to_block (&se->post, tmp);
3923 se->string_length = len;
3927 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3930 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3932 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
3933 tree type, cond, tmp, count, exit_label, n, max, largest;
3935 stmtblock_t block, body;
3938 /* We store in charsize the size of a character. */
3939 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
3940 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
3942 /* Get the arguments. */
3943 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3944 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
3946 ncopies = gfc_evaluate_now (args[2], &se->pre);
3947 ncopies_type = TREE_TYPE (ncopies);
3949 /* Check that NCOPIES is not negative. */
3950 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3951 build_int_cst (ncopies_type, 0));
3952 gfc_trans_runtime_check (cond, &se->pre, &expr->where,
3953 "Argument NCOPIES of REPEAT intrinsic is negative "
3954 "(its value is %lld)",
3955 fold_convert (long_integer_type_node, ncopies));
3957 /* If the source length is zero, any non negative value of NCOPIES
3958 is valid, and nothing happens. */
3959 n = gfc_create_var (ncopies_type, "ncopies");
3960 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3961 build_int_cst (size_type_node, 0));
3962 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
3963 build_int_cst (ncopies_type, 0), ncopies);
3964 gfc_add_modify_expr (&se->pre, n, tmp);
3967 /* Check that ncopies is not too large: ncopies should be less than
3968 (or equal to) MAX / slen, where MAX is the maximal integer of
3969 the gfc_charlen_type_node type. If slen == 0, we need a special
3970 case to avoid the division by zero. */
3971 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
3972 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
3973 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
3974 fold_convert (size_type_node, max), slen);
3975 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
3976 ? size_type_node : ncopies_type;
3977 cond = fold_build2 (GT_EXPR, boolean_type_node,
3978 fold_convert (largest, ncopies),
3979 fold_convert (largest, max));
3980 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3981 build_int_cst (size_type_node, 0));
3982 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
3984 gfc_trans_runtime_check (cond, &se->pre, &expr->where,
3985 "Argument NCOPIES of REPEAT intrinsic is too large");
3987 /* Compute the destination length. */
3988 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
3989 fold_convert (gfc_charlen_type_node, slen),
3990 fold_convert (gfc_charlen_type_node, ncopies));
3991 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3992 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
3994 /* Generate the code to do the repeat operation:
3995 for (i = 0; i < ncopies; i++)
3996 memmove (dest + (i * slen * size), src, slen*size); */
3997 gfc_start_block (&block);
3998 count = gfc_create_var (ncopies_type, "count");
3999 gfc_add_modify_expr (&block, count, build_int_cst (ncopies_type, 0));
4000 exit_label = gfc_build_label_decl (NULL_TREE);
4002 /* Start the loop body. */
4003 gfc_start_block (&body);
4005 /* Exit the loop if count >= ncopies. */
4006 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4007 tmp = build1_v (GOTO_EXPR, exit_label);
4008 TREE_USED (exit_label) = 1;
4009 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4010 build_empty_stmt ());
4011 gfc_add_expr_to_block (&body, tmp);
4013 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4014 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4015 fold_convert (gfc_charlen_type_node, slen),
4016 fold_convert (gfc_charlen_type_node, count));
4017 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4018 tmp, fold_convert (gfc_charlen_type_node, size));
4019 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4020 fold_convert (pvoid_type_node, dest),
4021 fold_convert (sizetype, tmp));
4022 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4023 fold_build2 (MULT_EXPR, size_type_node, slen,
4024 fold_convert (size_type_node, size)));
4025 gfc_add_expr_to_block (&body, tmp);
4027 /* Increment count. */
4028 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4029 count, build_int_cst (TREE_TYPE (count), 1));
4030 gfc_add_modify_expr (&body, count, tmp);
4032 /* Build the loop. */
4033 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4034 gfc_add_expr_to_block (&block, tmp);
4036 /* Add the exit label. */
4037 tmp = build1_v (LABEL_EXPR, exit_label);
4038 gfc_add_expr_to_block (&block, tmp);
4040 /* Finish the block. */
4041 tmp = gfc_finish_block (&block);
4042 gfc_add_expr_to_block (&se->pre, tmp);
4044 /* Set the result value. */
4046 se->string_length = dlen;
4050 /* Generate code for the IARGC intrinsic. */
4053 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4059 /* Call the library function. This always returns an INTEGER(4). */
4060 fndecl = gfor_fndecl_iargc;
4061 tmp = build_call_expr (fndecl, 0);
4063 /* Convert it to the required type. */
4064 type = gfc_typenode_for_spec (&expr->ts);
4065 tmp = fold_convert (type, tmp);
4071 /* The loc intrinsic returns the address of its argument as
4072 gfc_index_integer_kind integer. */
4075 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4081 gcc_assert (!se->ss);
4083 arg_expr = expr->value.function.actual->expr;
4084 ss = gfc_walk_expr (arg_expr);
4085 if (ss == gfc_ss_terminator)
4086 gfc_conv_expr_reference (se, arg_expr);
4088 gfc_conv_array_parameter (se, arg_expr, ss, 1);
4089 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4091 /* Create a temporary variable for loc return value. Without this,
4092 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4093 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4094 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
4095 se->expr = temp_var;
4098 /* Generate code for an intrinsic function. Some map directly to library
4099 calls, others get special handling. In some cases the name of the function
4100 used depends on the type specifiers. */
4103 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4105 gfc_intrinsic_sym *isym;
4110 isym = expr->value.function.isym;
4112 name = &expr->value.function.name[2];
4114 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4116 lib = gfc_is_intrinsic_libcall (expr);
4120 se->ignore_optional = 1;
4121 gfc_conv_intrinsic_funcall (se, expr);
4126 switch (expr->value.function.isym->id)
4131 case GFC_ISYM_REPEAT:
4132 gfc_conv_intrinsic_repeat (se, expr);
4136 gfc_conv_intrinsic_trim (se, expr);
4139 case GFC_ISYM_SC_KIND:
4140 gfc_conv_intrinsic_sc_kind (se, expr);
4143 case GFC_ISYM_SI_KIND:
4144 gfc_conv_intrinsic_si_kind (se, expr);
4147 case GFC_ISYM_SR_KIND:
4148 gfc_conv_intrinsic_sr_kind (se, expr);
4151 case GFC_ISYM_EXPONENT:
4152 gfc_conv_intrinsic_exponent (se, expr);
4156 kind = expr->value.function.actual->expr->ts.kind;
4158 fndecl = gfor_fndecl_string_scan;
4160 fndecl = gfor_fndecl_string_scan_char4;
4164 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4167 case GFC_ISYM_VERIFY:
4168 kind = expr->value.function.actual->expr->ts.kind;
4170 fndecl = gfor_fndecl_string_verify;
4172 fndecl = gfor_fndecl_string_verify_char4;
4176 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4179 case GFC_ISYM_ALLOCATED:
4180 gfc_conv_allocated (se, expr);
4183 case GFC_ISYM_ASSOCIATED:
4184 gfc_conv_associated(se, expr);
4188 gfc_conv_intrinsic_abs (se, expr);
4191 case GFC_ISYM_ADJUSTL:
4192 if (expr->ts.kind == 1)
4193 fndecl = gfor_fndecl_adjustl;
4194 else if (expr->ts.kind == 4)
4195 fndecl = gfor_fndecl_adjustl_char4;
4199 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4202 case GFC_ISYM_ADJUSTR:
4203 if (expr->ts.kind == 1)
4204 fndecl = gfor_fndecl_adjustr;
4205 else if (expr->ts.kind == 4)
4206 fndecl = gfor_fndecl_adjustr_char4;
4210 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4213 case GFC_ISYM_AIMAG:
4214 gfc_conv_intrinsic_imagpart (se, expr);
4218 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4222 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4225 case GFC_ISYM_ANINT:
4226 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4230 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4234 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4237 case GFC_ISYM_BTEST:
4238 gfc_conv_intrinsic_btest (se, expr);
4241 case GFC_ISYM_ACHAR:
4243 gfc_conv_intrinsic_char (se, expr);
4246 case GFC_ISYM_CONVERSION:
4248 case GFC_ISYM_LOGICAL:
4250 gfc_conv_intrinsic_conversion (se, expr);
4253 /* Integer conversions are handled separately to make sure we get the
4254 correct rounding mode. */
4259 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4263 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4266 case GFC_ISYM_CEILING:
4267 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4270 case GFC_ISYM_FLOOR:
4271 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4275 gfc_conv_intrinsic_mod (se, expr, 0);
4278 case GFC_ISYM_MODULO:
4279 gfc_conv_intrinsic_mod (se, expr, 1);
4282 case GFC_ISYM_CMPLX:
4283 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4286 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4287 gfc_conv_intrinsic_iargc (se, expr);
4290 case GFC_ISYM_COMPLEX:
4291 gfc_conv_intrinsic_cmplx (se, expr, 1);
4294 case GFC_ISYM_CONJG:
4295 gfc_conv_intrinsic_conjg (se, expr);
4298 case GFC_ISYM_COUNT:
4299 gfc_conv_intrinsic_count (se, expr);
4302 case GFC_ISYM_CTIME:
4303 gfc_conv_intrinsic_ctime (se, expr);
4307 gfc_conv_intrinsic_dim (se, expr);
4310 case GFC_ISYM_DOT_PRODUCT:
4311 gfc_conv_intrinsic_dot_product (se, expr);
4314 case GFC_ISYM_DPROD:
4315 gfc_conv_intrinsic_dprod (se, expr);
4318 case GFC_ISYM_FDATE:
4319 gfc_conv_intrinsic_fdate (se, expr);
4322 case GFC_ISYM_FRACTION:
4323 gfc_conv_intrinsic_fraction (se, expr);
4327 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4330 case GFC_ISYM_IBCLR:
4331 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4334 case GFC_ISYM_IBITS:
4335 gfc_conv_intrinsic_ibits (se, expr);
4338 case GFC_ISYM_IBSET:
4339 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4342 case GFC_ISYM_IACHAR:
4343 case GFC_ISYM_ICHAR:
4344 /* We assume ASCII character sequence. */
4345 gfc_conv_intrinsic_ichar (se, expr);
4348 case GFC_ISYM_IARGC:
4349 gfc_conv_intrinsic_iargc (se, expr);
4353 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4356 case GFC_ISYM_INDEX:
4357 kind = expr->value.function.actual->expr->ts.kind;
4359 fndecl = gfor_fndecl_string_index;
4361 fndecl = gfor_fndecl_string_index_char4;
4365 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4369 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4372 case GFC_ISYM_IS_IOSTAT_END:
4373 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4376 case GFC_ISYM_IS_IOSTAT_EOR:
4377 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4380 case GFC_ISYM_ISNAN:
4381 gfc_conv_intrinsic_isnan (se, expr);
4384 case GFC_ISYM_LSHIFT:
4385 gfc_conv_intrinsic_rlshift (se, expr, 0);
4388 case GFC_ISYM_RSHIFT:
4389 gfc_conv_intrinsic_rlshift (se, expr, 1);
4392 case GFC_ISYM_ISHFT:
4393 gfc_conv_intrinsic_ishft (se, expr);
4396 case GFC_ISYM_ISHFTC:
4397 gfc_conv_intrinsic_ishftc (se, expr);
4400 case GFC_ISYM_LBOUND:
4401 gfc_conv_intrinsic_bound (se, expr, 0);
4404 case GFC_ISYM_TRANSPOSE:
4405 if (se->ss && se->ss->useflags)
4407 gfc_conv_tmp_array_ref (se);
4408 gfc_advance_se_ss_chain (se);
4411 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4415 gfc_conv_intrinsic_len (se, expr);
4418 case GFC_ISYM_LEN_TRIM:
4419 gfc_conv_intrinsic_len_trim (se, expr);
4423 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4427 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4431 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4435 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4439 if (expr->ts.type == BT_CHARACTER)
4440 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4442 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4445 case GFC_ISYM_MAXLOC:
4446 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4449 case GFC_ISYM_MAXVAL:
4450 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4453 case GFC_ISYM_MERGE:
4454 gfc_conv_intrinsic_merge (se, expr);
4458 if (expr->ts.type == BT_CHARACTER)
4459 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4461 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4464 case GFC_ISYM_MINLOC:
4465 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4468 case GFC_ISYM_MINVAL:
4469 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4472 case GFC_ISYM_NEAREST:
4473 gfc_conv_intrinsic_nearest (se, expr);
4477 gfc_conv_intrinsic_not (se, expr);
4481 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4484 case GFC_ISYM_PRESENT:
4485 gfc_conv_intrinsic_present (se, expr);
4488 case GFC_ISYM_PRODUCT:
4489 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4492 case GFC_ISYM_RRSPACING:
4493 gfc_conv_intrinsic_rrspacing (se, expr);
4496 case GFC_ISYM_SET_EXPONENT:
4497 gfc_conv_intrinsic_set_exponent (se, expr);
4500 case GFC_ISYM_SCALE:
4501 gfc_conv_intrinsic_scale (se, expr);
4505 gfc_conv_intrinsic_sign (se, expr);
4509 gfc_conv_intrinsic_size (se, expr);
4512 case GFC_ISYM_SIZEOF:
4513 gfc_conv_intrinsic_sizeof (se, expr);
4516 case GFC_ISYM_SPACING:
4517 gfc_conv_intrinsic_spacing (se, expr);
4521 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4524 case GFC_ISYM_TRANSFER:
4527 if (se->ss->useflags)
4529 /* Access the previously obtained result. */
4530 gfc_conv_tmp_array_ref (se);
4531 gfc_advance_se_ss_chain (se);
4535 gfc_conv_intrinsic_array_transfer (se, expr);
4538 gfc_conv_intrinsic_transfer (se, expr);
4541 case GFC_ISYM_TTYNAM:
4542 gfc_conv_intrinsic_ttynam (se, expr);
4545 case GFC_ISYM_UBOUND:
4546 gfc_conv_intrinsic_bound (se, expr, 1);
4550 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4554 gfc_conv_intrinsic_loc (se, expr);
4557 case GFC_ISYM_ACCESS:
4558 case GFC_ISYM_CHDIR:
4559 case GFC_ISYM_CHMOD:
4560 case GFC_ISYM_DTIME:
4561 case GFC_ISYM_ETIME:
4563 case GFC_ISYM_FGETC:
4566 case GFC_ISYM_FPUTC:
4567 case GFC_ISYM_FSTAT:
4568 case GFC_ISYM_FTELL:
4569 case GFC_ISYM_GETCWD:
4570 case GFC_ISYM_GETGID:
4571 case GFC_ISYM_GETPID:
4572 case GFC_ISYM_GETUID:
4573 case GFC_ISYM_HOSTNM:
4575 case GFC_ISYM_IERRNO:
4576 case GFC_ISYM_IRAND:
4577 case GFC_ISYM_ISATTY:
4579 case GFC_ISYM_LSTAT:
4580 case GFC_ISYM_MALLOC:
4581 case GFC_ISYM_MATMUL:
4582 case GFC_ISYM_MCLOCK:
4583 case GFC_ISYM_MCLOCK8:
4585 case GFC_ISYM_RENAME:
4586 case GFC_ISYM_SECOND:
4587 case GFC_ISYM_SECNDS:
4588 case GFC_ISYM_SIGNAL:
4590 case GFC_ISYM_SYMLNK:
4591 case GFC_ISYM_SYSTEM:
4593 case GFC_ISYM_TIME8:
4594 case GFC_ISYM_UMASK:
4595 case GFC_ISYM_UNLINK:
4596 gfc_conv_intrinsic_funcall (se, expr);
4600 gfc_conv_intrinsic_lib_function (se, expr);
4606 /* This generates code to execute before entering the scalarization loop.
4607 Currently does nothing. */
4610 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4612 switch (ss->expr->value.function.isym->id)
4614 case GFC_ISYM_UBOUND:
4615 case GFC_ISYM_LBOUND:
4624 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4625 inside the scalarization loop. */
4628 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4632 /* The two argument version returns a scalar. */
4633 if (expr->value.function.actual->next->expr)
4636 newss = gfc_get_ss ();
4637 newss->type = GFC_SS_INTRINSIC;
4640 newss->data.info.dimen = 1;
4646 /* Walk an intrinsic array libcall. */
4649 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4653 gcc_assert (expr->rank > 0);
4655 newss = gfc_get_ss ();
4656 newss->type = GFC_SS_FUNCTION;
4659 newss->data.info.dimen = expr->rank;
4665 /* Returns nonzero if the specified intrinsic function call maps directly to a
4666 an external library call. Should only be used for functions that return
4670 gfc_is_intrinsic_libcall (gfc_expr * expr)
4672 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4673 gcc_assert (expr->rank > 0);
4675 switch (expr->value.function.isym->id)
4679 case GFC_ISYM_COUNT:
4680 case GFC_ISYM_MATMUL:
4681 case GFC_ISYM_MAXLOC:
4682 case GFC_ISYM_MAXVAL:
4683 case GFC_ISYM_MINLOC:
4684 case GFC_ISYM_MINVAL:
4685 case GFC_ISYM_PRODUCT:
4687 case GFC_ISYM_SHAPE:
4688 case GFC_ISYM_SPREAD:
4689 case GFC_ISYM_TRANSPOSE:
4690 /* Ignore absent optional parameters. */
4693 case GFC_ISYM_RESHAPE:
4694 case GFC_ISYM_CSHIFT:
4695 case GFC_ISYM_EOSHIFT:
4697 case GFC_ISYM_UNPACK:
4698 /* Pass absent optional parameters. */
4706 /* Walk an intrinsic function. */
4708 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
4709 gfc_intrinsic_sym * isym)
4713 if (isym->elemental)
4714 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
4716 if (expr->rank == 0)
4719 if (gfc_is_intrinsic_libcall (expr))
4720 return gfc_walk_intrinsic_libfunc (ss, expr);
4722 /* Special cases. */
4725 case GFC_ISYM_LBOUND:
4726 case GFC_ISYM_UBOUND:
4727 return gfc_walk_intrinsic_bound (ss, expr);
4729 case GFC_ISYM_TRANSFER:
4730 return gfc_walk_intrinsic_libfunc (ss, expr);
4733 /* This probably meant someone forgot to add an intrinsic to the above
4734 list(s) when they implemented it, or something's gone horribly
4740 #include "gt-fortran-trans-intrinsic.h"