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, size;
724 arg = expr->value.function.actual;
729 /* Create an implicit second parameter from the loop variable. */
730 gcc_assert (!arg2->expr);
731 gcc_assert (se->loop->dimen == 1);
732 gcc_assert (se->ss->expr == expr);
733 gfc_advance_se_ss_chain (se);
734 bound = se->loop->loopvar[0];
735 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
740 /* use the passed argument. */
741 gcc_assert (arg->next->expr);
742 gfc_init_se (&argse, NULL);
743 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
744 gfc_add_block_to_block (&se->pre, &argse.pre);
746 /* Convert from one based to zero based. */
747 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
751 /* TODO: don't re-evaluate the descriptor on each iteration. */
752 /* Get a descriptor for the first parameter. */
753 ss = gfc_walk_expr (arg->expr);
754 gcc_assert (ss != gfc_ss_terminator);
755 gfc_init_se (&argse, NULL);
756 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
757 gfc_add_block_to_block (&se->pre, &argse.pre);
758 gfc_add_block_to_block (&se->post, &argse.post);
762 if (INTEGER_CST_P (bound))
764 gcc_assert (TREE_INT_CST_HIGH (bound) == 0);
765 i = TREE_INT_CST_LOW (bound);
766 gcc_assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
770 if (flag_bounds_check)
772 bound = gfc_evaluate_now (bound, &se->pre);
773 cond = fold_build2 (LT_EXPR, boolean_type_node,
774 bound, build_int_cst (TREE_TYPE (bound), 0));
775 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
776 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
777 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
778 gfc_trans_runtime_check (cond, gfc_msg_fault, &se->pre, NULL);
782 ubound = gfc_conv_descriptor_ubound (desc, bound);
783 lbound = gfc_conv_descriptor_lbound (desc, bound);
785 /* Follow any component references. */
786 if (arg->expr->expr_type == EXPR_VARIABLE
787 || arg->expr->expr_type == EXPR_CONSTANT)
789 as = arg->expr->symtree->n.sym->as;
790 for (ref = arg->expr->ref; ref; ref = ref->next)
795 as = ref->u.c.component->as;
803 switch (ref->u.ar.type)
821 /* 13.14.53: Result value for LBOUND
823 Case (i): For an array section or for an array expression other than a
824 whole array or array structure component, LBOUND(ARRAY, DIM)
825 has the value 1. For a whole array or array structure
826 component, LBOUND(ARRAY, DIM) has the value:
827 (a) equal to the lower bound for subscript DIM of ARRAY if
828 dimension DIM of ARRAY does not have extent zero
829 or if ARRAY is an assumed-size array of rank DIM,
832 13.14.113: Result value for UBOUND
834 Case (i): For an array section or for an array expression other than a
835 whole array or array structure component, UBOUND(ARRAY, DIM)
836 has the value equal to the number of elements in the given
837 dimension; otherwise, it has a value equal to the upper bound
838 for subscript DIM of ARRAY if dimension DIM of ARRAY does
839 not have size zero and has value zero if dimension DIM has
844 tree stride = gfc_conv_descriptor_stride (desc, bound);
845 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
846 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
847 cond3 = fold_build2 (GT_EXPR, boolean_type_node, stride,
848 gfc_index_zero_node);
852 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
853 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond2);
855 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
856 ubound, gfc_index_zero_node);
860 if (as->type == AS_ASSUMED_SIZE)
861 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
862 build_int_cst (TREE_TYPE (bound),
865 cond = boolean_false_node;
867 cond1 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
868 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond1, cond2);
870 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
872 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
873 lbound, gfc_index_one_node);
880 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
881 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
885 se->expr = gfc_index_one_node;
888 type = gfc_typenode_for_spec (&expr->ts);
889 se->expr = convert (type, se->expr);
894 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
900 args = gfc_conv_intrinsic_function_args (se, expr);
901 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
902 val = TREE_VALUE (args);
904 switch (expr->value.function.actual->expr->ts.type)
908 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
912 switch (expr->ts.kind)
927 se->expr = build_function_call_expr (built_in_decls[n], args);
936 /* Create a complex value from one or two real components. */
939 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
946 type = gfc_typenode_for_spec (&expr->ts);
947 arg = gfc_conv_intrinsic_function_args (se, expr);
948 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
950 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
951 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
953 arg = TREE_VALUE (arg);
954 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
955 imag = convert (TREE_TYPE (type), imag);
958 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
960 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
963 /* Remainder function MOD(A, P) = A - INT(A / P) * P
964 MODULO(A, P) = A - FLOOR (A / P) * P */
965 /* TODO: MOD(x, 0) */
968 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
980 arg = gfc_conv_intrinsic_function_args (se, expr);
982 switch (expr->ts.type)
985 /* Integer case is easy, we've got a builtin op. */
986 arg2 = TREE_VALUE (TREE_CHAIN (arg));
987 arg = TREE_VALUE (arg);
988 type = TREE_TYPE (arg);
991 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
993 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
998 /* Check if we have a builtin fmod. */
999 switch (expr->ts.kind)
1018 /* Use it if it exists. */
1019 if (n != END_BUILTINS)
1021 tmp = built_in_decls[n];
1022 se->expr = build_function_call_expr (tmp, arg);
1027 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1028 arg = TREE_VALUE (arg);
1029 type = TREE_TYPE (arg);
1031 arg = gfc_evaluate_now (arg, &se->pre);
1032 arg2 = gfc_evaluate_now (arg2, &se->pre);
1035 modulo = arg - floor (arg/arg2) * arg2, so
1036 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1038 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1039 thereby avoiding another division and retaining the accuracy
1040 of the builtin function. */
1041 if (n != END_BUILTINS && modulo)
1043 tree zero = gfc_build_const (type, integer_zero_node);
1044 tmp = gfc_evaluate_now (se->expr, &se->pre);
1045 test = build2 (LT_EXPR, boolean_type_node, arg, zero);
1046 test2 = build2 (LT_EXPR, boolean_type_node, arg2, zero);
1047 test2 = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1048 test = build2 (NE_EXPR, boolean_type_node, tmp, zero);
1049 test = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1050 test = gfc_evaluate_now (test, &se->pre);
1051 se->expr = build3 (COND_EXPR, type, test,
1052 build2 (PLUS_EXPR, type, tmp, arg2), tmp);
1056 /* If we do not have a built_in fmod, the calculation is going to
1057 have to be done longhand. */
1058 tmp = build2 (RDIV_EXPR, type, arg, arg2);
1060 /* Test if the value is too large to handle sensibly. */
1061 gfc_set_model_kind (expr->ts.kind);
1063 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1064 ikind = expr->ts.kind;
1067 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1068 ikind = gfc_max_integer_kind;
1070 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1071 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1072 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
1074 mpfr_neg (huge, huge, GFC_RND_MODE);
1075 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1076 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
1077 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1079 itype = gfc_get_int_type (ikind);
1081 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1083 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1084 tmp = convert (type, tmp);
1085 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
1086 tmp = build2 (MULT_EXPR, type, tmp, arg2);
1087 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
1096 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1099 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1108 arg = gfc_conv_intrinsic_function_args (se, expr);
1109 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1110 arg = TREE_VALUE (arg);
1111 type = TREE_TYPE (arg);
1113 val = build2 (MINUS_EXPR, type, arg, arg2);
1114 val = gfc_evaluate_now (val, &se->pre);
1116 zero = gfc_build_const (type, integer_zero_node);
1117 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
1118 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
1122 /* SIGN(A, B) is absolute value of A times sign of B.
1123 The real value versions use library functions to ensure the correct
1124 handling of negative zero. Integer case implemented as:
1125 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
1129 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1140 arg = gfc_conv_intrinsic_function_args (se, expr);
1141 if (expr->ts.type == BT_REAL)
1143 switch (expr->ts.kind)
1146 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1149 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1153 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1158 se->expr = build_function_call_expr (tmp, arg);
1162 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1163 arg = TREE_VALUE (arg);
1164 type = TREE_TYPE (arg);
1165 zero = gfc_build_const (type, integer_zero_node);
1167 testa = fold_build2 (GE_EXPR, boolean_type_node, arg, zero);
1168 testb = fold_build2 (GE_EXPR, boolean_type_node, arg2, zero);
1169 tmp = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, testa, testb);
1170 se->expr = fold_build3 (COND_EXPR, type, tmp,
1171 build1 (NEGATE_EXPR, type, arg), arg);
1175 /* Test for the presence of an optional argument. */
1178 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1182 arg = expr->value.function.actual->expr;
1183 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1184 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1185 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1189 /* Calculate the double precision product of two single precision values. */
1192 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1198 arg = gfc_conv_intrinsic_function_args (se, expr);
1199 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1200 arg = TREE_VALUE (arg);
1202 /* Convert the args to double precision before multiplying. */
1203 type = gfc_typenode_for_spec (&expr->ts);
1204 arg = convert (type, arg);
1205 arg2 = convert (type, arg2);
1206 se->expr = build2 (MULT_EXPR, type, arg, arg2);
1210 /* Return a length one character string containing an ascii character. */
1213 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1219 arg = gfc_conv_intrinsic_function_args (se, expr);
1220 arg = TREE_VALUE (arg);
1222 /* We currently don't support character types != 1. */
1223 gcc_assert (expr->ts.kind == 1);
1224 type = gfc_character1_type_node;
1225 var = gfc_create_var (type, "char");
1227 arg = convert (type, arg);
1228 gfc_add_modify_expr (&se->pre, var, arg);
1229 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1230 se->string_length = integer_one_node;
1235 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1243 tree gfc_int8_type_node = gfc_get_int_type (8);
1245 type = build_pointer_type (gfc_character1_type_node);
1246 var = gfc_create_var (type, "pstr");
1247 len = gfc_create_var (gfc_int8_type_node, "len");
1249 tmp = gfc_conv_intrinsic_function_args (se, expr);
1250 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1251 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1252 arglist = chainon (arglist, tmp);
1254 tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
1255 gfc_add_expr_to_block (&se->pre, tmp);
1257 /* Free the temporary afterwards, if necessary. */
1258 cond = build2 (GT_EXPR, boolean_type_node, len,
1259 build_int_cst (TREE_TYPE (len), 0));
1260 arglist = gfc_chainon_list (NULL_TREE, var);
1261 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1262 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1263 gfc_add_expr_to_block (&se->post, tmp);
1266 se->string_length = len;
1271 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1279 tree gfc_int4_type_node = gfc_get_int_type (4);
1281 type = build_pointer_type (gfc_character1_type_node);
1282 var = gfc_create_var (type, "pstr");
1283 len = gfc_create_var (gfc_int4_type_node, "len");
1285 tmp = gfc_conv_intrinsic_function_args (se, expr);
1286 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1287 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1288 arglist = chainon (arglist, tmp);
1290 tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
1291 gfc_add_expr_to_block (&se->pre, tmp);
1293 /* Free the temporary afterwards, if necessary. */
1294 cond = build2 (GT_EXPR, boolean_type_node, len,
1295 build_int_cst (TREE_TYPE (len), 0));
1296 arglist = gfc_chainon_list (NULL_TREE, var);
1297 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1298 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1299 gfc_add_expr_to_block (&se->post, tmp);
1302 se->string_length = len;
1306 /* Return a character string containing the tty name. */
1309 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1317 tree gfc_int4_type_node = gfc_get_int_type (4);
1319 type = build_pointer_type (gfc_character1_type_node);
1320 var = gfc_create_var (type, "pstr");
1321 len = gfc_create_var (gfc_int4_type_node, "len");
1323 tmp = gfc_conv_intrinsic_function_args (se, expr);
1324 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1325 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1326 arglist = chainon (arglist, tmp);
1328 tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
1329 gfc_add_expr_to_block (&se->pre, tmp);
1331 /* Free the temporary afterwards, if necessary. */
1332 cond = build2 (GT_EXPR, boolean_type_node, len,
1333 build_int_cst (TREE_TYPE (len), 0));
1334 arglist = gfc_chainon_list (NULL_TREE, var);
1335 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1336 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1337 gfc_add_expr_to_block (&se->post, tmp);
1340 se->string_length = len;
1344 /* Get the minimum/maximum value of all the parameters.
1345 minmax (a1, a2, a3, ...)
1358 /* TODO: Mismatching types can occur when specific names are used.
1359 These should be handled during resolution. */
1361 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1372 arg = gfc_conv_intrinsic_function_args (se, expr);
1373 type = gfc_typenode_for_spec (&expr->ts);
1375 limit = TREE_VALUE (arg);
1376 if (TREE_TYPE (limit) != type)
1377 limit = convert (type, limit);
1378 /* Only evaluate the argument once. */
1379 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1380 limit = gfc_evaluate_now(limit, &se->pre);
1382 mvar = gfc_create_var (type, "M");
1383 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1384 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1386 val = TREE_VALUE (arg);
1387 if (TREE_TYPE (val) != type)
1388 val = convert (type, val);
1390 /* Only evaluate the argument once. */
1391 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1392 val = gfc_evaluate_now(val, &se->pre);
1394 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1396 tmp = build2 (op, boolean_type_node, val, limit);
1397 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1398 gfc_add_expr_to_block (&se->pre, tmp);
1399 elsecase = build_empty_stmt ();
1406 /* Create a symbol node for this intrinsic. The symbol from the frontend
1407 has the generic name. */
1410 gfc_get_symbol_for_expr (gfc_expr * expr)
1414 /* TODO: Add symbols for intrinsic function to the global namespace. */
1415 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1416 sym = gfc_new_symbol (expr->value.function.name, NULL);
1419 sym->attr.external = 1;
1420 sym->attr.function = 1;
1421 sym->attr.always_explicit = 1;
1422 sym->attr.proc = PROC_INTRINSIC;
1423 sym->attr.flavor = FL_PROCEDURE;
1427 sym->attr.dimension = 1;
1428 sym->as = gfc_get_array_spec ();
1429 sym->as->type = AS_ASSUMED_SHAPE;
1430 sym->as->rank = expr->rank;
1433 /* TODO: proper argument lists for external intrinsics. */
1437 /* Generate a call to an external intrinsic function. */
1439 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1444 gcc_assert (!se->ss || se->ss->expr == expr);
1447 gcc_assert (expr->rank > 0);
1449 gcc_assert (expr->rank == 0);
1451 sym = gfc_get_symbol_for_expr (expr);
1453 /* Calls to libgfortran_matmul need to be appended special arguments,
1454 to be able to call the BLAS ?gemm functions if required and possible. */
1455 append_args = NULL_TREE;
1456 if (expr->value.function.isym->generic_id == GFC_ISYM_MATMUL
1457 && sym->ts.type != BT_LOGICAL)
1459 tree cint = gfc_get_int_type (gfc_c_int_kind);
1461 if (gfc_option.flag_external_blas
1462 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1463 && (sym->ts.kind == gfc_default_real_kind
1464 || sym->ts.kind == gfc_default_double_kind))
1468 if (sym->ts.type == BT_REAL)
1470 if (sym->ts.kind == gfc_default_real_kind)
1471 gemm_fndecl = gfor_fndecl_sgemm;
1473 gemm_fndecl = gfor_fndecl_dgemm;
1477 if (sym->ts.kind == gfc_default_real_kind)
1478 gemm_fndecl = gfor_fndecl_cgemm;
1480 gemm_fndecl = gfor_fndecl_zgemm;
1483 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1484 append_args = gfc_chainon_list
1485 (append_args, build_int_cst
1486 (cint, gfc_option.blas_matmul_limit));
1487 append_args = gfc_chainon_list (append_args,
1488 gfc_build_addr_expr (NULL_TREE,
1493 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1494 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1495 append_args = gfc_chainon_list (append_args, null_pointer_node);
1499 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1503 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1523 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1532 gfc_actual_arglist *actual;
1539 gfc_conv_intrinsic_funcall (se, expr);
1543 actual = expr->value.function.actual;
1544 type = gfc_typenode_for_spec (&expr->ts);
1545 /* Initialize the result. */
1546 resvar = gfc_create_var (type, "test");
1548 tmp = convert (type, boolean_true_node);
1550 tmp = convert (type, boolean_false_node);
1551 gfc_add_modify_expr (&se->pre, resvar, tmp);
1553 /* Walk the arguments. */
1554 arrayss = gfc_walk_expr (actual->expr);
1555 gcc_assert (arrayss != gfc_ss_terminator);
1557 /* Initialize the scalarizer. */
1558 gfc_init_loopinfo (&loop);
1559 exit_label = gfc_build_label_decl (NULL_TREE);
1560 TREE_USED (exit_label) = 1;
1561 gfc_add_ss_to_loop (&loop, arrayss);
1563 /* Initialize the loop. */
1564 gfc_conv_ss_startstride (&loop);
1565 gfc_conv_loop_setup (&loop);
1567 gfc_mark_ss_chain_used (arrayss, 1);
1568 /* Generate the loop body. */
1569 gfc_start_scalarized_body (&loop, &body);
1571 /* If the condition matches then set the return value. */
1572 gfc_start_block (&block);
1574 tmp = convert (type, boolean_false_node);
1576 tmp = convert (type, boolean_true_node);
1577 gfc_add_modify_expr (&block, resvar, tmp);
1579 /* And break out of the loop. */
1580 tmp = build1_v (GOTO_EXPR, exit_label);
1581 gfc_add_expr_to_block (&block, tmp);
1583 found = gfc_finish_block (&block);
1585 /* Check this element. */
1586 gfc_init_se (&arrayse, NULL);
1587 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1588 arrayse.ss = arrayss;
1589 gfc_conv_expr_val (&arrayse, actual->expr);
1591 gfc_add_block_to_block (&body, &arrayse.pre);
1592 tmp = build2 (op, boolean_type_node, arrayse.expr,
1593 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1594 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1595 gfc_add_expr_to_block (&body, tmp);
1596 gfc_add_block_to_block (&body, &arrayse.post);
1598 gfc_trans_scalarizing_loops (&loop, &body);
1600 /* Add the exit label. */
1601 tmp = build1_v (LABEL_EXPR, exit_label);
1602 gfc_add_expr_to_block (&loop.pre, tmp);
1604 gfc_add_block_to_block (&se->pre, &loop.pre);
1605 gfc_add_block_to_block (&se->pre, &loop.post);
1606 gfc_cleanup_loop (&loop);
1611 /* COUNT(A) = Number of true elements in A. */
1613 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1620 gfc_actual_arglist *actual;
1626 gfc_conv_intrinsic_funcall (se, expr);
1630 actual = expr->value.function.actual;
1632 type = gfc_typenode_for_spec (&expr->ts);
1633 /* Initialize the result. */
1634 resvar = gfc_create_var (type, "count");
1635 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1637 /* Walk the arguments. */
1638 arrayss = gfc_walk_expr (actual->expr);
1639 gcc_assert (arrayss != gfc_ss_terminator);
1641 /* Initialize the scalarizer. */
1642 gfc_init_loopinfo (&loop);
1643 gfc_add_ss_to_loop (&loop, arrayss);
1645 /* Initialize the loop. */
1646 gfc_conv_ss_startstride (&loop);
1647 gfc_conv_loop_setup (&loop);
1649 gfc_mark_ss_chain_used (arrayss, 1);
1650 /* Generate the loop body. */
1651 gfc_start_scalarized_body (&loop, &body);
1653 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1654 build_int_cst (TREE_TYPE (resvar), 1));
1655 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1657 gfc_init_se (&arrayse, NULL);
1658 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1659 arrayse.ss = arrayss;
1660 gfc_conv_expr_val (&arrayse, actual->expr);
1661 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1663 gfc_add_block_to_block (&body, &arrayse.pre);
1664 gfc_add_expr_to_block (&body, tmp);
1665 gfc_add_block_to_block (&body, &arrayse.post);
1667 gfc_trans_scalarizing_loops (&loop, &body);
1669 gfc_add_block_to_block (&se->pre, &loop.pre);
1670 gfc_add_block_to_block (&se->pre, &loop.post);
1671 gfc_cleanup_loop (&loop);
1676 /* Inline implementation of the sum and product intrinsics. */
1678 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1686 gfc_actual_arglist *actual;
1691 gfc_expr *arrayexpr;
1696 gfc_conv_intrinsic_funcall (se, expr);
1700 type = gfc_typenode_for_spec (&expr->ts);
1701 /* Initialize the result. */
1702 resvar = gfc_create_var (type, "val");
1703 if (op == PLUS_EXPR)
1704 tmp = gfc_build_const (type, integer_zero_node);
1706 tmp = gfc_build_const (type, integer_one_node);
1708 gfc_add_modify_expr (&se->pre, resvar, tmp);
1710 /* Walk the arguments. */
1711 actual = expr->value.function.actual;
1712 arrayexpr = actual->expr;
1713 arrayss = gfc_walk_expr (arrayexpr);
1714 gcc_assert (arrayss != gfc_ss_terminator);
1716 actual = actual->next->next;
1717 gcc_assert (actual);
1718 maskexpr = actual->expr;
1719 if (maskexpr && maskexpr->rank != 0)
1721 maskss = gfc_walk_expr (maskexpr);
1722 gcc_assert (maskss != gfc_ss_terminator);
1727 /* Initialize the scalarizer. */
1728 gfc_init_loopinfo (&loop);
1729 gfc_add_ss_to_loop (&loop, arrayss);
1731 gfc_add_ss_to_loop (&loop, maskss);
1733 /* Initialize the loop. */
1734 gfc_conv_ss_startstride (&loop);
1735 gfc_conv_loop_setup (&loop);
1737 gfc_mark_ss_chain_used (arrayss, 1);
1739 gfc_mark_ss_chain_used (maskss, 1);
1740 /* Generate the loop body. */
1741 gfc_start_scalarized_body (&loop, &body);
1743 /* If we have a mask, only add this element if the mask is set. */
1746 gfc_init_se (&maskse, NULL);
1747 gfc_copy_loopinfo_to_se (&maskse, &loop);
1749 gfc_conv_expr_val (&maskse, maskexpr);
1750 gfc_add_block_to_block (&body, &maskse.pre);
1752 gfc_start_block (&block);
1755 gfc_init_block (&block);
1757 /* Do the actual summation/product. */
1758 gfc_init_se (&arrayse, NULL);
1759 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1760 arrayse.ss = arrayss;
1761 gfc_conv_expr_val (&arrayse, arrayexpr);
1762 gfc_add_block_to_block (&block, &arrayse.pre);
1764 tmp = build2 (op, type, resvar, arrayse.expr);
1765 gfc_add_modify_expr (&block, resvar, tmp);
1766 gfc_add_block_to_block (&block, &arrayse.post);
1770 /* We enclose the above in if (mask) {...} . */
1771 tmp = gfc_finish_block (&block);
1773 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1776 tmp = gfc_finish_block (&block);
1777 gfc_add_expr_to_block (&body, tmp);
1779 gfc_trans_scalarizing_loops (&loop, &body);
1781 /* For a scalar mask, enclose the loop in an if statement. */
1782 if (maskexpr && maskss == NULL)
1784 gfc_init_se (&maskse, NULL);
1785 gfc_conv_expr_val (&maskse, maskexpr);
1786 gfc_init_block (&block);
1787 gfc_add_block_to_block (&block, &loop.pre);
1788 gfc_add_block_to_block (&block, &loop.post);
1789 tmp = gfc_finish_block (&block);
1791 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1792 gfc_add_expr_to_block (&block, tmp);
1793 gfc_add_block_to_block (&se->pre, &block);
1797 gfc_add_block_to_block (&se->pre, &loop.pre);
1798 gfc_add_block_to_block (&se->pre, &loop.post);
1801 gfc_cleanup_loop (&loop);
1807 /* Inline implementation of the dot_product intrinsic. This function
1808 is based on gfc_conv_intrinsic_arith (the previous function). */
1810 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1818 gfc_actual_arglist *actual;
1819 gfc_ss *arrayss1, *arrayss2;
1820 gfc_se arrayse1, arrayse2;
1821 gfc_expr *arrayexpr1, *arrayexpr2;
1823 type = gfc_typenode_for_spec (&expr->ts);
1825 /* Initialize the result. */
1826 resvar = gfc_create_var (type, "val");
1827 if (expr->ts.type == BT_LOGICAL)
1828 tmp = convert (type, integer_zero_node);
1830 tmp = gfc_build_const (type, integer_zero_node);
1832 gfc_add_modify_expr (&se->pre, resvar, tmp);
1834 /* Walk argument #1. */
1835 actual = expr->value.function.actual;
1836 arrayexpr1 = actual->expr;
1837 arrayss1 = gfc_walk_expr (arrayexpr1);
1838 gcc_assert (arrayss1 != gfc_ss_terminator);
1840 /* Walk argument #2. */
1841 actual = actual->next;
1842 arrayexpr2 = actual->expr;
1843 arrayss2 = gfc_walk_expr (arrayexpr2);
1844 gcc_assert (arrayss2 != gfc_ss_terminator);
1846 /* Initialize the scalarizer. */
1847 gfc_init_loopinfo (&loop);
1848 gfc_add_ss_to_loop (&loop, arrayss1);
1849 gfc_add_ss_to_loop (&loop, arrayss2);
1851 /* Initialize the loop. */
1852 gfc_conv_ss_startstride (&loop);
1853 gfc_conv_loop_setup (&loop);
1855 gfc_mark_ss_chain_used (arrayss1, 1);
1856 gfc_mark_ss_chain_used (arrayss2, 1);
1858 /* Generate the loop body. */
1859 gfc_start_scalarized_body (&loop, &body);
1860 gfc_init_block (&block);
1862 /* Make the tree expression for [conjg(]array1[)]. */
1863 gfc_init_se (&arrayse1, NULL);
1864 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1865 arrayse1.ss = arrayss1;
1866 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1867 if (expr->ts.type == BT_COMPLEX)
1868 arrayse1.expr = build1 (CONJ_EXPR, type, arrayse1.expr);
1869 gfc_add_block_to_block (&block, &arrayse1.pre);
1871 /* Make the tree expression for array2. */
1872 gfc_init_se (&arrayse2, NULL);
1873 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
1874 arrayse2.ss = arrayss2;
1875 gfc_conv_expr_val (&arrayse2, arrayexpr2);
1876 gfc_add_block_to_block (&block, &arrayse2.pre);
1878 /* Do the actual product and sum. */
1879 if (expr->ts.type == BT_LOGICAL)
1881 tmp = build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
1882 tmp = build2 (TRUTH_OR_EXPR, type, resvar, tmp);
1886 tmp = build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
1887 tmp = build2 (PLUS_EXPR, type, resvar, tmp);
1889 gfc_add_modify_expr (&block, resvar, tmp);
1891 /* Finish up the loop block and the loop. */
1892 tmp = gfc_finish_block (&block);
1893 gfc_add_expr_to_block (&body, tmp);
1895 gfc_trans_scalarizing_loops (&loop, &body);
1896 gfc_add_block_to_block (&se->pre, &loop.pre);
1897 gfc_add_block_to_block (&se->pre, &loop.post);
1898 gfc_cleanup_loop (&loop);
1905 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1909 stmtblock_t ifblock;
1910 stmtblock_t elseblock;
1917 gfc_actual_arglist *actual;
1922 gfc_expr *arrayexpr;
1929 gfc_conv_intrinsic_funcall (se, expr);
1933 /* Initialize the result. */
1934 pos = gfc_create_var (gfc_array_index_type, "pos");
1935 type = gfc_typenode_for_spec (&expr->ts);
1937 /* Walk the arguments. */
1938 actual = expr->value.function.actual;
1939 arrayexpr = actual->expr;
1940 arrayss = gfc_walk_expr (arrayexpr);
1941 gcc_assert (arrayss != gfc_ss_terminator);
1943 actual = actual->next->next;
1944 gcc_assert (actual);
1945 maskexpr = actual->expr;
1946 if (maskexpr && maskexpr->rank != 0)
1948 maskss = gfc_walk_expr (maskexpr);
1949 gcc_assert (maskss != gfc_ss_terminator);
1954 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1955 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1956 switch (arrayexpr->ts.type)
1959 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1963 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1964 arrayexpr->ts.kind);
1971 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1973 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1974 gfc_add_modify_expr (&se->pre, limit, tmp);
1976 /* Initialize the scalarizer. */
1977 gfc_init_loopinfo (&loop);
1978 gfc_add_ss_to_loop (&loop, arrayss);
1980 gfc_add_ss_to_loop (&loop, maskss);
1982 /* Initialize the loop. */
1983 gfc_conv_ss_startstride (&loop);
1984 gfc_conv_loop_setup (&loop);
1986 gcc_assert (loop.dimen == 1);
1988 /* Initialize the position to zero, following Fortran 2003. We are free
1989 to do this because Fortran 95 allows the result of an entirely false
1990 mask to be processor dependent. */
1991 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
1993 gfc_mark_ss_chain_used (arrayss, 1);
1995 gfc_mark_ss_chain_used (maskss, 1);
1996 /* Generate the loop body. */
1997 gfc_start_scalarized_body (&loop, &body);
1999 /* If we have a mask, only check this element if the mask is set. */
2002 gfc_init_se (&maskse, NULL);
2003 gfc_copy_loopinfo_to_se (&maskse, &loop);
2005 gfc_conv_expr_val (&maskse, maskexpr);
2006 gfc_add_block_to_block (&body, &maskse.pre);
2008 gfc_start_block (&block);
2011 gfc_init_block (&block);
2013 /* Compare with the current limit. */
2014 gfc_init_se (&arrayse, NULL);
2015 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2016 arrayse.ss = arrayss;
2017 gfc_conv_expr_val (&arrayse, arrayexpr);
2018 gfc_add_block_to_block (&block, &arrayse.pre);
2020 /* We do the following if this is a more extreme value. */
2021 gfc_start_block (&ifblock);
2023 /* Assign the value to the limit... */
2024 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2026 /* Remember where we are. */
2027 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
2029 ifbody = gfc_finish_block (&ifblock);
2031 /* If it is a more extreme value or pos is still zero. */
2032 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node,
2033 build2 (op, boolean_type_node, arrayse.expr, limit),
2034 build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node));
2035 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2036 gfc_add_expr_to_block (&block, tmp);
2040 /* We enclose the above in if (mask) {...}. */
2041 tmp = gfc_finish_block (&block);
2043 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2046 tmp = gfc_finish_block (&block);
2047 gfc_add_expr_to_block (&body, tmp);
2049 gfc_trans_scalarizing_loops (&loop, &body);
2051 /* For a scalar mask, enclose the loop in an if statement. */
2052 if (maskexpr && maskss == NULL)
2054 gfc_init_se (&maskse, NULL);
2055 gfc_conv_expr_val (&maskse, maskexpr);
2056 gfc_init_block (&block);
2057 gfc_add_block_to_block (&block, &loop.pre);
2058 gfc_add_block_to_block (&block, &loop.post);
2059 tmp = gfc_finish_block (&block);
2061 /* For the else part of the scalar mask, just initialize
2062 the pos variable the same way as above. */
2064 gfc_init_block (&elseblock);
2065 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2066 elsetmp = gfc_finish_block (&elseblock);
2068 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2069 gfc_add_expr_to_block (&block, tmp);
2070 gfc_add_block_to_block (&se->pre, &block);
2074 gfc_add_block_to_block (&se->pre, &loop.pre);
2075 gfc_add_block_to_block (&se->pre, &loop.post);
2077 gfc_cleanup_loop (&loop);
2079 /* Return a value in the range 1..SIZE(array). */
2080 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
2081 gfc_index_one_node);
2082 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
2083 /* And convert to the required type. */
2084 se->expr = convert (type, tmp);
2088 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2097 gfc_actual_arglist *actual;
2102 gfc_expr *arrayexpr;
2108 gfc_conv_intrinsic_funcall (se, expr);
2112 type = gfc_typenode_for_spec (&expr->ts);
2113 /* Initialize the result. */
2114 limit = gfc_create_var (type, "limit");
2115 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2116 switch (expr->ts.type)
2119 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2123 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2130 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
2132 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2133 gfc_add_modify_expr (&se->pre, limit, tmp);
2135 /* Walk the arguments. */
2136 actual = expr->value.function.actual;
2137 arrayexpr = actual->expr;
2138 arrayss = gfc_walk_expr (arrayexpr);
2139 gcc_assert (arrayss != gfc_ss_terminator);
2141 actual = actual->next->next;
2142 gcc_assert (actual);
2143 maskexpr = actual->expr;
2144 if (maskexpr && maskexpr->rank != 0)
2146 maskss = gfc_walk_expr (maskexpr);
2147 gcc_assert (maskss != gfc_ss_terminator);
2152 /* Initialize the scalarizer. */
2153 gfc_init_loopinfo (&loop);
2154 gfc_add_ss_to_loop (&loop, arrayss);
2156 gfc_add_ss_to_loop (&loop, maskss);
2158 /* Initialize the loop. */
2159 gfc_conv_ss_startstride (&loop);
2160 gfc_conv_loop_setup (&loop);
2162 gfc_mark_ss_chain_used (arrayss, 1);
2164 gfc_mark_ss_chain_used (maskss, 1);
2165 /* Generate the loop body. */
2166 gfc_start_scalarized_body (&loop, &body);
2168 /* If we have a mask, only add this element if the mask is set. */
2171 gfc_init_se (&maskse, NULL);
2172 gfc_copy_loopinfo_to_se (&maskse, &loop);
2174 gfc_conv_expr_val (&maskse, maskexpr);
2175 gfc_add_block_to_block (&body, &maskse.pre);
2177 gfc_start_block (&block);
2180 gfc_init_block (&block);
2182 /* Compare with the current limit. */
2183 gfc_init_se (&arrayse, NULL);
2184 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2185 arrayse.ss = arrayss;
2186 gfc_conv_expr_val (&arrayse, arrayexpr);
2187 gfc_add_block_to_block (&block, &arrayse.pre);
2189 /* Assign the value to the limit... */
2190 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2192 /* If it is a more extreme value. */
2193 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
2194 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2195 gfc_add_expr_to_block (&block, tmp);
2196 gfc_add_block_to_block (&block, &arrayse.post);
2198 tmp = gfc_finish_block (&block);
2200 /* We enclose the above in if (mask) {...}. */
2201 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2202 gfc_add_expr_to_block (&body, tmp);
2204 gfc_trans_scalarizing_loops (&loop, &body);
2206 /* For a scalar mask, enclose the loop in an if statement. */
2207 if (maskexpr && maskss == NULL)
2209 gfc_init_se (&maskse, NULL);
2210 gfc_conv_expr_val (&maskse, maskexpr);
2211 gfc_init_block (&block);
2212 gfc_add_block_to_block (&block, &loop.pre);
2213 gfc_add_block_to_block (&block, &loop.post);
2214 tmp = gfc_finish_block (&block);
2216 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2217 gfc_add_expr_to_block (&block, tmp);
2218 gfc_add_block_to_block (&se->pre, &block);
2222 gfc_add_block_to_block (&se->pre, &loop.pre);
2223 gfc_add_block_to_block (&se->pre, &loop.post);
2226 gfc_cleanup_loop (&loop);
2231 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2233 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2240 arg = gfc_conv_intrinsic_function_args (se, expr);
2241 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2242 arg = TREE_VALUE (arg);
2243 type = TREE_TYPE (arg);
2245 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2246 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
2247 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2248 build_int_cst (type, 0));
2249 type = gfc_typenode_for_spec (&expr->ts);
2250 se->expr = convert (type, tmp);
2253 /* Generate code to perform the specified operation. */
2255 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2261 arg = gfc_conv_intrinsic_function_args (se, expr);
2262 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2263 arg = TREE_VALUE (arg);
2264 type = TREE_TYPE (arg);
2266 se->expr = fold_build2 (op, type, arg, arg2);
2271 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2275 arg = gfc_conv_intrinsic_function_args (se, expr);
2276 arg = TREE_VALUE (arg);
2278 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2281 /* Set or clear a single bit. */
2283 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2291 arg = gfc_conv_intrinsic_function_args (se, expr);
2292 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2293 arg = TREE_VALUE (arg);
2294 type = TREE_TYPE (arg);
2296 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2302 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2304 se->expr = fold_build2 (op, type, arg, tmp);
2307 /* Extract a sequence of bits.
2308 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2310 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2319 arg = gfc_conv_intrinsic_function_args (se, expr);
2320 arg2 = TREE_CHAIN (arg);
2321 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
2322 arg = TREE_VALUE (arg);
2323 arg2 = TREE_VALUE (arg2);
2324 type = TREE_TYPE (arg);
2326 mask = build_int_cst (NULL_TREE, -1);
2327 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
2328 mask = build1 (BIT_NOT_EXPR, type, mask);
2330 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
2332 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2335 /* RSHIFT (I, SHIFT) = I >> SHIFT
2336 LSHIFT (I, SHIFT) = I << SHIFT */
2338 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2343 arg = gfc_conv_intrinsic_function_args (se, expr);
2344 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2345 arg = TREE_VALUE (arg);
2347 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2348 TREE_TYPE (arg), arg, arg2);
2351 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2353 : ((shift >= 0) ? i << shift : i >> -shift)
2354 where all shifts are logical shifts. */
2356 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2369 arg = gfc_conv_intrinsic_function_args (se, expr);
2370 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2371 arg = TREE_VALUE (arg);
2372 type = TREE_TYPE (arg);
2373 utype = gfc_unsigned_type (type);
2375 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
2377 /* Left shift if positive. */
2378 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
2380 /* Right shift if negative.
2381 We convert to an unsigned type because we want a logical shift.
2382 The standard doesn't define the case of shifting negative
2383 numbers, and we try to be compatible with other compilers, most
2384 notably g77, here. */
2385 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
2386 convert (utype, arg), width));
2388 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
2389 build_int_cst (TREE_TYPE (arg2), 0));
2390 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2392 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2393 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2395 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
2396 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2398 se->expr = fold_build3 (COND_EXPR, type, cond,
2399 build_int_cst (type, 0), tmp);
2402 /* Circular shift. AKA rotate or barrel shift. */
2404 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2415 arg = gfc_conv_intrinsic_function_args (se, expr);
2416 arg2 = TREE_CHAIN (arg);
2417 arg3 = TREE_CHAIN (arg2);
2420 /* Use a library function for the 3 parameter version. */
2421 tree int4type = gfc_get_int_type (4);
2423 type = TREE_TYPE (TREE_VALUE (arg));
2424 /* We convert the first argument to at least 4 bytes, and
2425 convert back afterwards. This removes the need for library
2426 functions for all argument sizes, and function will be
2427 aligned to at least 32 bits, so there's no loss. */
2428 if (expr->ts.kind < 4)
2430 tmp = convert (int4type, TREE_VALUE (arg));
2431 TREE_VALUE (arg) = tmp;
2433 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2434 need loads of library functions. They cannot have values >
2435 BIT_SIZE (I) so the conversion is safe. */
2436 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
2437 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
2439 switch (expr->ts.kind)
2444 tmp = gfor_fndecl_math_ishftc4;
2447 tmp = gfor_fndecl_math_ishftc8;
2450 tmp = gfor_fndecl_math_ishftc16;
2455 se->expr = build_function_call_expr (tmp, arg);
2456 /* Convert the result back to the original type, if we extended
2457 the first argument's width above. */
2458 if (expr->ts.kind < 4)
2459 se->expr = convert (type, se->expr);
2463 arg = TREE_VALUE (arg);
2464 arg2 = TREE_VALUE (arg2);
2465 type = TREE_TYPE (arg);
2467 /* Rotate left if positive. */
2468 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
2470 /* Rotate right if negative. */
2471 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
2472 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
2474 zero = build_int_cst (TREE_TYPE (arg2), 0);
2475 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
2476 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2478 /* Do nothing if shift == 0. */
2479 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
2480 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
2483 /* The length of a character string. */
2485 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2495 gcc_assert (!se->ss);
2497 arg = expr->value.function.actual->expr;
2499 type = gfc_typenode_for_spec (&expr->ts);
2500 switch (arg->expr_type)
2503 len = build_int_cst (NULL_TREE, arg->value.character.length);
2507 /* Obtain the string length from the function used by
2508 trans-array.c(gfc_trans_array_constructor). */
2510 get_array_ctor_strlen (arg->value.constructor, &len);
2514 if (arg->ref == NULL
2515 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2517 /* This doesn't catch all cases.
2518 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2519 and the surrounding thread. */
2520 sym = arg->symtree->n.sym;
2521 decl = gfc_get_symbol_decl (sym);
2522 if (decl == current_function_decl && sym->attr.function
2523 && (sym->result == sym))
2524 decl = gfc_get_fake_result_decl (sym, 0);
2526 len = sym->ts.cl->backend_decl;
2531 /* Otherwise fall through. */
2534 /* Anybody stupid enough to do this deserves inefficient code. */
2535 ss = gfc_walk_expr (arg);
2536 gfc_init_se (&argse, se);
2537 if (ss == gfc_ss_terminator)
2538 gfc_conv_expr (&argse, arg);
2540 gfc_conv_expr_descriptor (&argse, arg, ss);
2541 gfc_add_block_to_block (&se->pre, &argse.pre);
2542 gfc_add_block_to_block (&se->post, &argse.post);
2543 len = argse.string_length;
2546 se->expr = convert (type, len);
2549 /* The length of a character string not including trailing blanks. */
2551 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2556 args = gfc_conv_intrinsic_function_args (se, expr);
2557 type = gfc_typenode_for_spec (&expr->ts);
2558 se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
2559 se->expr = convert (type, se->expr);
2563 /* Returns the starting position of a substring within a string. */
2566 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2568 tree logical4_type_node = gfc_get_logical_type (4);
2574 args = gfc_conv_intrinsic_function_args (se, expr);
2575 type = gfc_typenode_for_spec (&expr->ts);
2576 tmp = gfc_advance_chain (args, 3);
2577 if (TREE_CHAIN (tmp) == NULL_TREE)
2579 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2581 TREE_CHAIN (tmp) = back;
2585 back = TREE_CHAIN (tmp);
2586 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2589 se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
2590 se->expr = convert (type, se->expr);
2593 /* The ascii value for a single character. */
2595 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2600 arg = gfc_conv_intrinsic_function_args (se, expr);
2601 arg = TREE_VALUE (TREE_CHAIN (arg));
2602 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2603 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2604 type = gfc_typenode_for_spec (&expr->ts);
2606 se->expr = build_fold_indirect_ref (arg);
2607 se->expr = convert (type, se->expr);
2611 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2614 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2623 arg = gfc_conv_intrinsic_function_args (se, expr);
2624 if (expr->ts.type != BT_CHARACTER)
2626 tsource = TREE_VALUE (arg);
2627 arg = TREE_CHAIN (arg);
2628 fsource = TREE_VALUE (arg);
2629 mask = TREE_VALUE (TREE_CHAIN (arg));
2633 /* We do the same as in the non-character case, but the argument
2634 list is different because of the string length arguments. We
2635 also have to set the string length for the result. */
2636 len = TREE_VALUE (arg);
2637 arg = TREE_CHAIN (arg);
2638 tsource = TREE_VALUE (arg);
2639 arg = TREE_CHAIN (TREE_CHAIN (arg));
2640 fsource = TREE_VALUE (arg);
2641 mask = TREE_VALUE (TREE_CHAIN (arg));
2643 se->string_length = len;
2645 type = TREE_TYPE (tsource);
2646 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2651 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2653 gfc_actual_arglist *actual;
2660 gfc_init_se (&argse, NULL);
2661 actual = expr->value.function.actual;
2663 ss = gfc_walk_expr (actual->expr);
2664 gcc_assert (ss != gfc_ss_terminator);
2665 argse.want_pointer = 1;
2666 argse.data_not_needed = 1;
2667 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2668 gfc_add_block_to_block (&se->pre, &argse.pre);
2669 gfc_add_block_to_block (&se->post, &argse.post);
2670 args = gfc_chainon_list (NULL_TREE, argse.expr);
2672 actual = actual->next;
2675 gfc_init_se (&argse, NULL);
2676 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2677 gfc_add_block_to_block (&se->pre, &argse.pre);
2678 args = gfc_chainon_list (args, argse.expr);
2679 fndecl = gfor_fndecl_size1;
2682 fndecl = gfor_fndecl_size0;
2684 se->expr = build_function_call_expr (fndecl, args);
2685 type = gfc_typenode_for_spec (&expr->ts);
2686 se->expr = convert (type, se->expr);
2690 /* Intrinsic string comparison functions. */
2693 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2699 args = gfc_conv_intrinsic_function_args (se, expr);
2700 arg2 = TREE_CHAIN (TREE_CHAIN (args));
2702 se->expr = gfc_build_compare_string (TREE_VALUE (args),
2703 TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
2704 TREE_VALUE (TREE_CHAIN (arg2)));
2706 type = gfc_typenode_for_spec (&expr->ts);
2707 se->expr = fold_build2 (op, type, se->expr,
2708 build_int_cst (TREE_TYPE (se->expr), 0));
2711 /* Generate a call to the adjustl/adjustr library function. */
2713 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2721 args = gfc_conv_intrinsic_function_args (se, expr);
2722 len = TREE_VALUE (args);
2724 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2725 var = gfc_conv_string_tmp (se, type, len);
2726 args = tree_cons (NULL_TREE, var, args);
2728 tmp = build_function_call_expr (fndecl, args);
2729 gfc_add_expr_to_block (&se->pre, tmp);
2731 se->string_length = len;
2735 /* A helper function for gfc_conv_intrinsic_array_transfer to compute
2736 the size of tree expressions in bytes. */
2738 gfc_size_in_bytes (gfc_se *se, gfc_expr *e)
2742 if (e->ts.type == BT_CHARACTER)
2743 tmp = se->string_length;
2748 tmp = gfc_get_element_type (TREE_TYPE (se->expr));
2749 tmp = size_in_bytes (tmp);
2752 tmp = size_in_bytes (TREE_TYPE (TREE_TYPE (se->expr)));
2755 return fold_convert (gfc_array_index_type, tmp);
2759 /* Array transfer statement.
2760 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
2762 typeof<DEST> = typeof<MOLD>
2764 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
2765 sizeof (DEST(0) * SIZE). */
2768 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
2782 gfc_actual_arglist *arg;
2789 gcc_assert (se->loop);
2790 info = &se->ss->data.info;
2792 /* Convert SOURCE. The output from this stage is:-
2793 source_bytes = length of the source in bytes
2794 source = pointer to the source data. */
2795 arg = expr->value.function.actual;
2796 gfc_init_se (&argse, NULL);
2797 ss = gfc_walk_expr (arg->expr);
2799 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
2801 /* Obtain the pointer to source and the length of source in bytes. */
2802 if (ss == gfc_ss_terminator)
2804 gfc_conv_expr_reference (&argse, arg->expr);
2805 source = argse.expr;
2807 /* Obtain the source word length. */
2808 tmp = gfc_size_in_bytes (&argse, arg->expr);
2812 gfc_init_se (&argse, NULL);
2813 argse.want_pointer = 0;
2814 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2815 source = gfc_conv_descriptor_data_get (argse.expr);
2817 /* Repack the source if not a full variable array. */
2818 if (!(arg->expr->expr_type == EXPR_VARIABLE
2819 && arg->expr->ref->u.ar.type == AR_FULL))
2821 tmp = build_fold_addr_expr (argse.expr);
2822 tmp = gfc_chainon_list (NULL_TREE, tmp);
2823 source = build_function_call_expr (gfor_fndecl_in_pack, tmp);
2824 source = gfc_evaluate_now (source, &argse.pre);
2826 /* Free the temporary. */
2827 gfc_start_block (&block);
2828 tmp = convert (pvoid_type_node, source);
2829 tmp = gfc_chainon_list (NULL_TREE, tmp);
2830 tmp = build_function_call_expr (gfor_fndecl_internal_free, tmp);
2831 gfc_add_expr_to_block (&block, tmp);
2832 stmt = gfc_finish_block (&block);
2834 /* Clean up if it was repacked. */
2835 gfc_init_block (&block);
2836 tmp = gfc_conv_array_data (argse.expr);
2837 tmp = build2 (NE_EXPR, boolean_type_node, source, tmp);
2838 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
2839 gfc_add_expr_to_block (&block, tmp);
2840 gfc_add_block_to_block (&block, &se->post);
2841 gfc_init_block (&se->post);
2842 gfc_add_block_to_block (&se->post, &block);
2845 /* Obtain the source word length. */
2846 tmp = gfc_size_in_bytes (&argse, arg->expr);
2848 /* Obtain the size of the array in bytes. */
2849 extent = gfc_create_var (gfc_array_index_type, NULL);
2850 for (n = 0; n < arg->expr->rank; n++)
2853 idx = gfc_rank_cst[n];
2854 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2855 stride = gfc_conv_descriptor_stride (argse.expr, idx);
2856 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2857 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2858 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
2860 gfc_add_modify_expr (&argse.pre, extent, tmp);
2861 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2862 extent, gfc_index_one_node);
2863 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2868 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2869 gfc_add_block_to_block (&se->pre, &argse.pre);
2870 gfc_add_block_to_block (&se->post, &argse.post);
2872 /* Now convert MOLD. The sole output is:
2873 dest_word_len = destination word length in bytes. */
2876 gfc_init_se (&argse, NULL);
2877 ss = gfc_walk_expr (arg->expr);
2879 if (ss == gfc_ss_terminator)
2881 gfc_conv_expr_reference (&argse, arg->expr);
2883 /* Obtain the source word length. */
2884 tmp = gfc_size_in_bytes (&argse, arg->expr);
2888 gfc_init_se (&argse, NULL);
2889 argse.want_pointer = 0;
2890 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2892 /* Obtain the source word length. */
2893 tmp = gfc_size_in_bytes (&argse, arg->expr);
2896 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
2897 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
2899 /* Finally convert SIZE, if it is present. */
2901 size_words = gfc_create_var (gfc_array_index_type, NULL);
2905 gfc_init_se (&argse, NULL);
2906 gfc_conv_expr_reference (&argse, arg->expr);
2907 tmp = convert (gfc_array_index_type,
2908 build_fold_indirect_ref (argse.expr));
2909 gfc_add_block_to_block (&se->pre, &argse.pre);
2910 gfc_add_block_to_block (&se->post, &argse.post);
2915 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
2916 if (tmp != NULL_TREE)
2918 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2919 tmp, dest_word_len);
2920 tmp = build2 (MIN_EXPR, gfc_array_index_type, tmp, source_bytes);
2925 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
2926 gfc_add_modify_expr (&se->pre, size_words,
2927 build2 (CEIL_DIV_EXPR, gfc_array_index_type,
2928 size_bytes, dest_word_len));
2930 /* Evaluate the bounds of the result. If the loop range exists, we have
2931 to check if it is too large. If so, we modify loop->to be consistent
2932 with min(size, size(source)). Otherwise, size is made consistent with
2933 the loop range, so that the right number of bytes is transferred.*/
2934 n = se->loop->order[0];
2935 if (se->loop->to[n] != NULL_TREE)
2937 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2938 se->loop->to[n], se->loop->from[n]);
2939 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2940 tmp, gfc_index_one_node);
2941 tmp = build2 (MIN_EXPR, gfc_array_index_type,
2943 gfc_add_modify_expr (&se->pre, size_words, tmp);
2944 gfc_add_modify_expr (&se->pre, size_bytes,
2945 build2 (MULT_EXPR, gfc_array_index_type,
2946 size_words, dest_word_len));
2947 upper = build2 (PLUS_EXPR, gfc_array_index_type,
2948 size_words, se->loop->from[n]);
2949 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2950 upper, gfc_index_one_node);
2954 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2955 size_words, gfc_index_one_node);
2956 se->loop->from[n] = gfc_index_zero_node;
2959 se->loop->to[n] = upper;
2961 /* Build a destination descriptor, using the pointer, source, as the
2962 data field. This is already allocated so set callee_alloc. */
2963 tmp = gfc_typenode_for_spec (&expr->ts);
2964 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
2965 info, tmp, false, true, false, false);
2967 /* Use memcpy to do the transfer. */
2968 tmp = gfc_conv_descriptor_data_get (info->descriptor);
2969 args = gfc_chainon_list (NULL_TREE, tmp);
2970 tmp = fold_convert (pvoid_type_node, source);
2971 args = gfc_chainon_list (args, source);
2972 args = gfc_chainon_list (args, size_bytes);
2973 tmp = built_in_decls[BUILT_IN_MEMCPY];
2974 tmp = build_function_call_expr (tmp, args);
2975 gfc_add_expr_to_block (&se->pre, tmp);
2977 se->expr = info->descriptor;
2978 if (expr->ts.type == BT_CHARACTER)
2979 se->string_length = dest_word_len;
2983 /* Scalar transfer statement.
2984 TRANSFER (source, mold) = VIEW_CONVERT_EXPR<typeof<mold> >source. */
2987 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2989 gfc_actual_arglist *arg;
2995 /* Get a pointer to the source. */
2996 arg = expr->value.function.actual;
2997 ss = gfc_walk_expr (arg->expr);
2998 gfc_init_se (&argse, NULL);
2999 if (ss == gfc_ss_terminator)
3000 gfc_conv_expr_reference (&argse, arg->expr);
3002 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3003 gfc_add_block_to_block (&se->pre, &argse.pre);
3004 gfc_add_block_to_block (&se->post, &argse.post);
3008 type = gfc_typenode_for_spec (&expr->ts);
3009 if (expr->ts.type == BT_CHARACTER)
3011 ptr = convert (build_pointer_type (type), ptr);
3012 gfc_init_se (&argse, NULL);
3013 gfc_conv_expr (&argse, arg->expr);
3014 gfc_add_block_to_block (&se->pre, &argse.pre);
3015 gfc_add_block_to_block (&se->post, &argse.post);
3017 se->string_length = argse.string_length;
3021 tree tmp = build_fold_indirect_ref (ptr);
3022 se->expr = fold_build1 (VIEW_CONVERT_EXPR, type, tmp);
3027 /* Generate code for the ALLOCATED intrinsic.
3028 Generate inline code that directly check the address of the argument. */
3031 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3033 gfc_actual_arglist *arg1;
3038 gfc_init_se (&arg1se, NULL);
3039 arg1 = expr->value.function.actual;
3040 ss1 = gfc_walk_expr (arg1->expr);
3041 arg1se.descriptor_only = 1;
3042 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3044 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3045 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
3046 fold_convert (TREE_TYPE (tmp), null_pointer_node));
3047 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3051 /* Generate code for the ASSOCIATED intrinsic.
3052 If both POINTER and TARGET are arrays, generate a call to library function
3053 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3054 In other cases, generate inline code that directly compare the address of
3055 POINTER with the address of TARGET. */
3058 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3060 gfc_actual_arglist *arg1;
3061 gfc_actual_arglist *arg2;
3067 tree nonzero_charlen;
3068 tree nonzero_arraylen;
3071 gfc_init_se (&arg1se, NULL);
3072 gfc_init_se (&arg2se, NULL);
3073 arg1 = expr->value.function.actual;
3075 ss1 = gfc_walk_expr (arg1->expr);
3079 /* No optional target. */
3080 if (ss1 == gfc_ss_terminator)
3082 /* A pointer to a scalar. */
3083 arg1se.want_pointer = 1;
3084 gfc_conv_expr (&arg1se, arg1->expr);
3089 /* A pointer to an array. */
3090 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3091 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3093 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3094 gfc_add_block_to_block (&se->post, &arg1se.post);
3095 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
3096 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3101 /* An optional target. */
3102 ss2 = gfc_walk_expr (arg2->expr);
3104 nonzero_charlen = NULL_TREE;
3105 if (arg1->expr->ts.type == BT_CHARACTER)
3106 nonzero_charlen = build2 (NE_EXPR, boolean_type_node,
3107 arg1->expr->ts.cl->backend_decl,
3110 if (ss1 == gfc_ss_terminator)
3112 /* A pointer to a scalar. */
3113 gcc_assert (ss2 == gfc_ss_terminator);
3114 arg1se.want_pointer = 1;
3115 gfc_conv_expr (&arg1se, arg1->expr);
3116 arg2se.want_pointer = 1;
3117 gfc_conv_expr (&arg2se, arg2->expr);
3118 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3119 gfc_add_block_to_block (&se->post, &arg1se.post);
3120 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
3126 /* An array pointer of zero length is not associated if target is
3128 arg1se.descriptor_only = 1;
3129 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3130 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3131 gfc_rank_cst[arg1->expr->rank - 1]);
3132 nonzero_arraylen = build2 (NE_EXPR, boolean_type_node,
3133 tmp, integer_zero_node);
3135 /* A pointer to an array, call library function _gfor_associated. */
3136 gcc_assert (ss2 != gfc_ss_terminator);
3138 arg1se.want_pointer = 1;
3139 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3140 args = gfc_chainon_list (args, arg1se.expr);
3142 arg2se.want_pointer = 1;
3143 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3144 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3145 gfc_add_block_to_block (&se->post, &arg2se.post);
3146 args = gfc_chainon_list (args, arg2se.expr);
3147 fndecl = gfor_fndecl_associated;
3148 se->expr = build_function_call_expr (fndecl, args);
3149 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3150 se->expr, nonzero_arraylen);
3154 /* If target is present zero character length pointers cannot
3156 if (nonzero_charlen != NULL_TREE)
3157 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3158 se->expr, nonzero_charlen);
3161 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3165 /* Scan a string for any one of the characters in a set of characters. */
3168 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
3170 tree logical4_type_node = gfc_get_logical_type (4);
3176 args = gfc_conv_intrinsic_function_args (se, expr);
3177 type = gfc_typenode_for_spec (&expr->ts);
3178 tmp = gfc_advance_chain (args, 3);
3179 if (TREE_CHAIN (tmp) == NULL_TREE)
3181 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3183 TREE_CHAIN (tmp) = back;
3187 back = TREE_CHAIN (tmp);
3188 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3191 se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
3192 se->expr = convert (type, se->expr);
3196 /* Verify that a set of characters contains all the characters in a string
3197 by identifying the position of the first character in a string of
3198 characters that does not appear in a given set of characters. */
3201 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
3203 tree logical4_type_node = gfc_get_logical_type (4);
3209 args = gfc_conv_intrinsic_function_args (se, expr);
3210 type = gfc_typenode_for_spec (&expr->ts);
3211 tmp = gfc_advance_chain (args, 3);
3212 if (TREE_CHAIN (tmp) == NULL_TREE)
3214 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3216 TREE_CHAIN (tmp) = back;
3220 back = TREE_CHAIN (tmp);
3221 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3224 se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
3225 se->expr = convert (type, se->expr);
3229 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3232 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
3236 args = gfc_conv_intrinsic_function_args (se, expr);
3237 args = TREE_VALUE (args);
3238 args = build_fold_addr_expr (args);
3239 args = tree_cons (NULL_TREE, args, NULL_TREE);
3240 se->expr = build_function_call_expr (gfor_fndecl_si_kind, args);
3243 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3246 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
3248 gfc_actual_arglist *actual;
3253 for (actual = expr->value.function.actual; actual; actual = actual->next)
3255 gfc_init_se (&argse, se);
3257 /* Pass a NULL pointer for an absent arg. */
3258 if (actual->expr == NULL)
3259 argse.expr = null_pointer_node;
3261 gfc_conv_expr_reference (&argse, actual->expr);
3263 gfc_add_block_to_block (&se->pre, &argse.pre);
3264 gfc_add_block_to_block (&se->post, &argse.post);
3265 args = gfc_chainon_list (args, argse.expr);
3267 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3271 /* Generate code for TRIM (A) intrinsic function. */
3274 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3276 tree gfc_int4_type_node = gfc_get_int_type (4);
3285 arglist = NULL_TREE;
3287 type = build_pointer_type (gfc_character1_type_node);
3288 var = gfc_create_var (type, "pstr");
3289 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3290 len = gfc_create_var (gfc_int4_type_node, "len");
3292 tmp = gfc_conv_intrinsic_function_args (se, expr);
3293 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
3294 arglist = gfc_chainon_list (arglist, addr);
3295 arglist = chainon (arglist, tmp);
3297 tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
3298 gfc_add_expr_to_block (&se->pre, tmp);
3300 /* Free the temporary afterwards, if necessary. */
3301 cond = build2 (GT_EXPR, boolean_type_node, len,
3302 build_int_cst (TREE_TYPE (len), 0));
3303 arglist = gfc_chainon_list (NULL_TREE, var);
3304 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
3305 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3306 gfc_add_expr_to_block (&se->post, tmp);
3309 se->string_length = len;
3313 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3316 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3318 tree gfc_int4_type_node = gfc_get_int_type (4);
3327 args = gfc_conv_intrinsic_function_args (se, expr);
3328 len = TREE_VALUE (args);
3329 tmp = gfc_advance_chain (args, 2);
3330 ncopies = TREE_VALUE (tmp);
3331 len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
3332 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3333 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
3335 arglist = NULL_TREE;
3336 arglist = gfc_chainon_list (arglist, var);
3337 arglist = chainon (arglist, args);
3338 tmp = build_function_call_expr (gfor_fndecl_string_repeat, arglist);
3339 gfc_add_expr_to_block (&se->pre, tmp);
3342 se->string_length = len;
3346 /* Generate code for the IARGC intrinsic. */
3349 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3355 /* Call the library function. This always returns an INTEGER(4). */
3356 fndecl = gfor_fndecl_iargc;
3357 tmp = build_function_call_expr (fndecl, NULL_TREE);
3359 /* Convert it to the required type. */
3360 type = gfc_typenode_for_spec (&expr->ts);
3361 tmp = fold_convert (type, tmp);
3367 /* The loc intrinsic returns the address of its argument as
3368 gfc_index_integer_kind integer. */
3371 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3377 gcc_assert (!se->ss);
3379 arg_expr = expr->value.function.actual->expr;
3380 ss = gfc_walk_expr (arg_expr);
3381 if (ss == gfc_ss_terminator)
3382 gfc_conv_expr_reference (se, arg_expr);
3384 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3385 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
3387 /* Create a temporary variable for loc return value. Without this,
3388 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3389 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
3390 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3391 se->expr = temp_var;
3394 /* Generate code for an intrinsic function. Some map directly to library
3395 calls, others get special handling. In some cases the name of the function
3396 used depends on the type specifiers. */
3399 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
3401 gfc_intrinsic_sym *isym;
3405 isym = expr->value.function.isym;
3407 name = &expr->value.function.name[2];
3409 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
3411 lib = gfc_is_intrinsic_libcall (expr);
3415 se->ignore_optional = 1;
3416 gfc_conv_intrinsic_funcall (se, expr);
3421 switch (expr->value.function.isym->generic_id)
3426 case GFC_ISYM_REPEAT:
3427 gfc_conv_intrinsic_repeat (se, expr);
3431 gfc_conv_intrinsic_trim (se, expr);
3434 case GFC_ISYM_SI_KIND:
3435 gfc_conv_intrinsic_si_kind (se, expr);
3438 case GFC_ISYM_SR_KIND:
3439 gfc_conv_intrinsic_sr_kind (se, expr);
3442 case GFC_ISYM_EXPONENT:
3443 gfc_conv_intrinsic_exponent (se, expr);
3447 gfc_conv_intrinsic_scan (se, expr);
3450 case GFC_ISYM_VERIFY:
3451 gfc_conv_intrinsic_verify (se, expr);
3454 case GFC_ISYM_ALLOCATED:
3455 gfc_conv_allocated (se, expr);
3458 case GFC_ISYM_ASSOCIATED:
3459 gfc_conv_associated(se, expr);
3463 gfc_conv_intrinsic_abs (se, expr);
3466 case GFC_ISYM_ADJUSTL:
3467 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
3470 case GFC_ISYM_ADJUSTR:
3471 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
3474 case GFC_ISYM_AIMAG:
3475 gfc_conv_intrinsic_imagpart (se, expr);
3479 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
3483 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
3486 case GFC_ISYM_ANINT:
3487 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
3491 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3495 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
3498 case GFC_ISYM_BTEST:
3499 gfc_conv_intrinsic_btest (se, expr);
3502 case GFC_ISYM_ACHAR:
3504 gfc_conv_intrinsic_char (se, expr);
3507 case GFC_ISYM_CONVERSION:
3509 case GFC_ISYM_LOGICAL:
3511 gfc_conv_intrinsic_conversion (se, expr);
3514 /* Integer conversions are handled separately to make sure we get the
3515 correct rounding mode. */
3520 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
3524 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
3527 case GFC_ISYM_CEILING:
3528 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
3531 case GFC_ISYM_FLOOR:
3532 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
3536 gfc_conv_intrinsic_mod (se, expr, 0);
3539 case GFC_ISYM_MODULO:
3540 gfc_conv_intrinsic_mod (se, expr, 1);
3543 case GFC_ISYM_CMPLX:
3544 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3547 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3548 gfc_conv_intrinsic_iargc (se, expr);
3551 case GFC_ISYM_COMPLEX:
3552 gfc_conv_intrinsic_cmplx (se, expr, 1);
3555 case GFC_ISYM_CONJG:
3556 gfc_conv_intrinsic_conjg (se, expr);
3559 case GFC_ISYM_COUNT:
3560 gfc_conv_intrinsic_count (se, expr);
3563 case GFC_ISYM_CTIME:
3564 gfc_conv_intrinsic_ctime (se, expr);
3568 gfc_conv_intrinsic_dim (se, expr);
3571 case GFC_ISYM_DOT_PRODUCT:
3572 gfc_conv_intrinsic_dot_product (se, expr);
3575 case GFC_ISYM_DPROD:
3576 gfc_conv_intrinsic_dprod (se, expr);
3579 case GFC_ISYM_FDATE:
3580 gfc_conv_intrinsic_fdate (se, expr);
3584 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3587 case GFC_ISYM_IBCLR:
3588 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3591 case GFC_ISYM_IBITS:
3592 gfc_conv_intrinsic_ibits (se, expr);
3595 case GFC_ISYM_IBSET:
3596 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3599 case GFC_ISYM_IACHAR:
3600 case GFC_ISYM_ICHAR:
3601 /* We assume ASCII character sequence. */
3602 gfc_conv_intrinsic_ichar (se, expr);
3605 case GFC_ISYM_IARGC:
3606 gfc_conv_intrinsic_iargc (se, expr);
3610 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3613 case GFC_ISYM_INDEX:
3614 gfc_conv_intrinsic_index (se, expr);
3618 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3621 case GFC_ISYM_LSHIFT:
3622 gfc_conv_intrinsic_rlshift (se, expr, 0);
3625 case GFC_ISYM_RSHIFT:
3626 gfc_conv_intrinsic_rlshift (se, expr, 1);
3629 case GFC_ISYM_ISHFT:
3630 gfc_conv_intrinsic_ishft (se, expr);
3633 case GFC_ISYM_ISHFTC:
3634 gfc_conv_intrinsic_ishftc (se, expr);
3637 case GFC_ISYM_LBOUND:
3638 gfc_conv_intrinsic_bound (se, expr, 0);
3641 case GFC_ISYM_TRANSPOSE:
3642 if (se->ss && se->ss->useflags)
3644 gfc_conv_tmp_array_ref (se);
3645 gfc_advance_se_ss_chain (se);
3648 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3652 gfc_conv_intrinsic_len (se, expr);
3655 case GFC_ISYM_LEN_TRIM:
3656 gfc_conv_intrinsic_len_trim (se, expr);
3660 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3664 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3668 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3672 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3676 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3679 case GFC_ISYM_MAXLOC:
3680 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3683 case GFC_ISYM_MAXVAL:
3684 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3687 case GFC_ISYM_MERGE:
3688 gfc_conv_intrinsic_merge (se, expr);
3692 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3695 case GFC_ISYM_MINLOC:
3696 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3699 case GFC_ISYM_MINVAL:
3700 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3704 gfc_conv_intrinsic_not (se, expr);
3708 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3711 case GFC_ISYM_PRESENT:
3712 gfc_conv_intrinsic_present (se, expr);
3715 case GFC_ISYM_PRODUCT:
3716 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3720 gfc_conv_intrinsic_sign (se, expr);
3724 gfc_conv_intrinsic_size (se, expr);
3728 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3731 case GFC_ISYM_TRANSFER:
3734 if (se->ss->useflags)
3736 /* Access the previously obtained result. */
3737 gfc_conv_tmp_array_ref (se);
3738 gfc_advance_se_ss_chain (se);
3742 gfc_conv_intrinsic_array_transfer (se, expr);
3745 gfc_conv_intrinsic_transfer (se, expr);
3748 case GFC_ISYM_TTYNAM:
3749 gfc_conv_intrinsic_ttynam (se, expr);
3752 case GFC_ISYM_UBOUND:
3753 gfc_conv_intrinsic_bound (se, expr, 1);
3757 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3761 gfc_conv_intrinsic_loc (se, expr);
3764 case GFC_ISYM_ACCESS:
3765 case GFC_ISYM_CHDIR:
3766 case GFC_ISYM_CHMOD:
3767 case GFC_ISYM_ETIME:
3769 case GFC_ISYM_FGETC:
3772 case GFC_ISYM_FPUTC:
3773 case GFC_ISYM_FSTAT:
3774 case GFC_ISYM_FTELL:
3775 case GFC_ISYM_GETCWD:
3776 case GFC_ISYM_GETGID:
3777 case GFC_ISYM_GETPID:
3778 case GFC_ISYM_GETUID:
3779 case GFC_ISYM_HOSTNM:
3781 case GFC_ISYM_IERRNO:
3782 case GFC_ISYM_IRAND:
3783 case GFC_ISYM_ISATTY:
3785 case GFC_ISYM_LSTAT:
3786 case GFC_ISYM_MALLOC:
3787 case GFC_ISYM_MATMUL:
3788 case GFC_ISYM_MCLOCK:
3789 case GFC_ISYM_MCLOCK8:
3791 case GFC_ISYM_RENAME:
3792 case GFC_ISYM_SECOND:
3793 case GFC_ISYM_SECNDS:
3794 case GFC_ISYM_SIGNAL:
3796 case GFC_ISYM_SYMLNK:
3797 case GFC_ISYM_SYSTEM:
3799 case GFC_ISYM_TIME8:
3800 case GFC_ISYM_UMASK:
3801 case GFC_ISYM_UNLINK:
3802 gfc_conv_intrinsic_funcall (se, expr);
3806 gfc_conv_intrinsic_lib_function (se, expr);
3812 /* This generates code to execute before entering the scalarization loop.
3813 Currently does nothing. */
3816 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
3818 switch (ss->expr->value.function.isym->generic_id)
3820 case GFC_ISYM_UBOUND:
3821 case GFC_ISYM_LBOUND:
3830 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
3831 inside the scalarization loop. */
3834 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
3838 /* The two argument version returns a scalar. */
3839 if (expr->value.function.actual->next->expr)
3842 newss = gfc_get_ss ();
3843 newss->type = GFC_SS_INTRINSIC;
3846 newss->data.info.dimen = 1;
3852 /* Walk an intrinsic array libcall. */
3855 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
3859 gcc_assert (expr->rank > 0);
3861 newss = gfc_get_ss ();
3862 newss->type = GFC_SS_FUNCTION;
3865 newss->data.info.dimen = expr->rank;
3871 /* Returns nonzero if the specified intrinsic function call maps directly to a
3872 an external library call. Should only be used for functions that return
3876 gfc_is_intrinsic_libcall (gfc_expr * expr)
3878 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3879 gcc_assert (expr->rank > 0);
3881 switch (expr->value.function.isym->generic_id)
3885 case GFC_ISYM_COUNT:
3886 case GFC_ISYM_MATMUL:
3887 case GFC_ISYM_MAXLOC:
3888 case GFC_ISYM_MAXVAL:
3889 case GFC_ISYM_MINLOC:
3890 case GFC_ISYM_MINVAL:
3891 case GFC_ISYM_PRODUCT:
3893 case GFC_ISYM_SHAPE:
3894 case GFC_ISYM_SPREAD:
3895 case GFC_ISYM_TRANSPOSE:
3896 /* Ignore absent optional parameters. */
3899 case GFC_ISYM_RESHAPE:
3900 case GFC_ISYM_CSHIFT:
3901 case GFC_ISYM_EOSHIFT:
3903 case GFC_ISYM_UNPACK:
3904 /* Pass absent optional parameters. */
3912 /* Walk an intrinsic function. */
3914 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3915 gfc_intrinsic_sym * isym)
3919 if (isym->elemental)
3920 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
3922 if (expr->rank == 0)
3925 if (gfc_is_intrinsic_libcall (expr))
3926 return gfc_walk_intrinsic_libfunc (ss, expr);
3928 /* Special cases. */
3929 switch (isym->generic_id)
3931 case GFC_ISYM_LBOUND:
3932 case GFC_ISYM_UBOUND:
3933 return gfc_walk_intrinsic_bound (ss, expr);
3935 case GFC_ISYM_TRANSFER:
3936 return gfc_walk_intrinsic_libfunc (ss, expr);
3939 /* This probably meant someone forgot to add an intrinsic to the above
3940 list(s) when they implemented it, or something's gone horribly wrong.
3942 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3943 expr->value.function.name);
3947 #include "gt-fortran-trans-intrinsic.h"