1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
32 #include "tree-gimple.h"
36 #include "intrinsic.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43 #include "trans-stmt.h"
45 /* This maps fortran intrinsic math functions to external library or GCC
47 typedef struct gfc_intrinsic_map_t GTY(())
49 /* The explicit enum is required to work around inadequacies in the
50 garbage collection/gengtype parsing mechanism. */
51 enum gfc_generic_isym_id id;
53 /* Enum value from the "language-independent", aka C-centric, part
54 of gcc, or END_BUILTINS of no such value set. */
55 enum built_in_function code_r4;
56 enum built_in_function code_r8;
57 enum built_in_function code_r10;
58 enum built_in_function code_r16;
59 enum built_in_function code_c4;
60 enum built_in_function code_c8;
61 enum built_in_function code_c10;
62 enum built_in_function code_c16;
64 /* True if the naming pattern is to prepend "c" for complex and
65 append "f" for kind=4. False if the naming pattern is to
66 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
69 /* True if a complex version of the function exists. */
70 bool complex_available;
72 /* True if the function should be marked const. */
75 /* The base library name of this function. */
78 /* Cache decls created for the various operand types. */
90 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
91 defines complex variants of all of the entries in mathbuiltins.def
93 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
94 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
95 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, 0, 0, 0, 0, true, \
96 false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
97 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
99 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
100 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
101 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
102 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
103 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
104 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
106 #define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
107 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
108 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 true, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
110 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
112 #define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
113 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
114 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
115 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
116 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
118 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
120 /* Functions built into gcc itself. */
121 #include "mathbuiltins.def"
123 /* Functions in libm. */
124 /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
125 pattern for other mathbuiltins.def entries. At present we have no
126 optimizations for this in the common sources. */
127 LIBM_FUNCTION (SCALE, "scalbn", false),
129 /* Functions in libgfortran. */
130 LIBF_FUNCTION (FRACTION, "fraction", false),
131 LIBF_FUNCTION (NEAREST, "nearest", false),
132 LIBF_FUNCTION (RRSPACING, "rrspacing", false),
133 LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
134 LIBF_FUNCTION (SPACING, "spacing", false),
137 LIBF_FUNCTION (NONE, NULL, false)
139 #undef DEFINE_MATH_BUILTIN
140 #undef DEFINE_MATH_BUILTIN_C
144 /* Structure for storing components of a floating number to be used by
145 elemental functions to manipulate reals. */
148 tree arg; /* Variable tree to view convert to integer. */
149 tree expn; /* Variable tree to save exponent. */
150 tree frac; /* Variable tree to save fraction. */
151 tree smask; /* Constant tree of sign's mask. */
152 tree emask; /* Constant tree of exponent's mask. */
153 tree fmask; /* Constant tree of fraction's mask. */
154 tree edigits; /* Constant tree of the number of exponent bits. */
155 tree fdigits; /* Constant tree of the number of fraction bits. */
156 tree f1; /* Constant tree of the f1 defined in the real model. */
157 tree bias; /* Constant tree of the bias of exponent in the memory. */
158 tree type; /* Type tree of arg1. */
159 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
164 /* Evaluate the arguments to an intrinsic function. */
167 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
169 gfc_actual_arglist *actual;
171 gfc_intrinsic_arg *formal;
176 formal = expr->value.function.isym->formal;
178 for (actual = expr->value.function.actual; actual; actual = actual->next,
179 formal = formal ? formal->next : NULL)
182 /* Skip omitted optional arguments. */
186 /* Evaluate the parameter. This will substitute scalarized
187 references automatically. */
188 gfc_init_se (&argse, se);
190 if (e->ts.type == BT_CHARACTER)
192 gfc_conv_expr (&argse, e);
193 gfc_conv_string_parameter (&argse);
194 args = gfc_chainon_list (args, argse.string_length);
197 gfc_conv_expr_val (&argse, e);
199 /* If an optional argument is itself an optional dummy argument,
200 check its presence and substitute a null if absent. */
201 if (e->expr_type ==EXPR_VARIABLE
202 && e->symtree->n.sym->attr.optional
205 gfc_conv_missing_dummy (&argse, e, formal->ts);
207 gfc_add_block_to_block (&se->pre, &argse.pre);
208 gfc_add_block_to_block (&se->post, &argse.post);
209 args = gfc_chainon_list (args, argse.expr);
215 /* Conversions between different types are output by the frontend as
216 intrinsic functions. We implement these directly with inline code. */
219 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
224 /* Evaluate the argument. */
225 type = gfc_typenode_for_spec (&expr->ts);
226 gcc_assert (expr->value.function.actual->expr);
227 arg = gfc_conv_intrinsic_function_args (se, expr);
228 arg = TREE_VALUE (arg);
230 /* Conversion from complex to non-complex involves taking the real
231 component of the value. */
232 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
233 && expr->ts.type != BT_COMPLEX)
237 artype = TREE_TYPE (TREE_TYPE (arg));
238 arg = build1 (REALPART_EXPR, artype, arg);
241 se->expr = convert (type, arg);
244 /* This is needed because the gcc backend only implements
245 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
246 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
247 Similarly for CEILING. */
250 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
257 argtype = TREE_TYPE (arg);
258 arg = gfc_evaluate_now (arg, pblock);
260 intval = convert (type, arg);
261 intval = gfc_evaluate_now (intval, pblock);
263 tmp = convert (argtype, intval);
264 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
266 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
267 build_int_cst (type, 1));
268 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
273 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
274 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
277 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
286 argtype = TREE_TYPE (arg);
287 arg = gfc_evaluate_now (arg, pblock);
289 real_from_string (&r, "0.5");
290 pos = build_real (argtype, r);
292 real_from_string (&r, "-0.5");
293 neg = build_real (argtype, r);
295 tmp = gfc_build_const (argtype, integer_zero_node);
296 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
298 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
299 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
300 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
304 /* Convert a real to an integer using a specific rounding mode.
305 Ideally we would just build the corresponding GENERIC node,
306 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
309 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
315 return build_fixbound_expr (pblock, arg, type, 0);
319 return build_fixbound_expr (pblock, arg, type, 1);
323 return build_round_expr (pblock, arg, type);
326 return build1 (op, type, arg);
331 /* Round a real value using the specified rounding mode.
332 We use a temporary integer of that same kind size as the result.
333 Values larger than those that can be represented by this kind are
334 unchanged, as they will not be accurate enough to represent the
336 huge = HUGE (KIND (a))
337 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
341 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum tree_code op)
352 kind = expr->ts.kind;
355 /* We have builtin functions for some cases. */
398 /* Evaluate the argument. */
399 gcc_assert (expr->value.function.actual->expr);
400 arg = gfc_conv_intrinsic_function_args (se, expr);
402 /* Use a builtin function if one exists. */
403 if (n != END_BUILTINS)
405 tmp = built_in_decls[n];
406 se->expr = build_function_call_expr (tmp, arg);
410 /* This code is probably redundant, but we'll keep it lying around just
412 type = gfc_typenode_for_spec (&expr->ts);
413 arg = TREE_VALUE (arg);
414 arg = gfc_evaluate_now (arg, &se->pre);
416 /* Test if the value is too large to handle sensibly. */
417 gfc_set_model_kind (kind);
419 n = gfc_validate_kind (BT_INTEGER, kind, false);
420 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
421 tmp = gfc_conv_mpfr_to_tree (huge, kind);
422 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
424 mpfr_neg (huge, huge, GFC_RND_MODE);
425 tmp = gfc_conv_mpfr_to_tree (huge, kind);
426 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
427 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
428 itype = gfc_get_int_type (kind);
430 tmp = build_fix_expr (&se->pre, arg, itype, op);
431 tmp = convert (type, tmp);
432 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
437 /* Convert to an integer using the specified rounding mode. */
440 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
445 /* Evaluate the argument. */
446 type = gfc_typenode_for_spec (&expr->ts);
447 gcc_assert (expr->value.function.actual->expr);
448 arg = gfc_conv_intrinsic_function_args (se, expr);
449 arg = TREE_VALUE (arg);
451 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
453 /* Conversion to a different integer kind. */
454 se->expr = convert (type, arg);
458 /* Conversion from complex to non-complex involves taking the real
459 component of the value. */
460 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
461 && expr->ts.type != BT_COMPLEX)
465 artype = TREE_TYPE (TREE_TYPE (arg));
466 arg = build1 (REALPART_EXPR, artype, arg);
469 se->expr = build_fix_expr (&se->pre, arg, type, op);
474 /* Get the imaginary component of a value. */
477 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
481 arg = gfc_conv_intrinsic_function_args (se, expr);
482 arg = TREE_VALUE (arg);
483 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
487 /* Get the complex conjugate of a value. */
490 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
494 arg = gfc_conv_intrinsic_function_args (se, expr);
495 arg = TREE_VALUE (arg);
496 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
500 /* Initialize function decls for library functions. The external functions
501 are created as required. Builtin functions are added here. */
504 gfc_build_intrinsic_lib_fndecls (void)
506 gfc_intrinsic_map_t *m;
508 /* Add GCC builtin functions. */
509 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
511 if (m->code_r4 != END_BUILTINS)
512 m->real4_decl = built_in_decls[m->code_r4];
513 if (m->code_r8 != END_BUILTINS)
514 m->real8_decl = built_in_decls[m->code_r8];
515 if (m->code_r10 != END_BUILTINS)
516 m->real10_decl = built_in_decls[m->code_r10];
517 if (m->code_r16 != END_BUILTINS)
518 m->real16_decl = built_in_decls[m->code_r16];
519 if (m->code_c4 != END_BUILTINS)
520 m->complex4_decl = built_in_decls[m->code_c4];
521 if (m->code_c8 != END_BUILTINS)
522 m->complex8_decl = built_in_decls[m->code_c8];
523 if (m->code_c10 != END_BUILTINS)
524 m->complex10_decl = built_in_decls[m->code_c10];
525 if (m->code_c16 != END_BUILTINS)
526 m->complex16_decl = built_in_decls[m->code_c16];
531 /* Create a fndecl for a simple intrinsic library function. */
534 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
539 gfc_actual_arglist *actual;
542 char name[GFC_MAX_SYMBOL_LEN + 3];
545 if (ts->type == BT_REAL)
550 pdecl = &m->real4_decl;
553 pdecl = &m->real8_decl;
556 pdecl = &m->real10_decl;
559 pdecl = &m->real16_decl;
565 else if (ts->type == BT_COMPLEX)
567 gcc_assert (m->complex_available);
572 pdecl = &m->complex4_decl;
575 pdecl = &m->complex8_decl;
578 pdecl = &m->complex10_decl;
581 pdecl = &m->complex16_decl;
596 snprintf (name, sizeof (name), "%s%s%s",
597 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
598 else if (ts->kind == 8)
599 snprintf (name, sizeof (name), "%s%s",
600 ts->type == BT_COMPLEX ? "c" : "", m->name);
603 gcc_assert (ts->kind == 10 || ts->kind == 16);
604 snprintf (name, sizeof (name), "%s%s%s",
605 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
610 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
611 ts->type == BT_COMPLEX ? 'c' : 'r',
615 argtypes = NULL_TREE;
616 for (actual = expr->value.function.actual; actual; actual = actual->next)
618 type = gfc_typenode_for_spec (&actual->expr->ts);
619 argtypes = gfc_chainon_list (argtypes, type);
621 argtypes = gfc_chainon_list (argtypes, void_type_node);
622 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
623 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
625 /* Mark the decl as external. */
626 DECL_EXTERNAL (fndecl) = 1;
627 TREE_PUBLIC (fndecl) = 1;
629 /* Mark it __attribute__((const)), if possible. */
630 TREE_READONLY (fndecl) = m->is_constant;
632 rest_of_decl_compilation (fndecl, 1, 0);
639 /* Convert an intrinsic function into an external or builtin call. */
642 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
644 gfc_intrinsic_map_t *m;
647 gfc_generic_isym_id id;
649 id = expr->value.function.isym->generic_id;
650 /* Find the entry for this function. */
651 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
657 if (m->id == GFC_ISYM_NONE)
659 internal_error ("Intrinsic function %s(%d) not recognized",
660 expr->value.function.name, id);
663 /* Get the decl and generate the call. */
664 args = gfc_conv_intrinsic_function_args (se, expr);
665 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
666 se->expr = build_function_call_expr (fndecl, args);
669 /* Generate code for EXPONENT(X) intrinsic function. */
672 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
677 args = gfc_conv_intrinsic_function_args (se, expr);
679 a1 = expr->value.function.actual->expr;
683 fndecl = gfor_fndecl_math_exponent4;
686 fndecl = gfor_fndecl_math_exponent8;
689 fndecl = gfor_fndecl_math_exponent10;
692 fndecl = gfor_fndecl_math_exponent16;
698 se->expr = build_function_call_expr (fndecl, args);
701 /* Evaluate a single upper or lower bound. */
702 /* TODO: bound intrinsic generates way too much unnecessary code. */
705 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
707 gfc_actual_arglist *arg;
708 gfc_actual_arglist *arg2;
718 arg = expr->value.function.actual;
723 /* Create an implicit second parameter from the loop variable. */
724 gcc_assert (!arg2->expr);
725 gcc_assert (se->loop->dimen == 1);
726 gcc_assert (se->ss->expr == expr);
727 gfc_advance_se_ss_chain (se);
728 bound = se->loop->loopvar[0];
729 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
734 /* use the passed argument. */
735 gcc_assert (arg->next->expr);
736 gfc_init_se (&argse, NULL);
737 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
738 gfc_add_block_to_block (&se->pre, &argse.pre);
740 /* Convert from one based to zero based. */
741 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
745 /* TODO: don't re-evaluate the descriptor on each iteration. */
746 /* Get a descriptor for the first parameter. */
747 ss = gfc_walk_expr (arg->expr);
748 gcc_assert (ss != gfc_ss_terminator);
749 gfc_init_se (&argse, NULL);
750 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
751 gfc_add_block_to_block (&se->pre, &argse.pre);
752 gfc_add_block_to_block (&se->post, &argse.post);
756 if (INTEGER_CST_P (bound))
758 gcc_assert (TREE_INT_CST_HIGH (bound) == 0);
759 i = TREE_INT_CST_LOW (bound);
760 gcc_assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
764 if (flag_bounds_check)
766 bound = gfc_evaluate_now (bound, &se->pre);
767 cond = fold_build2 (LT_EXPR, boolean_type_node,
768 bound, build_int_cst (TREE_TYPE (bound), 0));
769 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
770 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
771 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
772 gfc_trans_runtime_check (cond, gfc_msg_fault, &se->pre, NULL);
777 se->expr = gfc_conv_descriptor_ubound(desc, bound);
779 se->expr = gfc_conv_descriptor_lbound(desc, bound);
781 type = gfc_typenode_for_spec (&expr->ts);
782 se->expr = convert (type, se->expr);
787 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
793 args = gfc_conv_intrinsic_function_args (se, expr);
794 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
795 val = TREE_VALUE (args);
797 switch (expr->value.function.actual->expr->ts.type)
801 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
805 switch (expr->ts.kind)
820 se->expr = build_function_call_expr (built_in_decls[n], args);
829 /* Create a complex value from one or two real components. */
832 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
839 type = gfc_typenode_for_spec (&expr->ts);
840 arg = gfc_conv_intrinsic_function_args (se, expr);
841 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
843 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
844 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
846 arg = TREE_VALUE (arg);
847 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
848 imag = convert (TREE_TYPE (type), imag);
851 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
853 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
856 /* Remainder function MOD(A, P) = A - INT(A / P) * P
857 MODULO(A, P) = A - FLOOR (A / P) * P */
858 /* TODO: MOD(x, 0) */
861 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
873 arg = gfc_conv_intrinsic_function_args (se, expr);
874 arg2 = TREE_VALUE (TREE_CHAIN (arg));
875 arg = TREE_VALUE (arg);
876 type = TREE_TYPE (arg);
878 switch (expr->ts.type)
881 /* Integer case is easy, we've got a builtin op. */
883 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
885 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
889 /* Real values we have to do the hard way. */
890 arg = gfc_evaluate_now (arg, &se->pre);
891 arg2 = gfc_evaluate_now (arg2, &se->pre);
893 tmp = build2 (RDIV_EXPR, type, arg, arg2);
894 /* Test if the value is too large to handle sensibly. */
895 gfc_set_model_kind (expr->ts.kind);
897 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
898 ikind = expr->ts.kind;
901 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
902 ikind = gfc_max_integer_kind;
904 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
905 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
906 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
908 mpfr_neg (huge, huge, GFC_RND_MODE);
909 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
910 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
911 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
913 itype = gfc_get_int_type (ikind);
915 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_FLOOR_EXPR);
917 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
918 tmp = convert (type, tmp);
919 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
920 tmp = build2 (MULT_EXPR, type, tmp, arg2);
921 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
930 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
933 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
942 arg = gfc_conv_intrinsic_function_args (se, expr);
943 arg2 = TREE_VALUE (TREE_CHAIN (arg));
944 arg = TREE_VALUE (arg);
945 type = TREE_TYPE (arg);
947 val = build2 (MINUS_EXPR, type, arg, arg2);
948 val = gfc_evaluate_now (val, &se->pre);
950 zero = gfc_build_const (type, integer_zero_node);
951 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
952 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
956 /* SIGN(A, B) is absolute value of A times sign of B.
957 The real value versions use library functions to ensure the correct
958 handling of negative zero. Integer case implemented as:
959 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
963 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
974 arg = gfc_conv_intrinsic_function_args (se, expr);
975 if (expr->ts.type == BT_REAL)
977 switch (expr->ts.kind)
980 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
983 tmp = built_in_decls[BUILT_IN_COPYSIGN];
987 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
992 se->expr = build_function_call_expr (tmp, arg);
996 arg2 = TREE_VALUE (TREE_CHAIN (arg));
997 arg = TREE_VALUE (arg);
998 type = TREE_TYPE (arg);
999 zero = gfc_build_const (type, integer_zero_node);
1001 testa = fold_build2 (GE_EXPR, boolean_type_node, arg, zero);
1002 testb = fold_build2 (GE_EXPR, boolean_type_node, arg2, zero);
1003 tmp = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, testa, testb);
1004 se->expr = fold_build3 (COND_EXPR, type, tmp,
1005 build1 (NEGATE_EXPR, type, arg), arg);
1009 /* Test for the presence of an optional argument. */
1012 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1016 arg = expr->value.function.actual->expr;
1017 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1018 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1019 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1023 /* Calculate the double precision product of two single precision values. */
1026 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1032 arg = gfc_conv_intrinsic_function_args (se, expr);
1033 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1034 arg = TREE_VALUE (arg);
1036 /* Convert the args to double precision before multiplying. */
1037 type = gfc_typenode_for_spec (&expr->ts);
1038 arg = convert (type, arg);
1039 arg2 = convert (type, arg2);
1040 se->expr = build2 (MULT_EXPR, type, arg, arg2);
1044 /* Return a length one character string containing an ascii character. */
1047 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1053 arg = gfc_conv_intrinsic_function_args (se, expr);
1054 arg = TREE_VALUE (arg);
1056 /* We currently don't support character types != 1. */
1057 gcc_assert (expr->ts.kind == 1);
1058 type = gfc_character1_type_node;
1059 var = gfc_create_var (type, "char");
1061 arg = convert (type, arg);
1062 gfc_add_modify_expr (&se->pre, var, arg);
1063 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1064 se->string_length = integer_one_node;
1069 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1077 tree gfc_int8_type_node = gfc_get_int_type (8);
1079 type = build_pointer_type (gfc_character1_type_node);
1080 var = gfc_create_var (type, "pstr");
1081 len = gfc_create_var (gfc_int8_type_node, "len");
1083 tmp = gfc_conv_intrinsic_function_args (se, expr);
1084 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1085 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1086 arglist = chainon (arglist, tmp);
1088 tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
1089 gfc_add_expr_to_block (&se->pre, tmp);
1091 /* Free the temporary afterwards, if necessary. */
1092 cond = build2 (GT_EXPR, boolean_type_node, len,
1093 build_int_cst (TREE_TYPE (len), 0));
1094 arglist = gfc_chainon_list (NULL_TREE, var);
1095 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1096 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1097 gfc_add_expr_to_block (&se->post, tmp);
1100 se->string_length = len;
1105 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1113 tree gfc_int4_type_node = gfc_get_int_type (4);
1115 type = build_pointer_type (gfc_character1_type_node);
1116 var = gfc_create_var (type, "pstr");
1117 len = gfc_create_var (gfc_int4_type_node, "len");
1119 tmp = gfc_conv_intrinsic_function_args (se, expr);
1120 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1121 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1122 arglist = chainon (arglist, tmp);
1124 tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
1125 gfc_add_expr_to_block (&se->pre, tmp);
1127 /* Free the temporary afterwards, if necessary. */
1128 cond = build2 (GT_EXPR, boolean_type_node, len,
1129 build_int_cst (TREE_TYPE (len), 0));
1130 arglist = gfc_chainon_list (NULL_TREE, var);
1131 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1132 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1133 gfc_add_expr_to_block (&se->post, tmp);
1136 se->string_length = len;
1140 /* Return a character string containing the tty name. */
1143 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1151 tree gfc_int4_type_node = gfc_get_int_type (4);
1153 type = build_pointer_type (gfc_character1_type_node);
1154 var = gfc_create_var (type, "pstr");
1155 len = gfc_create_var (gfc_int4_type_node, "len");
1157 tmp = gfc_conv_intrinsic_function_args (se, expr);
1158 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1159 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1160 arglist = chainon (arglist, tmp);
1162 tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
1163 gfc_add_expr_to_block (&se->pre, tmp);
1165 /* Free the temporary afterwards, if necessary. */
1166 cond = build2 (GT_EXPR, boolean_type_node, len,
1167 build_int_cst (TREE_TYPE (len), 0));
1168 arglist = gfc_chainon_list (NULL_TREE, var);
1169 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1170 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1171 gfc_add_expr_to_block (&se->post, tmp);
1174 se->string_length = len;
1178 /* Get the minimum/maximum value of all the parameters.
1179 minmax (a1, a2, a3, ...)
1192 /* TODO: Mismatching types can occur when specific names are used.
1193 These should be handled during resolution. */
1195 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1206 arg = gfc_conv_intrinsic_function_args (se, expr);
1207 type = gfc_typenode_for_spec (&expr->ts);
1209 limit = TREE_VALUE (arg);
1210 if (TREE_TYPE (limit) != type)
1211 limit = convert (type, limit);
1212 /* Only evaluate the argument once. */
1213 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1214 limit = gfc_evaluate_now(limit, &se->pre);
1216 mvar = gfc_create_var (type, "M");
1217 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1218 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1220 val = TREE_VALUE (arg);
1221 if (TREE_TYPE (val) != type)
1222 val = convert (type, val);
1224 /* Only evaluate the argument once. */
1225 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1226 val = gfc_evaluate_now(val, &se->pre);
1228 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1230 tmp = build2 (op, boolean_type_node, val, limit);
1231 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1232 gfc_add_expr_to_block (&se->pre, tmp);
1233 elsecase = build_empty_stmt ();
1240 /* Create a symbol node for this intrinsic. The symbol from the frontend
1241 has the generic name. */
1244 gfc_get_symbol_for_expr (gfc_expr * expr)
1248 /* TODO: Add symbols for intrinsic function to the global namespace. */
1249 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1250 sym = gfc_new_symbol (expr->value.function.name, NULL);
1253 sym->attr.external = 1;
1254 sym->attr.function = 1;
1255 sym->attr.always_explicit = 1;
1256 sym->attr.proc = PROC_INTRINSIC;
1257 sym->attr.flavor = FL_PROCEDURE;
1261 sym->attr.dimension = 1;
1262 sym->as = gfc_get_array_spec ();
1263 sym->as->type = AS_ASSUMED_SHAPE;
1264 sym->as->rank = expr->rank;
1267 /* TODO: proper argument lists for external intrinsics. */
1271 /* Generate a call to an external intrinsic function. */
1273 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1277 gcc_assert (!se->ss || se->ss->expr == expr);
1280 gcc_assert (expr->rank > 0);
1282 gcc_assert (expr->rank == 0);
1284 sym = gfc_get_symbol_for_expr (expr);
1285 gfc_conv_function_call (se, sym, expr->value.function.actual);
1289 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1309 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1318 gfc_actual_arglist *actual;
1325 gfc_conv_intrinsic_funcall (se, expr);
1329 actual = expr->value.function.actual;
1330 type = gfc_typenode_for_spec (&expr->ts);
1331 /* Initialize the result. */
1332 resvar = gfc_create_var (type, "test");
1334 tmp = convert (type, boolean_true_node);
1336 tmp = convert (type, boolean_false_node);
1337 gfc_add_modify_expr (&se->pre, resvar, tmp);
1339 /* Walk the arguments. */
1340 arrayss = gfc_walk_expr (actual->expr);
1341 gcc_assert (arrayss != gfc_ss_terminator);
1343 /* Initialize the scalarizer. */
1344 gfc_init_loopinfo (&loop);
1345 exit_label = gfc_build_label_decl (NULL_TREE);
1346 TREE_USED (exit_label) = 1;
1347 gfc_add_ss_to_loop (&loop, arrayss);
1349 /* Initialize the loop. */
1350 gfc_conv_ss_startstride (&loop);
1351 gfc_conv_loop_setup (&loop);
1353 gfc_mark_ss_chain_used (arrayss, 1);
1354 /* Generate the loop body. */
1355 gfc_start_scalarized_body (&loop, &body);
1357 /* If the condition matches then set the return value. */
1358 gfc_start_block (&block);
1360 tmp = convert (type, boolean_false_node);
1362 tmp = convert (type, boolean_true_node);
1363 gfc_add_modify_expr (&block, resvar, tmp);
1365 /* And break out of the loop. */
1366 tmp = build1_v (GOTO_EXPR, exit_label);
1367 gfc_add_expr_to_block (&block, tmp);
1369 found = gfc_finish_block (&block);
1371 /* Check this element. */
1372 gfc_init_se (&arrayse, NULL);
1373 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1374 arrayse.ss = arrayss;
1375 gfc_conv_expr_val (&arrayse, actual->expr);
1377 gfc_add_block_to_block (&body, &arrayse.pre);
1378 tmp = build2 (op, boolean_type_node, arrayse.expr,
1379 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1380 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1381 gfc_add_expr_to_block (&body, tmp);
1382 gfc_add_block_to_block (&body, &arrayse.post);
1384 gfc_trans_scalarizing_loops (&loop, &body);
1386 /* Add the exit label. */
1387 tmp = build1_v (LABEL_EXPR, exit_label);
1388 gfc_add_expr_to_block (&loop.pre, tmp);
1390 gfc_add_block_to_block (&se->pre, &loop.pre);
1391 gfc_add_block_to_block (&se->pre, &loop.post);
1392 gfc_cleanup_loop (&loop);
1397 /* COUNT(A) = Number of true elements in A. */
1399 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1406 gfc_actual_arglist *actual;
1412 gfc_conv_intrinsic_funcall (se, expr);
1416 actual = expr->value.function.actual;
1418 type = gfc_typenode_for_spec (&expr->ts);
1419 /* Initialize the result. */
1420 resvar = gfc_create_var (type, "count");
1421 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1423 /* Walk the arguments. */
1424 arrayss = gfc_walk_expr (actual->expr);
1425 gcc_assert (arrayss != gfc_ss_terminator);
1427 /* Initialize the scalarizer. */
1428 gfc_init_loopinfo (&loop);
1429 gfc_add_ss_to_loop (&loop, arrayss);
1431 /* Initialize the loop. */
1432 gfc_conv_ss_startstride (&loop);
1433 gfc_conv_loop_setup (&loop);
1435 gfc_mark_ss_chain_used (arrayss, 1);
1436 /* Generate the loop body. */
1437 gfc_start_scalarized_body (&loop, &body);
1439 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1440 build_int_cst (TREE_TYPE (resvar), 1));
1441 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1443 gfc_init_se (&arrayse, NULL);
1444 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1445 arrayse.ss = arrayss;
1446 gfc_conv_expr_val (&arrayse, actual->expr);
1447 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1449 gfc_add_block_to_block (&body, &arrayse.pre);
1450 gfc_add_expr_to_block (&body, tmp);
1451 gfc_add_block_to_block (&body, &arrayse.post);
1453 gfc_trans_scalarizing_loops (&loop, &body);
1455 gfc_add_block_to_block (&se->pre, &loop.pre);
1456 gfc_add_block_to_block (&se->pre, &loop.post);
1457 gfc_cleanup_loop (&loop);
1462 /* Inline implementation of the sum and product intrinsics. */
1464 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1472 gfc_actual_arglist *actual;
1477 gfc_expr *arrayexpr;
1482 gfc_conv_intrinsic_funcall (se, expr);
1486 type = gfc_typenode_for_spec (&expr->ts);
1487 /* Initialize the result. */
1488 resvar = gfc_create_var (type, "val");
1489 if (op == PLUS_EXPR)
1490 tmp = gfc_build_const (type, integer_zero_node);
1492 tmp = gfc_build_const (type, integer_one_node);
1494 gfc_add_modify_expr (&se->pre, resvar, tmp);
1496 /* Walk the arguments. */
1497 actual = expr->value.function.actual;
1498 arrayexpr = actual->expr;
1499 arrayss = gfc_walk_expr (arrayexpr);
1500 gcc_assert (arrayss != gfc_ss_terminator);
1502 actual = actual->next->next;
1503 gcc_assert (actual);
1504 maskexpr = actual->expr;
1505 if (maskexpr && maskexpr->rank != 0)
1507 maskss = gfc_walk_expr (maskexpr);
1508 gcc_assert (maskss != gfc_ss_terminator);
1513 /* Initialize the scalarizer. */
1514 gfc_init_loopinfo (&loop);
1515 gfc_add_ss_to_loop (&loop, arrayss);
1517 gfc_add_ss_to_loop (&loop, maskss);
1519 /* Initialize the loop. */
1520 gfc_conv_ss_startstride (&loop);
1521 gfc_conv_loop_setup (&loop);
1523 gfc_mark_ss_chain_used (arrayss, 1);
1525 gfc_mark_ss_chain_used (maskss, 1);
1526 /* Generate the loop body. */
1527 gfc_start_scalarized_body (&loop, &body);
1529 /* If we have a mask, only add this element if the mask is set. */
1532 gfc_init_se (&maskse, NULL);
1533 gfc_copy_loopinfo_to_se (&maskse, &loop);
1535 gfc_conv_expr_val (&maskse, maskexpr);
1536 gfc_add_block_to_block (&body, &maskse.pre);
1538 gfc_start_block (&block);
1541 gfc_init_block (&block);
1543 /* Do the actual summation/product. */
1544 gfc_init_se (&arrayse, NULL);
1545 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1546 arrayse.ss = arrayss;
1547 gfc_conv_expr_val (&arrayse, arrayexpr);
1548 gfc_add_block_to_block (&block, &arrayse.pre);
1550 tmp = build2 (op, type, resvar, arrayse.expr);
1551 gfc_add_modify_expr (&block, resvar, tmp);
1552 gfc_add_block_to_block (&block, &arrayse.post);
1556 /* We enclose the above in if (mask) {...} . */
1557 tmp = gfc_finish_block (&block);
1559 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1562 tmp = gfc_finish_block (&block);
1563 gfc_add_expr_to_block (&body, tmp);
1565 gfc_trans_scalarizing_loops (&loop, &body);
1567 /* For a scalar mask, enclose the loop in an if statement. */
1568 if (maskexpr && maskss == NULL)
1570 gfc_init_se (&maskse, NULL);
1571 gfc_conv_expr_val (&maskse, maskexpr);
1572 gfc_init_block (&block);
1573 gfc_add_block_to_block (&block, &loop.pre);
1574 gfc_add_block_to_block (&block, &loop.post);
1575 tmp = gfc_finish_block (&block);
1577 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1578 gfc_add_expr_to_block (&block, tmp);
1579 gfc_add_block_to_block (&se->pre, &block);
1583 gfc_add_block_to_block (&se->pre, &loop.pre);
1584 gfc_add_block_to_block (&se->pre, &loop.post);
1587 gfc_cleanup_loop (&loop);
1593 /* Inline implementation of the dot_product intrinsic. This function
1594 is based on gfc_conv_intrinsic_arith (the previous function). */
1596 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1604 gfc_actual_arglist *actual;
1605 gfc_ss *arrayss1, *arrayss2;
1606 gfc_se arrayse1, arrayse2;
1607 gfc_expr *arrayexpr1, *arrayexpr2;
1609 type = gfc_typenode_for_spec (&expr->ts);
1611 /* Initialize the result. */
1612 resvar = gfc_create_var (type, "val");
1613 if (expr->ts.type == BT_LOGICAL)
1614 tmp = convert (type, integer_zero_node);
1616 tmp = gfc_build_const (type, integer_zero_node);
1618 gfc_add_modify_expr (&se->pre, resvar, tmp);
1620 /* Walk argument #1. */
1621 actual = expr->value.function.actual;
1622 arrayexpr1 = actual->expr;
1623 arrayss1 = gfc_walk_expr (arrayexpr1);
1624 gcc_assert (arrayss1 != gfc_ss_terminator);
1626 /* Walk argument #2. */
1627 actual = actual->next;
1628 arrayexpr2 = actual->expr;
1629 arrayss2 = gfc_walk_expr (arrayexpr2);
1630 gcc_assert (arrayss2 != gfc_ss_terminator);
1632 /* Initialize the scalarizer. */
1633 gfc_init_loopinfo (&loop);
1634 gfc_add_ss_to_loop (&loop, arrayss1);
1635 gfc_add_ss_to_loop (&loop, arrayss2);
1637 /* Initialize the loop. */
1638 gfc_conv_ss_startstride (&loop);
1639 gfc_conv_loop_setup (&loop);
1641 gfc_mark_ss_chain_used (arrayss1, 1);
1642 gfc_mark_ss_chain_used (arrayss2, 1);
1644 /* Generate the loop body. */
1645 gfc_start_scalarized_body (&loop, &body);
1646 gfc_init_block (&block);
1648 /* Make the tree expression for [conjg(]array1[)]. */
1649 gfc_init_se (&arrayse1, NULL);
1650 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1651 arrayse1.ss = arrayss1;
1652 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1653 if (expr->ts.type == BT_COMPLEX)
1654 arrayse1.expr = build1 (CONJ_EXPR, type, arrayse1.expr);
1655 gfc_add_block_to_block (&block, &arrayse1.pre);
1657 /* Make the tree expression for array2. */
1658 gfc_init_se (&arrayse2, NULL);
1659 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
1660 arrayse2.ss = arrayss2;
1661 gfc_conv_expr_val (&arrayse2, arrayexpr2);
1662 gfc_add_block_to_block (&block, &arrayse2.pre);
1664 /* Do the actual product and sum. */
1665 if (expr->ts.type == BT_LOGICAL)
1667 tmp = build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
1668 tmp = build2 (TRUTH_OR_EXPR, type, resvar, tmp);
1672 tmp = build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
1673 tmp = build2 (PLUS_EXPR, type, resvar, tmp);
1675 gfc_add_modify_expr (&block, resvar, tmp);
1677 /* Finish up the loop block and the loop. */
1678 tmp = gfc_finish_block (&block);
1679 gfc_add_expr_to_block (&body, tmp);
1681 gfc_trans_scalarizing_loops (&loop, &body);
1682 gfc_add_block_to_block (&se->pre, &loop.pre);
1683 gfc_add_block_to_block (&se->pre, &loop.post);
1684 gfc_cleanup_loop (&loop);
1691 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1695 stmtblock_t ifblock;
1696 stmtblock_t elseblock;
1703 gfc_actual_arglist *actual;
1708 gfc_expr *arrayexpr;
1715 gfc_conv_intrinsic_funcall (se, expr);
1719 /* Initialize the result. */
1720 pos = gfc_create_var (gfc_array_index_type, "pos");
1721 type = gfc_typenode_for_spec (&expr->ts);
1723 /* Walk the arguments. */
1724 actual = expr->value.function.actual;
1725 arrayexpr = actual->expr;
1726 arrayss = gfc_walk_expr (arrayexpr);
1727 gcc_assert (arrayss != gfc_ss_terminator);
1729 actual = actual->next->next;
1730 gcc_assert (actual);
1731 maskexpr = actual->expr;
1732 if (maskexpr && maskexpr->rank != 0)
1734 maskss = gfc_walk_expr (maskexpr);
1735 gcc_assert (maskss != gfc_ss_terminator);
1740 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1741 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1742 switch (arrayexpr->ts.type)
1745 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1749 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1750 arrayexpr->ts.kind);
1757 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1759 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1760 gfc_add_modify_expr (&se->pre, limit, tmp);
1762 /* Initialize the scalarizer. */
1763 gfc_init_loopinfo (&loop);
1764 gfc_add_ss_to_loop (&loop, arrayss);
1766 gfc_add_ss_to_loop (&loop, maskss);
1768 /* Initialize the loop. */
1769 gfc_conv_ss_startstride (&loop);
1770 gfc_conv_loop_setup (&loop);
1772 gcc_assert (loop.dimen == 1);
1774 /* Initialize the position to zero, following Fortran 2003. We are free
1775 to do this because Fortran 95 allows the result of an entirely false
1776 mask to be processor dependent. */
1777 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
1779 gfc_mark_ss_chain_used (arrayss, 1);
1781 gfc_mark_ss_chain_used (maskss, 1);
1782 /* Generate the loop body. */
1783 gfc_start_scalarized_body (&loop, &body);
1785 /* If we have a mask, only check this element if the mask is set. */
1788 gfc_init_se (&maskse, NULL);
1789 gfc_copy_loopinfo_to_se (&maskse, &loop);
1791 gfc_conv_expr_val (&maskse, maskexpr);
1792 gfc_add_block_to_block (&body, &maskse.pre);
1794 gfc_start_block (&block);
1797 gfc_init_block (&block);
1799 /* Compare with the current limit. */
1800 gfc_init_se (&arrayse, NULL);
1801 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1802 arrayse.ss = arrayss;
1803 gfc_conv_expr_val (&arrayse, arrayexpr);
1804 gfc_add_block_to_block (&block, &arrayse.pre);
1806 /* We do the following if this is a more extreme value. */
1807 gfc_start_block (&ifblock);
1809 /* Assign the value to the limit... */
1810 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1812 /* Remember where we are. */
1813 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1815 ifbody = gfc_finish_block (&ifblock);
1817 /* If it is a more extreme value or pos is still zero. */
1818 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node,
1819 build2 (op, boolean_type_node, arrayse.expr, limit),
1820 build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node));
1821 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1822 gfc_add_expr_to_block (&block, tmp);
1826 /* We enclose the above in if (mask) {...}. */
1827 tmp = gfc_finish_block (&block);
1829 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1832 tmp = gfc_finish_block (&block);
1833 gfc_add_expr_to_block (&body, tmp);
1835 gfc_trans_scalarizing_loops (&loop, &body);
1837 /* For a scalar mask, enclose the loop in an if statement. */
1838 if (maskexpr && maskss == NULL)
1840 gfc_init_se (&maskse, NULL);
1841 gfc_conv_expr_val (&maskse, maskexpr);
1842 gfc_init_block (&block);
1843 gfc_add_block_to_block (&block, &loop.pre);
1844 gfc_add_block_to_block (&block, &loop.post);
1845 tmp = gfc_finish_block (&block);
1847 /* For the else part of the scalar mask, just initialize
1848 the pos variable the same way as above. */
1850 gfc_init_block (&elseblock);
1851 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
1852 elsetmp = gfc_finish_block (&elseblock);
1854 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
1855 gfc_add_expr_to_block (&block, tmp);
1856 gfc_add_block_to_block (&se->pre, &block);
1860 gfc_add_block_to_block (&se->pre, &loop.pre);
1861 gfc_add_block_to_block (&se->pre, &loop.post);
1863 gfc_cleanup_loop (&loop);
1865 /* Return a value in the range 1..SIZE(array). */
1866 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1867 gfc_index_one_node);
1868 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
1869 /* And convert to the required type. */
1870 se->expr = convert (type, tmp);
1874 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1883 gfc_actual_arglist *actual;
1888 gfc_expr *arrayexpr;
1894 gfc_conv_intrinsic_funcall (se, expr);
1898 type = gfc_typenode_for_spec (&expr->ts);
1899 /* Initialize the result. */
1900 limit = gfc_create_var (type, "limit");
1901 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
1902 switch (expr->ts.type)
1905 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1909 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1916 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1918 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1919 gfc_add_modify_expr (&se->pre, limit, tmp);
1921 /* Walk the arguments. */
1922 actual = expr->value.function.actual;
1923 arrayexpr = actual->expr;
1924 arrayss = gfc_walk_expr (arrayexpr);
1925 gcc_assert (arrayss != gfc_ss_terminator);
1927 actual = actual->next->next;
1928 gcc_assert (actual);
1929 maskexpr = actual->expr;
1930 if (maskexpr && maskexpr->rank != 0)
1932 maskss = gfc_walk_expr (maskexpr);
1933 gcc_assert (maskss != gfc_ss_terminator);
1938 /* Initialize the scalarizer. */
1939 gfc_init_loopinfo (&loop);
1940 gfc_add_ss_to_loop (&loop, arrayss);
1942 gfc_add_ss_to_loop (&loop, maskss);
1944 /* Initialize the loop. */
1945 gfc_conv_ss_startstride (&loop);
1946 gfc_conv_loop_setup (&loop);
1948 gfc_mark_ss_chain_used (arrayss, 1);
1950 gfc_mark_ss_chain_used (maskss, 1);
1951 /* Generate the loop body. */
1952 gfc_start_scalarized_body (&loop, &body);
1954 /* If we have a mask, only add this element if the mask is set. */
1957 gfc_init_se (&maskse, NULL);
1958 gfc_copy_loopinfo_to_se (&maskse, &loop);
1960 gfc_conv_expr_val (&maskse, maskexpr);
1961 gfc_add_block_to_block (&body, &maskse.pre);
1963 gfc_start_block (&block);
1966 gfc_init_block (&block);
1968 /* Compare with the current limit. */
1969 gfc_init_se (&arrayse, NULL);
1970 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1971 arrayse.ss = arrayss;
1972 gfc_conv_expr_val (&arrayse, arrayexpr);
1973 gfc_add_block_to_block (&block, &arrayse.pre);
1975 /* Assign the value to the limit... */
1976 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
1978 /* If it is a more extreme value. */
1979 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
1980 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1981 gfc_add_expr_to_block (&block, tmp);
1982 gfc_add_block_to_block (&block, &arrayse.post);
1984 tmp = gfc_finish_block (&block);
1986 /* We enclose the above in if (mask) {...}. */
1987 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1988 gfc_add_expr_to_block (&body, tmp);
1990 gfc_trans_scalarizing_loops (&loop, &body);
1992 /* For a scalar mask, enclose the loop in an if statement. */
1993 if (maskexpr && maskss == NULL)
1995 gfc_init_se (&maskse, NULL);
1996 gfc_conv_expr_val (&maskse, maskexpr);
1997 gfc_init_block (&block);
1998 gfc_add_block_to_block (&block, &loop.pre);
1999 gfc_add_block_to_block (&block, &loop.post);
2000 tmp = gfc_finish_block (&block);
2002 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2003 gfc_add_expr_to_block (&block, tmp);
2004 gfc_add_block_to_block (&se->pre, &block);
2008 gfc_add_block_to_block (&se->pre, &loop.pre);
2009 gfc_add_block_to_block (&se->pre, &loop.post);
2012 gfc_cleanup_loop (&loop);
2017 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2019 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2026 arg = gfc_conv_intrinsic_function_args (se, expr);
2027 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2028 arg = TREE_VALUE (arg);
2029 type = TREE_TYPE (arg);
2031 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2032 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
2033 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2034 build_int_cst (type, 0));
2035 type = gfc_typenode_for_spec (&expr->ts);
2036 se->expr = convert (type, tmp);
2039 /* Generate code to perform the specified operation. */
2041 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2047 arg = gfc_conv_intrinsic_function_args (se, expr);
2048 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2049 arg = TREE_VALUE (arg);
2050 type = TREE_TYPE (arg);
2052 se->expr = fold_build2 (op, type, arg, arg2);
2057 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2061 arg = gfc_conv_intrinsic_function_args (se, expr);
2062 arg = TREE_VALUE (arg);
2064 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2067 /* Set or clear a single bit. */
2069 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2077 arg = gfc_conv_intrinsic_function_args (se, expr);
2078 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2079 arg = TREE_VALUE (arg);
2080 type = TREE_TYPE (arg);
2082 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2088 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2090 se->expr = fold_build2 (op, type, arg, tmp);
2093 /* Extract a sequence of bits.
2094 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2096 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2105 arg = gfc_conv_intrinsic_function_args (se, expr);
2106 arg2 = TREE_CHAIN (arg);
2107 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
2108 arg = TREE_VALUE (arg);
2109 arg2 = TREE_VALUE (arg2);
2110 type = TREE_TYPE (arg);
2112 mask = build_int_cst (NULL_TREE, -1);
2113 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
2114 mask = build1 (BIT_NOT_EXPR, type, mask);
2116 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
2118 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2121 /* RSHIFT (I, SHIFT) = I >> SHIFT
2122 LSHIFT (I, SHIFT) = I << SHIFT */
2124 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2129 arg = gfc_conv_intrinsic_function_args (se, expr);
2130 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2131 arg = TREE_VALUE (arg);
2133 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2134 TREE_TYPE (arg), arg, arg2);
2137 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2139 : ((shift >= 0) ? i << shift : i >> -shift)
2140 where all shifts are logical shifts. */
2142 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2155 arg = gfc_conv_intrinsic_function_args (se, expr);
2156 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2157 arg = TREE_VALUE (arg);
2158 type = TREE_TYPE (arg);
2159 utype = gfc_unsigned_type (type);
2161 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
2163 /* Left shift if positive. */
2164 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
2166 /* Right shift if negative.
2167 We convert to an unsigned type because we want a logical shift.
2168 The standard doesn't define the case of shifting negative
2169 numbers, and we try to be compatible with other compilers, most
2170 notably g77, here. */
2171 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
2172 convert (utype, arg), width));
2174 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
2175 build_int_cst (TREE_TYPE (arg2), 0));
2176 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2178 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2179 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2181 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
2182 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2184 se->expr = fold_build3 (COND_EXPR, type, cond,
2185 build_int_cst (type, 0), tmp);
2188 /* Circular shift. AKA rotate or barrel shift. */
2190 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2201 arg = gfc_conv_intrinsic_function_args (se, expr);
2202 arg2 = TREE_CHAIN (arg);
2203 arg3 = TREE_CHAIN (arg2);
2206 /* Use a library function for the 3 parameter version. */
2207 tree int4type = gfc_get_int_type (4);
2209 type = TREE_TYPE (TREE_VALUE (arg));
2210 /* We convert the first argument to at least 4 bytes, and
2211 convert back afterwards. This removes the need for library
2212 functions for all argument sizes, and function will be
2213 aligned to at least 32 bits, so there's no loss. */
2214 if (expr->ts.kind < 4)
2216 tmp = convert (int4type, TREE_VALUE (arg));
2217 TREE_VALUE (arg) = tmp;
2219 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2220 need loads of library functions. They cannot have values >
2221 BIT_SIZE (I) so the conversion is safe. */
2222 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
2223 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
2225 switch (expr->ts.kind)
2230 tmp = gfor_fndecl_math_ishftc4;
2233 tmp = gfor_fndecl_math_ishftc8;
2236 tmp = gfor_fndecl_math_ishftc16;
2241 se->expr = build_function_call_expr (tmp, arg);
2242 /* Convert the result back to the original type, if we extended
2243 the first argument's width above. */
2244 if (expr->ts.kind < 4)
2245 se->expr = convert (type, se->expr);
2249 arg = TREE_VALUE (arg);
2250 arg2 = TREE_VALUE (arg2);
2251 type = TREE_TYPE (arg);
2253 /* Rotate left if positive. */
2254 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
2256 /* Rotate right if negative. */
2257 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
2258 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
2260 zero = build_int_cst (TREE_TYPE (arg2), 0);
2261 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
2262 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2264 /* Do nothing if shift == 0. */
2265 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
2266 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
2269 /* The length of a character string. */
2271 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2280 gcc_assert (!se->ss);
2282 arg = expr->value.function.actual->expr;
2284 type = gfc_typenode_for_spec (&expr->ts);
2285 switch (arg->expr_type)
2288 len = build_int_cst (NULL_TREE, arg->value.character.length);
2292 /* Obtain the string length from the function used by
2293 trans-array.c(gfc_trans_array_constructor). */
2295 get_array_ctor_strlen (arg->value.constructor, &len);
2299 if (arg->expr_type == EXPR_VARIABLE
2300 && (arg->ref == NULL || (arg->ref->next == NULL
2301 && arg->ref->type == REF_ARRAY)))
2303 /* This doesn't catch all cases.
2304 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2305 and the surrounding thread. */
2306 sym = arg->symtree->n.sym;
2307 decl = gfc_get_symbol_decl (sym);
2308 if (decl == current_function_decl && sym->attr.function
2309 && (sym->result == sym))
2310 decl = gfc_get_fake_result_decl (sym, 0);
2312 len = sym->ts.cl->backend_decl;
2317 /* Anybody stupid enough to do this deserves inefficient code. */
2318 gfc_init_se (&argse, se);
2319 gfc_conv_expr (&argse, arg);
2320 gfc_add_block_to_block (&se->pre, &argse.pre);
2321 gfc_add_block_to_block (&se->post, &argse.post);
2322 len = argse.string_length;
2326 se->expr = convert (type, len);
2329 /* The length of a character string not including trailing blanks. */
2331 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2336 args = gfc_conv_intrinsic_function_args (se, expr);
2337 type = gfc_typenode_for_spec (&expr->ts);
2338 se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
2339 se->expr = convert (type, se->expr);
2343 /* Returns the starting position of a substring within a string. */
2346 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2348 tree logical4_type_node = gfc_get_logical_type (4);
2354 args = gfc_conv_intrinsic_function_args (se, expr);
2355 type = gfc_typenode_for_spec (&expr->ts);
2356 tmp = gfc_advance_chain (args, 3);
2357 if (TREE_CHAIN (tmp) == NULL_TREE)
2359 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2361 TREE_CHAIN (tmp) = back;
2365 back = TREE_CHAIN (tmp);
2366 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2369 se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
2370 se->expr = convert (type, se->expr);
2373 /* The ascii value for a single character. */
2375 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2380 arg = gfc_conv_intrinsic_function_args (se, expr);
2381 arg = TREE_VALUE (TREE_CHAIN (arg));
2382 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2383 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2384 type = gfc_typenode_for_spec (&expr->ts);
2386 se->expr = build_fold_indirect_ref (arg);
2387 se->expr = convert (type, se->expr);
2391 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2394 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2403 arg = gfc_conv_intrinsic_function_args (se, expr);
2404 if (expr->ts.type != BT_CHARACTER)
2406 tsource = TREE_VALUE (arg);
2407 arg = TREE_CHAIN (arg);
2408 fsource = TREE_VALUE (arg);
2409 mask = TREE_VALUE (TREE_CHAIN (arg));
2413 /* We do the same as in the non-character case, but the argument
2414 list is different because of the string length arguments. We
2415 also have to set the string length for the result. */
2416 len = TREE_VALUE (arg);
2417 arg = TREE_CHAIN (arg);
2418 tsource = TREE_VALUE (arg);
2419 arg = TREE_CHAIN (TREE_CHAIN (arg));
2420 fsource = TREE_VALUE (arg);
2421 mask = TREE_VALUE (TREE_CHAIN (arg));
2423 se->string_length = len;
2425 type = TREE_TYPE (tsource);
2426 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2431 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2433 gfc_actual_arglist *actual;
2440 gfc_init_se (&argse, NULL);
2441 actual = expr->value.function.actual;
2443 ss = gfc_walk_expr (actual->expr);
2444 gcc_assert (ss != gfc_ss_terminator);
2445 argse.want_pointer = 1;
2446 argse.data_not_needed = 1;
2447 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2448 gfc_add_block_to_block (&se->pre, &argse.pre);
2449 gfc_add_block_to_block (&se->post, &argse.post);
2450 args = gfc_chainon_list (NULL_TREE, argse.expr);
2452 actual = actual->next;
2455 gfc_init_se (&argse, NULL);
2456 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2457 gfc_add_block_to_block (&se->pre, &argse.pre);
2458 args = gfc_chainon_list (args, argse.expr);
2459 fndecl = gfor_fndecl_size1;
2462 fndecl = gfor_fndecl_size0;
2464 se->expr = build_function_call_expr (fndecl, args);
2465 type = gfc_typenode_for_spec (&expr->ts);
2466 se->expr = convert (type, se->expr);
2470 /* Intrinsic string comparison functions. */
2473 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2479 args = gfc_conv_intrinsic_function_args (se, expr);
2480 arg2 = TREE_CHAIN (TREE_CHAIN (args));
2482 se->expr = gfc_build_compare_string (TREE_VALUE (args),
2483 TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
2484 TREE_VALUE (TREE_CHAIN (arg2)));
2486 type = gfc_typenode_for_spec (&expr->ts);
2487 se->expr = fold_build2 (op, type, se->expr,
2488 build_int_cst (TREE_TYPE (se->expr), 0));
2491 /* Generate a call to the adjustl/adjustr library function. */
2493 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2501 args = gfc_conv_intrinsic_function_args (se, expr);
2502 len = TREE_VALUE (args);
2504 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2505 var = gfc_conv_string_tmp (se, type, len);
2506 args = tree_cons (NULL_TREE, var, args);
2508 tmp = build_function_call_expr (fndecl, args);
2509 gfc_add_expr_to_block (&se->pre, tmp);
2511 se->string_length = len;
2515 /* A helper function for gfc_conv_intrinsic_array_transfer to compute
2516 the size of tree expressions in bytes. */
2518 gfc_size_in_bytes (gfc_se *se, gfc_expr *e)
2522 if (e->ts.type == BT_CHARACTER)
2523 tmp = se->string_length;
2528 tmp = gfc_get_element_type (TREE_TYPE (se->expr));
2529 tmp = size_in_bytes (tmp);
2532 tmp = size_in_bytes (TREE_TYPE (TREE_TYPE (se->expr)));
2535 return fold_convert (gfc_array_index_type, tmp);
2539 /* Array transfer statement.
2540 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
2542 typeof<DEST> = typeof<MOLD>
2544 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
2545 sizeof (DEST(0) * SIZE). */
2548 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
2562 gfc_actual_arglist *arg;
2569 gcc_assert (se->loop);
2570 info = &se->ss->data.info;
2572 /* Convert SOURCE. The output from this stage is:-
2573 source_bytes = length of the source in bytes
2574 source = pointer to the source data. */
2575 arg = expr->value.function.actual;
2576 gfc_init_se (&argse, NULL);
2577 ss = gfc_walk_expr (arg->expr);
2579 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
2581 /* Obtain the pointer to source and the length of source in bytes. */
2582 if (ss == gfc_ss_terminator)
2584 gfc_conv_expr_reference (&argse, arg->expr);
2585 source = argse.expr;
2587 /* Obtain the source word length. */
2588 tmp = gfc_size_in_bytes (&argse, arg->expr);
2592 gfc_init_se (&argse, NULL);
2593 argse.want_pointer = 0;
2594 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2595 source = gfc_conv_descriptor_data_get (argse.expr);
2597 /* Repack the source if not a full variable array. */
2598 if (!(arg->expr->expr_type == EXPR_VARIABLE
2599 && arg->expr->ref->u.ar.type == AR_FULL))
2601 tmp = build_fold_addr_expr (argse.expr);
2602 tmp = gfc_chainon_list (NULL_TREE, tmp);
2603 source = build_function_call_expr (gfor_fndecl_in_pack, tmp);
2604 source = gfc_evaluate_now (source, &argse.pre);
2606 /* Free the temporary. */
2607 gfc_start_block (&block);
2608 tmp = convert (pvoid_type_node, source);
2609 tmp = gfc_chainon_list (NULL_TREE, tmp);
2610 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
2611 gfc_add_expr_to_block (&block, tmp);
2612 stmt = gfc_finish_block (&block);
2614 /* Clean up if it was repacked. */
2615 gfc_init_block (&block);
2616 tmp = gfc_conv_array_data (argse.expr);
2617 tmp = build2 (NE_EXPR, boolean_type_node, source, tmp);
2618 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
2619 gfc_add_expr_to_block (&block, tmp);
2620 gfc_add_block_to_block (&block, &se->post);
2621 gfc_init_block (&se->post);
2622 gfc_add_block_to_block (&se->post, &block);
2625 /* Obtain the source word length. */
2626 tmp = gfc_size_in_bytes (&argse, arg->expr);
2628 /* Obtain the size of the array in bytes. */
2629 extent = gfc_create_var (gfc_array_index_type, NULL);
2630 for (n = 0; n < arg->expr->rank; n++)
2633 idx = gfc_rank_cst[n];
2634 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2635 stride = gfc_conv_descriptor_stride (argse.expr, idx);
2636 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2637 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2638 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
2640 gfc_add_modify_expr (&argse.pre, extent, tmp);
2641 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2642 extent, gfc_index_one_node);
2643 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2648 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2649 gfc_add_block_to_block (&se->pre, &argse.pre);
2650 gfc_add_block_to_block (&se->post, &argse.post);
2652 /* Now convert MOLD. The sole output is:
2653 dest_word_len = destination word length in bytes. */
2656 gfc_init_se (&argse, NULL);
2657 ss = gfc_walk_expr (arg->expr);
2659 if (ss == gfc_ss_terminator)
2661 gfc_conv_expr_reference (&argse, arg->expr);
2663 /* Obtain the source word length. */
2664 tmp = gfc_size_in_bytes (&argse, arg->expr);
2668 gfc_init_se (&argse, NULL);
2669 argse.want_pointer = 0;
2670 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2672 /* Obtain the source word length. */
2673 tmp = gfc_size_in_bytes (&argse, arg->expr);
2676 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
2677 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
2679 /* Finally convert SIZE, if it is present. */
2681 size_words = gfc_create_var (gfc_array_index_type, NULL);
2685 gfc_init_se (&argse, NULL);
2686 gfc_conv_expr_reference (&argse, arg->expr);
2687 tmp = convert (gfc_array_index_type,
2688 build_fold_indirect_ref (argse.expr));
2689 gfc_add_block_to_block (&se->pre, &argse.pre);
2690 gfc_add_block_to_block (&se->post, &argse.post);
2695 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
2696 if (tmp != NULL_TREE)
2698 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2699 tmp, dest_word_len);
2700 tmp = build2 (MIN_EXPR, gfc_array_index_type, tmp, source_bytes);
2705 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
2706 gfc_add_modify_expr (&se->pre, size_words,
2707 build2 (CEIL_DIV_EXPR, gfc_array_index_type,
2708 size_bytes, dest_word_len));
2710 /* Evaluate the bounds of the result. If the loop range exists, we have
2711 to check if it is too large. If so, we modify loop->to be consistent
2712 with min(size, size(source)). Otherwise, size is made consistent with
2713 the loop range, so that the right number of bytes is transferred.*/
2714 n = se->loop->order[0];
2715 if (se->loop->to[n] != NULL_TREE)
2717 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2718 se->loop->to[n], se->loop->from[n]);
2719 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2720 tmp, gfc_index_one_node);
2721 tmp = build2 (MIN_EXPR, gfc_array_index_type,
2723 gfc_add_modify_expr (&se->pre, size_words, tmp);
2724 gfc_add_modify_expr (&se->pre, size_bytes,
2725 build2 (MULT_EXPR, gfc_array_index_type,
2726 size_words, dest_word_len));
2727 upper = build2 (PLUS_EXPR, gfc_array_index_type,
2728 size_words, se->loop->from[n]);
2729 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2730 upper, gfc_index_one_node);
2734 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2735 size_words, gfc_index_one_node);
2736 se->loop->from[n] = gfc_index_zero_node;
2739 se->loop->to[n] = upper;
2741 /* Build a destination descriptor, using the pointer, source, as the
2742 data field. This is already allocated so set callee_alloc. */
2743 tmp = gfc_typenode_for_spec (&expr->ts);
2744 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
2745 info, tmp, false, true, false, false);
2747 /* Use memcpy to do the transfer. */
2748 tmp = gfc_conv_descriptor_data_get (info->descriptor);
2749 args = gfc_chainon_list (NULL_TREE, tmp);
2750 tmp = fold_convert (pvoid_type_node, source);
2751 args = gfc_chainon_list (args, source);
2752 args = gfc_chainon_list (args, size_bytes);
2753 tmp = built_in_decls[BUILT_IN_MEMCPY];
2754 tmp = build_function_call_expr (tmp, args);
2755 gfc_add_expr_to_block (&se->pre, tmp);
2757 se->expr = info->descriptor;
2758 if (expr->ts.type == BT_CHARACTER)
2759 se->string_length = dest_word_len;
2763 /* Scalar transfer statement.
2764 TRANSFER (source, mold) = *(typeof<mold> *)&source. */
2767 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2769 gfc_actual_arglist *arg;
2775 /* Get a pointer to the source. */
2776 arg = expr->value.function.actual;
2777 ss = gfc_walk_expr (arg->expr);
2778 gfc_init_se (&argse, NULL);
2779 if (ss == gfc_ss_terminator)
2780 gfc_conv_expr_reference (&argse, arg->expr);
2782 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2783 gfc_add_block_to_block (&se->pre, &argse.pre);
2784 gfc_add_block_to_block (&se->post, &argse.post);
2788 type = gfc_typenode_for_spec (&expr->ts);
2789 ptr = convert (build_pointer_type (type), ptr);
2790 if (expr->ts.type == BT_CHARACTER)
2792 gfc_init_se (&argse, NULL);
2793 gfc_conv_expr (&argse, arg->expr);
2794 gfc_add_block_to_block (&se->pre, &argse.pre);
2795 gfc_add_block_to_block (&se->post, &argse.post);
2797 se->string_length = argse.string_length;
2801 se->expr = build_fold_indirect_ref (ptr);
2806 /* Generate code for the ALLOCATED intrinsic.
2807 Generate inline code that directly check the address of the argument. */
2810 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2812 gfc_actual_arglist *arg1;
2817 gfc_init_se (&arg1se, NULL);
2818 arg1 = expr->value.function.actual;
2819 ss1 = gfc_walk_expr (arg1->expr);
2820 arg1se.descriptor_only = 1;
2821 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2823 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
2824 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
2825 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2826 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2830 /* Generate code for the ASSOCIATED intrinsic.
2831 If both POINTER and TARGET are arrays, generate a call to library function
2832 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2833 In other cases, generate inline code that directly compare the address of
2834 POINTER with the address of TARGET. */
2837 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2839 gfc_actual_arglist *arg1;
2840 gfc_actual_arglist *arg2;
2846 tree nonzero_charlen;
2847 tree nonzero_arraylen;
2850 gfc_init_se (&arg1se, NULL);
2851 gfc_init_se (&arg2se, NULL);
2852 arg1 = expr->value.function.actual;
2854 ss1 = gfc_walk_expr (arg1->expr);
2858 /* No optional target. */
2859 if (ss1 == gfc_ss_terminator)
2861 /* A pointer to a scalar. */
2862 arg1se.want_pointer = 1;
2863 gfc_conv_expr (&arg1se, arg1->expr);
2868 /* A pointer to an array. */
2869 arg1se.descriptor_only = 1;
2870 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2871 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
2873 gfc_add_block_to_block (&se->pre, &arg1se.pre);
2874 gfc_add_block_to_block (&se->post, &arg1se.post);
2875 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
2876 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
2881 /* An optional target. */
2882 ss2 = gfc_walk_expr (arg2->expr);
2884 nonzero_charlen = NULL_TREE;
2885 if (arg1->expr->ts.type == BT_CHARACTER)
2886 nonzero_charlen = build2 (NE_EXPR, boolean_type_node,
2887 arg1->expr->ts.cl->backend_decl,
2890 if (ss1 == gfc_ss_terminator)
2892 /* A pointer to a scalar. */
2893 gcc_assert (ss2 == gfc_ss_terminator);
2894 arg1se.want_pointer = 1;
2895 gfc_conv_expr (&arg1se, arg1->expr);
2896 arg2se.want_pointer = 1;
2897 gfc_conv_expr (&arg2se, arg2->expr);
2898 gfc_add_block_to_block (&se->pre, &arg1se.pre);
2899 gfc_add_block_to_block (&se->post, &arg1se.post);
2900 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2906 /* An array pointer of zero length is not associated if target is
2908 arg1se.descriptor_only = 1;
2909 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2910 tmp = gfc_conv_descriptor_stride (arg1se.expr,
2911 gfc_rank_cst[arg1->expr->rank - 1]);
2912 nonzero_arraylen = build2 (NE_EXPR, boolean_type_node,
2913 tmp, integer_zero_node);
2915 /* A pointer to an array, call library function _gfor_associated. */
2916 gcc_assert (ss2 != gfc_ss_terminator);
2918 arg1se.want_pointer = 1;
2919 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2920 args = gfc_chainon_list (args, arg1se.expr);
2922 arg2se.want_pointer = 1;
2923 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2924 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2925 gfc_add_block_to_block (&se->post, &arg2se.post);
2926 args = gfc_chainon_list (args, arg2se.expr);
2927 fndecl = gfor_fndecl_associated;
2928 se->expr = build_function_call_expr (fndecl, args);
2929 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
2930 se->expr, nonzero_arraylen);
2934 /* If target is present zero character length pointers cannot
2936 if (nonzero_charlen != NULL_TREE)
2937 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
2938 se->expr, nonzero_charlen);
2941 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2945 /* Scan a string for any one of the characters in a set of characters. */
2948 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2950 tree logical4_type_node = gfc_get_logical_type (4);
2956 args = gfc_conv_intrinsic_function_args (se, expr);
2957 type = gfc_typenode_for_spec (&expr->ts);
2958 tmp = gfc_advance_chain (args, 3);
2959 if (TREE_CHAIN (tmp) == NULL_TREE)
2961 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2963 TREE_CHAIN (tmp) = back;
2967 back = TREE_CHAIN (tmp);
2968 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2971 se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
2972 se->expr = convert (type, se->expr);
2976 /* Verify that a set of characters contains all the characters in a string
2977 by identifying the position of the first character in a string of
2978 characters that does not appear in a given set of characters. */
2981 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2983 tree logical4_type_node = gfc_get_logical_type (4);
2989 args = gfc_conv_intrinsic_function_args (se, expr);
2990 type = gfc_typenode_for_spec (&expr->ts);
2991 tmp = gfc_advance_chain (args, 3);
2992 if (TREE_CHAIN (tmp) == NULL_TREE)
2994 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2996 TREE_CHAIN (tmp) = back;
3000 back = TREE_CHAIN (tmp);
3001 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3004 se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
3005 se->expr = convert (type, se->expr);
3009 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3012 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
3016 args = gfc_conv_intrinsic_function_args (se, expr);
3017 args = TREE_VALUE (args);
3018 args = build_fold_addr_expr (args);
3019 args = tree_cons (NULL_TREE, args, NULL_TREE);
3020 se->expr = build_function_call_expr (gfor_fndecl_si_kind, args);
3023 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3026 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
3028 gfc_actual_arglist *actual;
3033 for (actual = expr->value.function.actual; actual; actual = actual->next)
3035 gfc_init_se (&argse, se);
3037 /* Pass a NULL pointer for an absent arg. */
3038 if (actual->expr == NULL)
3039 argse.expr = null_pointer_node;
3041 gfc_conv_expr_reference (&argse, actual->expr);
3043 gfc_add_block_to_block (&se->pre, &argse.pre);
3044 gfc_add_block_to_block (&se->post, &argse.post);
3045 args = gfc_chainon_list (args, argse.expr);
3047 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3051 /* Generate code for TRIM (A) intrinsic function. */
3054 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3056 tree gfc_int4_type_node = gfc_get_int_type (4);
3065 arglist = NULL_TREE;
3067 type = build_pointer_type (gfc_character1_type_node);
3068 var = gfc_create_var (type, "pstr");
3069 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3070 len = gfc_create_var (gfc_int4_type_node, "len");
3072 tmp = gfc_conv_intrinsic_function_args (se, expr);
3073 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
3074 arglist = gfc_chainon_list (arglist, addr);
3075 arglist = chainon (arglist, tmp);
3077 tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
3078 gfc_add_expr_to_block (&se->pre, tmp);
3080 /* Free the temporary afterwards, if necessary. */
3081 cond = build2 (GT_EXPR, boolean_type_node, len,
3082 build_int_cst (TREE_TYPE (len), 0));
3083 arglist = gfc_chainon_list (NULL_TREE, var);
3084 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
3085 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3086 gfc_add_expr_to_block (&se->post, tmp);
3089 se->string_length = len;
3093 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3096 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3098 tree gfc_int4_type_node = gfc_get_int_type (4);
3107 args = gfc_conv_intrinsic_function_args (se, expr);
3108 len = TREE_VALUE (args);
3109 tmp = gfc_advance_chain (args, 2);
3110 ncopies = TREE_VALUE (tmp);
3111 len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
3112 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3113 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
3115 arglist = NULL_TREE;
3116 arglist = gfc_chainon_list (arglist, var);
3117 arglist = chainon (arglist, args);
3118 tmp = build_function_call_expr (gfor_fndecl_string_repeat, arglist);
3119 gfc_add_expr_to_block (&se->pre, tmp);
3122 se->string_length = len;
3126 /* Generate code for the IARGC intrinsic. */
3129 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3135 /* Call the library function. This always returns an INTEGER(4). */
3136 fndecl = gfor_fndecl_iargc;
3137 tmp = build_function_call_expr (fndecl, NULL_TREE);
3139 /* Convert it to the required type. */
3140 type = gfc_typenode_for_spec (&expr->ts);
3141 tmp = fold_convert (type, tmp);
3147 /* The loc intrinsic returns the address of its argument as
3148 gfc_index_integer_kind integer. */
3151 gfc_conv_intrinsic_loc(gfc_se * se, gfc_expr * expr)
3157 gcc_assert (!se->ss);
3159 arg_expr = expr->value.function.actual->expr;
3160 ss = gfc_walk_expr (arg_expr);
3161 if (ss == gfc_ss_terminator)
3162 gfc_conv_expr_reference (se, arg_expr);
3164 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3165 se->expr= convert (gfc_unsigned_type (long_integer_type_node),
3168 /* Create a temporary variable for loc return value. Without this,
3169 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3170 temp_var = gfc_create_var (gfc_unsigned_type (long_integer_type_node),
3172 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3173 se->expr = temp_var;
3176 /* Generate code for an intrinsic function. Some map directly to library
3177 calls, others get special handling. In some cases the name of the function
3178 used depends on the type specifiers. */
3181 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
3183 gfc_intrinsic_sym *isym;
3187 isym = expr->value.function.isym;
3189 name = &expr->value.function.name[2];
3191 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
3193 lib = gfc_is_intrinsic_libcall (expr);
3197 se->ignore_optional = 1;
3198 gfc_conv_intrinsic_funcall (se, expr);
3203 switch (expr->value.function.isym->generic_id)
3208 case GFC_ISYM_REPEAT:
3209 gfc_conv_intrinsic_repeat (se, expr);
3213 gfc_conv_intrinsic_trim (se, expr);
3216 case GFC_ISYM_SI_KIND:
3217 gfc_conv_intrinsic_si_kind (se, expr);
3220 case GFC_ISYM_SR_KIND:
3221 gfc_conv_intrinsic_sr_kind (se, expr);
3224 case GFC_ISYM_EXPONENT:
3225 gfc_conv_intrinsic_exponent (se, expr);
3229 gfc_conv_intrinsic_scan (se, expr);
3232 case GFC_ISYM_VERIFY:
3233 gfc_conv_intrinsic_verify (se, expr);
3236 case GFC_ISYM_ALLOCATED:
3237 gfc_conv_allocated (se, expr);
3240 case GFC_ISYM_ASSOCIATED:
3241 gfc_conv_associated(se, expr);
3245 gfc_conv_intrinsic_abs (se, expr);
3248 case GFC_ISYM_ADJUSTL:
3249 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
3252 case GFC_ISYM_ADJUSTR:
3253 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
3256 case GFC_ISYM_AIMAG:
3257 gfc_conv_intrinsic_imagpart (se, expr);
3261 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
3265 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
3268 case GFC_ISYM_ANINT:
3269 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
3273 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3277 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
3280 case GFC_ISYM_BTEST:
3281 gfc_conv_intrinsic_btest (se, expr);
3284 case GFC_ISYM_ACHAR:
3286 gfc_conv_intrinsic_char (se, expr);
3289 case GFC_ISYM_CONVERSION:
3291 case GFC_ISYM_LOGICAL:
3293 gfc_conv_intrinsic_conversion (se, expr);
3296 /* Integer conversions are handled separately to make sure we get the
3297 correct rounding mode. */
3302 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
3306 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
3309 case GFC_ISYM_CEILING:
3310 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
3313 case GFC_ISYM_FLOOR:
3314 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
3318 gfc_conv_intrinsic_mod (se, expr, 0);
3321 case GFC_ISYM_MODULO:
3322 gfc_conv_intrinsic_mod (se, expr, 1);
3325 case GFC_ISYM_CMPLX:
3326 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3329 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3330 gfc_conv_intrinsic_iargc (se, expr);
3333 case GFC_ISYM_COMPLEX:
3334 gfc_conv_intrinsic_cmplx (se, expr, 1);
3337 case GFC_ISYM_CONJG:
3338 gfc_conv_intrinsic_conjg (se, expr);
3341 case GFC_ISYM_COUNT:
3342 gfc_conv_intrinsic_count (se, expr);
3345 case GFC_ISYM_CTIME:
3346 gfc_conv_intrinsic_ctime (se, expr);
3350 gfc_conv_intrinsic_dim (se, expr);
3353 case GFC_ISYM_DOT_PRODUCT:
3354 gfc_conv_intrinsic_dot_product (se, expr);
3357 case GFC_ISYM_DPROD:
3358 gfc_conv_intrinsic_dprod (se, expr);
3361 case GFC_ISYM_FDATE:
3362 gfc_conv_intrinsic_fdate (se, expr);
3366 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3369 case GFC_ISYM_IBCLR:
3370 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3373 case GFC_ISYM_IBITS:
3374 gfc_conv_intrinsic_ibits (se, expr);
3377 case GFC_ISYM_IBSET:
3378 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3381 case GFC_ISYM_IACHAR:
3382 case GFC_ISYM_ICHAR:
3383 /* We assume ASCII character sequence. */
3384 gfc_conv_intrinsic_ichar (se, expr);
3387 case GFC_ISYM_IARGC:
3388 gfc_conv_intrinsic_iargc (se, expr);
3392 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3395 case GFC_ISYM_INDEX:
3396 gfc_conv_intrinsic_index (se, expr);
3400 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3403 case GFC_ISYM_LSHIFT:
3404 gfc_conv_intrinsic_rlshift (se, expr, 0);
3407 case GFC_ISYM_RSHIFT:
3408 gfc_conv_intrinsic_rlshift (se, expr, 1);
3411 case GFC_ISYM_ISHFT:
3412 gfc_conv_intrinsic_ishft (se, expr);
3415 case GFC_ISYM_ISHFTC:
3416 gfc_conv_intrinsic_ishftc (se, expr);
3419 case GFC_ISYM_LBOUND:
3420 gfc_conv_intrinsic_bound (se, expr, 0);
3423 case GFC_ISYM_TRANSPOSE:
3424 if (se->ss && se->ss->useflags)
3426 gfc_conv_tmp_array_ref (se);
3427 gfc_advance_se_ss_chain (se);
3430 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3434 gfc_conv_intrinsic_len (se, expr);
3437 case GFC_ISYM_LEN_TRIM:
3438 gfc_conv_intrinsic_len_trim (se, expr);
3442 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3446 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3450 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3454 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3458 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3461 case GFC_ISYM_MAXLOC:
3462 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3465 case GFC_ISYM_MAXVAL:
3466 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3469 case GFC_ISYM_MERGE:
3470 gfc_conv_intrinsic_merge (se, expr);
3474 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3477 case GFC_ISYM_MINLOC:
3478 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3481 case GFC_ISYM_MINVAL:
3482 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3486 gfc_conv_intrinsic_not (se, expr);
3490 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3493 case GFC_ISYM_PRESENT:
3494 gfc_conv_intrinsic_present (se, expr);
3497 case GFC_ISYM_PRODUCT:
3498 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3502 gfc_conv_intrinsic_sign (se, expr);
3506 gfc_conv_intrinsic_size (se, expr);
3510 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3513 case GFC_ISYM_TRANSFER:
3516 if (se->ss->useflags)
3518 /* Access the previously obtained result. */
3519 gfc_conv_tmp_array_ref (se);
3520 gfc_advance_se_ss_chain (se);
3524 gfc_conv_intrinsic_array_transfer (se, expr);
3527 gfc_conv_intrinsic_transfer (se, expr);
3530 case GFC_ISYM_TTYNAM:
3531 gfc_conv_intrinsic_ttynam (se, expr);
3534 case GFC_ISYM_UBOUND:
3535 gfc_conv_intrinsic_bound (se, expr, 1);
3539 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3543 gfc_conv_intrinsic_loc (se, expr);
3546 case GFC_ISYM_ACCESS:
3547 case GFC_ISYM_CHDIR:
3548 case GFC_ISYM_CHMOD:
3549 case GFC_ISYM_ETIME:
3551 case GFC_ISYM_FGETC:
3554 case GFC_ISYM_FPUTC:
3555 case GFC_ISYM_FSTAT:
3556 case GFC_ISYM_FTELL:
3557 case GFC_ISYM_GETCWD:
3558 case GFC_ISYM_GETGID:
3559 case GFC_ISYM_GETPID:
3560 case GFC_ISYM_GETUID:
3561 case GFC_ISYM_HOSTNM:
3563 case GFC_ISYM_IERRNO:
3564 case GFC_ISYM_IRAND:
3565 case GFC_ISYM_ISATTY:
3567 case GFC_ISYM_LSTAT:
3568 case GFC_ISYM_MALLOC:
3569 case GFC_ISYM_MATMUL:
3570 case GFC_ISYM_MCLOCK:
3571 case GFC_ISYM_MCLOCK8:
3573 case GFC_ISYM_RENAME:
3574 case GFC_ISYM_SECOND:
3575 case GFC_ISYM_SECNDS:
3576 case GFC_ISYM_SIGNAL:
3578 case GFC_ISYM_SYMLNK:
3579 case GFC_ISYM_SYSTEM:
3581 case GFC_ISYM_TIME8:
3582 case GFC_ISYM_UMASK:
3583 case GFC_ISYM_UNLINK:
3584 gfc_conv_intrinsic_funcall (se, expr);
3588 gfc_conv_intrinsic_lib_function (se, expr);
3594 /* This generates code to execute before entering the scalarization loop.
3595 Currently does nothing. */
3598 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
3600 switch (ss->expr->value.function.isym->generic_id)
3602 case GFC_ISYM_UBOUND:
3603 case GFC_ISYM_LBOUND:
3612 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
3613 inside the scalarization loop. */
3616 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
3620 /* The two argument version returns a scalar. */
3621 if (expr->value.function.actual->next->expr)
3624 newss = gfc_get_ss ();
3625 newss->type = GFC_SS_INTRINSIC;
3628 newss->data.info.dimen = 1;
3634 /* Walk an intrinsic array libcall. */
3637 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
3641 gcc_assert (expr->rank > 0);
3643 newss = gfc_get_ss ();
3644 newss->type = GFC_SS_FUNCTION;
3647 newss->data.info.dimen = expr->rank;
3653 /* Returns nonzero if the specified intrinsic function call maps directly to a
3654 an external library call. Should only be used for functions that return
3658 gfc_is_intrinsic_libcall (gfc_expr * expr)
3660 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3661 gcc_assert (expr->rank > 0);
3663 switch (expr->value.function.isym->generic_id)
3667 case GFC_ISYM_COUNT:
3668 case GFC_ISYM_MATMUL:
3669 case GFC_ISYM_MAXLOC:
3670 case GFC_ISYM_MAXVAL:
3671 case GFC_ISYM_MINLOC:
3672 case GFC_ISYM_MINVAL:
3673 case GFC_ISYM_PRODUCT:
3675 case GFC_ISYM_SHAPE:
3676 case GFC_ISYM_SPREAD:
3677 case GFC_ISYM_TRANSPOSE:
3678 /* Ignore absent optional parameters. */
3681 case GFC_ISYM_RESHAPE:
3682 case GFC_ISYM_CSHIFT:
3683 case GFC_ISYM_EOSHIFT:
3685 case GFC_ISYM_UNPACK:
3686 /* Pass absent optional parameters. */
3694 /* Walk an intrinsic function. */
3696 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3697 gfc_intrinsic_sym * isym)
3701 if (isym->elemental)
3702 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
3704 if (expr->rank == 0)
3707 if (gfc_is_intrinsic_libcall (expr))
3708 return gfc_walk_intrinsic_libfunc (ss, expr);
3710 /* Special cases. */
3711 switch (isym->generic_id)
3713 case GFC_ISYM_LBOUND:
3714 case GFC_ISYM_UBOUND:
3715 return gfc_walk_intrinsic_bound (ss, expr);
3717 case GFC_ISYM_TRANSFER:
3718 return gfc_walk_intrinsic_libfunc (ss, expr);
3721 /* This probably meant someone forgot to add an intrinsic to the above
3722 list(s) when they implemented it, or something's gone horribly wrong.
3724 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3725 expr->value.function.name);
3729 #include "gt-fortran-trans-intrinsic.h"