1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
37 #include "intrinsic.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
44 #include "trans-stmt.h"
46 /* This maps fortran intrinsic math functions to external library or GCC
48 typedef struct gfc_intrinsic_map_t GTY(())
50 /* The explicit enum is required to work around inadequacies in the
51 garbage collection/gengtype parsing mechanism. */
54 /* Enum value from the "language-independent", aka C-centric, part
55 of gcc, or END_BUILTINS of no such value set. */
56 enum built_in_function code_r4;
57 enum built_in_function code_r8;
58 enum built_in_function code_r10;
59 enum built_in_function code_r16;
60 enum built_in_function code_c4;
61 enum built_in_function code_c8;
62 enum built_in_function code_c10;
63 enum built_in_function code_c16;
65 /* True if the naming pattern is to prepend "c" for complex and
66 append "f" for kind=4. False if the naming pattern is to
67 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
70 /* True if a complex version of the function exists. */
71 bool complex_available;
73 /* True if the function should be marked const. */
76 /* The base library name of this function. */
79 /* Cache decls created for the various operand types. */
91 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
92 defines complex variants of all of the entries in mathbuiltins.def
94 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
95 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
96 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, 0, 0, 0, 0, true, \
97 false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
98 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
100 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
101 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
102 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
103 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
104 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
105 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
107 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
108 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
111 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
113 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
115 /* Functions built into gcc itself. */
116 #include "mathbuiltins.def"
118 /* Functions in libgfortran. */
119 LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
122 LIB_FUNCTION (NONE, NULL, false)
126 #undef DEFINE_MATH_BUILTIN
127 #undef DEFINE_MATH_BUILTIN_C
129 /* Structure for storing components of a floating number to be used by
130 elemental functions to manipulate reals. */
133 tree arg; /* Variable tree to view convert to integer. */
134 tree expn; /* Variable tree to save exponent. */
135 tree frac; /* Variable tree to save fraction. */
136 tree smask; /* Constant tree of sign's mask. */
137 tree emask; /* Constant tree of exponent's mask. */
138 tree fmask; /* Constant tree of fraction's mask. */
139 tree edigits; /* Constant tree of the number of exponent bits. */
140 tree fdigits; /* Constant tree of the number of fraction bits. */
141 tree f1; /* Constant tree of the f1 defined in the real model. */
142 tree bias; /* Constant tree of the bias of exponent in the memory. */
143 tree type; /* Type tree of arg1. */
144 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
148 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
150 /* Evaluate the arguments to an intrinsic function. The value
151 of NARGS may be less than the actual number of arguments in EXPR
152 to allow optional "KIND" arguments that are not included in the
153 generated code to be ignored. */
156 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
157 tree *argarray, int nargs)
159 gfc_actual_arglist *actual;
161 gfc_intrinsic_arg *formal;
165 formal = expr->value.function.isym->formal;
166 actual = expr->value.function.actual;
168 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
169 actual = actual->next,
170 formal = formal ? formal->next : NULL)
174 /* Skip omitted optional arguments. */
181 /* Evaluate the parameter. This will substitute scalarized
182 references automatically. */
183 gfc_init_se (&argse, se);
185 if (e->ts.type == BT_CHARACTER)
187 gfc_conv_expr (&argse, e);
188 gfc_conv_string_parameter (&argse);
189 argarray[curr_arg++] = argse.string_length;
190 gcc_assert (curr_arg < nargs);
193 gfc_conv_expr_val (&argse, e);
195 /* If an optional argument is itself an optional dummy argument,
196 check its presence and substitute a null if absent. */
197 if (e->expr_type == EXPR_VARIABLE
198 && e->symtree->n.sym->attr.optional
201 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
203 gfc_add_block_to_block (&se->pre, &argse.pre);
204 gfc_add_block_to_block (&se->post, &argse.post);
205 argarray[curr_arg] = argse.expr;
209 /* Count the number of actual arguments to the intrinsic function EXPR
210 including any "hidden" string length arguments. */
213 gfc_intrinsic_argument_list_length (gfc_expr *expr)
216 gfc_actual_arglist *actual;
218 for (actual = expr->value.function.actual; actual; actual = actual->next)
223 if (actual->expr->ts.type == BT_CHARACTER)
233 /* Conversions between different types are output by the frontend as
234 intrinsic functions. We implement these directly with inline code. */
237 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
243 nargs = gfc_intrinsic_argument_list_length (expr);
244 args = (tree *) alloca (sizeof (tree) * nargs);
246 /* Evaluate all the arguments passed. Whilst we're only interested in the
247 first one here, there are other parts of the front-end that assume this
248 and will trigger an ICE if it's not the case. */
249 type = gfc_typenode_for_spec (&expr->ts);
250 gcc_assert (expr->value.function.actual->expr);
251 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
253 /* Conversion between character kinds involves a call to a library
255 if (expr->ts.type == BT_CHARACTER)
257 tree fndecl, var, addr, tmp;
259 if (expr->ts.kind == 1
260 && expr->value.function.actual->expr->ts.kind == 4)
261 fndecl = gfor_fndecl_convert_char4_to_char1;
262 else if (expr->ts.kind == 4
263 && expr->value.function.actual->expr->ts.kind == 1)
264 fndecl = gfor_fndecl_convert_char1_to_char4;
268 /* Create the variable storing the converted value. */
269 type = gfc_get_pchar_type (expr->ts.kind);
270 var = gfc_create_var (type, "str");
271 addr = gfc_build_addr_expr (build_pointer_type (type), var);
273 /* Call the library function that will perform the conversion. */
274 gcc_assert (nargs >= 2);
275 tmp = build_call_expr (fndecl, 3, addr, args[0], args[1]);
276 gfc_add_expr_to_block (&se->pre, tmp);
278 /* Free the temporary afterwards. */
279 tmp = gfc_call_free (var);
280 gfc_add_expr_to_block (&se->post, tmp);
283 se->string_length = args[0];
288 /* Conversion from complex to non-complex involves taking the real
289 component of the value. */
290 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
291 && expr->ts.type != BT_COMPLEX)
295 artype = TREE_TYPE (TREE_TYPE (args[0]));
296 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
299 se->expr = convert (type, args[0]);
302 /* This is needed because the gcc backend only implements
303 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
304 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
305 Similarly for CEILING. */
308 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
315 argtype = TREE_TYPE (arg);
316 arg = gfc_evaluate_now (arg, pblock);
318 intval = convert (type, arg);
319 intval = gfc_evaluate_now (intval, pblock);
321 tmp = convert (argtype, intval);
322 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
324 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
325 build_int_cst (type, 1));
326 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
331 /* Round to nearest integer, away from zero. */
334 build_round_expr (tree arg, tree restype)
339 int argprec, resprec;
341 argtype = TREE_TYPE (arg);
342 argprec = TYPE_PRECISION (argtype);
343 resprec = TYPE_PRECISION (restype);
345 /* Depending on the type of the result, choose the long int intrinsic
346 (lround family) or long long intrinsic (llround). We might also
347 need to convert the result afterwards. */
348 if (resprec <= LONG_TYPE_SIZE)
350 else if (resprec <= LONG_LONG_TYPE_SIZE)
355 /* Now, depending on the argument type, we choose between intrinsics. */
356 if (argprec == TYPE_PRECISION (float_type_node))
357 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
358 else if (argprec == TYPE_PRECISION (double_type_node))
359 fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
360 else if (argprec == TYPE_PRECISION (long_double_type_node))
361 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
365 return fold_convert (restype, build_call_expr (fn, 1, arg));
369 /* Convert a real to an integer using a specific rounding mode.
370 Ideally we would just build the corresponding GENERIC node,
371 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
374 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
375 enum rounding_mode op)
380 return build_fixbound_expr (pblock, arg, type, 0);
384 return build_fixbound_expr (pblock, arg, type, 1);
388 return build_round_expr (arg, type);
392 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
401 /* Round a real value using the specified rounding mode.
402 We use a temporary integer of that same kind size as the result.
403 Values larger than those that can be represented by this kind are
404 unchanged, as they will not be accurate enough to represent the
406 huge = HUGE (KIND (a))
407 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
411 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
422 kind = expr->ts.kind;
423 nargs = gfc_intrinsic_argument_list_length (expr);
426 /* We have builtin functions for some cases. */
469 /* Evaluate the argument. */
470 gcc_assert (expr->value.function.actual->expr);
471 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
473 /* Use a builtin function if one exists. */
474 if (n != END_BUILTINS)
476 tmp = built_in_decls[n];
477 se->expr = build_call_expr (tmp, 1, arg[0]);
481 /* This code is probably redundant, but we'll keep it lying around just
483 type = gfc_typenode_for_spec (&expr->ts);
484 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
486 /* Test if the value is too large to handle sensibly. */
487 gfc_set_model_kind (kind);
489 n = gfc_validate_kind (BT_INTEGER, kind, false);
490 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
491 tmp = gfc_conv_mpfr_to_tree (huge, kind);
492 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
494 mpfr_neg (huge, huge, GFC_RND_MODE);
495 tmp = gfc_conv_mpfr_to_tree (huge, kind);
496 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
497 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
498 itype = gfc_get_int_type (kind);
500 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
501 tmp = convert (type, tmp);
502 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
507 /* Convert to an integer using the specified rounding mode. */
510 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
516 nargs = gfc_intrinsic_argument_list_length (expr);
517 args = (tree *) alloca (sizeof (tree) * nargs);
519 /* Evaluate the argument, we process all arguments even though we only
520 use the first one for code generation purposes. */
521 type = gfc_typenode_for_spec (&expr->ts);
522 gcc_assert (expr->value.function.actual->expr);
523 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
525 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
527 /* Conversion to a different integer kind. */
528 se->expr = convert (type, args[0]);
532 /* Conversion from complex to non-complex involves taking the real
533 component of the value. */
534 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
535 && expr->ts.type != BT_COMPLEX)
539 artype = TREE_TYPE (TREE_TYPE (args[0]));
540 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
543 se->expr = build_fix_expr (&se->pre, args[0], type, op);
548 /* Get the imaginary component of a value. */
551 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
555 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
556 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
560 /* Get the complex conjugate of a value. */
563 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
567 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
568 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
572 /* Initialize function decls for library functions. The external functions
573 are created as required. Builtin functions are added here. */
576 gfc_build_intrinsic_lib_fndecls (void)
578 gfc_intrinsic_map_t *m;
580 /* Add GCC builtin functions. */
581 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
583 if (m->code_r4 != END_BUILTINS)
584 m->real4_decl = built_in_decls[m->code_r4];
585 if (m->code_r8 != END_BUILTINS)
586 m->real8_decl = built_in_decls[m->code_r8];
587 if (m->code_r10 != END_BUILTINS)
588 m->real10_decl = built_in_decls[m->code_r10];
589 if (m->code_r16 != END_BUILTINS)
590 m->real16_decl = built_in_decls[m->code_r16];
591 if (m->code_c4 != END_BUILTINS)
592 m->complex4_decl = built_in_decls[m->code_c4];
593 if (m->code_c8 != END_BUILTINS)
594 m->complex8_decl = built_in_decls[m->code_c8];
595 if (m->code_c10 != END_BUILTINS)
596 m->complex10_decl = built_in_decls[m->code_c10];
597 if (m->code_c16 != END_BUILTINS)
598 m->complex16_decl = built_in_decls[m->code_c16];
603 /* Create a fndecl for a simple intrinsic library function. */
606 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
611 gfc_actual_arglist *actual;
614 char name[GFC_MAX_SYMBOL_LEN + 3];
617 if (ts->type == BT_REAL)
622 pdecl = &m->real4_decl;
625 pdecl = &m->real8_decl;
628 pdecl = &m->real10_decl;
631 pdecl = &m->real16_decl;
637 else if (ts->type == BT_COMPLEX)
639 gcc_assert (m->complex_available);
644 pdecl = &m->complex4_decl;
647 pdecl = &m->complex8_decl;
650 pdecl = &m->complex10_decl;
653 pdecl = &m->complex16_decl;
668 snprintf (name, sizeof (name), "%s%s%s",
669 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
670 else if (ts->kind == 8)
671 snprintf (name, sizeof (name), "%s%s",
672 ts->type == BT_COMPLEX ? "c" : "", m->name);
675 gcc_assert (ts->kind == 10 || ts->kind == 16);
676 snprintf (name, sizeof (name), "%s%s%s",
677 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
682 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
683 ts->type == BT_COMPLEX ? 'c' : 'r',
687 argtypes = NULL_TREE;
688 for (actual = expr->value.function.actual; actual; actual = actual->next)
690 type = gfc_typenode_for_spec (&actual->expr->ts);
691 argtypes = gfc_chainon_list (argtypes, type);
693 argtypes = gfc_chainon_list (argtypes, void_type_node);
694 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
695 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
697 /* Mark the decl as external. */
698 DECL_EXTERNAL (fndecl) = 1;
699 TREE_PUBLIC (fndecl) = 1;
701 /* Mark it __attribute__((const)), if possible. */
702 TREE_READONLY (fndecl) = m->is_constant;
704 rest_of_decl_compilation (fndecl, 1, 0);
711 /* Convert an intrinsic function into an external or builtin call. */
714 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
716 gfc_intrinsic_map_t *m;
720 unsigned int num_args;
723 id = expr->value.function.isym->id;
724 /* Find the entry for this function. */
725 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
731 if (m->id == GFC_ISYM_NONE)
733 internal_error ("Intrinsic function %s(%d) not recognized",
734 expr->value.function.name, id);
737 /* Get the decl and generate the call. */
738 num_args = gfc_intrinsic_argument_list_length (expr);
739 args = (tree *) alloca (sizeof (tree) * num_args);
741 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
742 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
743 rettype = TREE_TYPE (TREE_TYPE (fndecl));
745 fndecl = build_addr (fndecl, current_function_decl);
746 se->expr = build_call_array (rettype, fndecl, num_args, args);
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 (true, false, cond, &se->pre, &expr->where,
872 ubound = gfc_conv_descriptor_ubound (desc, bound);
873 lbound = gfc_conv_descriptor_lbound (desc, bound);
875 /* Follow any component references. */
876 if (arg->expr->expr_type == EXPR_VARIABLE
877 || arg->expr->expr_type == EXPR_CONSTANT)
879 as = arg->expr->symtree->n.sym->as;
880 for (ref = arg->expr->ref; ref; ref = ref->next)
885 as = ref->u.c.component->as;
893 switch (ref->u.ar.type)
911 /* 13.14.53: Result value for LBOUND
913 Case (i): For an array section or for an array expression other than a
914 whole array or array structure component, LBOUND(ARRAY, DIM)
915 has the value 1. For a whole array or array structure
916 component, LBOUND(ARRAY, DIM) has the value:
917 (a) equal to the lower bound for subscript DIM of ARRAY if
918 dimension DIM of ARRAY does not have extent zero
919 or if ARRAY is an assumed-size array of rank DIM,
922 13.14.113: Result value for UBOUND
924 Case (i): For an array section or for an array expression other than a
925 whole array or array structure component, UBOUND(ARRAY, DIM)
926 has the value equal to the number of elements in the given
927 dimension; otherwise, it has a value equal to the upper bound
928 for subscript DIM of ARRAY if dimension DIM of ARRAY does
929 not have size zero and has value zero if dimension DIM has
934 tree stride = gfc_conv_descriptor_stride (desc, bound);
936 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
937 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
939 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
940 gfc_index_zero_node);
941 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
943 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
944 gfc_index_zero_node);
945 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
949 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
951 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
952 ubound, gfc_index_zero_node);
956 if (as->type == AS_ASSUMED_SIZE)
957 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
958 build_int_cst (TREE_TYPE (bound),
959 arg->expr->rank - 1));
961 cond = boolean_false_node;
963 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
964 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
966 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
967 lbound, gfc_index_one_node);
974 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
975 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
977 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
978 gfc_index_zero_node);
981 se->expr = gfc_index_one_node;
984 type = gfc_typenode_for_spec (&expr->ts);
985 se->expr = convert (type, se->expr);
990 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
995 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
997 switch (expr->value.function.actual->expr->ts.type)
1001 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
1005 switch (expr->ts.kind)
1020 se->expr = build_call_expr (built_in_decls[n], 1, arg);
1029 /* Create a complex value from one or two real components. */
1032 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1038 unsigned int num_args;
1040 num_args = gfc_intrinsic_argument_list_length (expr);
1041 args = (tree *) alloca (sizeof (tree) * num_args);
1043 type = gfc_typenode_for_spec (&expr->ts);
1044 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1045 real = convert (TREE_TYPE (type), args[0]);
1047 imag = convert (TREE_TYPE (type), args[1]);
1048 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1050 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1052 imag = convert (TREE_TYPE (type), imag);
1055 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1057 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1060 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1061 MODULO(A, P) = A - FLOOR (A / P) * P */
1062 /* TODO: MOD(x, 0) */
1065 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1076 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1078 switch (expr->ts.type)
1081 /* Integer case is easy, we've got a builtin op. */
1082 type = TREE_TYPE (args[0]);
1085 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1087 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1092 /* Check if we have a builtin fmod. */
1093 switch (expr->ts.kind)
1112 /* Use it if it exists. */
1113 if (n != END_BUILTINS)
1115 tmp = build_addr (built_in_decls[n], current_function_decl);
1116 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1122 type = TREE_TYPE (args[0]);
1124 args[0] = gfc_evaluate_now (args[0], &se->pre);
1125 args[1] = gfc_evaluate_now (args[1], &se->pre);
1128 modulo = arg - floor (arg/arg2) * arg2, so
1129 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1131 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1132 thereby avoiding another division and retaining the accuracy
1133 of the builtin function. */
1134 if (n != END_BUILTINS && modulo)
1136 tree zero = gfc_build_const (type, integer_zero_node);
1137 tmp = gfc_evaluate_now (se->expr, &se->pre);
1138 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1139 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1140 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1141 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1142 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1143 test = gfc_evaluate_now (test, &se->pre);
1144 se->expr = fold_build3 (COND_EXPR, type, test,
1145 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1150 /* If we do not have a built_in fmod, the calculation is going to
1151 have to be done longhand. */
1152 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1154 /* Test if the value is too large to handle sensibly. */
1155 gfc_set_model_kind (expr->ts.kind);
1157 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1158 ikind = expr->ts.kind;
1161 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1162 ikind = gfc_max_integer_kind;
1164 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1165 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1166 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1168 mpfr_neg (huge, huge, GFC_RND_MODE);
1169 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1170 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1171 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1173 itype = gfc_get_int_type (ikind);
1175 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1177 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1178 tmp = convert (type, tmp);
1179 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1180 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1181 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1190 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1193 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1201 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1202 type = TREE_TYPE (args[0]);
1204 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1205 val = gfc_evaluate_now (val, &se->pre);
1207 zero = gfc_build_const (type, integer_zero_node);
1208 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1209 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1213 /* SIGN(A, B) is absolute value of A times sign of B.
1214 The real value versions use library functions to ensure the correct
1215 handling of negative zero. Integer case implemented as:
1216 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1220 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1226 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1227 if (expr->ts.type == BT_REAL)
1229 switch (expr->ts.kind)
1232 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1235 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1239 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1244 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1248 /* Having excluded floating point types, we know we are now dealing
1249 with signed integer types. */
1250 type = TREE_TYPE (args[0]);
1252 /* Args[0] is used multiple times below. */
1253 args[0] = gfc_evaluate_now (args[0], &se->pre);
1255 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1256 the signs of A and B are the same, and of all ones if they differ. */
1257 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1258 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1259 build_int_cst (type, TYPE_PRECISION (type) - 1));
1260 tmp = gfc_evaluate_now (tmp, &se->pre);
1262 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1263 is all ones (i.e. -1). */
1264 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1265 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1270 /* Test for the presence of an optional argument. */
1273 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1277 arg = expr->value.function.actual->expr;
1278 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1279 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1280 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1284 /* Calculate the double precision product of two single precision values. */
1287 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1292 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1294 /* Convert the args to double precision before multiplying. */
1295 type = gfc_typenode_for_spec (&expr->ts);
1296 args[0] = convert (type, args[0]);
1297 args[1] = convert (type, args[1]);
1298 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1302 /* Return a length one character string containing an ascii character. */
1305 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1310 unsigned int num_args;
1312 num_args = gfc_intrinsic_argument_list_length (expr);
1313 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1315 type = gfc_get_char_type (expr->ts.kind);
1316 var = gfc_create_var (type, "char");
1318 arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1319 gfc_add_modify (&se->pre, var, arg[0]);
1320 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1321 se->string_length = integer_one_node;
1326 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1334 unsigned int num_args;
1336 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1337 args = (tree *) alloca (sizeof (tree) * num_args);
1339 var = gfc_create_var (pchar_type_node, "pstr");
1340 len = gfc_create_var (gfc_get_int_type (8), "len");
1342 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1343 args[0] = build_fold_addr_expr (var);
1344 args[1] = build_fold_addr_expr (len);
1346 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1347 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1348 fndecl, num_args, args);
1349 gfc_add_expr_to_block (&se->pre, tmp);
1351 /* Free the temporary afterwards, if necessary. */
1352 cond = fold_build2 (GT_EXPR, boolean_type_node,
1353 len, build_int_cst (TREE_TYPE (len), 0));
1354 tmp = gfc_call_free (var);
1355 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1356 gfc_add_expr_to_block (&se->post, tmp);
1359 se->string_length = len;
1364 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1372 unsigned int num_args;
1374 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1375 args = (tree *) alloca (sizeof (tree) * num_args);
1377 var = gfc_create_var (pchar_type_node, "pstr");
1378 len = gfc_create_var (gfc_get_int_type (4), "len");
1380 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1381 args[0] = build_fold_addr_expr (var);
1382 args[1] = build_fold_addr_expr (len);
1384 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1385 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1386 fndecl, num_args, args);
1387 gfc_add_expr_to_block (&se->pre, tmp);
1389 /* Free the temporary afterwards, if necessary. */
1390 cond = fold_build2 (GT_EXPR, boolean_type_node,
1391 len, build_int_cst (TREE_TYPE (len), 0));
1392 tmp = gfc_call_free (var);
1393 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1394 gfc_add_expr_to_block (&se->post, tmp);
1397 se->string_length = len;
1401 /* Return a character string containing the tty name. */
1404 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1412 unsigned int num_args;
1414 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1415 args = (tree *) alloca (sizeof (tree) * num_args);
1417 var = gfc_create_var (pchar_type_node, "pstr");
1418 len = gfc_create_var (gfc_get_int_type (4), "len");
1420 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1421 args[0] = build_fold_addr_expr (var);
1422 args[1] = build_fold_addr_expr (len);
1424 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1425 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1426 fndecl, num_args, args);
1427 gfc_add_expr_to_block (&se->pre, tmp);
1429 /* Free the temporary afterwards, if necessary. */
1430 cond = fold_build2 (GT_EXPR, boolean_type_node,
1431 len, build_int_cst (TREE_TYPE (len), 0));
1432 tmp = gfc_call_free (var);
1433 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1434 gfc_add_expr_to_block (&se->post, tmp);
1437 se->string_length = len;
1441 /* Get the minimum/maximum value of all the parameters.
1442 minmax (a1, a2, a3, ...)
1445 if (a2 .op. mvar || isnan(mvar))
1447 if (a3 .op. mvar || isnan(mvar))
1454 /* TODO: Mismatching types can occur when specific names are used.
1455 These should be handled during resolution. */
1457 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1465 gfc_actual_arglist *argexpr;
1466 unsigned int i, nargs;
1468 nargs = gfc_intrinsic_argument_list_length (expr);
1469 args = (tree *) alloca (sizeof (tree) * nargs);
1471 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1472 type = gfc_typenode_for_spec (&expr->ts);
1474 argexpr = expr->value.function.actual;
1475 if (TREE_TYPE (args[0]) != type)
1476 args[0] = convert (type, args[0]);
1477 /* Only evaluate the argument once. */
1478 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1479 args[0] = gfc_evaluate_now (args[0], &se->pre);
1481 mvar = gfc_create_var (type, "M");
1482 gfc_add_modify (&se->pre, mvar, args[0]);
1483 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1489 /* Handle absent optional arguments by ignoring the comparison. */
1490 if (argexpr->expr->expr_type == EXPR_VARIABLE
1491 && argexpr->expr->symtree->n.sym->attr.optional
1492 && TREE_CODE (val) == INDIRECT_REF)
1494 (NE_EXPR, boolean_type_node, TREE_OPERAND (val, 0),
1495 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1500 /* Only evaluate the argument once. */
1501 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1502 val = gfc_evaluate_now (val, &se->pre);
1505 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1507 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1509 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1510 __builtin_isnan might be made dependent on that module being loaded,
1511 to help performance of programs that don't rely on IEEE semantics. */
1512 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1514 isnan = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1515 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1516 fold_convert (boolean_type_node, isnan));
1518 tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
1520 if (cond != NULL_TREE)
1521 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1523 gfc_add_expr_to_block (&se->pre, tmp);
1524 argexpr = argexpr->next;
1530 /* Generate library calls for MIN and MAX intrinsics for character
1533 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1536 tree var, len, fndecl, tmp, cond, function;
1539 nargs = gfc_intrinsic_argument_list_length (expr);
1540 args = (tree *) alloca (sizeof (tree) * (nargs + 4));
1541 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1543 /* Create the result variables. */
1544 len = gfc_create_var (gfc_charlen_type_node, "len");
1545 args[0] = build_fold_addr_expr (len);
1546 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1547 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1548 args[2] = build_int_cst (NULL_TREE, op);
1549 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1551 if (expr->ts.kind == 1)
1552 function = gfor_fndecl_string_minmax;
1553 else if (expr->ts.kind == 4)
1554 function = gfor_fndecl_string_minmax_char4;
1558 /* Make the function call. */
1559 fndecl = build_addr (function, current_function_decl);
1560 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
1562 gfc_add_expr_to_block (&se->pre, tmp);
1564 /* Free the temporary afterwards, if necessary. */
1565 cond = fold_build2 (GT_EXPR, boolean_type_node,
1566 len, build_int_cst (TREE_TYPE (len), 0));
1567 tmp = gfc_call_free (var);
1568 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1569 gfc_add_expr_to_block (&se->post, tmp);
1572 se->string_length = len;
1576 /* Create a symbol node for this intrinsic. The symbol from the frontend
1577 has the generic name. */
1580 gfc_get_symbol_for_expr (gfc_expr * expr)
1584 /* TODO: Add symbols for intrinsic function to the global namespace. */
1585 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1586 sym = gfc_new_symbol (expr->value.function.name, NULL);
1589 sym->attr.external = 1;
1590 sym->attr.function = 1;
1591 sym->attr.always_explicit = 1;
1592 sym->attr.proc = PROC_INTRINSIC;
1593 sym->attr.flavor = FL_PROCEDURE;
1597 sym->attr.dimension = 1;
1598 sym->as = gfc_get_array_spec ();
1599 sym->as->type = AS_ASSUMED_SHAPE;
1600 sym->as->rank = expr->rank;
1603 /* TODO: proper argument lists for external intrinsics. */
1607 /* Generate a call to an external intrinsic function. */
1609 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1614 gcc_assert (!se->ss || se->ss->expr == expr);
1617 gcc_assert (expr->rank > 0);
1619 gcc_assert (expr->rank == 0);
1621 sym = gfc_get_symbol_for_expr (expr);
1623 /* Calls to libgfortran_matmul need to be appended special arguments,
1624 to be able to call the BLAS ?gemm functions if required and possible. */
1625 append_args = NULL_TREE;
1626 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1627 && sym->ts.type != BT_LOGICAL)
1629 tree cint = gfc_get_int_type (gfc_c_int_kind);
1631 if (gfc_option.flag_external_blas
1632 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1633 && (sym->ts.kind == gfc_default_real_kind
1634 || sym->ts.kind == gfc_default_double_kind))
1638 if (sym->ts.type == BT_REAL)
1640 if (sym->ts.kind == gfc_default_real_kind)
1641 gemm_fndecl = gfor_fndecl_sgemm;
1643 gemm_fndecl = gfor_fndecl_dgemm;
1647 if (sym->ts.kind == gfc_default_real_kind)
1648 gemm_fndecl = gfor_fndecl_cgemm;
1650 gemm_fndecl = gfor_fndecl_zgemm;
1653 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1654 append_args = gfc_chainon_list
1655 (append_args, build_int_cst
1656 (cint, gfc_option.blas_matmul_limit));
1657 append_args = gfc_chainon_list (append_args,
1658 gfc_build_addr_expr (NULL_TREE,
1663 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1664 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1665 append_args = gfc_chainon_list (append_args, null_pointer_node);
1669 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1673 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1693 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1702 gfc_actual_arglist *actual;
1709 gfc_conv_intrinsic_funcall (se, expr);
1713 actual = expr->value.function.actual;
1714 type = gfc_typenode_for_spec (&expr->ts);
1715 /* Initialize the result. */
1716 resvar = gfc_create_var (type, "test");
1718 tmp = convert (type, boolean_true_node);
1720 tmp = convert (type, boolean_false_node);
1721 gfc_add_modify (&se->pre, resvar, tmp);
1723 /* Walk the arguments. */
1724 arrayss = gfc_walk_expr (actual->expr);
1725 gcc_assert (arrayss != gfc_ss_terminator);
1727 /* Initialize the scalarizer. */
1728 gfc_init_loopinfo (&loop);
1729 exit_label = gfc_build_label_decl (NULL_TREE);
1730 TREE_USED (exit_label) = 1;
1731 gfc_add_ss_to_loop (&loop, arrayss);
1733 /* Initialize the loop. */
1734 gfc_conv_ss_startstride (&loop);
1735 gfc_conv_loop_setup (&loop, &expr->where);
1737 gfc_mark_ss_chain_used (arrayss, 1);
1738 /* Generate the loop body. */
1739 gfc_start_scalarized_body (&loop, &body);
1741 /* If the condition matches then set the return value. */
1742 gfc_start_block (&block);
1744 tmp = convert (type, boolean_false_node);
1746 tmp = convert (type, boolean_true_node);
1747 gfc_add_modify (&block, resvar, tmp);
1749 /* And break out of the loop. */
1750 tmp = build1_v (GOTO_EXPR, exit_label);
1751 gfc_add_expr_to_block (&block, tmp);
1753 found = gfc_finish_block (&block);
1755 /* Check this element. */
1756 gfc_init_se (&arrayse, NULL);
1757 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1758 arrayse.ss = arrayss;
1759 gfc_conv_expr_val (&arrayse, actual->expr);
1761 gfc_add_block_to_block (&body, &arrayse.pre);
1762 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1763 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1764 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1765 gfc_add_expr_to_block (&body, tmp);
1766 gfc_add_block_to_block (&body, &arrayse.post);
1768 gfc_trans_scalarizing_loops (&loop, &body);
1770 /* Add the exit label. */
1771 tmp = build1_v (LABEL_EXPR, exit_label);
1772 gfc_add_expr_to_block (&loop.pre, tmp);
1774 gfc_add_block_to_block (&se->pre, &loop.pre);
1775 gfc_add_block_to_block (&se->pre, &loop.post);
1776 gfc_cleanup_loop (&loop);
1781 /* COUNT(A) = Number of true elements in A. */
1783 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1790 gfc_actual_arglist *actual;
1796 gfc_conv_intrinsic_funcall (se, expr);
1800 actual = expr->value.function.actual;
1802 type = gfc_typenode_for_spec (&expr->ts);
1803 /* Initialize the result. */
1804 resvar = gfc_create_var (type, "count");
1805 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1807 /* Walk the arguments. */
1808 arrayss = gfc_walk_expr (actual->expr);
1809 gcc_assert (arrayss != gfc_ss_terminator);
1811 /* Initialize the scalarizer. */
1812 gfc_init_loopinfo (&loop);
1813 gfc_add_ss_to_loop (&loop, arrayss);
1815 /* Initialize the loop. */
1816 gfc_conv_ss_startstride (&loop);
1817 gfc_conv_loop_setup (&loop, &expr->where);
1819 gfc_mark_ss_chain_used (arrayss, 1);
1820 /* Generate the loop body. */
1821 gfc_start_scalarized_body (&loop, &body);
1823 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1824 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1825 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1827 gfc_init_se (&arrayse, NULL);
1828 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1829 arrayse.ss = arrayss;
1830 gfc_conv_expr_val (&arrayse, actual->expr);
1831 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1833 gfc_add_block_to_block (&body, &arrayse.pre);
1834 gfc_add_expr_to_block (&body, tmp);
1835 gfc_add_block_to_block (&body, &arrayse.post);
1837 gfc_trans_scalarizing_loops (&loop, &body);
1839 gfc_add_block_to_block (&se->pre, &loop.pre);
1840 gfc_add_block_to_block (&se->pre, &loop.post);
1841 gfc_cleanup_loop (&loop);
1846 /* Inline implementation of the sum and product intrinsics. */
1848 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1856 gfc_actual_arglist *actual;
1861 gfc_expr *arrayexpr;
1866 gfc_conv_intrinsic_funcall (se, expr);
1870 type = gfc_typenode_for_spec (&expr->ts);
1871 /* Initialize the result. */
1872 resvar = gfc_create_var (type, "val");
1873 if (op == PLUS_EXPR)
1874 tmp = gfc_build_const (type, integer_zero_node);
1876 tmp = gfc_build_const (type, integer_one_node);
1878 gfc_add_modify (&se->pre, resvar, tmp);
1880 /* Walk the arguments. */
1881 actual = expr->value.function.actual;
1882 arrayexpr = actual->expr;
1883 arrayss = gfc_walk_expr (arrayexpr);
1884 gcc_assert (arrayss != gfc_ss_terminator);
1886 actual = actual->next->next;
1887 gcc_assert (actual);
1888 maskexpr = actual->expr;
1889 if (maskexpr && maskexpr->rank != 0)
1891 maskss = gfc_walk_expr (maskexpr);
1892 gcc_assert (maskss != gfc_ss_terminator);
1897 /* Initialize the scalarizer. */
1898 gfc_init_loopinfo (&loop);
1899 gfc_add_ss_to_loop (&loop, arrayss);
1901 gfc_add_ss_to_loop (&loop, maskss);
1903 /* Initialize the loop. */
1904 gfc_conv_ss_startstride (&loop);
1905 gfc_conv_loop_setup (&loop, &expr->where);
1907 gfc_mark_ss_chain_used (arrayss, 1);
1909 gfc_mark_ss_chain_used (maskss, 1);
1910 /* Generate the loop body. */
1911 gfc_start_scalarized_body (&loop, &body);
1913 /* If we have a mask, only add this element if the mask is set. */
1916 gfc_init_se (&maskse, NULL);
1917 gfc_copy_loopinfo_to_se (&maskse, &loop);
1919 gfc_conv_expr_val (&maskse, maskexpr);
1920 gfc_add_block_to_block (&body, &maskse.pre);
1922 gfc_start_block (&block);
1925 gfc_init_block (&block);
1927 /* Do the actual summation/product. */
1928 gfc_init_se (&arrayse, NULL);
1929 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1930 arrayse.ss = arrayss;
1931 gfc_conv_expr_val (&arrayse, arrayexpr);
1932 gfc_add_block_to_block (&block, &arrayse.pre);
1934 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1935 gfc_add_modify (&block, resvar, tmp);
1936 gfc_add_block_to_block (&block, &arrayse.post);
1940 /* We enclose the above in if (mask) {...} . */
1941 tmp = gfc_finish_block (&block);
1943 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1946 tmp = gfc_finish_block (&block);
1947 gfc_add_expr_to_block (&body, tmp);
1949 gfc_trans_scalarizing_loops (&loop, &body);
1951 /* For a scalar mask, enclose the loop in an if statement. */
1952 if (maskexpr && maskss == NULL)
1954 gfc_init_se (&maskse, NULL);
1955 gfc_conv_expr_val (&maskse, maskexpr);
1956 gfc_init_block (&block);
1957 gfc_add_block_to_block (&block, &loop.pre);
1958 gfc_add_block_to_block (&block, &loop.post);
1959 tmp = gfc_finish_block (&block);
1961 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1962 gfc_add_expr_to_block (&block, tmp);
1963 gfc_add_block_to_block (&se->pre, &block);
1967 gfc_add_block_to_block (&se->pre, &loop.pre);
1968 gfc_add_block_to_block (&se->pre, &loop.post);
1971 gfc_cleanup_loop (&loop);
1977 /* Inline implementation of the dot_product intrinsic. This function
1978 is based on gfc_conv_intrinsic_arith (the previous function). */
1980 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1988 gfc_actual_arglist *actual;
1989 gfc_ss *arrayss1, *arrayss2;
1990 gfc_se arrayse1, arrayse2;
1991 gfc_expr *arrayexpr1, *arrayexpr2;
1993 type = gfc_typenode_for_spec (&expr->ts);
1995 /* Initialize the result. */
1996 resvar = gfc_create_var (type, "val");
1997 if (expr->ts.type == BT_LOGICAL)
1998 tmp = build_int_cst (type, 0);
2000 tmp = gfc_build_const (type, integer_zero_node);
2002 gfc_add_modify (&se->pre, resvar, tmp);
2004 /* Walk argument #1. */
2005 actual = expr->value.function.actual;
2006 arrayexpr1 = actual->expr;
2007 arrayss1 = gfc_walk_expr (arrayexpr1);
2008 gcc_assert (arrayss1 != gfc_ss_terminator);
2010 /* Walk argument #2. */
2011 actual = actual->next;
2012 arrayexpr2 = actual->expr;
2013 arrayss2 = gfc_walk_expr (arrayexpr2);
2014 gcc_assert (arrayss2 != gfc_ss_terminator);
2016 /* Initialize the scalarizer. */
2017 gfc_init_loopinfo (&loop);
2018 gfc_add_ss_to_loop (&loop, arrayss1);
2019 gfc_add_ss_to_loop (&loop, arrayss2);
2021 /* Initialize the loop. */
2022 gfc_conv_ss_startstride (&loop);
2023 gfc_conv_loop_setup (&loop, &expr->where);
2025 gfc_mark_ss_chain_used (arrayss1, 1);
2026 gfc_mark_ss_chain_used (arrayss2, 1);
2028 /* Generate the loop body. */
2029 gfc_start_scalarized_body (&loop, &body);
2030 gfc_init_block (&block);
2032 /* Make the tree expression for [conjg(]array1[)]. */
2033 gfc_init_se (&arrayse1, NULL);
2034 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2035 arrayse1.ss = arrayss1;
2036 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2037 if (expr->ts.type == BT_COMPLEX)
2038 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2039 gfc_add_block_to_block (&block, &arrayse1.pre);
2041 /* Make the tree expression for array2. */
2042 gfc_init_se (&arrayse2, NULL);
2043 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2044 arrayse2.ss = arrayss2;
2045 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2046 gfc_add_block_to_block (&block, &arrayse2.pre);
2048 /* Do the actual product and sum. */
2049 if (expr->ts.type == BT_LOGICAL)
2051 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2052 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2056 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2057 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2059 gfc_add_modify (&block, resvar, tmp);
2061 /* Finish up the loop block and the loop. */
2062 tmp = gfc_finish_block (&block);
2063 gfc_add_expr_to_block (&body, tmp);
2065 gfc_trans_scalarizing_loops (&loop, &body);
2066 gfc_add_block_to_block (&se->pre, &loop.pre);
2067 gfc_add_block_to_block (&se->pre, &loop.post);
2068 gfc_cleanup_loop (&loop);
2075 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
2079 stmtblock_t ifblock;
2080 stmtblock_t elseblock;
2088 gfc_actual_arglist *actual;
2093 gfc_expr *arrayexpr;
2100 gfc_conv_intrinsic_funcall (se, expr);
2104 /* Initialize the result. */
2105 pos = gfc_create_var (gfc_array_index_type, "pos");
2106 offset = gfc_create_var (gfc_array_index_type, "offset");
2107 type = gfc_typenode_for_spec (&expr->ts);
2109 /* Walk the arguments. */
2110 actual = expr->value.function.actual;
2111 arrayexpr = actual->expr;
2112 arrayss = gfc_walk_expr (arrayexpr);
2113 gcc_assert (arrayss != gfc_ss_terminator);
2115 actual = actual->next->next;
2116 gcc_assert (actual);
2117 maskexpr = actual->expr;
2118 if (maskexpr && maskexpr->rank != 0)
2120 maskss = gfc_walk_expr (maskexpr);
2121 gcc_assert (maskss != gfc_ss_terminator);
2126 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2127 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2128 switch (arrayexpr->ts.type)
2131 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
2135 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2136 arrayexpr->ts.kind);
2143 /* We start with the most negative possible value for MAXLOC, and the most
2144 positive possible value for MINLOC. The most negative possible value is
2145 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2146 possible value is HUGE in both cases. */
2148 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2149 gfc_add_modify (&se->pre, limit, tmp);
2151 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2152 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2153 build_int_cst (type, 1));
2155 /* Initialize the scalarizer. */
2156 gfc_init_loopinfo (&loop);
2157 gfc_add_ss_to_loop (&loop, arrayss);
2159 gfc_add_ss_to_loop (&loop, maskss);
2161 /* Initialize the loop. */
2162 gfc_conv_ss_startstride (&loop);
2163 gfc_conv_loop_setup (&loop, &expr->where);
2165 gcc_assert (loop.dimen == 1);
2167 /* Initialize the position to zero, following Fortran 2003. We are free
2168 to do this because Fortran 95 allows the result of an entirely false
2169 mask to be processor dependent. */
2170 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2172 gfc_mark_ss_chain_used (arrayss, 1);
2174 gfc_mark_ss_chain_used (maskss, 1);
2175 /* Generate the loop body. */
2176 gfc_start_scalarized_body (&loop, &body);
2178 /* If we have a mask, only check this element if the mask is set. */
2181 gfc_init_se (&maskse, NULL);
2182 gfc_copy_loopinfo_to_se (&maskse, &loop);
2184 gfc_conv_expr_val (&maskse, maskexpr);
2185 gfc_add_block_to_block (&body, &maskse.pre);
2187 gfc_start_block (&block);
2190 gfc_init_block (&block);
2192 /* Compare with the current limit. */
2193 gfc_init_se (&arrayse, NULL);
2194 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2195 arrayse.ss = arrayss;
2196 gfc_conv_expr_val (&arrayse, arrayexpr);
2197 gfc_add_block_to_block (&block, &arrayse.pre);
2199 /* We do the following if this is a more extreme value. */
2200 gfc_start_block (&ifblock);
2202 /* Assign the value to the limit... */
2203 gfc_add_modify (&ifblock, limit, arrayse.expr);
2205 /* Remember where we are. An offset must be added to the loop
2206 counter to obtain the required position. */
2208 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2209 gfc_index_one_node, loop.from[0]);
2211 tmp = build_int_cst (gfc_array_index_type, 1);
2213 gfc_add_modify (&block, offset, tmp);
2215 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2216 loop.loopvar[0], offset);
2217 gfc_add_modify (&ifblock, pos, tmp);
2219 ifbody = gfc_finish_block (&ifblock);
2221 /* If it is a more extreme value or pos is still zero and the value
2222 equal to the limit. */
2223 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2224 fold_build2 (EQ_EXPR, boolean_type_node,
2225 pos, gfc_index_zero_node),
2226 fold_build2 (EQ_EXPR, boolean_type_node,
2227 arrayse.expr, limit));
2228 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2229 fold_build2 (op, boolean_type_node,
2230 arrayse.expr, limit), tmp);
2231 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2232 gfc_add_expr_to_block (&block, tmp);
2236 /* We enclose the above in if (mask) {...}. */
2237 tmp = gfc_finish_block (&block);
2239 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2242 tmp = gfc_finish_block (&block);
2243 gfc_add_expr_to_block (&body, tmp);
2245 gfc_trans_scalarizing_loops (&loop, &body);
2247 /* For a scalar mask, enclose the loop in an if statement. */
2248 if (maskexpr && maskss == NULL)
2250 gfc_init_se (&maskse, NULL);
2251 gfc_conv_expr_val (&maskse, maskexpr);
2252 gfc_init_block (&block);
2253 gfc_add_block_to_block (&block, &loop.pre);
2254 gfc_add_block_to_block (&block, &loop.post);
2255 tmp = gfc_finish_block (&block);
2257 /* For the else part of the scalar mask, just initialize
2258 the pos variable the same way as above. */
2260 gfc_init_block (&elseblock);
2261 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2262 elsetmp = gfc_finish_block (&elseblock);
2264 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2265 gfc_add_expr_to_block (&block, tmp);
2266 gfc_add_block_to_block (&se->pre, &block);
2270 gfc_add_block_to_block (&se->pre, &loop.pre);
2271 gfc_add_block_to_block (&se->pre, &loop.post);
2273 gfc_cleanup_loop (&loop);
2275 se->expr = convert (type, pos);
2279 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2288 gfc_actual_arglist *actual;
2293 gfc_expr *arrayexpr;
2299 gfc_conv_intrinsic_funcall (se, expr);
2303 type = gfc_typenode_for_spec (&expr->ts);
2304 /* Initialize the result. */
2305 limit = gfc_create_var (type, "limit");
2306 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2307 switch (expr->ts.type)
2310 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2314 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2321 /* We start with the most negative possible value for MAXVAL, and the most
2322 positive possible value for MINVAL. The most negative possible value is
2323 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2324 possible value is HUGE in both cases. */
2326 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2328 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2329 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2330 tmp, build_int_cst (type, 1));
2332 gfc_add_modify (&se->pre, limit, tmp);
2334 /* Walk the arguments. */
2335 actual = expr->value.function.actual;
2336 arrayexpr = actual->expr;
2337 arrayss = gfc_walk_expr (arrayexpr);
2338 gcc_assert (arrayss != gfc_ss_terminator);
2340 actual = actual->next->next;
2341 gcc_assert (actual);
2342 maskexpr = actual->expr;
2343 if (maskexpr && maskexpr->rank != 0)
2345 maskss = gfc_walk_expr (maskexpr);
2346 gcc_assert (maskss != gfc_ss_terminator);
2351 /* Initialize the scalarizer. */
2352 gfc_init_loopinfo (&loop);
2353 gfc_add_ss_to_loop (&loop, arrayss);
2355 gfc_add_ss_to_loop (&loop, maskss);
2357 /* Initialize the loop. */
2358 gfc_conv_ss_startstride (&loop);
2359 gfc_conv_loop_setup (&loop, &expr->where);
2361 gfc_mark_ss_chain_used (arrayss, 1);
2363 gfc_mark_ss_chain_used (maskss, 1);
2364 /* Generate the loop body. */
2365 gfc_start_scalarized_body (&loop, &body);
2367 /* If we have a mask, only add this element if the mask is set. */
2370 gfc_init_se (&maskse, NULL);
2371 gfc_copy_loopinfo_to_se (&maskse, &loop);
2373 gfc_conv_expr_val (&maskse, maskexpr);
2374 gfc_add_block_to_block (&body, &maskse.pre);
2376 gfc_start_block (&block);
2379 gfc_init_block (&block);
2381 /* Compare with the current limit. */
2382 gfc_init_se (&arrayse, NULL);
2383 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2384 arrayse.ss = arrayss;
2385 gfc_conv_expr_val (&arrayse, arrayexpr);
2386 gfc_add_block_to_block (&block, &arrayse.pre);
2388 /* Assign the value to the limit... */
2389 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2391 /* If it is a more extreme value. */
2392 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2393 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2394 gfc_add_expr_to_block (&block, tmp);
2395 gfc_add_block_to_block (&block, &arrayse.post);
2397 tmp = gfc_finish_block (&block);
2399 /* We enclose the above in if (mask) {...}. */
2400 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2401 gfc_add_expr_to_block (&body, tmp);
2403 gfc_trans_scalarizing_loops (&loop, &body);
2405 /* For a scalar mask, enclose the loop in an if statement. */
2406 if (maskexpr && maskss == NULL)
2408 gfc_init_se (&maskse, NULL);
2409 gfc_conv_expr_val (&maskse, maskexpr);
2410 gfc_init_block (&block);
2411 gfc_add_block_to_block (&block, &loop.pre);
2412 gfc_add_block_to_block (&block, &loop.post);
2413 tmp = gfc_finish_block (&block);
2415 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2416 gfc_add_expr_to_block (&block, tmp);
2417 gfc_add_block_to_block (&se->pre, &block);
2421 gfc_add_block_to_block (&se->pre, &loop.pre);
2422 gfc_add_block_to_block (&se->pre, &loop.post);
2425 gfc_cleanup_loop (&loop);
2430 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2432 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2438 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2439 type = TREE_TYPE (args[0]);
2441 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2442 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2443 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2444 build_int_cst (type, 0));
2445 type = gfc_typenode_for_spec (&expr->ts);
2446 se->expr = convert (type, tmp);
2449 /* Generate code to perform the specified operation. */
2451 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2455 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2456 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2461 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2465 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2466 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2469 /* Set or clear a single bit. */
2471 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2478 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2479 type = TREE_TYPE (args[0]);
2481 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2487 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2489 se->expr = fold_build2 (op, type, args[0], tmp);
2492 /* Extract a sequence of bits.
2493 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2495 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2502 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2503 type = TREE_TYPE (args[0]);
2505 mask = build_int_cst (type, -1);
2506 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2507 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2509 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2511 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2514 /* RSHIFT (I, SHIFT) = I >> SHIFT
2515 LSHIFT (I, SHIFT) = I << SHIFT */
2517 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2521 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2523 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2524 TREE_TYPE (args[0]), args[0], args[1]);
2527 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2529 : ((shift >= 0) ? i << shift : i >> -shift)
2530 where all shifts are logical shifts. */
2532 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2544 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2545 type = TREE_TYPE (args[0]);
2546 utype = unsigned_type_for (type);
2548 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2550 /* Left shift if positive. */
2551 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2553 /* Right shift if negative.
2554 We convert to an unsigned type because we want a logical shift.
2555 The standard doesn't define the case of shifting negative
2556 numbers, and we try to be compatible with other compilers, most
2557 notably g77, here. */
2558 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2559 convert (utype, args[0]), width));
2561 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2562 build_int_cst (TREE_TYPE (args[1]), 0));
2563 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2565 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2566 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2568 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2569 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2571 se->expr = fold_build3 (COND_EXPR, type, cond,
2572 build_int_cst (type, 0), tmp);
2576 /* Circular shift. AKA rotate or barrel shift. */
2579 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2587 unsigned int num_args;
2589 num_args = gfc_intrinsic_argument_list_length (expr);
2590 args = (tree *) alloca (sizeof (tree) * num_args);
2592 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2596 /* Use a library function for the 3 parameter version. */
2597 tree int4type = gfc_get_int_type (4);
2599 type = TREE_TYPE (args[0]);
2600 /* We convert the first argument to at least 4 bytes, and
2601 convert back afterwards. This removes the need for library
2602 functions for all argument sizes, and function will be
2603 aligned to at least 32 bits, so there's no loss. */
2604 if (expr->ts.kind < 4)
2605 args[0] = convert (int4type, args[0]);
2607 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2608 need loads of library functions. They cannot have values >
2609 BIT_SIZE (I) so the conversion is safe. */
2610 args[1] = convert (int4type, args[1]);
2611 args[2] = convert (int4type, args[2]);
2613 switch (expr->ts.kind)
2618 tmp = gfor_fndecl_math_ishftc4;
2621 tmp = gfor_fndecl_math_ishftc8;
2624 tmp = gfor_fndecl_math_ishftc16;
2629 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2630 /* Convert the result back to the original type, if we extended
2631 the first argument's width above. */
2632 if (expr->ts.kind < 4)
2633 se->expr = convert (type, se->expr);
2637 type = TREE_TYPE (args[0]);
2639 /* Rotate left if positive. */
2640 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2642 /* Rotate right if negative. */
2643 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2644 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2646 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2647 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2648 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2650 /* Do nothing if shift == 0. */
2651 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2652 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2655 /* The length of a character string. */
2657 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2667 gcc_assert (!se->ss);
2669 arg = expr->value.function.actual->expr;
2671 type = gfc_typenode_for_spec (&expr->ts);
2672 switch (arg->expr_type)
2675 len = build_int_cst (NULL_TREE, arg->value.character.length);
2679 /* Obtain the string length from the function used by
2680 trans-array.c(gfc_trans_array_constructor). */
2682 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2686 if (arg->ref == NULL
2687 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2689 /* This doesn't catch all cases.
2690 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2691 and the surrounding thread. */
2692 sym = arg->symtree->n.sym;
2693 decl = gfc_get_symbol_decl (sym);
2694 if (decl == current_function_decl && sym->attr.function
2695 && (sym->result == sym))
2696 decl = gfc_get_fake_result_decl (sym, 0);
2698 len = sym->ts.cl->backend_decl;
2703 /* Otherwise fall through. */
2706 /* Anybody stupid enough to do this deserves inefficient code. */
2707 ss = gfc_walk_expr (arg);
2708 gfc_init_se (&argse, se);
2709 if (ss == gfc_ss_terminator)
2710 gfc_conv_expr (&argse, arg);
2712 gfc_conv_expr_descriptor (&argse, arg, ss);
2713 gfc_add_block_to_block (&se->pre, &argse.pre);
2714 gfc_add_block_to_block (&se->post, &argse.post);
2715 len = argse.string_length;
2718 se->expr = convert (type, len);
2721 /* The length of a character string not including trailing blanks. */
2723 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2725 int kind = expr->value.function.actual->expr->ts.kind;
2726 tree args[2], type, fndecl;
2728 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2729 type = gfc_typenode_for_spec (&expr->ts);
2732 fndecl = gfor_fndecl_string_len_trim;
2734 fndecl = gfor_fndecl_string_len_trim_char4;
2738 se->expr = build_call_expr (fndecl, 2, args[0], args[1]);
2739 se->expr = convert (type, se->expr);
2743 /* Returns the starting position of a substring within a string. */
2746 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2749 tree logical4_type_node = gfc_get_logical_type (4);
2753 unsigned int num_args;
2755 args = (tree *) alloca (sizeof (tree) * 5);
2757 /* Get number of arguments; characters count double due to the
2758 string length argument. Kind= is not passed to the library
2759 and thus ignored. */
2760 if (expr->value.function.actual->next->next->expr == NULL)
2765 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2766 type = gfc_typenode_for_spec (&expr->ts);
2769 args[4] = build_int_cst (logical4_type_node, 0);
2771 args[4] = convert (logical4_type_node, args[4]);
2773 fndecl = build_addr (function, current_function_decl);
2774 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
2776 se->expr = convert (type, se->expr);
2780 /* The ascii value for a single character. */
2782 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2784 tree args[2], type, pchartype;
2786 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2787 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
2788 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
2789 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
2790 type = gfc_typenode_for_spec (&expr->ts);
2792 se->expr = build_fold_indirect_ref (args[1]);
2793 se->expr = convert (type, se->expr);
2797 /* Intrinsic ISNAN calls __builtin_isnan. */
2800 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
2804 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2805 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
2806 STRIP_TYPE_NOPS (se->expr);
2807 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2811 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
2812 their argument against a constant integer value. */
2815 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
2819 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2820 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
2821 arg, build_int_cst (TREE_TYPE (arg), value));
2826 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2829 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2837 unsigned int num_args;
2839 num_args = gfc_intrinsic_argument_list_length (expr);
2840 args = (tree *) alloca (sizeof (tree) * num_args);
2842 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2843 if (expr->ts.type != BT_CHARACTER)
2851 /* We do the same as in the non-character case, but the argument
2852 list is different because of the string length arguments. We
2853 also have to set the string length for the result. */
2859 se->string_length = len;
2861 type = TREE_TYPE (tsource);
2862 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2866 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
2868 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
2870 tree arg, type, tmp;
2873 switch (expr->ts.kind)
2876 frexp = BUILT_IN_FREXPF;
2879 frexp = BUILT_IN_FREXP;
2883 frexp = BUILT_IN_FREXPL;
2889 type = gfc_typenode_for_spec (&expr->ts);
2890 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2891 tmp = gfc_create_var (integer_type_node, NULL);
2892 se->expr = build_call_expr (built_in_decls[frexp], 2,
2893 fold_convert (type, arg),
2894 build_fold_addr_expr (tmp));
2895 se->expr = fold_convert (type, se->expr);
2899 /* NEAREST (s, dir) is translated into
2900 tmp = copysign (INF, dir);
2901 return nextafter (s, tmp);
2904 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
2906 tree args[2], type, tmp;
2907 int nextafter, copysign, inf;
2909 switch (expr->ts.kind)
2912 nextafter = BUILT_IN_NEXTAFTERF;
2913 copysign = BUILT_IN_COPYSIGNF;
2914 inf = BUILT_IN_INFF;
2917 nextafter = BUILT_IN_NEXTAFTER;
2918 copysign = BUILT_IN_COPYSIGN;
2923 nextafter = BUILT_IN_NEXTAFTERL;
2924 copysign = BUILT_IN_COPYSIGNL;
2925 inf = BUILT_IN_INFL;
2931 type = gfc_typenode_for_spec (&expr->ts);
2932 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2933 tmp = build_call_expr (built_in_decls[copysign], 2,
2934 build_call_expr (built_in_decls[inf], 0),
2935 fold_convert (type, args[1]));
2936 se->expr = build_call_expr (built_in_decls[nextafter], 2,
2937 fold_convert (type, args[0]), tmp);
2938 se->expr = fold_convert (type, se->expr);
2942 /* SPACING (s) is translated into
2950 e = MAX_EXPR (e, emin);
2951 res = scalbn (1., e);
2955 where prec is the precision of s, gfc_real_kinds[k].digits,
2956 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
2957 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
2960 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2962 tree arg, type, prec, emin, tiny, res, e;
2964 int frexp, scalbn, k;
2967 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
2968 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
2969 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
2970 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind);
2972 switch (expr->ts.kind)
2975 frexp = BUILT_IN_FREXPF;
2976 scalbn = BUILT_IN_SCALBNF;
2979 frexp = BUILT_IN_FREXP;
2980 scalbn = BUILT_IN_SCALBN;
2984 frexp = BUILT_IN_FREXPL;
2985 scalbn = BUILT_IN_SCALBNL;
2991 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2992 arg = gfc_evaluate_now (arg, &se->pre);
2994 type = gfc_typenode_for_spec (&expr->ts);
2995 e = gfc_create_var (integer_type_node, NULL);
2996 res = gfc_create_var (type, NULL);
2999 /* Build the block for s /= 0. */
3000 gfc_start_block (&block);
3001 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3002 build_fold_addr_expr (e));
3003 gfc_add_expr_to_block (&block, tmp);
3005 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3006 gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3009 tmp = build_call_expr (built_in_decls[scalbn], 2,
3010 build_real_from_int_cst (type, integer_one_node), e);
3011 gfc_add_modify (&block, res, tmp);
3013 /* Finish by building the IF statement. */
3014 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3015 build_real_from_int_cst (type, integer_zero_node));
3016 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3017 gfc_finish_block (&block));
3019 gfc_add_expr_to_block (&se->pre, tmp);
3024 /* RRSPACING (s) is translated into
3031 x = scalbn (x, precision - e);
3035 where precision is gfc_real_kinds[k].digits. */
3038 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3040 tree arg, type, e, x, cond, stmt, tmp;
3041 int frexp, scalbn, fabs, prec, k;
3044 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3045 prec = gfc_real_kinds[k].digits;
3046 switch (expr->ts.kind)
3049 frexp = BUILT_IN_FREXPF;
3050 scalbn = BUILT_IN_SCALBNF;
3051 fabs = BUILT_IN_FABSF;
3054 frexp = BUILT_IN_FREXP;
3055 scalbn = BUILT_IN_SCALBN;
3056 fabs = BUILT_IN_FABS;
3060 frexp = BUILT_IN_FREXPL;
3061 scalbn = BUILT_IN_SCALBNL;
3062 fabs = BUILT_IN_FABSL;
3068 type = gfc_typenode_for_spec (&expr->ts);
3069 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3070 arg = gfc_evaluate_now (arg, &se->pre);
3072 e = gfc_create_var (integer_type_node, NULL);
3073 x = gfc_create_var (type, NULL);
3074 gfc_add_modify (&se->pre, x,
3075 build_call_expr (built_in_decls[fabs], 1, arg));
3078 gfc_start_block (&block);
3079 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3080 build_fold_addr_expr (e));
3081 gfc_add_expr_to_block (&block, tmp);
3083 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3084 build_int_cst (NULL_TREE, prec), e);
3085 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3086 gfc_add_modify (&block, x, tmp);
3087 stmt = gfc_finish_block (&block);
3089 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3090 build_real_from_int_cst (type, integer_zero_node));
3091 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3092 gfc_add_expr_to_block (&se->pre, tmp);
3094 se->expr = fold_convert (type, x);
3098 /* SCALE (s, i) is translated into scalbn (s, i). */
3100 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3105 switch (expr->ts.kind)
3108 scalbn = BUILT_IN_SCALBNF;
3111 scalbn = BUILT_IN_SCALBN;
3115 scalbn = BUILT_IN_SCALBNL;
3121 type = gfc_typenode_for_spec (&expr->ts);
3122 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3123 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3124 fold_convert (type, args[0]),
3125 fold_convert (integer_type_node, args[1]));
3126 se->expr = fold_convert (type, se->expr);
3130 /* SET_EXPONENT (s, i) is translated into
3131 scalbn (frexp (s, &dummy_int), i). */
3133 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3135 tree args[2], type, tmp;
3138 switch (expr->ts.kind)
3141 frexp = BUILT_IN_FREXPF;
3142 scalbn = BUILT_IN_SCALBNF;
3145 frexp = BUILT_IN_FREXP;
3146 scalbn = BUILT_IN_SCALBN;
3150 frexp = BUILT_IN_FREXPL;
3151 scalbn = BUILT_IN_SCALBNL;
3157 type = gfc_typenode_for_spec (&expr->ts);
3158 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3160 tmp = gfc_create_var (integer_type_node, NULL);
3161 tmp = build_call_expr (built_in_decls[frexp], 2,
3162 fold_convert (type, args[0]),
3163 build_fold_addr_expr (tmp));
3164 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3165 fold_convert (integer_type_node, args[1]));
3166 se->expr = fold_convert (type, se->expr);
3171 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3173 gfc_actual_arglist *actual;
3181 gfc_init_se (&argse, NULL);
3182 actual = expr->value.function.actual;
3184 ss = gfc_walk_expr (actual->expr);
3185 gcc_assert (ss != gfc_ss_terminator);
3186 argse.want_pointer = 1;
3187 argse.data_not_needed = 1;
3188 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3189 gfc_add_block_to_block (&se->pre, &argse.pre);
3190 gfc_add_block_to_block (&se->post, &argse.post);
3191 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3193 /* Build the call to size0. */
3194 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3196 actual = actual->next;
3200 gfc_init_se (&argse, NULL);
3201 gfc_conv_expr_type (&argse, actual->expr,
3202 gfc_array_index_type);
3203 gfc_add_block_to_block (&se->pre, &argse.pre);
3205 /* Build the call to size1. */
3206 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3209 /* Unusually, for an intrinsic, size does not exclude
3210 an optional arg2, so we must test for it. */
3211 if (actual->expr->expr_type == EXPR_VARIABLE
3212 && actual->expr->symtree->n.sym->attr.dummy
3213 && actual->expr->symtree->n.sym->attr.optional)
3216 gfc_init_se (&argse, NULL);
3217 argse.want_pointer = 1;
3218 argse.data_not_needed = 1;
3219 gfc_conv_expr (&argse, actual->expr);
3220 gfc_add_block_to_block (&se->pre, &argse.pre);
3221 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3222 argse.expr, null_pointer_node);
3223 tmp = gfc_evaluate_now (tmp, &se->pre);
3224 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3225 tmp, fncall1, fncall0);
3233 type = gfc_typenode_for_spec (&expr->ts);
3234 se->expr = convert (type, se->expr);
3238 /* Helper function to compute the size of a character variable,
3239 excluding the terminating null characters. The result has
3240 gfc_array_index_type type. */
3243 size_of_string_in_bytes (int kind, tree string_length)
3246 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3248 bytesize = build_int_cst (gfc_array_index_type,
3249 gfc_character_kinds[i].bit_size / 8);
3251 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3252 fold_convert (gfc_array_index_type, string_length));
3257 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3270 arg = expr->value.function.actual->expr;
3272 gfc_init_se (&argse, NULL);
3273 ss = gfc_walk_expr (arg);
3275 if (ss == gfc_ss_terminator)
3277 gfc_conv_expr_reference (&argse, arg);
3278 source = argse.expr;
3280 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3282 /* Obtain the source word length. */
3283 if (arg->ts.type == BT_CHARACTER)
3284 se->expr = size_of_string_in_bytes (arg->ts.kind,
3285 argse.string_length);
3287 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
3291 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3292 argse.want_pointer = 0;
3293 gfc_conv_expr_descriptor (&argse, arg, ss);
3294 source = gfc_conv_descriptor_data_get (argse.expr);
3295 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3297 /* Obtain the argument's word length. */
3298 if (arg->ts.type == BT_CHARACTER)
3299 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3301 tmp = fold_convert (gfc_array_index_type,
3302 size_in_bytes (type));
3303 gfc_add_modify (&argse.pre, source_bytes, tmp);
3305 /* Obtain the size of the array in bytes. */
3306 for (n = 0; n < arg->rank; n++)
3309 idx = gfc_rank_cst[n];
3310 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3311 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3312 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3314 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3315 tmp, gfc_index_one_node);
3316 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3318 gfc_add_modify (&argse.pre, source_bytes, tmp);
3320 se->expr = source_bytes;
3323 gfc_add_block_to_block (&se->pre, &argse.pre);
3327 /* Intrinsic string comparison functions. */
3330 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
3334 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3337 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
3338 expr->value.function.actual->expr->ts.kind);
3339 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3340 build_int_cst (TREE_TYPE (se->expr), 0));
3343 /* Generate a call to the adjustl/adjustr library function. */
3345 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3353 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3356 type = TREE_TYPE (args[2]);
3357 var = gfc_conv_string_tmp (se, type, len);
3360 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3361 gfc_add_expr_to_block (&se->pre, tmp);
3363 se->string_length = len;
3367 /* Array transfer statement.
3368 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3370 typeof<DEST> = typeof<MOLD>
3372 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3373 sizeof (DEST(0) * SIZE). */
3376 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
3391 gfc_actual_arglist *arg;
3398 gcc_assert (se->loop);
3399 info = &se->ss->data.info;
3401 /* Convert SOURCE. The output from this stage is:-
3402 source_bytes = length of the source in bytes
3403 source = pointer to the source data. */
3404 arg = expr->value.function.actual;
3405 gfc_init_se (&argse, NULL);
3406 ss = gfc_walk_expr (arg->expr);
3408 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3410 /* Obtain the pointer to source and the length of source in bytes. */
3411 if (ss == gfc_ss_terminator)
3413 gfc_conv_expr_reference (&argse, arg->expr);
3414 source = argse.expr;
3416 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3418 /* Obtain the source word length. */
3419 if (arg->expr->ts.type == BT_CHARACTER)
3420 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3421 argse.string_length);
3423 tmp = fold_convert (gfc_array_index_type,
3424 size_in_bytes (source_type));
3428 argse.want_pointer = 0;
3429 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3430 source = gfc_conv_descriptor_data_get (argse.expr);
3431 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3433 /* Repack the source if not a full variable array. */
3434 if (!(arg->expr->expr_type == EXPR_VARIABLE
3435 && arg->expr->ref->u.ar.type == AR_FULL))
3437 tmp = build_fold_addr_expr (argse.expr);
3439 if (gfc_option.warn_array_temp)
3440 gfc_warning ("Creating array temporary at %L", &expr->where);
3442 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3443 source = gfc_evaluate_now (source, &argse.pre);
3445 /* Free the temporary. */
3446 gfc_start_block (&block);
3447 tmp = gfc_call_free (convert (pvoid_type_node, source));
3448 gfc_add_expr_to_block (&block, tmp);
3449 stmt = gfc_finish_block (&block);
3451 /* Clean up if it was repacked. */
3452 gfc_init_block (&block);
3453 tmp = gfc_conv_array_data (argse.expr);
3454 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3455 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3456 gfc_add_expr_to_block (&block, tmp);
3457 gfc_add_block_to_block (&block, &se->post);
3458 gfc_init_block (&se->post);
3459 gfc_add_block_to_block (&se->post, &block);
3462 /* Obtain the source word length. */
3463 if (arg->expr->ts.type == BT_CHARACTER)
3464 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
3465 argse.string_length);
3467 tmp = fold_convert (gfc_array_index_type,
3468 size_in_bytes (source_type));
3470 /* Obtain the size of the array in bytes. */
3471 extent = gfc_create_var (gfc_array_index_type, NULL);
3472 for (n = 0; n < arg->expr->rank; n++)
3475 idx = gfc_rank_cst[n];
3476 gfc_add_modify (&argse.pre, source_bytes, tmp);
3477 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3478 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3479 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3480 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3482 gfc_add_modify (&argse.pre, extent, tmp);
3483 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3484 extent, gfc_index_one_node);
3485 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3490 gfc_add_modify (&argse.pre, source_bytes, tmp);
3491 gfc_add_block_to_block (&se->pre, &argse.pre);
3492 gfc_add_block_to_block (&se->post, &argse.post);
3494 /* Now convert MOLD. The outputs are:
3495 mold_type = the TREE type of MOLD
3496 dest_word_len = destination word length in bytes. */
3499 gfc_init_se (&argse, NULL);
3500 ss = gfc_walk_expr (arg->expr);
3502 if (ss == gfc_ss_terminator)
3504 gfc_conv_expr_reference (&argse, arg->expr);
3505 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3509 gfc_init_se (&argse, NULL);
3510 argse.want_pointer = 0;
3511 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3512 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3515 if (arg->expr->ts.type == BT_CHARACTER)
3517 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
3518 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3521 tmp = fold_convert (gfc_array_index_type,
3522 size_in_bytes (mold_type));
3524 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3525 gfc_add_modify (&se->pre, dest_word_len, tmp);
3527 /* Finally convert SIZE, if it is present. */
3529 size_words = gfc_create_var (gfc_array_index_type, NULL);
3533 gfc_init_se (&argse, NULL);
3534 gfc_conv_expr_reference (&argse, arg->expr);
3535 tmp = convert (gfc_array_index_type,
3536 build_fold_indirect_ref (argse.expr));
3537 gfc_add_block_to_block (&se->pre, &argse.pre);
3538 gfc_add_block_to_block (&se->post, &argse.post);
3543 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3544 if (tmp != NULL_TREE)
3546 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3547 tmp, dest_word_len);
3548 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3554 gfc_add_modify (&se->pre, size_bytes, tmp);
3555 gfc_add_modify (&se->pre, size_words,
3556 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3557 size_bytes, dest_word_len));
3559 /* Evaluate the bounds of the result. If the loop range exists, we have
3560 to check if it is too large. If so, we modify loop->to be consistent
3561 with min(size, size(source)). Otherwise, size is made consistent with
3562 the loop range, so that the right number of bytes is transferred.*/
3563 n = se->loop->order[0];
3564 if (se->loop->to[n] != NULL_TREE)
3566 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3567 se->loop->to[n], se->loop->from[n]);
3568 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3569 tmp, gfc_index_one_node);
3570 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3572 gfc_add_modify (&se->pre, size_words, tmp);
3573 gfc_add_modify (&se->pre, size_bytes,
3574 fold_build2 (MULT_EXPR, gfc_array_index_type,
3575 size_words, dest_word_len));
3576 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3577 size_words, se->loop->from[n]);
3578 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3579 upper, gfc_index_one_node);
3583 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3584 size_words, gfc_index_one_node);
3585 se->loop->from[n] = gfc_index_zero_node;
3588 se->loop->to[n] = upper;
3590 /* Build a destination descriptor, using the pointer, source, as the
3591 data field. This is already allocated so set callee_alloc.
3592 FIXME callee_alloc is not set! */
3594 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3595 info, mold_type, false, true, false,
3598 /* Cast the pointer to the result. */
3599 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3600 tmp = fold_convert (pvoid_type_node, tmp);
3602 /* Use memcpy to do the transfer. */
3603 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3606 fold_convert (pvoid_type_node, source),
3608 gfc_add_expr_to_block (&se->pre, tmp);
3610 se->expr = info->descriptor;
3611 if (expr->ts.type == BT_CHARACTER)
3612 se->string_length = dest_word_len;
3616 /* Scalar transfer statement.
3617 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3620 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3622 gfc_actual_arglist *arg;
3629 /* Get a pointer to the source. */
3630 arg = expr->value.function.actual;
3631 ss = gfc_walk_expr (arg->expr);
3632 gfc_init_se (&argse, NULL);
3633 if (ss == gfc_ss_terminator)
3634 gfc_conv_expr_reference (&argse, arg->expr);
3636 gfc_conv_array_parameter (&argse, arg->expr, ss, 1, NULL, NULL);
3637 gfc_add_block_to_block (&se->pre, &argse.pre);
3638 gfc_add_block_to_block (&se->post, &argse.post);
3642 type = gfc_typenode_for_spec (&expr->ts);
3644 if (expr->ts.type == BT_CHARACTER)
3646 ptr = convert (build_pointer_type (type), ptr);
3647 gfc_init_se (&argse, NULL);
3648 gfc_conv_expr (&argse, arg->expr);
3649 gfc_add_block_to_block (&se->pre, &argse.pre);
3650 gfc_add_block_to_block (&se->post, &argse.post);
3652 se->string_length = argse.string_length;
3657 tmpdecl = gfc_create_var (type, "transfer");
3658 moldsize = size_in_bytes (type);
3660 /* Use memcpy to do the transfer. */
3661 tmp = fold_build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3662 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3663 fold_convert (pvoid_type_node, tmp),
3664 fold_convert (pvoid_type_node, ptr),
3666 gfc_add_expr_to_block (&se->pre, tmp);
3673 /* Generate code for the ALLOCATED intrinsic.
3674 Generate inline code that directly check the address of the argument. */
3677 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3679 gfc_actual_arglist *arg1;
3684 gfc_init_se (&arg1se, NULL);
3685 arg1 = expr->value.function.actual;
3686 ss1 = gfc_walk_expr (arg1->expr);
3687 arg1se.descriptor_only = 1;
3688 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3690 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3691 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3692 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3693 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3697 /* Generate code for the ASSOCIATED intrinsic.
3698 If both POINTER and TARGET are arrays, generate a call to library function
3699 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3700 In other cases, generate inline code that directly compare the address of
3701 POINTER with the address of TARGET. */
3704 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3706 gfc_actual_arglist *arg1;
3707 gfc_actual_arglist *arg2;
3712 tree nonzero_charlen;
3713 tree nonzero_arraylen;
3716 gfc_init_se (&arg1se, NULL);
3717 gfc_init_se (&arg2se, NULL);
3718 arg1 = expr->value.function.actual;
3720 ss1 = gfc_walk_expr (arg1->expr);
3724 /* No optional target. */
3725 if (ss1 == gfc_ss_terminator)
3727 /* A pointer to a scalar. */
3728 arg1se.want_pointer = 1;
3729 gfc_conv_expr (&arg1se, arg1->expr);
3734 /* A pointer to an array. */
3735 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3736 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3738 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3739 gfc_add_block_to_block (&se->post, &arg1se.post);
3740 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
3741 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3746 /* An optional target. */
3747 ss2 = gfc_walk_expr (arg2->expr);
3749 nonzero_charlen = NULL_TREE;
3750 if (arg1->expr->ts.type == BT_CHARACTER)
3751 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
3752 arg1->expr->ts.cl->backend_decl,
3755 if (ss1 == gfc_ss_terminator)
3757 /* A pointer to a scalar. */
3758 gcc_assert (ss2 == gfc_ss_terminator);
3759 arg1se.want_pointer = 1;
3760 gfc_conv_expr (&arg1se, arg1->expr);
3761 arg2se.want_pointer = 1;
3762 gfc_conv_expr (&arg2se, arg2->expr);
3763 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3764 gfc_add_block_to_block (&se->post, &arg1se.post);
3765 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
3766 arg1se.expr, arg2se.expr);
3767 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
3768 arg1se.expr, null_pointer_node);
3769 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3774 /* An array pointer of zero length is not associated if target is
3776 arg1se.descriptor_only = 1;
3777 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3778 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3779 gfc_rank_cst[arg1->expr->rank - 1]);
3780 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
3781 build_int_cst (TREE_TYPE (tmp), 0));
3783 /* A pointer to an array, call library function _gfor_associated. */
3784 gcc_assert (ss2 != gfc_ss_terminator);
3785 arg1se.want_pointer = 1;
3786 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3788 arg2se.want_pointer = 1;
3789 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3790 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3791 gfc_add_block_to_block (&se->post, &arg2se.post);
3792 se->expr = build_call_expr (gfor_fndecl_associated, 2,
3793 arg1se.expr, arg2se.expr);
3794 se->expr = convert (boolean_type_node, se->expr);
3795 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3796 se->expr, nonzero_arraylen);
3799 /* If target is present zero character length pointers cannot
3801 if (nonzero_charlen != NULL_TREE)
3802 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3803 se->expr, nonzero_charlen);
3806 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3810 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
3813 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
3817 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3818 se->expr = build_call_expr (gfor_fndecl_sc_kind, 2, args[0], args[1]);
3819 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3823 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3826 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
3830 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3832 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
3833 type = gfc_get_int_type (4);
3834 arg = build_fold_addr_expr (fold_convert (type, arg));
3836 /* Convert it to the required type. */
3837 type = gfc_typenode_for_spec (&expr->ts);
3838 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
3839 se->expr = fold_convert (type, se->expr);
3843 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3846 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
3848 gfc_actual_arglist *actual;
3853 for (actual = expr->value.function.actual; actual; actual = actual->next)
3855 gfc_init_se (&argse, se);
3857 /* Pass a NULL pointer for an absent arg. */
3858 if (actual->expr == NULL)
3859 argse.expr = null_pointer_node;
3865 if (actual->expr->ts.kind != gfc_c_int_kind)
3867 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
3868 ts.type = BT_INTEGER;
3869 ts.kind = gfc_c_int_kind;
3870 gfc_convert_type (actual->expr, &ts, 2);
3872 gfc_conv_expr_reference (&argse, actual->expr);
3875 gfc_add_block_to_block (&se->pre, &argse.pre);
3876 gfc_add_block_to_block (&se->post, &argse.post);
3877 args = gfc_chainon_list (args, argse.expr);
3880 /* Convert it to the required type. */
3881 type = gfc_typenode_for_spec (&expr->ts);
3882 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3883 se->expr = fold_convert (type, se->expr);
3887 /* Generate code for TRIM (A) intrinsic function. */
3890 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3900 unsigned int num_args;
3902 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
3903 args = (tree *) alloca (sizeof (tree) * num_args);
3905 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
3906 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3907 len = gfc_create_var (gfc_get_int_type (4), "len");
3909 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
3910 args[0] = build_fold_addr_expr (len);
3913 if (expr->ts.kind == 1)
3914 function = gfor_fndecl_string_trim;
3915 else if (expr->ts.kind == 4)
3916 function = gfor_fndecl_string_trim_char4;
3920 fndecl = build_addr (function, current_function_decl);
3921 tmp = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
3923 gfc_add_expr_to_block (&se->pre, tmp);
3925 /* Free the temporary afterwards, if necessary. */
3926 cond = fold_build2 (GT_EXPR, boolean_type_node,
3927 len, build_int_cst (TREE_TYPE (len), 0));
3928 tmp = gfc_call_free (var);
3929 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3930 gfc_add_expr_to_block (&se->post, tmp);
3933 se->string_length = len;
3937 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3940 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3942 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
3943 tree type, cond, tmp, count, exit_label, n, max, largest;
3945 stmtblock_t block, body;
3948 /* We store in charsize the size of a character. */
3949 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
3950 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
3952 /* Get the arguments. */
3953 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3954 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
3956 ncopies = gfc_evaluate_now (args[2], &se->pre);
3957 ncopies_type = TREE_TYPE (ncopies);
3959 /* Check that NCOPIES is not negative. */
3960 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3961 build_int_cst (ncopies_type, 0));
3962 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
3963 "Argument NCOPIES of REPEAT intrinsic is negative "
3964 "(its value is %lld)",
3965 fold_convert (long_integer_type_node, ncopies));
3967 /* If the source length is zero, any non negative value of NCOPIES
3968 is valid, and nothing happens. */
3969 n = gfc_create_var (ncopies_type, "ncopies");
3970 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3971 build_int_cst (size_type_node, 0));
3972 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
3973 build_int_cst (ncopies_type, 0), ncopies);
3974 gfc_add_modify (&se->pre, n, tmp);
3977 /* Check that ncopies is not too large: ncopies should be less than
3978 (or equal to) MAX / slen, where MAX is the maximal integer of
3979 the gfc_charlen_type_node type. If slen == 0, we need a special
3980 case to avoid the division by zero. */
3981 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
3982 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
3983 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
3984 fold_convert (size_type_node, max), slen);
3985 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
3986 ? size_type_node : ncopies_type;
3987 cond = fold_build2 (GT_EXPR, boolean_type_node,
3988 fold_convert (largest, ncopies),
3989 fold_convert (largest, max));
3990 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3991 build_int_cst (size_type_node, 0));
3992 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
3994 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
3995 "Argument NCOPIES of REPEAT intrinsic is too large");
3997 /* Compute the destination length. */
3998 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
3999 fold_convert (gfc_charlen_type_node, slen),
4000 fold_convert (gfc_charlen_type_node, ncopies));
4001 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
4002 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4004 /* Generate the code to do the repeat operation:
4005 for (i = 0; i < ncopies; i++)
4006 memmove (dest + (i * slen * size), src, slen*size); */
4007 gfc_start_block (&block);
4008 count = gfc_create_var (ncopies_type, "count");
4009 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4010 exit_label = gfc_build_label_decl (NULL_TREE);
4012 /* Start the loop body. */
4013 gfc_start_block (&body);
4015 /* Exit the loop if count >= ncopies. */
4016 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4017 tmp = build1_v (GOTO_EXPR, exit_label);
4018 TREE_USED (exit_label) = 1;
4019 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4020 build_empty_stmt ());
4021 gfc_add_expr_to_block (&body, tmp);
4023 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4024 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4025 fold_convert (gfc_charlen_type_node, slen),
4026 fold_convert (gfc_charlen_type_node, count));
4027 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4028 tmp, fold_convert (gfc_charlen_type_node, size));
4029 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4030 fold_convert (pvoid_type_node, dest),
4031 fold_convert (sizetype, tmp));
4032 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4033 fold_build2 (MULT_EXPR, size_type_node, slen,
4034 fold_convert (size_type_node, size)));
4035 gfc_add_expr_to_block (&body, tmp);
4037 /* Increment count. */
4038 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4039 count, build_int_cst (TREE_TYPE (count), 1));
4040 gfc_add_modify (&body, count, tmp);
4042 /* Build the loop. */
4043 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4044 gfc_add_expr_to_block (&block, tmp);
4046 /* Add the exit label. */
4047 tmp = build1_v (LABEL_EXPR, exit_label);
4048 gfc_add_expr_to_block (&block, tmp);
4050 /* Finish the block. */
4051 tmp = gfc_finish_block (&block);
4052 gfc_add_expr_to_block (&se->pre, tmp);
4054 /* Set the result value. */
4056 se->string_length = dlen;
4060 /* Generate code for the IARGC intrinsic. */
4063 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4069 /* Call the library function. This always returns an INTEGER(4). */
4070 fndecl = gfor_fndecl_iargc;
4071 tmp = build_call_expr (fndecl, 0);
4073 /* Convert it to the required type. */
4074 type = gfc_typenode_for_spec (&expr->ts);
4075 tmp = fold_convert (type, tmp);
4081 /* The loc intrinsic returns the address of its argument as
4082 gfc_index_integer_kind integer. */
4085 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4091 gcc_assert (!se->ss);
4093 arg_expr = expr->value.function.actual->expr;
4094 ss = gfc_walk_expr (arg_expr);
4095 if (ss == gfc_ss_terminator)
4096 gfc_conv_expr_reference (se, arg_expr);
4098 gfc_conv_array_parameter (se, arg_expr, ss, 1, NULL, NULL);
4099 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4101 /* Create a temporary variable for loc return value. Without this,
4102 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4103 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4104 gfc_add_modify (&se->pre, temp_var, se->expr);
4105 se->expr = temp_var;
4108 /* Generate code for an intrinsic function. Some map directly to library
4109 calls, others get special handling. In some cases the name of the function
4110 used depends on the type specifiers. */
4113 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4115 gfc_intrinsic_sym *isym;
4120 isym = expr->value.function.isym;
4122 name = &expr->value.function.name[2];
4124 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4126 lib = gfc_is_intrinsic_libcall (expr);
4130 se->ignore_optional = 1;
4131 gfc_conv_intrinsic_funcall (se, expr);
4136 switch (expr->value.function.isym->id)
4141 case GFC_ISYM_REPEAT:
4142 gfc_conv_intrinsic_repeat (se, expr);
4146 gfc_conv_intrinsic_trim (se, expr);
4149 case GFC_ISYM_SC_KIND:
4150 gfc_conv_intrinsic_sc_kind (se, expr);
4153 case GFC_ISYM_SI_KIND:
4154 gfc_conv_intrinsic_si_kind (se, expr);
4157 case GFC_ISYM_SR_KIND:
4158 gfc_conv_intrinsic_sr_kind (se, expr);
4161 case GFC_ISYM_EXPONENT:
4162 gfc_conv_intrinsic_exponent (se, expr);
4166 kind = expr->value.function.actual->expr->ts.kind;
4168 fndecl = gfor_fndecl_string_scan;
4170 fndecl = gfor_fndecl_string_scan_char4;
4174 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4177 case GFC_ISYM_VERIFY:
4178 kind = expr->value.function.actual->expr->ts.kind;
4180 fndecl = gfor_fndecl_string_verify;
4182 fndecl = gfor_fndecl_string_verify_char4;
4186 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4189 case GFC_ISYM_ALLOCATED:
4190 gfc_conv_allocated (se, expr);
4193 case GFC_ISYM_ASSOCIATED:
4194 gfc_conv_associated(se, expr);
4198 gfc_conv_intrinsic_abs (se, expr);
4201 case GFC_ISYM_ADJUSTL:
4202 if (expr->ts.kind == 1)
4203 fndecl = gfor_fndecl_adjustl;
4204 else if (expr->ts.kind == 4)
4205 fndecl = gfor_fndecl_adjustl_char4;
4209 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4212 case GFC_ISYM_ADJUSTR:
4213 if (expr->ts.kind == 1)
4214 fndecl = gfor_fndecl_adjustr;
4215 else if (expr->ts.kind == 4)
4216 fndecl = gfor_fndecl_adjustr_char4;
4220 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4223 case GFC_ISYM_AIMAG:
4224 gfc_conv_intrinsic_imagpart (se, expr);
4228 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4232 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4235 case GFC_ISYM_ANINT:
4236 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4240 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4244 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4247 case GFC_ISYM_BTEST:
4248 gfc_conv_intrinsic_btest (se, expr);
4251 case GFC_ISYM_ACHAR:
4253 gfc_conv_intrinsic_char (se, expr);
4256 case GFC_ISYM_CONVERSION:
4258 case GFC_ISYM_LOGICAL:
4260 gfc_conv_intrinsic_conversion (se, expr);
4263 /* Integer conversions are handled separately to make sure we get the
4264 correct rounding mode. */
4269 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4273 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4276 case GFC_ISYM_CEILING:
4277 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4280 case GFC_ISYM_FLOOR:
4281 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4285 gfc_conv_intrinsic_mod (se, expr, 0);
4288 case GFC_ISYM_MODULO:
4289 gfc_conv_intrinsic_mod (se, expr, 1);
4292 case GFC_ISYM_CMPLX:
4293 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4296 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4297 gfc_conv_intrinsic_iargc (se, expr);
4300 case GFC_ISYM_COMPLEX:
4301 gfc_conv_intrinsic_cmplx (se, expr, 1);
4304 case GFC_ISYM_CONJG:
4305 gfc_conv_intrinsic_conjg (se, expr);
4308 case GFC_ISYM_COUNT:
4309 gfc_conv_intrinsic_count (se, expr);
4312 case GFC_ISYM_CTIME:
4313 gfc_conv_intrinsic_ctime (se, expr);
4317 gfc_conv_intrinsic_dim (se, expr);
4320 case GFC_ISYM_DOT_PRODUCT:
4321 gfc_conv_intrinsic_dot_product (se, expr);
4324 case GFC_ISYM_DPROD:
4325 gfc_conv_intrinsic_dprod (se, expr);
4328 case GFC_ISYM_FDATE:
4329 gfc_conv_intrinsic_fdate (se, expr);
4332 case GFC_ISYM_FRACTION:
4333 gfc_conv_intrinsic_fraction (se, expr);
4337 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4340 case GFC_ISYM_IBCLR:
4341 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4344 case GFC_ISYM_IBITS:
4345 gfc_conv_intrinsic_ibits (se, expr);
4348 case GFC_ISYM_IBSET:
4349 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4352 case GFC_ISYM_IACHAR:
4353 case GFC_ISYM_ICHAR:
4354 /* We assume ASCII character sequence. */
4355 gfc_conv_intrinsic_ichar (se, expr);
4358 case GFC_ISYM_IARGC:
4359 gfc_conv_intrinsic_iargc (se, expr);
4363 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4366 case GFC_ISYM_INDEX:
4367 kind = expr->value.function.actual->expr->ts.kind;
4369 fndecl = gfor_fndecl_string_index;
4371 fndecl = gfor_fndecl_string_index_char4;
4375 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4379 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4382 case GFC_ISYM_IS_IOSTAT_END:
4383 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4386 case GFC_ISYM_IS_IOSTAT_EOR:
4387 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4390 case GFC_ISYM_ISNAN:
4391 gfc_conv_intrinsic_isnan (se, expr);
4394 case GFC_ISYM_LSHIFT:
4395 gfc_conv_intrinsic_rlshift (se, expr, 0);
4398 case GFC_ISYM_RSHIFT:
4399 gfc_conv_intrinsic_rlshift (se, expr, 1);
4402 case GFC_ISYM_ISHFT:
4403 gfc_conv_intrinsic_ishft (se, expr);
4406 case GFC_ISYM_ISHFTC:
4407 gfc_conv_intrinsic_ishftc (se, expr);
4410 case GFC_ISYM_LBOUND:
4411 gfc_conv_intrinsic_bound (se, expr, 0);
4414 case GFC_ISYM_TRANSPOSE:
4415 if (se->ss && se->ss->useflags)
4417 gfc_conv_tmp_array_ref (se);
4418 gfc_advance_se_ss_chain (se);
4421 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4425 gfc_conv_intrinsic_len (se, expr);
4428 case GFC_ISYM_LEN_TRIM:
4429 gfc_conv_intrinsic_len_trim (se, expr);
4433 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4437 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4441 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4445 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4449 if (expr->ts.type == BT_CHARACTER)
4450 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4452 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4455 case GFC_ISYM_MAXLOC:
4456 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4459 case GFC_ISYM_MAXVAL:
4460 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4463 case GFC_ISYM_MERGE:
4464 gfc_conv_intrinsic_merge (se, expr);
4468 if (expr->ts.type == BT_CHARACTER)
4469 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4471 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4474 case GFC_ISYM_MINLOC:
4475 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4478 case GFC_ISYM_MINVAL:
4479 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4482 case GFC_ISYM_NEAREST:
4483 gfc_conv_intrinsic_nearest (se, expr);
4487 gfc_conv_intrinsic_not (se, expr);
4491 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4494 case GFC_ISYM_PRESENT:
4495 gfc_conv_intrinsic_present (se, expr);
4498 case GFC_ISYM_PRODUCT:
4499 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4502 case GFC_ISYM_RRSPACING:
4503 gfc_conv_intrinsic_rrspacing (se, expr);
4506 case GFC_ISYM_SET_EXPONENT:
4507 gfc_conv_intrinsic_set_exponent (se, expr);
4510 case GFC_ISYM_SCALE:
4511 gfc_conv_intrinsic_scale (se, expr);
4515 gfc_conv_intrinsic_sign (se, expr);
4519 gfc_conv_intrinsic_size (se, expr);
4522 case GFC_ISYM_SIZEOF:
4523 gfc_conv_intrinsic_sizeof (se, expr);
4526 case GFC_ISYM_SPACING:
4527 gfc_conv_intrinsic_spacing (se, expr);
4531 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4534 case GFC_ISYM_TRANSFER:
4537 if (se->ss->useflags)
4539 /* Access the previously obtained result. */
4540 gfc_conv_tmp_array_ref (se);
4541 gfc_advance_se_ss_chain (se);
4545 gfc_conv_intrinsic_array_transfer (se, expr);
4548 gfc_conv_intrinsic_transfer (se, expr);
4551 case GFC_ISYM_TTYNAM:
4552 gfc_conv_intrinsic_ttynam (se, expr);
4555 case GFC_ISYM_UBOUND:
4556 gfc_conv_intrinsic_bound (se, expr, 1);
4560 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4564 gfc_conv_intrinsic_loc (se, expr);
4567 case GFC_ISYM_ACCESS:
4568 case GFC_ISYM_CHDIR:
4569 case GFC_ISYM_CHMOD:
4570 case GFC_ISYM_DTIME:
4571 case GFC_ISYM_ETIME:
4573 case GFC_ISYM_FGETC:
4576 case GFC_ISYM_FPUTC:
4577 case GFC_ISYM_FSTAT:
4578 case GFC_ISYM_FTELL:
4579 case GFC_ISYM_GETCWD:
4580 case GFC_ISYM_GETGID:
4581 case GFC_ISYM_GETPID:
4582 case GFC_ISYM_GETUID:
4583 case GFC_ISYM_HOSTNM:
4585 case GFC_ISYM_IERRNO:
4586 case GFC_ISYM_IRAND:
4587 case GFC_ISYM_ISATTY:
4589 case GFC_ISYM_LSTAT:
4590 case GFC_ISYM_MALLOC:
4591 case GFC_ISYM_MATMUL:
4592 case GFC_ISYM_MCLOCK:
4593 case GFC_ISYM_MCLOCK8:
4595 case GFC_ISYM_RENAME:
4596 case GFC_ISYM_SECOND:
4597 case GFC_ISYM_SECNDS:
4598 case GFC_ISYM_SIGNAL:
4600 case GFC_ISYM_SYMLNK:
4601 case GFC_ISYM_SYSTEM:
4603 case GFC_ISYM_TIME8:
4604 case GFC_ISYM_UMASK:
4605 case GFC_ISYM_UNLINK:
4606 gfc_conv_intrinsic_funcall (se, expr);
4610 gfc_conv_intrinsic_lib_function (se, expr);
4616 /* This generates code to execute before entering the scalarization loop.
4617 Currently does nothing. */
4620 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4622 switch (ss->expr->value.function.isym->id)
4624 case GFC_ISYM_UBOUND:
4625 case GFC_ISYM_LBOUND:
4634 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4635 inside the scalarization loop. */
4638 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4642 /* The two argument version returns a scalar. */
4643 if (expr->value.function.actual->next->expr)
4646 newss = gfc_get_ss ();
4647 newss->type = GFC_SS_INTRINSIC;
4650 newss->data.info.dimen = 1;
4656 /* Walk an intrinsic array libcall. */
4659 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4663 gcc_assert (expr->rank > 0);
4665 newss = gfc_get_ss ();
4666 newss->type = GFC_SS_FUNCTION;
4669 newss->data.info.dimen = expr->rank;
4675 /* Returns nonzero if the specified intrinsic function call maps directly to
4676 an external library call. Should only be used for functions that return
4680 gfc_is_intrinsic_libcall (gfc_expr * expr)
4682 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4683 gcc_assert (expr->rank > 0);
4685 switch (expr->value.function.isym->id)
4689 case GFC_ISYM_COUNT:
4690 case GFC_ISYM_MATMUL:
4691 case GFC_ISYM_MAXLOC:
4692 case GFC_ISYM_MAXVAL:
4693 case GFC_ISYM_MINLOC:
4694 case GFC_ISYM_MINVAL:
4695 case GFC_ISYM_PRODUCT:
4697 case GFC_ISYM_SHAPE:
4698 case GFC_ISYM_SPREAD:
4699 case GFC_ISYM_TRANSPOSE:
4700 /* Ignore absent optional parameters. */
4703 case GFC_ISYM_RESHAPE:
4704 case GFC_ISYM_CSHIFT:
4705 case GFC_ISYM_EOSHIFT:
4707 case GFC_ISYM_UNPACK:
4708 /* Pass absent optional parameters. */
4716 /* Walk an intrinsic function. */
4718 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
4719 gfc_intrinsic_sym * isym)
4723 if (isym->elemental)
4724 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
4726 if (expr->rank == 0)
4729 if (gfc_is_intrinsic_libcall (expr))
4730 return gfc_walk_intrinsic_libfunc (ss, expr);
4732 /* Special cases. */
4735 case GFC_ISYM_LBOUND:
4736 case GFC_ISYM_UBOUND:
4737 return gfc_walk_intrinsic_bound (ss, expr);
4739 case GFC_ISYM_TRANSFER:
4740 return gfc_walk_intrinsic_libfunc (ss, expr);
4743 /* This probably meant someone forgot to add an intrinsic to the above
4744 list(s) when they implemented it, or something's gone horribly
4750 #include "gt-fortran-trans-intrinsic.h"