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. */
163 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
165 /* Evaluate the arguments to an intrinsic function. */
168 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
170 gfc_actual_arglist *actual;
172 gfc_intrinsic_arg *formal;
177 formal = expr->value.function.isym->formal;
179 for (actual = expr->value.function.actual; actual; actual = actual->next,
180 formal = formal ? formal->next : NULL)
183 /* Skip omitted optional arguments. */
187 /* Evaluate the parameter. This will substitute scalarized
188 references automatically. */
189 gfc_init_se (&argse, se);
191 if (e->ts.type == BT_CHARACTER)
193 gfc_conv_expr (&argse, e);
194 gfc_conv_string_parameter (&argse);
195 args = gfc_chainon_list (args, argse.string_length);
198 gfc_conv_expr_val (&argse, e);
200 /* If an optional argument is itself an optional dummy argument,
201 check its presence and substitute a null if absent. */
202 if (e->expr_type ==EXPR_VARIABLE
203 && e->symtree->n.sym->attr.optional
206 gfc_conv_missing_dummy (&argse, e, formal->ts);
208 gfc_add_block_to_block (&se->pre, &argse.pre);
209 gfc_add_block_to_block (&se->post, &argse.post);
210 args = gfc_chainon_list (args, argse.expr);
216 /* Conversions between different types are output by the frontend as
217 intrinsic functions. We implement these directly with inline code. */
220 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
225 /* Evaluate the argument. */
226 type = gfc_typenode_for_spec (&expr->ts);
227 gcc_assert (expr->value.function.actual->expr);
228 arg = gfc_conv_intrinsic_function_args (se, expr);
229 arg = TREE_VALUE (arg);
231 /* Conversion from complex to non-complex involves taking the real
232 component of the value. */
233 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
234 && expr->ts.type != BT_COMPLEX)
238 artype = TREE_TYPE (TREE_TYPE (arg));
239 arg = build1 (REALPART_EXPR, artype, arg);
242 se->expr = convert (type, arg);
245 /* This is needed because the gcc backend only implements
246 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
247 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
248 Similarly for CEILING. */
251 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
258 argtype = TREE_TYPE (arg);
259 arg = gfc_evaluate_now (arg, pblock);
261 intval = convert (type, arg);
262 intval = gfc_evaluate_now (intval, pblock);
264 tmp = convert (argtype, intval);
265 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
267 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
268 build_int_cst (type, 1));
269 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
274 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
275 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
278 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
287 argtype = TREE_TYPE (arg);
288 arg = gfc_evaluate_now (arg, pblock);
290 real_from_string (&r, "0.5");
291 pos = build_real (argtype, r);
293 real_from_string (&r, "-0.5");
294 neg = build_real (argtype, r);
296 tmp = gfc_build_const (argtype, integer_zero_node);
297 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
299 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
300 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
301 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
305 /* Convert a real to an integer using a specific rounding mode.
306 Ideally we would just build the corresponding GENERIC node,
307 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
310 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
311 enum rounding_mode op)
316 return build_fixbound_expr (pblock, arg, type, 0);
320 return build_fixbound_expr (pblock, arg, type, 1);
324 return build_round_expr (pblock, arg, type);
327 gcc_assert (op == RND_TRUNC);
328 return build1 (FIX_TRUNC_EXPR, type, arg);
333 /* Round a real value using the specified rounding mode.
334 We use a temporary integer of that same kind size as the result.
335 Values larger than those that can be represented by this kind are
336 unchanged, as they will not be accurate enough to represent the
338 huge = HUGE (KIND (a))
339 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
343 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
354 kind = expr->ts.kind;
357 /* We have builtin functions for some cases. */
400 /* Evaluate the argument. */
401 gcc_assert (expr->value.function.actual->expr);
402 arg = gfc_conv_intrinsic_function_args (se, expr);
404 /* Use a builtin function if one exists. */
405 if (n != END_BUILTINS)
407 tmp = built_in_decls[n];
408 se->expr = build_function_call_expr (tmp, arg);
412 /* This code is probably redundant, but we'll keep it lying around just
414 type = gfc_typenode_for_spec (&expr->ts);
415 arg = TREE_VALUE (arg);
416 arg = gfc_evaluate_now (arg, &se->pre);
418 /* Test if the value is too large to handle sensibly. */
419 gfc_set_model_kind (kind);
421 n = gfc_validate_kind (BT_INTEGER, kind, false);
422 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
423 tmp = gfc_conv_mpfr_to_tree (huge, kind);
424 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
426 mpfr_neg (huge, huge, GFC_RND_MODE);
427 tmp = gfc_conv_mpfr_to_tree (huge, kind);
428 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
429 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
430 itype = gfc_get_int_type (kind);
432 tmp = build_fix_expr (&se->pre, arg, itype, op);
433 tmp = convert (type, tmp);
434 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
439 /* Convert to an integer using the specified rounding mode. */
442 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
447 /* Evaluate the argument. */
448 type = gfc_typenode_for_spec (&expr->ts);
449 gcc_assert (expr->value.function.actual->expr);
450 arg = gfc_conv_intrinsic_function_args (se, expr);
451 arg = TREE_VALUE (arg);
453 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
455 /* Conversion to a different integer kind. */
456 se->expr = convert (type, arg);
460 /* Conversion from complex to non-complex involves taking the real
461 component of the value. */
462 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
463 && expr->ts.type != BT_COMPLEX)
467 artype = TREE_TYPE (TREE_TYPE (arg));
468 arg = build1 (REALPART_EXPR, artype, arg);
471 se->expr = build_fix_expr (&se->pre, arg, type, op);
476 /* Get the imaginary component of a value. */
479 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
483 arg = gfc_conv_intrinsic_function_args (se, expr);
484 arg = TREE_VALUE (arg);
485 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
489 /* Get the complex conjugate of a value. */
492 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
496 arg = gfc_conv_intrinsic_function_args (se, expr);
497 arg = TREE_VALUE (arg);
498 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
502 /* Initialize function decls for library functions. The external functions
503 are created as required. Builtin functions are added here. */
506 gfc_build_intrinsic_lib_fndecls (void)
508 gfc_intrinsic_map_t *m;
510 /* Add GCC builtin functions. */
511 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
513 if (m->code_r4 != END_BUILTINS)
514 m->real4_decl = built_in_decls[m->code_r4];
515 if (m->code_r8 != END_BUILTINS)
516 m->real8_decl = built_in_decls[m->code_r8];
517 if (m->code_r10 != END_BUILTINS)
518 m->real10_decl = built_in_decls[m->code_r10];
519 if (m->code_r16 != END_BUILTINS)
520 m->real16_decl = built_in_decls[m->code_r16];
521 if (m->code_c4 != END_BUILTINS)
522 m->complex4_decl = built_in_decls[m->code_c4];
523 if (m->code_c8 != END_BUILTINS)
524 m->complex8_decl = built_in_decls[m->code_c8];
525 if (m->code_c10 != END_BUILTINS)
526 m->complex10_decl = built_in_decls[m->code_c10];
527 if (m->code_c16 != END_BUILTINS)
528 m->complex16_decl = built_in_decls[m->code_c16];
533 /* Create a fndecl for a simple intrinsic library function. */
536 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
541 gfc_actual_arglist *actual;
544 char name[GFC_MAX_SYMBOL_LEN + 3];
547 if (ts->type == BT_REAL)
552 pdecl = &m->real4_decl;
555 pdecl = &m->real8_decl;
558 pdecl = &m->real10_decl;
561 pdecl = &m->real16_decl;
567 else if (ts->type == BT_COMPLEX)
569 gcc_assert (m->complex_available);
574 pdecl = &m->complex4_decl;
577 pdecl = &m->complex8_decl;
580 pdecl = &m->complex10_decl;
583 pdecl = &m->complex16_decl;
598 snprintf (name, sizeof (name), "%s%s%s",
599 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
600 else if (ts->kind == 8)
601 snprintf (name, sizeof (name), "%s%s",
602 ts->type == BT_COMPLEX ? "c" : "", m->name);
605 gcc_assert (ts->kind == 10 || ts->kind == 16);
606 snprintf (name, sizeof (name), "%s%s%s",
607 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
612 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
613 ts->type == BT_COMPLEX ? 'c' : 'r',
617 argtypes = NULL_TREE;
618 for (actual = expr->value.function.actual; actual; actual = actual->next)
620 type = gfc_typenode_for_spec (&actual->expr->ts);
621 argtypes = gfc_chainon_list (argtypes, type);
623 argtypes = gfc_chainon_list (argtypes, void_type_node);
624 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
625 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
627 /* Mark the decl as external. */
628 DECL_EXTERNAL (fndecl) = 1;
629 TREE_PUBLIC (fndecl) = 1;
631 /* Mark it __attribute__((const)), if possible. */
632 TREE_READONLY (fndecl) = m->is_constant;
634 rest_of_decl_compilation (fndecl, 1, 0);
641 /* Convert an intrinsic function into an external or builtin call. */
644 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
646 gfc_intrinsic_map_t *m;
649 gfc_generic_isym_id id;
651 id = expr->value.function.isym->generic_id;
652 /* Find the entry for this function. */
653 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
659 if (m->id == GFC_ISYM_NONE)
661 internal_error ("Intrinsic function %s(%d) not recognized",
662 expr->value.function.name, id);
665 /* Get the decl and generate the call. */
666 args = gfc_conv_intrinsic_function_args (se, expr);
667 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
668 se->expr = build_function_call_expr (fndecl, args);
671 /* Generate code for EXPONENT(X) intrinsic function. */
674 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
679 args = gfc_conv_intrinsic_function_args (se, expr);
681 a1 = expr->value.function.actual->expr;
685 fndecl = gfor_fndecl_math_exponent4;
688 fndecl = gfor_fndecl_math_exponent8;
691 fndecl = gfor_fndecl_math_exponent10;
694 fndecl = gfor_fndecl_math_exponent16;
700 se->expr = build_function_call_expr (fndecl, args);
703 /* Evaluate a single upper or lower bound. */
704 /* TODO: bound intrinsic generates way too much unnecessary code. */
707 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
709 gfc_actual_arglist *arg;
710 gfc_actual_arglist *arg2;
715 tree cond, cond1, cond2, cond3, cond4, size;
723 arg = expr->value.function.actual;
728 /* Create an implicit second parameter from the loop variable. */
729 gcc_assert (!arg2->expr);
730 gcc_assert (se->loop->dimen == 1);
731 gcc_assert (se->ss->expr == expr);
732 gfc_advance_se_ss_chain (se);
733 bound = se->loop->loopvar[0];
734 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
739 /* use the passed argument. */
740 gcc_assert (arg->next->expr);
741 gfc_init_se (&argse, NULL);
742 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
743 gfc_add_block_to_block (&se->pre, &argse.pre);
745 /* Convert from one based to zero based. */
746 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
750 /* TODO: don't re-evaluate the descriptor on each iteration. */
751 /* Get a descriptor for the first parameter. */
752 ss = gfc_walk_expr (arg->expr);
753 gcc_assert (ss != gfc_ss_terminator);
754 gfc_init_se (&argse, NULL);
755 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
756 gfc_add_block_to_block (&se->pre, &argse.pre);
757 gfc_add_block_to_block (&se->post, &argse.post);
761 if (INTEGER_CST_P (bound))
765 hi = TREE_INT_CST_HIGH (bound);
766 low = TREE_INT_CST_LOW (bound);
767 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
768 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
769 "dimension index", upper ? "UBOUND" : "LBOUND",
774 if (flag_bounds_check)
776 bound = gfc_evaluate_now (bound, &se->pre);
777 cond = fold_build2 (LT_EXPR, boolean_type_node,
778 bound, build_int_cst (TREE_TYPE (bound), 0));
779 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
780 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
781 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
782 gfc_trans_runtime_check (cond, gfc_msg_fault, &se->pre, &expr->where);
786 ubound = gfc_conv_descriptor_ubound (desc, bound);
787 lbound = gfc_conv_descriptor_lbound (desc, bound);
789 /* Follow any component references. */
790 if (arg->expr->expr_type == EXPR_VARIABLE
791 || arg->expr->expr_type == EXPR_CONSTANT)
793 as = arg->expr->symtree->n.sym->as;
794 for (ref = arg->expr->ref; ref; ref = ref->next)
799 as = ref->u.c.component->as;
807 switch (ref->u.ar.type)
825 /* 13.14.53: Result value for LBOUND
827 Case (i): For an array section or for an array expression other than a
828 whole array or array structure component, LBOUND(ARRAY, DIM)
829 has the value 1. For a whole array or array structure
830 component, LBOUND(ARRAY, DIM) has the value:
831 (a) equal to the lower bound for subscript DIM of ARRAY if
832 dimension DIM of ARRAY does not have extent zero
833 or if ARRAY is an assumed-size array of rank DIM,
836 13.14.113: Result value for UBOUND
838 Case (i): For an array section or for an array expression other than a
839 whole array or array structure component, UBOUND(ARRAY, DIM)
840 has the value equal to the number of elements in the given
841 dimension; otherwise, it has a value equal to the upper bound
842 for subscript DIM of ARRAY if dimension DIM of ARRAY does
843 not have size zero and has value zero if dimension DIM has
848 tree stride = gfc_conv_descriptor_stride (desc, bound);
850 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
851 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
853 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
854 gfc_index_zero_node);
855 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
857 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
858 gfc_index_zero_node);
859 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
863 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
865 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
866 ubound, gfc_index_zero_node);
870 if (as->type == AS_ASSUMED_SIZE)
871 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
872 build_int_cst (TREE_TYPE (bound),
873 arg->expr->rank - 1));
875 cond = boolean_false_node;
877 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
878 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
880 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
881 lbound, gfc_index_one_node);
888 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
889 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
893 se->expr = gfc_index_one_node;
896 type = gfc_typenode_for_spec (&expr->ts);
897 se->expr = convert (type, se->expr);
902 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
908 args = gfc_conv_intrinsic_function_args (se, expr);
909 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
910 val = TREE_VALUE (args);
912 switch (expr->value.function.actual->expr->ts.type)
916 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
920 switch (expr->ts.kind)
935 se->expr = build_function_call_expr (built_in_decls[n], args);
944 /* Create a complex value from one or two real components. */
947 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
954 type = gfc_typenode_for_spec (&expr->ts);
955 arg = gfc_conv_intrinsic_function_args (se, expr);
956 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
958 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
959 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
961 arg = TREE_VALUE (arg);
962 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
963 imag = convert (TREE_TYPE (type), imag);
966 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
968 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
971 /* Remainder function MOD(A, P) = A - INT(A / P) * P
972 MODULO(A, P) = A - FLOOR (A / P) * P */
973 /* TODO: MOD(x, 0) */
976 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
988 arg = gfc_conv_intrinsic_function_args (se, expr);
990 switch (expr->ts.type)
993 /* Integer case is easy, we've got a builtin op. */
994 arg2 = TREE_VALUE (TREE_CHAIN (arg));
995 arg = TREE_VALUE (arg);
996 type = TREE_TYPE (arg);
999 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
1001 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
1006 /* Check if we have a builtin fmod. */
1007 switch (expr->ts.kind)
1026 /* Use it if it exists. */
1027 if (n != END_BUILTINS)
1029 tmp = built_in_decls[n];
1030 se->expr = build_function_call_expr (tmp, arg);
1035 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1036 arg = TREE_VALUE (arg);
1037 type = TREE_TYPE (arg);
1039 arg = gfc_evaluate_now (arg, &se->pre);
1040 arg2 = gfc_evaluate_now (arg2, &se->pre);
1043 modulo = arg - floor (arg/arg2) * arg2, so
1044 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1046 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1047 thereby avoiding another division and retaining the accuracy
1048 of the builtin function. */
1049 if (n != END_BUILTINS && modulo)
1051 tree zero = gfc_build_const (type, integer_zero_node);
1052 tmp = gfc_evaluate_now (se->expr, &se->pre);
1053 test = build2 (LT_EXPR, boolean_type_node, arg, zero);
1054 test2 = build2 (LT_EXPR, boolean_type_node, arg2, zero);
1055 test2 = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1056 test = build2 (NE_EXPR, boolean_type_node, tmp, zero);
1057 test = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1058 test = gfc_evaluate_now (test, &se->pre);
1059 se->expr = build3 (COND_EXPR, type, test,
1060 build2 (PLUS_EXPR, type, tmp, arg2), tmp);
1064 /* If we do not have a built_in fmod, the calculation is going to
1065 have to be done longhand. */
1066 tmp = build2 (RDIV_EXPR, type, arg, arg2);
1068 /* Test if the value is too large to handle sensibly. */
1069 gfc_set_model_kind (expr->ts.kind);
1071 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1072 ikind = expr->ts.kind;
1075 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1076 ikind = gfc_max_integer_kind;
1078 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1079 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1080 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
1082 mpfr_neg (huge, huge, GFC_RND_MODE);
1083 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1084 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
1085 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1087 itype = gfc_get_int_type (ikind);
1089 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1091 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1092 tmp = convert (type, tmp);
1093 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
1094 tmp = build2 (MULT_EXPR, type, tmp, arg2);
1095 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
1104 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1107 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1116 arg = gfc_conv_intrinsic_function_args (se, expr);
1117 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1118 arg = TREE_VALUE (arg);
1119 type = TREE_TYPE (arg);
1121 val = build2 (MINUS_EXPR, type, arg, arg2);
1122 val = gfc_evaluate_now (val, &se->pre);
1124 zero = gfc_build_const (type, integer_zero_node);
1125 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
1126 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
1130 /* SIGN(A, B) is absolute value of A times sign of B.
1131 The real value versions use library functions to ensure the correct
1132 handling of negative zero. Integer case implemented as:
1133 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
1137 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1148 arg = gfc_conv_intrinsic_function_args (se, expr);
1149 if (expr->ts.type == BT_REAL)
1151 switch (expr->ts.kind)
1154 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1157 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1161 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1166 se->expr = build_function_call_expr (tmp, arg);
1170 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1171 arg = TREE_VALUE (arg);
1172 type = TREE_TYPE (arg);
1173 zero = gfc_build_const (type, integer_zero_node);
1175 testa = fold_build2 (GE_EXPR, boolean_type_node, arg, zero);
1176 testb = fold_build2 (GE_EXPR, boolean_type_node, arg2, zero);
1177 tmp = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, testa, testb);
1178 se->expr = fold_build3 (COND_EXPR, type, tmp,
1179 build1 (NEGATE_EXPR, type, arg), arg);
1183 /* Test for the presence of an optional argument. */
1186 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1190 arg = expr->value.function.actual->expr;
1191 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1192 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1193 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1197 /* Calculate the double precision product of two single precision values. */
1200 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1206 arg = gfc_conv_intrinsic_function_args (se, expr);
1207 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1208 arg = TREE_VALUE (arg);
1210 /* Convert the args to double precision before multiplying. */
1211 type = gfc_typenode_for_spec (&expr->ts);
1212 arg = convert (type, arg);
1213 arg2 = convert (type, arg2);
1214 se->expr = build2 (MULT_EXPR, type, arg, arg2);
1218 /* Return a length one character string containing an ascii character. */
1221 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1227 arg = gfc_conv_intrinsic_function_args (se, expr);
1228 arg = TREE_VALUE (arg);
1230 /* We currently don't support character types != 1. */
1231 gcc_assert (expr->ts.kind == 1);
1232 type = gfc_character1_type_node;
1233 var = gfc_create_var (type, "char");
1235 arg = convert (type, arg);
1236 gfc_add_modify_expr (&se->pre, var, arg);
1237 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1238 se->string_length = integer_one_node;
1243 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1251 tree gfc_int8_type_node = gfc_get_int_type (8);
1253 type = build_pointer_type (gfc_character1_type_node);
1254 var = gfc_create_var (type, "pstr");
1255 len = gfc_create_var (gfc_int8_type_node, "len");
1257 tmp = gfc_conv_intrinsic_function_args (se, expr);
1258 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1259 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1260 arglist = chainon (arglist, tmp);
1262 tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
1263 gfc_add_expr_to_block (&se->pre, tmp);
1265 /* Free the temporary afterwards, if necessary. */
1266 cond = build2 (GT_EXPR, boolean_type_node, len,
1267 build_int_cst (TREE_TYPE (len), 0));
1268 arglist = gfc_chainon_list (NULL_TREE, var);
1269 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1270 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1271 gfc_add_expr_to_block (&se->post, tmp);
1274 se->string_length = len;
1279 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1287 tree gfc_int4_type_node = gfc_get_int_type (4);
1289 type = build_pointer_type (gfc_character1_type_node);
1290 var = gfc_create_var (type, "pstr");
1291 len = gfc_create_var (gfc_int4_type_node, "len");
1293 tmp = gfc_conv_intrinsic_function_args (se, expr);
1294 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1295 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1296 arglist = chainon (arglist, tmp);
1298 tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
1299 gfc_add_expr_to_block (&se->pre, tmp);
1301 /* Free the temporary afterwards, if necessary. */
1302 cond = build2 (GT_EXPR, boolean_type_node, len,
1303 build_int_cst (TREE_TYPE (len), 0));
1304 arglist = gfc_chainon_list (NULL_TREE, var);
1305 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1306 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1307 gfc_add_expr_to_block (&se->post, tmp);
1310 se->string_length = len;
1314 /* Return a character string containing the tty name. */
1317 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1325 tree gfc_int4_type_node = gfc_get_int_type (4);
1327 type = build_pointer_type (gfc_character1_type_node);
1328 var = gfc_create_var (type, "pstr");
1329 len = gfc_create_var (gfc_int4_type_node, "len");
1331 tmp = gfc_conv_intrinsic_function_args (se, expr);
1332 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1333 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1334 arglist = chainon (arglist, tmp);
1336 tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
1337 gfc_add_expr_to_block (&se->pre, tmp);
1339 /* Free the temporary afterwards, if necessary. */
1340 cond = build2 (GT_EXPR, boolean_type_node, len,
1341 build_int_cst (TREE_TYPE (len), 0));
1342 arglist = gfc_chainon_list (NULL_TREE, var);
1343 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1344 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1345 gfc_add_expr_to_block (&se->post, tmp);
1348 se->string_length = len;
1352 /* Get the minimum/maximum value of all the parameters.
1353 minmax (a1, a2, a3, ...)
1366 /* TODO: Mismatching types can occur when specific names are used.
1367 These should be handled during resolution. */
1369 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1380 arg = gfc_conv_intrinsic_function_args (se, expr);
1381 type = gfc_typenode_for_spec (&expr->ts);
1383 limit = TREE_VALUE (arg);
1384 if (TREE_TYPE (limit) != type)
1385 limit = convert (type, limit);
1386 /* Only evaluate the argument once. */
1387 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1388 limit = gfc_evaluate_now(limit, &se->pre);
1390 mvar = gfc_create_var (type, "M");
1391 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1392 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1394 val = TREE_VALUE (arg);
1395 if (TREE_TYPE (val) != type)
1396 val = convert (type, val);
1398 /* Only evaluate the argument once. */
1399 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1400 val = gfc_evaluate_now(val, &se->pre);
1402 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1404 tmp = build2 (op, boolean_type_node, val, limit);
1405 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1406 gfc_add_expr_to_block (&se->pre, tmp);
1407 elsecase = build_empty_stmt ();
1414 /* Create a symbol node for this intrinsic. The symbol from the frontend
1415 has the generic name. */
1418 gfc_get_symbol_for_expr (gfc_expr * expr)
1422 /* TODO: Add symbols for intrinsic function to the global namespace. */
1423 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1424 sym = gfc_new_symbol (expr->value.function.name, NULL);
1427 sym->attr.external = 1;
1428 sym->attr.function = 1;
1429 sym->attr.always_explicit = 1;
1430 sym->attr.proc = PROC_INTRINSIC;
1431 sym->attr.flavor = FL_PROCEDURE;
1435 sym->attr.dimension = 1;
1436 sym->as = gfc_get_array_spec ();
1437 sym->as->type = AS_ASSUMED_SHAPE;
1438 sym->as->rank = expr->rank;
1441 /* TODO: proper argument lists for external intrinsics. */
1445 /* Generate a call to an external intrinsic function. */
1447 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1452 gcc_assert (!se->ss || se->ss->expr == expr);
1455 gcc_assert (expr->rank > 0);
1457 gcc_assert (expr->rank == 0);
1459 sym = gfc_get_symbol_for_expr (expr);
1461 /* Calls to libgfortran_matmul need to be appended special arguments,
1462 to be able to call the BLAS ?gemm functions if required and possible. */
1463 append_args = NULL_TREE;
1464 if (expr->value.function.isym->generic_id == GFC_ISYM_MATMUL
1465 && sym->ts.type != BT_LOGICAL)
1467 tree cint = gfc_get_int_type (gfc_c_int_kind);
1469 if (gfc_option.flag_external_blas
1470 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1471 && (sym->ts.kind == gfc_default_real_kind
1472 || sym->ts.kind == gfc_default_double_kind))
1476 if (sym->ts.type == BT_REAL)
1478 if (sym->ts.kind == gfc_default_real_kind)
1479 gemm_fndecl = gfor_fndecl_sgemm;
1481 gemm_fndecl = gfor_fndecl_dgemm;
1485 if (sym->ts.kind == gfc_default_real_kind)
1486 gemm_fndecl = gfor_fndecl_cgemm;
1488 gemm_fndecl = gfor_fndecl_zgemm;
1491 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1492 append_args = gfc_chainon_list
1493 (append_args, build_int_cst
1494 (cint, gfc_option.blas_matmul_limit));
1495 append_args = gfc_chainon_list (append_args,
1496 gfc_build_addr_expr (NULL_TREE,
1501 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1502 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1503 append_args = gfc_chainon_list (append_args, null_pointer_node);
1507 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1511 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1531 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1540 gfc_actual_arglist *actual;
1547 gfc_conv_intrinsic_funcall (se, expr);
1551 actual = expr->value.function.actual;
1552 type = gfc_typenode_for_spec (&expr->ts);
1553 /* Initialize the result. */
1554 resvar = gfc_create_var (type, "test");
1556 tmp = convert (type, boolean_true_node);
1558 tmp = convert (type, boolean_false_node);
1559 gfc_add_modify_expr (&se->pre, resvar, tmp);
1561 /* Walk the arguments. */
1562 arrayss = gfc_walk_expr (actual->expr);
1563 gcc_assert (arrayss != gfc_ss_terminator);
1565 /* Initialize the scalarizer. */
1566 gfc_init_loopinfo (&loop);
1567 exit_label = gfc_build_label_decl (NULL_TREE);
1568 TREE_USED (exit_label) = 1;
1569 gfc_add_ss_to_loop (&loop, arrayss);
1571 /* Initialize the loop. */
1572 gfc_conv_ss_startstride (&loop);
1573 gfc_conv_loop_setup (&loop);
1575 gfc_mark_ss_chain_used (arrayss, 1);
1576 /* Generate the loop body. */
1577 gfc_start_scalarized_body (&loop, &body);
1579 /* If the condition matches then set the return value. */
1580 gfc_start_block (&block);
1582 tmp = convert (type, boolean_false_node);
1584 tmp = convert (type, boolean_true_node);
1585 gfc_add_modify_expr (&block, resvar, tmp);
1587 /* And break out of the loop. */
1588 tmp = build1_v (GOTO_EXPR, exit_label);
1589 gfc_add_expr_to_block (&block, tmp);
1591 found = gfc_finish_block (&block);
1593 /* Check this element. */
1594 gfc_init_se (&arrayse, NULL);
1595 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1596 arrayse.ss = arrayss;
1597 gfc_conv_expr_val (&arrayse, actual->expr);
1599 gfc_add_block_to_block (&body, &arrayse.pre);
1600 tmp = build2 (op, boolean_type_node, arrayse.expr,
1601 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1602 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1603 gfc_add_expr_to_block (&body, tmp);
1604 gfc_add_block_to_block (&body, &arrayse.post);
1606 gfc_trans_scalarizing_loops (&loop, &body);
1608 /* Add the exit label. */
1609 tmp = build1_v (LABEL_EXPR, exit_label);
1610 gfc_add_expr_to_block (&loop.pre, tmp);
1612 gfc_add_block_to_block (&se->pre, &loop.pre);
1613 gfc_add_block_to_block (&se->pre, &loop.post);
1614 gfc_cleanup_loop (&loop);
1619 /* COUNT(A) = Number of true elements in A. */
1621 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1628 gfc_actual_arglist *actual;
1634 gfc_conv_intrinsic_funcall (se, expr);
1638 actual = expr->value.function.actual;
1640 type = gfc_typenode_for_spec (&expr->ts);
1641 /* Initialize the result. */
1642 resvar = gfc_create_var (type, "count");
1643 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1645 /* Walk the arguments. */
1646 arrayss = gfc_walk_expr (actual->expr);
1647 gcc_assert (arrayss != gfc_ss_terminator);
1649 /* Initialize the scalarizer. */
1650 gfc_init_loopinfo (&loop);
1651 gfc_add_ss_to_loop (&loop, arrayss);
1653 /* Initialize the loop. */
1654 gfc_conv_ss_startstride (&loop);
1655 gfc_conv_loop_setup (&loop);
1657 gfc_mark_ss_chain_used (arrayss, 1);
1658 /* Generate the loop body. */
1659 gfc_start_scalarized_body (&loop, &body);
1661 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1662 build_int_cst (TREE_TYPE (resvar), 1));
1663 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1665 gfc_init_se (&arrayse, NULL);
1666 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1667 arrayse.ss = arrayss;
1668 gfc_conv_expr_val (&arrayse, actual->expr);
1669 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1671 gfc_add_block_to_block (&body, &arrayse.pre);
1672 gfc_add_expr_to_block (&body, tmp);
1673 gfc_add_block_to_block (&body, &arrayse.post);
1675 gfc_trans_scalarizing_loops (&loop, &body);
1677 gfc_add_block_to_block (&se->pre, &loop.pre);
1678 gfc_add_block_to_block (&se->pre, &loop.post);
1679 gfc_cleanup_loop (&loop);
1684 /* Inline implementation of the sum and product intrinsics. */
1686 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1694 gfc_actual_arglist *actual;
1699 gfc_expr *arrayexpr;
1704 gfc_conv_intrinsic_funcall (se, expr);
1708 type = gfc_typenode_for_spec (&expr->ts);
1709 /* Initialize the result. */
1710 resvar = gfc_create_var (type, "val");
1711 if (op == PLUS_EXPR)
1712 tmp = gfc_build_const (type, integer_zero_node);
1714 tmp = gfc_build_const (type, integer_one_node);
1716 gfc_add_modify_expr (&se->pre, resvar, tmp);
1718 /* Walk the arguments. */
1719 actual = expr->value.function.actual;
1720 arrayexpr = actual->expr;
1721 arrayss = gfc_walk_expr (arrayexpr);
1722 gcc_assert (arrayss != gfc_ss_terminator);
1724 actual = actual->next->next;
1725 gcc_assert (actual);
1726 maskexpr = actual->expr;
1727 if (maskexpr && maskexpr->rank != 0)
1729 maskss = gfc_walk_expr (maskexpr);
1730 gcc_assert (maskss != gfc_ss_terminator);
1735 /* Initialize the scalarizer. */
1736 gfc_init_loopinfo (&loop);
1737 gfc_add_ss_to_loop (&loop, arrayss);
1739 gfc_add_ss_to_loop (&loop, maskss);
1741 /* Initialize the loop. */
1742 gfc_conv_ss_startstride (&loop);
1743 gfc_conv_loop_setup (&loop);
1745 gfc_mark_ss_chain_used (arrayss, 1);
1747 gfc_mark_ss_chain_used (maskss, 1);
1748 /* Generate the loop body. */
1749 gfc_start_scalarized_body (&loop, &body);
1751 /* If we have a mask, only add this element if the mask is set. */
1754 gfc_init_se (&maskse, NULL);
1755 gfc_copy_loopinfo_to_se (&maskse, &loop);
1757 gfc_conv_expr_val (&maskse, maskexpr);
1758 gfc_add_block_to_block (&body, &maskse.pre);
1760 gfc_start_block (&block);
1763 gfc_init_block (&block);
1765 /* Do the actual summation/product. */
1766 gfc_init_se (&arrayse, NULL);
1767 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1768 arrayse.ss = arrayss;
1769 gfc_conv_expr_val (&arrayse, arrayexpr);
1770 gfc_add_block_to_block (&block, &arrayse.pre);
1772 tmp = build2 (op, type, resvar, arrayse.expr);
1773 gfc_add_modify_expr (&block, resvar, tmp);
1774 gfc_add_block_to_block (&block, &arrayse.post);
1778 /* We enclose the above in if (mask) {...} . */
1779 tmp = gfc_finish_block (&block);
1781 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1784 tmp = gfc_finish_block (&block);
1785 gfc_add_expr_to_block (&body, tmp);
1787 gfc_trans_scalarizing_loops (&loop, &body);
1789 /* For a scalar mask, enclose the loop in an if statement. */
1790 if (maskexpr && maskss == NULL)
1792 gfc_init_se (&maskse, NULL);
1793 gfc_conv_expr_val (&maskse, maskexpr);
1794 gfc_init_block (&block);
1795 gfc_add_block_to_block (&block, &loop.pre);
1796 gfc_add_block_to_block (&block, &loop.post);
1797 tmp = gfc_finish_block (&block);
1799 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1800 gfc_add_expr_to_block (&block, tmp);
1801 gfc_add_block_to_block (&se->pre, &block);
1805 gfc_add_block_to_block (&se->pre, &loop.pre);
1806 gfc_add_block_to_block (&se->pre, &loop.post);
1809 gfc_cleanup_loop (&loop);
1815 /* Inline implementation of the dot_product intrinsic. This function
1816 is based on gfc_conv_intrinsic_arith (the previous function). */
1818 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1826 gfc_actual_arglist *actual;
1827 gfc_ss *arrayss1, *arrayss2;
1828 gfc_se arrayse1, arrayse2;
1829 gfc_expr *arrayexpr1, *arrayexpr2;
1831 type = gfc_typenode_for_spec (&expr->ts);
1833 /* Initialize the result. */
1834 resvar = gfc_create_var (type, "val");
1835 if (expr->ts.type == BT_LOGICAL)
1836 tmp = convert (type, integer_zero_node);
1838 tmp = gfc_build_const (type, integer_zero_node);
1840 gfc_add_modify_expr (&se->pre, resvar, tmp);
1842 /* Walk argument #1. */
1843 actual = expr->value.function.actual;
1844 arrayexpr1 = actual->expr;
1845 arrayss1 = gfc_walk_expr (arrayexpr1);
1846 gcc_assert (arrayss1 != gfc_ss_terminator);
1848 /* Walk argument #2. */
1849 actual = actual->next;
1850 arrayexpr2 = actual->expr;
1851 arrayss2 = gfc_walk_expr (arrayexpr2);
1852 gcc_assert (arrayss2 != gfc_ss_terminator);
1854 /* Initialize the scalarizer. */
1855 gfc_init_loopinfo (&loop);
1856 gfc_add_ss_to_loop (&loop, arrayss1);
1857 gfc_add_ss_to_loop (&loop, arrayss2);
1859 /* Initialize the loop. */
1860 gfc_conv_ss_startstride (&loop);
1861 gfc_conv_loop_setup (&loop);
1863 gfc_mark_ss_chain_used (arrayss1, 1);
1864 gfc_mark_ss_chain_used (arrayss2, 1);
1866 /* Generate the loop body. */
1867 gfc_start_scalarized_body (&loop, &body);
1868 gfc_init_block (&block);
1870 /* Make the tree expression for [conjg(]array1[)]. */
1871 gfc_init_se (&arrayse1, NULL);
1872 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1873 arrayse1.ss = arrayss1;
1874 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1875 if (expr->ts.type == BT_COMPLEX)
1876 arrayse1.expr = build1 (CONJ_EXPR, type, arrayse1.expr);
1877 gfc_add_block_to_block (&block, &arrayse1.pre);
1879 /* Make the tree expression for array2. */
1880 gfc_init_se (&arrayse2, NULL);
1881 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
1882 arrayse2.ss = arrayss2;
1883 gfc_conv_expr_val (&arrayse2, arrayexpr2);
1884 gfc_add_block_to_block (&block, &arrayse2.pre);
1886 /* Do the actual product and sum. */
1887 if (expr->ts.type == BT_LOGICAL)
1889 tmp = build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
1890 tmp = build2 (TRUTH_OR_EXPR, type, resvar, tmp);
1894 tmp = build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
1895 tmp = build2 (PLUS_EXPR, type, resvar, tmp);
1897 gfc_add_modify_expr (&block, resvar, tmp);
1899 /* Finish up the loop block and the loop. */
1900 tmp = gfc_finish_block (&block);
1901 gfc_add_expr_to_block (&body, tmp);
1903 gfc_trans_scalarizing_loops (&loop, &body);
1904 gfc_add_block_to_block (&se->pre, &loop.pre);
1905 gfc_add_block_to_block (&se->pre, &loop.post);
1906 gfc_cleanup_loop (&loop);
1913 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1917 stmtblock_t ifblock;
1918 stmtblock_t elseblock;
1925 gfc_actual_arglist *actual;
1930 gfc_expr *arrayexpr;
1937 gfc_conv_intrinsic_funcall (se, expr);
1941 /* Initialize the result. */
1942 pos = gfc_create_var (gfc_array_index_type, "pos");
1943 type = gfc_typenode_for_spec (&expr->ts);
1945 /* Walk the arguments. */
1946 actual = expr->value.function.actual;
1947 arrayexpr = actual->expr;
1948 arrayss = gfc_walk_expr (arrayexpr);
1949 gcc_assert (arrayss != gfc_ss_terminator);
1951 actual = actual->next->next;
1952 gcc_assert (actual);
1953 maskexpr = actual->expr;
1954 if (maskexpr && maskexpr->rank != 0)
1956 maskss = gfc_walk_expr (maskexpr);
1957 gcc_assert (maskss != gfc_ss_terminator);
1962 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1963 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1964 switch (arrayexpr->ts.type)
1967 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1971 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1972 arrayexpr->ts.kind);
1979 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1981 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1982 gfc_add_modify_expr (&se->pre, limit, tmp);
1984 /* Initialize the scalarizer. */
1985 gfc_init_loopinfo (&loop);
1986 gfc_add_ss_to_loop (&loop, arrayss);
1988 gfc_add_ss_to_loop (&loop, maskss);
1990 /* Initialize the loop. */
1991 gfc_conv_ss_startstride (&loop);
1992 gfc_conv_loop_setup (&loop);
1994 gcc_assert (loop.dimen == 1);
1996 /* Initialize the position to zero, following Fortran 2003. We are free
1997 to do this because Fortran 95 allows the result of an entirely false
1998 mask to be processor dependent. */
1999 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2001 gfc_mark_ss_chain_used (arrayss, 1);
2003 gfc_mark_ss_chain_used (maskss, 1);
2004 /* Generate the loop body. */
2005 gfc_start_scalarized_body (&loop, &body);
2007 /* If we have a mask, only check this element if the mask is set. */
2010 gfc_init_se (&maskse, NULL);
2011 gfc_copy_loopinfo_to_se (&maskse, &loop);
2013 gfc_conv_expr_val (&maskse, maskexpr);
2014 gfc_add_block_to_block (&body, &maskse.pre);
2016 gfc_start_block (&block);
2019 gfc_init_block (&block);
2021 /* Compare with the current limit. */
2022 gfc_init_se (&arrayse, NULL);
2023 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2024 arrayse.ss = arrayss;
2025 gfc_conv_expr_val (&arrayse, arrayexpr);
2026 gfc_add_block_to_block (&block, &arrayse.pre);
2028 /* We do the following if this is a more extreme value. */
2029 gfc_start_block (&ifblock);
2031 /* Assign the value to the limit... */
2032 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2034 /* Remember where we are. */
2035 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
2037 ifbody = gfc_finish_block (&ifblock);
2039 /* If it is a more extreme value or pos is still zero. */
2040 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node,
2041 build2 (op, boolean_type_node, arrayse.expr, limit),
2042 build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node));
2043 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2044 gfc_add_expr_to_block (&block, tmp);
2048 /* We enclose the above in if (mask) {...}. */
2049 tmp = gfc_finish_block (&block);
2051 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2054 tmp = gfc_finish_block (&block);
2055 gfc_add_expr_to_block (&body, tmp);
2057 gfc_trans_scalarizing_loops (&loop, &body);
2059 /* For a scalar mask, enclose the loop in an if statement. */
2060 if (maskexpr && maskss == NULL)
2062 gfc_init_se (&maskse, NULL);
2063 gfc_conv_expr_val (&maskse, maskexpr);
2064 gfc_init_block (&block);
2065 gfc_add_block_to_block (&block, &loop.pre);
2066 gfc_add_block_to_block (&block, &loop.post);
2067 tmp = gfc_finish_block (&block);
2069 /* For the else part of the scalar mask, just initialize
2070 the pos variable the same way as above. */
2072 gfc_init_block (&elseblock);
2073 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2074 elsetmp = gfc_finish_block (&elseblock);
2076 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2077 gfc_add_expr_to_block (&block, tmp);
2078 gfc_add_block_to_block (&se->pre, &block);
2082 gfc_add_block_to_block (&se->pre, &loop.pre);
2083 gfc_add_block_to_block (&se->pre, &loop.post);
2085 gfc_cleanup_loop (&loop);
2087 /* Return a value in the range 1..SIZE(array). */
2088 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
2089 gfc_index_one_node);
2090 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
2091 /* And convert to the required type. */
2092 se->expr = convert (type, tmp);
2096 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2105 gfc_actual_arglist *actual;
2110 gfc_expr *arrayexpr;
2116 gfc_conv_intrinsic_funcall (se, expr);
2120 type = gfc_typenode_for_spec (&expr->ts);
2121 /* Initialize the result. */
2122 limit = gfc_create_var (type, "limit");
2123 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2124 switch (expr->ts.type)
2127 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2131 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2138 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
2140 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2141 gfc_add_modify_expr (&se->pre, limit, tmp);
2143 /* Walk the arguments. */
2144 actual = expr->value.function.actual;
2145 arrayexpr = actual->expr;
2146 arrayss = gfc_walk_expr (arrayexpr);
2147 gcc_assert (arrayss != gfc_ss_terminator);
2149 actual = actual->next->next;
2150 gcc_assert (actual);
2151 maskexpr = actual->expr;
2152 if (maskexpr && maskexpr->rank != 0)
2154 maskss = gfc_walk_expr (maskexpr);
2155 gcc_assert (maskss != gfc_ss_terminator);
2160 /* Initialize the scalarizer. */
2161 gfc_init_loopinfo (&loop);
2162 gfc_add_ss_to_loop (&loop, arrayss);
2164 gfc_add_ss_to_loop (&loop, maskss);
2166 /* Initialize the loop. */
2167 gfc_conv_ss_startstride (&loop);
2168 gfc_conv_loop_setup (&loop);
2170 gfc_mark_ss_chain_used (arrayss, 1);
2172 gfc_mark_ss_chain_used (maskss, 1);
2173 /* Generate the loop body. */
2174 gfc_start_scalarized_body (&loop, &body);
2176 /* If we have a mask, only add this element if the mask is set. */
2179 gfc_init_se (&maskse, NULL);
2180 gfc_copy_loopinfo_to_se (&maskse, &loop);
2182 gfc_conv_expr_val (&maskse, maskexpr);
2183 gfc_add_block_to_block (&body, &maskse.pre);
2185 gfc_start_block (&block);
2188 gfc_init_block (&block);
2190 /* Compare with the current limit. */
2191 gfc_init_se (&arrayse, NULL);
2192 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2193 arrayse.ss = arrayss;
2194 gfc_conv_expr_val (&arrayse, arrayexpr);
2195 gfc_add_block_to_block (&block, &arrayse.pre);
2197 /* Assign the value to the limit... */
2198 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2200 /* If it is a more extreme value. */
2201 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
2202 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2203 gfc_add_expr_to_block (&block, tmp);
2204 gfc_add_block_to_block (&block, &arrayse.post);
2206 tmp = gfc_finish_block (&block);
2208 /* We enclose the above in if (mask) {...}. */
2209 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2210 gfc_add_expr_to_block (&body, tmp);
2212 gfc_trans_scalarizing_loops (&loop, &body);
2214 /* For a scalar mask, enclose the loop in an if statement. */
2215 if (maskexpr && maskss == NULL)
2217 gfc_init_se (&maskse, NULL);
2218 gfc_conv_expr_val (&maskse, maskexpr);
2219 gfc_init_block (&block);
2220 gfc_add_block_to_block (&block, &loop.pre);
2221 gfc_add_block_to_block (&block, &loop.post);
2222 tmp = gfc_finish_block (&block);
2224 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2225 gfc_add_expr_to_block (&block, tmp);
2226 gfc_add_block_to_block (&se->pre, &block);
2230 gfc_add_block_to_block (&se->pre, &loop.pre);
2231 gfc_add_block_to_block (&se->pre, &loop.post);
2234 gfc_cleanup_loop (&loop);
2239 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2241 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2248 arg = gfc_conv_intrinsic_function_args (se, expr);
2249 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2250 arg = TREE_VALUE (arg);
2251 type = TREE_TYPE (arg);
2253 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2254 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
2255 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2256 build_int_cst (type, 0));
2257 type = gfc_typenode_for_spec (&expr->ts);
2258 se->expr = convert (type, tmp);
2261 /* Generate code to perform the specified operation. */
2263 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2269 arg = gfc_conv_intrinsic_function_args (se, expr);
2270 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2271 arg = TREE_VALUE (arg);
2272 type = TREE_TYPE (arg);
2274 se->expr = fold_build2 (op, type, arg, arg2);
2279 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2283 arg = gfc_conv_intrinsic_function_args (se, expr);
2284 arg = TREE_VALUE (arg);
2286 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2289 /* Set or clear a single bit. */
2291 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2299 arg = gfc_conv_intrinsic_function_args (se, expr);
2300 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2301 arg = TREE_VALUE (arg);
2302 type = TREE_TYPE (arg);
2304 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2310 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2312 se->expr = fold_build2 (op, type, arg, tmp);
2315 /* Extract a sequence of bits.
2316 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2318 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2327 arg = gfc_conv_intrinsic_function_args (se, expr);
2328 arg2 = TREE_CHAIN (arg);
2329 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
2330 arg = TREE_VALUE (arg);
2331 arg2 = TREE_VALUE (arg2);
2332 type = TREE_TYPE (arg);
2334 mask = build_int_cst (NULL_TREE, -1);
2335 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
2336 mask = build1 (BIT_NOT_EXPR, type, mask);
2338 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
2340 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2343 /* RSHIFT (I, SHIFT) = I >> SHIFT
2344 LSHIFT (I, SHIFT) = I << SHIFT */
2346 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2351 arg = gfc_conv_intrinsic_function_args (se, expr);
2352 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2353 arg = TREE_VALUE (arg);
2355 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2356 TREE_TYPE (arg), arg, arg2);
2359 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2361 : ((shift >= 0) ? i << shift : i >> -shift)
2362 where all shifts are logical shifts. */
2364 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2377 arg = gfc_conv_intrinsic_function_args (se, expr);
2378 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2379 arg = TREE_VALUE (arg);
2380 type = TREE_TYPE (arg);
2381 utype = gfc_unsigned_type (type);
2383 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
2385 /* Left shift if positive. */
2386 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
2388 /* Right shift if negative.
2389 We convert to an unsigned type because we want a logical shift.
2390 The standard doesn't define the case of shifting negative
2391 numbers, and we try to be compatible with other compilers, most
2392 notably g77, here. */
2393 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
2394 convert (utype, arg), width));
2396 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
2397 build_int_cst (TREE_TYPE (arg2), 0));
2398 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2400 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2401 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2403 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
2404 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2406 se->expr = fold_build3 (COND_EXPR, type, cond,
2407 build_int_cst (type, 0), tmp);
2410 /* Circular shift. AKA rotate or barrel shift. */
2412 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2423 arg = gfc_conv_intrinsic_function_args (se, expr);
2424 arg2 = TREE_CHAIN (arg);
2425 arg3 = TREE_CHAIN (arg2);
2428 /* Use a library function for the 3 parameter version. */
2429 tree int4type = gfc_get_int_type (4);
2431 type = TREE_TYPE (TREE_VALUE (arg));
2432 /* We convert the first argument to at least 4 bytes, and
2433 convert back afterwards. This removes the need for library
2434 functions for all argument sizes, and function will be
2435 aligned to at least 32 bits, so there's no loss. */
2436 if (expr->ts.kind < 4)
2438 tmp = convert (int4type, TREE_VALUE (arg));
2439 TREE_VALUE (arg) = tmp;
2441 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2442 need loads of library functions. They cannot have values >
2443 BIT_SIZE (I) so the conversion is safe. */
2444 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
2445 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
2447 switch (expr->ts.kind)
2452 tmp = gfor_fndecl_math_ishftc4;
2455 tmp = gfor_fndecl_math_ishftc8;
2458 tmp = gfor_fndecl_math_ishftc16;
2463 se->expr = build_function_call_expr (tmp, arg);
2464 /* Convert the result back to the original type, if we extended
2465 the first argument's width above. */
2466 if (expr->ts.kind < 4)
2467 se->expr = convert (type, se->expr);
2471 arg = TREE_VALUE (arg);
2472 arg2 = TREE_VALUE (arg2);
2473 type = TREE_TYPE (arg);
2475 /* Rotate left if positive. */
2476 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
2478 /* Rotate right if negative. */
2479 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
2480 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
2482 zero = build_int_cst (TREE_TYPE (arg2), 0);
2483 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
2484 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2486 /* Do nothing if shift == 0. */
2487 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
2488 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
2491 /* The length of a character string. */
2493 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2503 gcc_assert (!se->ss);
2505 arg = expr->value.function.actual->expr;
2507 type = gfc_typenode_for_spec (&expr->ts);
2508 switch (arg->expr_type)
2511 len = build_int_cst (NULL_TREE, arg->value.character.length);
2515 /* Obtain the string length from the function used by
2516 trans-array.c(gfc_trans_array_constructor). */
2518 get_array_ctor_strlen (arg->value.constructor, &len);
2522 if (arg->ref == NULL
2523 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2525 /* This doesn't catch all cases.
2526 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2527 and the surrounding thread. */
2528 sym = arg->symtree->n.sym;
2529 decl = gfc_get_symbol_decl (sym);
2530 if (decl == current_function_decl && sym->attr.function
2531 && (sym->result == sym))
2532 decl = gfc_get_fake_result_decl (sym, 0);
2534 len = sym->ts.cl->backend_decl;
2539 /* Otherwise fall through. */
2542 /* Anybody stupid enough to do this deserves inefficient code. */
2543 ss = gfc_walk_expr (arg);
2544 gfc_init_se (&argse, se);
2545 if (ss == gfc_ss_terminator)
2546 gfc_conv_expr (&argse, arg);
2548 gfc_conv_expr_descriptor (&argse, arg, ss);
2549 gfc_add_block_to_block (&se->pre, &argse.pre);
2550 gfc_add_block_to_block (&se->post, &argse.post);
2551 len = argse.string_length;
2554 se->expr = convert (type, len);
2557 /* The length of a character string not including trailing blanks. */
2559 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2564 args = gfc_conv_intrinsic_function_args (se, expr);
2565 type = gfc_typenode_for_spec (&expr->ts);
2566 se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
2567 se->expr = convert (type, se->expr);
2571 /* Returns the starting position of a substring within a string. */
2574 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2576 tree logical4_type_node = gfc_get_logical_type (4);
2582 args = gfc_conv_intrinsic_function_args (se, expr);
2583 type = gfc_typenode_for_spec (&expr->ts);
2584 tmp = gfc_advance_chain (args, 3);
2585 if (TREE_CHAIN (tmp) == NULL_TREE)
2587 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2589 TREE_CHAIN (tmp) = back;
2593 back = TREE_CHAIN (tmp);
2594 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2597 se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
2598 se->expr = convert (type, se->expr);
2601 /* The ascii value for a single character. */
2603 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2608 arg = gfc_conv_intrinsic_function_args (se, expr);
2609 arg = TREE_VALUE (TREE_CHAIN (arg));
2610 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2611 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2612 type = gfc_typenode_for_spec (&expr->ts);
2614 se->expr = build_fold_indirect_ref (arg);
2615 se->expr = convert (type, se->expr);
2619 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2622 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2631 arg = gfc_conv_intrinsic_function_args (se, expr);
2632 if (expr->ts.type != BT_CHARACTER)
2634 tsource = TREE_VALUE (arg);
2635 arg = TREE_CHAIN (arg);
2636 fsource = TREE_VALUE (arg);
2637 mask = TREE_VALUE (TREE_CHAIN (arg));
2641 /* We do the same as in the non-character case, but the argument
2642 list is different because of the string length arguments. We
2643 also have to set the string length for the result. */
2644 len = TREE_VALUE (arg);
2645 arg = TREE_CHAIN (arg);
2646 tsource = TREE_VALUE (arg);
2647 arg = TREE_CHAIN (TREE_CHAIN (arg));
2648 fsource = TREE_VALUE (arg);
2649 mask = TREE_VALUE (TREE_CHAIN (arg));
2651 se->string_length = len;
2653 type = TREE_TYPE (tsource);
2654 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2659 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2661 gfc_actual_arglist *actual;
2668 gfc_init_se (&argse, NULL);
2669 actual = expr->value.function.actual;
2671 ss = gfc_walk_expr (actual->expr);
2672 gcc_assert (ss != gfc_ss_terminator);
2673 argse.want_pointer = 1;
2674 argse.data_not_needed = 1;
2675 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2676 gfc_add_block_to_block (&se->pre, &argse.pre);
2677 gfc_add_block_to_block (&se->post, &argse.post);
2678 args = gfc_chainon_list (NULL_TREE, argse.expr);
2680 actual = actual->next;
2683 gfc_init_se (&argse, NULL);
2684 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2685 gfc_add_block_to_block (&se->pre, &argse.pre);
2686 args = gfc_chainon_list (args, argse.expr);
2687 fndecl = gfor_fndecl_size1;
2690 fndecl = gfor_fndecl_size0;
2692 se->expr = build_function_call_expr (fndecl, args);
2693 type = gfc_typenode_for_spec (&expr->ts);
2694 se->expr = convert (type, se->expr);
2698 /* Intrinsic string comparison functions. */
2701 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2707 args = gfc_conv_intrinsic_function_args (se, expr);
2708 arg2 = TREE_CHAIN (TREE_CHAIN (args));
2710 se->expr = gfc_build_compare_string (TREE_VALUE (args),
2711 TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
2712 TREE_VALUE (TREE_CHAIN (arg2)));
2714 type = gfc_typenode_for_spec (&expr->ts);
2715 se->expr = fold_build2 (op, type, se->expr,
2716 build_int_cst (TREE_TYPE (se->expr), 0));
2719 /* Generate a call to the adjustl/adjustr library function. */
2721 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2729 args = gfc_conv_intrinsic_function_args (se, expr);
2730 len = TREE_VALUE (args);
2732 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2733 var = gfc_conv_string_tmp (se, type, len);
2734 args = tree_cons (NULL_TREE, var, args);
2736 tmp = build_function_call_expr (fndecl, args);
2737 gfc_add_expr_to_block (&se->pre, tmp);
2739 se->string_length = len;
2743 /* A helper function for gfc_conv_intrinsic_array_transfer to compute
2744 the size of tree expressions in bytes. */
2746 gfc_size_in_bytes (gfc_se *se, gfc_expr *e)
2750 if (e->ts.type == BT_CHARACTER)
2751 tmp = se->string_length;
2756 tmp = gfc_get_element_type (TREE_TYPE (se->expr));
2757 tmp = size_in_bytes (tmp);
2760 tmp = size_in_bytes (TREE_TYPE (TREE_TYPE (se->expr)));
2763 return fold_convert (gfc_array_index_type, tmp);
2767 /* Array transfer statement.
2768 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
2770 typeof<DEST> = typeof<MOLD>
2772 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
2773 sizeof (DEST(0) * SIZE). */
2776 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
2790 gfc_actual_arglist *arg;
2797 gcc_assert (se->loop);
2798 info = &se->ss->data.info;
2800 /* Convert SOURCE. The output from this stage is:-
2801 source_bytes = length of the source in bytes
2802 source = pointer to the source data. */
2803 arg = expr->value.function.actual;
2804 gfc_init_se (&argse, NULL);
2805 ss = gfc_walk_expr (arg->expr);
2807 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
2809 /* Obtain the pointer to source and the length of source in bytes. */
2810 if (ss == gfc_ss_terminator)
2812 gfc_conv_expr_reference (&argse, arg->expr);
2813 source = argse.expr;
2815 /* Obtain the source word length. */
2816 tmp = gfc_size_in_bytes (&argse, arg->expr);
2820 gfc_init_se (&argse, NULL);
2821 argse.want_pointer = 0;
2822 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2823 source = gfc_conv_descriptor_data_get (argse.expr);
2825 /* Repack the source if not a full variable array. */
2826 if (!(arg->expr->expr_type == EXPR_VARIABLE
2827 && arg->expr->ref->u.ar.type == AR_FULL))
2829 tmp = build_fold_addr_expr (argse.expr);
2830 tmp = gfc_chainon_list (NULL_TREE, tmp);
2831 source = build_function_call_expr (gfor_fndecl_in_pack, tmp);
2832 source = gfc_evaluate_now (source, &argse.pre);
2834 /* Free the temporary. */
2835 gfc_start_block (&block);
2836 tmp = convert (pvoid_type_node, source);
2837 tmp = gfc_chainon_list (NULL_TREE, tmp);
2838 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
2839 gfc_add_expr_to_block (&block, tmp);
2840 stmt = gfc_finish_block (&block);
2842 /* Clean up if it was repacked. */
2843 gfc_init_block (&block);
2844 tmp = gfc_conv_array_data (argse.expr);
2845 tmp = build2 (NE_EXPR, boolean_type_node, source, tmp);
2846 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
2847 gfc_add_expr_to_block (&block, tmp);
2848 gfc_add_block_to_block (&block, &se->post);
2849 gfc_init_block (&se->post);
2850 gfc_add_block_to_block (&se->post, &block);
2853 /* Obtain the source word length. */
2854 tmp = gfc_size_in_bytes (&argse, arg->expr);
2856 /* Obtain the size of the array in bytes. */
2857 extent = gfc_create_var (gfc_array_index_type, NULL);
2858 for (n = 0; n < arg->expr->rank; n++)
2861 idx = gfc_rank_cst[n];
2862 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2863 stride = gfc_conv_descriptor_stride (argse.expr, idx);
2864 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2865 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2866 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
2868 gfc_add_modify_expr (&argse.pre, extent, tmp);
2869 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2870 extent, gfc_index_one_node);
2871 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2876 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2877 gfc_add_block_to_block (&se->pre, &argse.pre);
2878 gfc_add_block_to_block (&se->post, &argse.post);
2880 /* Now convert MOLD. The sole output is:
2881 dest_word_len = destination word length in bytes. */
2884 gfc_init_se (&argse, NULL);
2885 ss = gfc_walk_expr (arg->expr);
2887 if (ss == gfc_ss_terminator)
2889 gfc_conv_expr_reference (&argse, arg->expr);
2891 /* Obtain the source word length. */
2892 tmp = gfc_size_in_bytes (&argse, arg->expr);
2896 gfc_init_se (&argse, NULL);
2897 argse.want_pointer = 0;
2898 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2900 /* Obtain the source word length. */
2901 tmp = gfc_size_in_bytes (&argse, arg->expr);
2904 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
2905 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
2907 /* Finally convert SIZE, if it is present. */
2909 size_words = gfc_create_var (gfc_array_index_type, NULL);
2913 gfc_init_se (&argse, NULL);
2914 gfc_conv_expr_reference (&argse, arg->expr);
2915 tmp = convert (gfc_array_index_type,
2916 build_fold_indirect_ref (argse.expr));
2917 gfc_add_block_to_block (&se->pre, &argse.pre);
2918 gfc_add_block_to_block (&se->post, &argse.post);
2923 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
2924 if (tmp != NULL_TREE)
2926 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2927 tmp, dest_word_len);
2928 tmp = build2 (MIN_EXPR, gfc_array_index_type, tmp, source_bytes);
2933 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
2934 gfc_add_modify_expr (&se->pre, size_words,
2935 build2 (CEIL_DIV_EXPR, gfc_array_index_type,
2936 size_bytes, dest_word_len));
2938 /* Evaluate the bounds of the result. If the loop range exists, we have
2939 to check if it is too large. If so, we modify loop->to be consistent
2940 with min(size, size(source)). Otherwise, size is made consistent with
2941 the loop range, so that the right number of bytes is transferred.*/
2942 n = se->loop->order[0];
2943 if (se->loop->to[n] != NULL_TREE)
2945 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2946 se->loop->to[n], se->loop->from[n]);
2947 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2948 tmp, gfc_index_one_node);
2949 tmp = build2 (MIN_EXPR, gfc_array_index_type,
2951 gfc_add_modify_expr (&se->pre, size_words, tmp);
2952 gfc_add_modify_expr (&se->pre, size_bytes,
2953 build2 (MULT_EXPR, gfc_array_index_type,
2954 size_words, dest_word_len));
2955 upper = build2 (PLUS_EXPR, gfc_array_index_type,
2956 size_words, se->loop->from[n]);
2957 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2958 upper, gfc_index_one_node);
2962 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2963 size_words, gfc_index_one_node);
2964 se->loop->from[n] = gfc_index_zero_node;
2967 se->loop->to[n] = upper;
2969 /* Build a destination descriptor, using the pointer, source, as the
2970 data field. This is already allocated so set callee_alloc. */
2971 tmp = gfc_typenode_for_spec (&expr->ts);
2972 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
2973 info, tmp, false, true, false, false);
2975 /* Use memcpy to do the transfer. */
2976 tmp = gfc_conv_descriptor_data_get (info->descriptor);
2977 args = gfc_chainon_list (NULL_TREE, tmp);
2978 tmp = fold_convert (pvoid_type_node, source);
2979 args = gfc_chainon_list (args, source);
2980 args = gfc_chainon_list (args, size_bytes);
2981 tmp = built_in_decls[BUILT_IN_MEMCPY];
2982 tmp = build_function_call_expr (tmp, args);
2983 gfc_add_expr_to_block (&se->pre, tmp);
2985 se->expr = info->descriptor;
2986 if (expr->ts.type == BT_CHARACTER)
2987 se->string_length = dest_word_len;
2991 /* Scalar transfer statement.
2992 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
2995 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2997 gfc_actual_arglist *arg;
3002 tree tmpdecl, tmp, args;
3004 /* Get a pointer to the source. */
3005 arg = expr->value.function.actual;
3006 ss = gfc_walk_expr (arg->expr);
3007 gfc_init_se (&argse, NULL);
3008 if (ss == gfc_ss_terminator)
3009 gfc_conv_expr_reference (&argse, arg->expr);
3011 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3012 gfc_add_block_to_block (&se->pre, &argse.pre);
3013 gfc_add_block_to_block (&se->post, &argse.post);
3017 type = gfc_typenode_for_spec (&expr->ts);
3019 if (expr->ts.type == BT_CHARACTER)
3021 ptr = convert (build_pointer_type (type), ptr);
3022 gfc_init_se (&argse, NULL);
3023 gfc_conv_expr (&argse, arg->expr);
3024 gfc_add_block_to_block (&se->pre, &argse.pre);
3025 gfc_add_block_to_block (&se->post, &argse.post);
3027 se->string_length = argse.string_length;
3032 tmpdecl = gfc_create_var (type, "transfer");
3033 moldsize = size_in_bytes (type);
3035 /* Use memcpy to do the transfer. */
3036 tmp = build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3037 tmp = fold_convert (pvoid_type_node, tmp);
3038 args = gfc_chainon_list (NULL_TREE, tmp);
3039 tmp = fold_convert (pvoid_type_node, ptr);
3040 args = gfc_chainon_list (args, tmp);
3041 args = gfc_chainon_list (args, moldsize);
3042 tmp = built_in_decls[BUILT_IN_MEMCPY];
3043 tmp = build_function_call_expr (tmp, args);
3044 gfc_add_expr_to_block (&se->pre, tmp);
3051 /* Generate code for the ALLOCATED intrinsic.
3052 Generate inline code that directly check the address of the argument. */
3055 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3057 gfc_actual_arglist *arg1;
3062 gfc_init_se (&arg1se, NULL);
3063 arg1 = expr->value.function.actual;
3064 ss1 = gfc_walk_expr (arg1->expr);
3065 arg1se.descriptor_only = 1;
3066 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3068 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3069 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
3070 fold_convert (TREE_TYPE (tmp), null_pointer_node));
3071 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3075 /* Generate code for the ASSOCIATED intrinsic.
3076 If both POINTER and TARGET are arrays, generate a call to library function
3077 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3078 In other cases, generate inline code that directly compare the address of
3079 POINTER with the address of TARGET. */
3082 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3084 gfc_actual_arglist *arg1;
3085 gfc_actual_arglist *arg2;
3091 tree nonzero_charlen;
3092 tree nonzero_arraylen;
3095 gfc_init_se (&arg1se, NULL);
3096 gfc_init_se (&arg2se, NULL);
3097 arg1 = expr->value.function.actual;
3099 ss1 = gfc_walk_expr (arg1->expr);
3103 /* No optional target. */
3104 if (ss1 == gfc_ss_terminator)
3106 /* A pointer to a scalar. */
3107 arg1se.want_pointer = 1;
3108 gfc_conv_expr (&arg1se, arg1->expr);
3113 /* A pointer to an array. */
3114 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3115 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3117 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3118 gfc_add_block_to_block (&se->post, &arg1se.post);
3119 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
3120 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3125 /* An optional target. */
3126 ss2 = gfc_walk_expr (arg2->expr);
3128 nonzero_charlen = NULL_TREE;
3129 if (arg1->expr->ts.type == BT_CHARACTER)
3130 nonzero_charlen = build2 (NE_EXPR, boolean_type_node,
3131 arg1->expr->ts.cl->backend_decl,
3134 if (ss1 == gfc_ss_terminator)
3136 /* A pointer to a scalar. */
3137 gcc_assert (ss2 == gfc_ss_terminator);
3138 arg1se.want_pointer = 1;
3139 gfc_conv_expr (&arg1se, arg1->expr);
3140 arg2se.want_pointer = 1;
3141 gfc_conv_expr (&arg2se, arg2->expr);
3142 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3143 gfc_add_block_to_block (&se->post, &arg1se.post);
3144 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
3150 /* An array pointer of zero length is not associated if target is
3152 arg1se.descriptor_only = 1;
3153 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3154 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3155 gfc_rank_cst[arg1->expr->rank - 1]);
3156 nonzero_arraylen = build2 (NE_EXPR, boolean_type_node,
3157 tmp, integer_zero_node);
3159 /* A pointer to an array, call library function _gfor_associated. */
3160 gcc_assert (ss2 != gfc_ss_terminator);
3162 arg1se.want_pointer = 1;
3163 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3164 args = gfc_chainon_list (args, arg1se.expr);
3166 arg2se.want_pointer = 1;
3167 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3168 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3169 gfc_add_block_to_block (&se->post, &arg2se.post);
3170 args = gfc_chainon_list (args, arg2se.expr);
3171 fndecl = gfor_fndecl_associated;
3172 se->expr = build_function_call_expr (fndecl, args);
3173 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3174 se->expr, nonzero_arraylen);
3178 /* If target is present zero character length pointers cannot
3180 if (nonzero_charlen != NULL_TREE)
3181 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3182 se->expr, nonzero_charlen);
3185 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3189 /* Scan a string for any one of the characters in a set of characters. */
3192 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
3194 tree logical4_type_node = gfc_get_logical_type (4);
3200 args = gfc_conv_intrinsic_function_args (se, expr);
3201 type = gfc_typenode_for_spec (&expr->ts);
3202 tmp = gfc_advance_chain (args, 3);
3203 if (TREE_CHAIN (tmp) == NULL_TREE)
3205 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3207 TREE_CHAIN (tmp) = back;
3211 back = TREE_CHAIN (tmp);
3212 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3215 se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
3216 se->expr = convert (type, se->expr);
3220 /* Verify that a set of characters contains all the characters in a string
3221 by identifying the position of the first character in a string of
3222 characters that does not appear in a given set of characters. */
3225 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
3227 tree logical4_type_node = gfc_get_logical_type (4);
3233 args = gfc_conv_intrinsic_function_args (se, expr);
3234 type = gfc_typenode_for_spec (&expr->ts);
3235 tmp = gfc_advance_chain (args, 3);
3236 if (TREE_CHAIN (tmp) == NULL_TREE)
3238 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3240 TREE_CHAIN (tmp) = back;
3244 back = TREE_CHAIN (tmp);
3245 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3248 se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
3249 se->expr = convert (type, se->expr);
3253 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3256 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
3260 args = gfc_conv_intrinsic_function_args (se, expr);
3261 args = TREE_VALUE (args);
3262 args = build_fold_addr_expr (args);
3263 args = tree_cons (NULL_TREE, args, NULL_TREE);
3264 se->expr = build_function_call_expr (gfor_fndecl_si_kind, args);
3267 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3270 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
3272 gfc_actual_arglist *actual;
3277 for (actual = expr->value.function.actual; actual; actual = actual->next)
3279 gfc_init_se (&argse, se);
3281 /* Pass a NULL pointer for an absent arg. */
3282 if (actual->expr == NULL)
3283 argse.expr = null_pointer_node;
3285 gfc_conv_expr_reference (&argse, actual->expr);
3287 gfc_add_block_to_block (&se->pre, &argse.pre);
3288 gfc_add_block_to_block (&se->post, &argse.post);
3289 args = gfc_chainon_list (args, argse.expr);
3291 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3295 /* Generate code for TRIM (A) intrinsic function. */
3298 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3300 tree gfc_int4_type_node = gfc_get_int_type (4);
3309 arglist = NULL_TREE;
3311 type = build_pointer_type (gfc_character1_type_node);
3312 var = gfc_create_var (type, "pstr");
3313 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3314 len = gfc_create_var (gfc_int4_type_node, "len");
3316 tmp = gfc_conv_intrinsic_function_args (se, expr);
3317 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
3318 arglist = gfc_chainon_list (arglist, addr);
3319 arglist = chainon (arglist, tmp);
3321 tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
3322 gfc_add_expr_to_block (&se->pre, tmp);
3324 /* Free the temporary afterwards, if necessary. */
3325 cond = build2 (GT_EXPR, boolean_type_node, len,
3326 build_int_cst (TREE_TYPE (len), 0));
3327 arglist = gfc_chainon_list (NULL_TREE, var);
3328 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
3329 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3330 gfc_add_expr_to_block (&se->post, tmp);
3333 se->string_length = len;
3337 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3340 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3342 tree gfc_int4_type_node = gfc_get_int_type (4);
3351 args = gfc_conv_intrinsic_function_args (se, expr);
3352 len = TREE_VALUE (args);
3353 tmp = gfc_advance_chain (args, 2);
3354 ncopies = TREE_VALUE (tmp);
3355 len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
3356 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3357 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
3359 arglist = NULL_TREE;
3360 arglist = gfc_chainon_list (arglist, var);
3361 arglist = chainon (arglist, args);
3362 tmp = build_function_call_expr (gfor_fndecl_string_repeat, arglist);
3363 gfc_add_expr_to_block (&se->pre, tmp);
3366 se->string_length = len;
3370 /* Generate code for the IARGC intrinsic. */
3373 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3379 /* Call the library function. This always returns an INTEGER(4). */
3380 fndecl = gfor_fndecl_iargc;
3381 tmp = build_function_call_expr (fndecl, NULL_TREE);
3383 /* Convert it to the required type. */
3384 type = gfc_typenode_for_spec (&expr->ts);
3385 tmp = fold_convert (type, tmp);
3391 /* The loc intrinsic returns the address of its argument as
3392 gfc_index_integer_kind integer. */
3395 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3401 gcc_assert (!se->ss);
3403 arg_expr = expr->value.function.actual->expr;
3404 ss = gfc_walk_expr (arg_expr);
3405 if (ss == gfc_ss_terminator)
3406 gfc_conv_expr_reference (se, arg_expr);
3408 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3409 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
3411 /* Create a temporary variable for loc return value. Without this,
3412 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3413 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
3414 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3415 se->expr = temp_var;
3418 /* Generate code for an intrinsic function. Some map directly to library
3419 calls, others get special handling. In some cases the name of the function
3420 used depends on the type specifiers. */
3423 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
3425 gfc_intrinsic_sym *isym;
3429 isym = expr->value.function.isym;
3431 name = &expr->value.function.name[2];
3433 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
3435 lib = gfc_is_intrinsic_libcall (expr);
3439 se->ignore_optional = 1;
3440 gfc_conv_intrinsic_funcall (se, expr);
3445 switch (expr->value.function.isym->generic_id)
3450 case GFC_ISYM_REPEAT:
3451 gfc_conv_intrinsic_repeat (se, expr);
3455 gfc_conv_intrinsic_trim (se, expr);
3458 case GFC_ISYM_SI_KIND:
3459 gfc_conv_intrinsic_si_kind (se, expr);
3462 case GFC_ISYM_SR_KIND:
3463 gfc_conv_intrinsic_sr_kind (se, expr);
3466 case GFC_ISYM_EXPONENT:
3467 gfc_conv_intrinsic_exponent (se, expr);
3471 gfc_conv_intrinsic_scan (se, expr);
3474 case GFC_ISYM_VERIFY:
3475 gfc_conv_intrinsic_verify (se, expr);
3478 case GFC_ISYM_ALLOCATED:
3479 gfc_conv_allocated (se, expr);
3482 case GFC_ISYM_ASSOCIATED:
3483 gfc_conv_associated(se, expr);
3487 gfc_conv_intrinsic_abs (se, expr);
3490 case GFC_ISYM_ADJUSTL:
3491 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
3494 case GFC_ISYM_ADJUSTR:
3495 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
3498 case GFC_ISYM_AIMAG:
3499 gfc_conv_intrinsic_imagpart (se, expr);
3503 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
3507 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
3510 case GFC_ISYM_ANINT:
3511 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
3515 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3519 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
3522 case GFC_ISYM_BTEST:
3523 gfc_conv_intrinsic_btest (se, expr);
3526 case GFC_ISYM_ACHAR:
3528 gfc_conv_intrinsic_char (se, expr);
3531 case GFC_ISYM_CONVERSION:
3533 case GFC_ISYM_LOGICAL:
3535 gfc_conv_intrinsic_conversion (se, expr);
3538 /* Integer conversions are handled separately to make sure we get the
3539 correct rounding mode. */
3544 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
3548 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
3551 case GFC_ISYM_CEILING:
3552 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
3555 case GFC_ISYM_FLOOR:
3556 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
3560 gfc_conv_intrinsic_mod (se, expr, 0);
3563 case GFC_ISYM_MODULO:
3564 gfc_conv_intrinsic_mod (se, expr, 1);
3567 case GFC_ISYM_CMPLX:
3568 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3571 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3572 gfc_conv_intrinsic_iargc (se, expr);
3575 case GFC_ISYM_COMPLEX:
3576 gfc_conv_intrinsic_cmplx (se, expr, 1);
3579 case GFC_ISYM_CONJG:
3580 gfc_conv_intrinsic_conjg (se, expr);
3583 case GFC_ISYM_COUNT:
3584 gfc_conv_intrinsic_count (se, expr);
3587 case GFC_ISYM_CTIME:
3588 gfc_conv_intrinsic_ctime (se, expr);
3592 gfc_conv_intrinsic_dim (se, expr);
3595 case GFC_ISYM_DOT_PRODUCT:
3596 gfc_conv_intrinsic_dot_product (se, expr);
3599 case GFC_ISYM_DPROD:
3600 gfc_conv_intrinsic_dprod (se, expr);
3603 case GFC_ISYM_FDATE:
3604 gfc_conv_intrinsic_fdate (se, expr);
3608 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3611 case GFC_ISYM_IBCLR:
3612 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3615 case GFC_ISYM_IBITS:
3616 gfc_conv_intrinsic_ibits (se, expr);
3619 case GFC_ISYM_IBSET:
3620 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3623 case GFC_ISYM_IACHAR:
3624 case GFC_ISYM_ICHAR:
3625 /* We assume ASCII character sequence. */
3626 gfc_conv_intrinsic_ichar (se, expr);
3629 case GFC_ISYM_IARGC:
3630 gfc_conv_intrinsic_iargc (se, expr);
3634 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3637 case GFC_ISYM_INDEX:
3638 gfc_conv_intrinsic_index (se, expr);
3642 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3645 case GFC_ISYM_LSHIFT:
3646 gfc_conv_intrinsic_rlshift (se, expr, 0);
3649 case GFC_ISYM_RSHIFT:
3650 gfc_conv_intrinsic_rlshift (se, expr, 1);
3653 case GFC_ISYM_ISHFT:
3654 gfc_conv_intrinsic_ishft (se, expr);
3657 case GFC_ISYM_ISHFTC:
3658 gfc_conv_intrinsic_ishftc (se, expr);
3661 case GFC_ISYM_LBOUND:
3662 gfc_conv_intrinsic_bound (se, expr, 0);
3665 case GFC_ISYM_TRANSPOSE:
3666 if (se->ss && se->ss->useflags)
3668 gfc_conv_tmp_array_ref (se);
3669 gfc_advance_se_ss_chain (se);
3672 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3676 gfc_conv_intrinsic_len (se, expr);
3679 case GFC_ISYM_LEN_TRIM:
3680 gfc_conv_intrinsic_len_trim (se, expr);
3684 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3688 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3692 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3696 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3700 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3703 case GFC_ISYM_MAXLOC:
3704 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3707 case GFC_ISYM_MAXVAL:
3708 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3711 case GFC_ISYM_MERGE:
3712 gfc_conv_intrinsic_merge (se, expr);
3716 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3719 case GFC_ISYM_MINLOC:
3720 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3723 case GFC_ISYM_MINVAL:
3724 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3728 gfc_conv_intrinsic_not (se, expr);
3732 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3735 case GFC_ISYM_PRESENT:
3736 gfc_conv_intrinsic_present (se, expr);
3739 case GFC_ISYM_PRODUCT:
3740 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3744 gfc_conv_intrinsic_sign (se, expr);
3748 gfc_conv_intrinsic_size (se, expr);
3752 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3755 case GFC_ISYM_TRANSFER:
3758 if (se->ss->useflags)
3760 /* Access the previously obtained result. */
3761 gfc_conv_tmp_array_ref (se);
3762 gfc_advance_se_ss_chain (se);
3766 gfc_conv_intrinsic_array_transfer (se, expr);
3769 gfc_conv_intrinsic_transfer (se, expr);
3772 case GFC_ISYM_TTYNAM:
3773 gfc_conv_intrinsic_ttynam (se, expr);
3776 case GFC_ISYM_UBOUND:
3777 gfc_conv_intrinsic_bound (se, expr, 1);
3781 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3785 gfc_conv_intrinsic_loc (se, expr);
3788 case GFC_ISYM_ACCESS:
3789 case GFC_ISYM_CHDIR:
3790 case GFC_ISYM_CHMOD:
3791 case GFC_ISYM_ETIME:
3793 case GFC_ISYM_FGETC:
3796 case GFC_ISYM_FPUTC:
3797 case GFC_ISYM_FSTAT:
3798 case GFC_ISYM_FTELL:
3799 case GFC_ISYM_GETCWD:
3800 case GFC_ISYM_GETGID:
3801 case GFC_ISYM_GETPID:
3802 case GFC_ISYM_GETUID:
3803 case GFC_ISYM_HOSTNM:
3805 case GFC_ISYM_IERRNO:
3806 case GFC_ISYM_IRAND:
3807 case GFC_ISYM_ISATTY:
3809 case GFC_ISYM_LSTAT:
3810 case GFC_ISYM_MALLOC:
3811 case GFC_ISYM_MATMUL:
3812 case GFC_ISYM_MCLOCK:
3813 case GFC_ISYM_MCLOCK8:
3815 case GFC_ISYM_RENAME:
3816 case GFC_ISYM_SECOND:
3817 case GFC_ISYM_SECNDS:
3818 case GFC_ISYM_SIGNAL:
3820 case GFC_ISYM_SYMLNK:
3821 case GFC_ISYM_SYSTEM:
3823 case GFC_ISYM_TIME8:
3824 case GFC_ISYM_UMASK:
3825 case GFC_ISYM_UNLINK:
3826 gfc_conv_intrinsic_funcall (se, expr);
3830 gfc_conv_intrinsic_lib_function (se, expr);
3836 /* This generates code to execute before entering the scalarization loop.
3837 Currently does nothing. */
3840 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
3842 switch (ss->expr->value.function.isym->generic_id)
3844 case GFC_ISYM_UBOUND:
3845 case GFC_ISYM_LBOUND:
3854 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
3855 inside the scalarization loop. */
3858 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
3862 /* The two argument version returns a scalar. */
3863 if (expr->value.function.actual->next->expr)
3866 newss = gfc_get_ss ();
3867 newss->type = GFC_SS_INTRINSIC;
3870 newss->data.info.dimen = 1;
3876 /* Walk an intrinsic array libcall. */
3879 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
3883 gcc_assert (expr->rank > 0);
3885 newss = gfc_get_ss ();
3886 newss->type = GFC_SS_FUNCTION;
3889 newss->data.info.dimen = expr->rank;
3895 /* Returns nonzero if the specified intrinsic function call maps directly to a
3896 an external library call. Should only be used for functions that return
3900 gfc_is_intrinsic_libcall (gfc_expr * expr)
3902 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3903 gcc_assert (expr->rank > 0);
3905 switch (expr->value.function.isym->generic_id)
3909 case GFC_ISYM_COUNT:
3910 case GFC_ISYM_MATMUL:
3911 case GFC_ISYM_MAXLOC:
3912 case GFC_ISYM_MAXVAL:
3913 case GFC_ISYM_MINLOC:
3914 case GFC_ISYM_MINVAL:
3915 case GFC_ISYM_PRODUCT:
3917 case GFC_ISYM_SHAPE:
3918 case GFC_ISYM_SPREAD:
3919 case GFC_ISYM_TRANSPOSE:
3920 /* Ignore absent optional parameters. */
3923 case GFC_ISYM_RESHAPE:
3924 case GFC_ISYM_CSHIFT:
3925 case GFC_ISYM_EOSHIFT:
3927 case GFC_ISYM_UNPACK:
3928 /* Pass absent optional parameters. */
3936 /* Walk an intrinsic function. */
3938 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3939 gfc_intrinsic_sym * isym)
3943 if (isym->elemental)
3944 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
3946 if (expr->rank == 0)
3949 if (gfc_is_intrinsic_libcall (expr))
3950 return gfc_walk_intrinsic_libfunc (ss, expr);
3952 /* Special cases. */
3953 switch (isym->generic_id)
3955 case GFC_ISYM_LBOUND:
3956 case GFC_ISYM_UBOUND:
3957 return gfc_walk_intrinsic_bound (ss, expr);
3959 case GFC_ISYM_TRANSFER:
3960 return gfc_walk_intrinsic_libfunc (ss, expr);
3963 /* This probably meant someone forgot to add an intrinsic to the above
3964 list(s) when they implemented it, or something's gone horribly wrong.
3966 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3967 expr->value.function.name);
3971 #include "gt-fortran-trans-intrinsic.h"