1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
28 #include "coretypes.h"
33 #include "tree-gimple.h"
37 #include "intrinsic.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
44 #include "trans-stmt.h"
46 /* This maps fortran intrinsic math functions to external library or GCC
48 typedef struct gfc_intrinsic_map_t GTY(())
50 /* The explicit enum is required to work around inadequacies in the
51 garbage collection/gengtype parsing mechanism. */
54 /* Enum value from the "language-independent", aka C-centric, part
55 of gcc, or END_BUILTINS of no such value set. */
56 enum built_in_function code_r4;
57 enum built_in_function code_r8;
58 enum built_in_function code_r10;
59 enum built_in_function code_r16;
60 enum built_in_function code_c4;
61 enum built_in_function code_c8;
62 enum built_in_function code_c10;
63 enum built_in_function code_c16;
65 /* True if the naming pattern is to prepend "c" for complex and
66 append "f" for kind=4. False if the naming pattern is to
67 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
70 /* True if a complex version of the function exists. */
71 bool complex_available;
73 /* True if the function should be marked const. */
76 /* The base library name of this function. */
79 /* Cache decls created for the various operand types. */
91 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
92 defines complex variants of all of the entries in mathbuiltins.def
94 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
95 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
96 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, 0, 0, 0, 0, true, \
97 false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
98 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
100 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
101 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
102 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
103 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
104 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
105 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
107 #define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
108 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 true, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
111 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
113 #define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
114 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
115 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
116 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
117 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
119 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
121 /* Functions built into gcc itself. */
122 #include "mathbuiltins.def"
124 /* Functions in libm. */
125 /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
126 pattern for other mathbuiltins.def entries. At present we have no
127 optimizations for this in the common sources. */
128 LIBM_FUNCTION (SCALE, "scalbn", false),
130 /* Functions in libgfortran. */
131 LIBF_FUNCTION (FRACTION, "fraction", false),
132 LIBF_FUNCTION (NEAREST, "nearest", false),
133 LIBF_FUNCTION (RRSPACING, "rrspacing", false),
134 LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
135 LIBF_FUNCTION (SPACING, "spacing", false),
138 LIBF_FUNCTION (NONE, NULL, false)
140 #undef DEFINE_MATH_BUILTIN
141 #undef DEFINE_MATH_BUILTIN_C
145 /* Structure for storing components of a floating number to be used by
146 elemental functions to manipulate reals. */
149 tree arg; /* Variable tree to view convert to integer. */
150 tree expn; /* Variable tree to save exponent. */
151 tree frac; /* Variable tree to save fraction. */
152 tree smask; /* Constant tree of sign's mask. */
153 tree emask; /* Constant tree of exponent's mask. */
154 tree fmask; /* Constant tree of fraction's mask. */
155 tree edigits; /* Constant tree of the number of exponent bits. */
156 tree fdigits; /* Constant tree of the number of fraction bits. */
157 tree f1; /* Constant tree of the f1 defined in the real model. */
158 tree bias; /* Constant tree of the bias of exponent in the memory. */
159 tree type; /* Type tree of arg1. */
160 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
164 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
166 /* Evaluate the arguments to an intrinsic function. */
167 /* FIXME: This function and its callers should be rewritten so that it's
168 not necessary to cons up a list to hold the arguments. */
171 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
173 gfc_actual_arglist *actual;
175 gfc_intrinsic_arg *formal;
180 formal = expr->value.function.isym->formal;
182 for (actual = expr->value.function.actual; actual; actual = actual->next,
183 formal = formal ? formal->next : NULL)
186 /* Skip omitted optional arguments. */
190 /* Evaluate the parameter. This will substitute scalarized
191 references automatically. */
192 gfc_init_se (&argse, se);
194 if (e->ts.type == BT_CHARACTER)
196 gfc_conv_expr (&argse, e);
197 gfc_conv_string_parameter (&argse);
198 args = gfc_chainon_list (args, argse.string_length);
201 gfc_conv_expr_val (&argse, e);
203 /* If an optional argument is itself an optional dummy argument,
204 check its presence and substitute a null if absent. */
205 if (e->expr_type ==EXPR_VARIABLE
206 && e->symtree->n.sym->attr.optional
209 gfc_conv_missing_dummy (&argse, e, formal->ts);
211 gfc_add_block_to_block (&se->pre, &argse.pre);
212 gfc_add_block_to_block (&se->post, &argse.post);
213 args = gfc_chainon_list (args, argse.expr);
219 /* Conversions between different types are output by the frontend as
220 intrinsic functions. We implement these directly with inline code. */
223 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
228 /* Evaluate the argument. */
229 type = gfc_typenode_for_spec (&expr->ts);
230 gcc_assert (expr->value.function.actual->expr);
231 arg = gfc_conv_intrinsic_function_args (se, expr);
232 arg = TREE_VALUE (arg);
234 /* Conversion from complex to non-complex involves taking the real
235 component of the value. */
236 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
237 && expr->ts.type != BT_COMPLEX)
241 artype = TREE_TYPE (TREE_TYPE (arg));
242 arg = build1 (REALPART_EXPR, artype, arg);
245 se->expr = convert (type, arg);
248 /* This is needed because the gcc backend only implements
249 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
250 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
251 Similarly for CEILING. */
254 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
261 argtype = TREE_TYPE (arg);
262 arg = gfc_evaluate_now (arg, pblock);
264 intval = convert (type, arg);
265 intval = gfc_evaluate_now (intval, pblock);
267 tmp = convert (argtype, intval);
268 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
270 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
271 build_int_cst (type, 1));
272 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
277 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
278 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
281 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
290 argtype = TREE_TYPE (arg);
291 arg = gfc_evaluate_now (arg, pblock);
293 real_from_string (&r, "0.5");
294 pos = build_real (argtype, r);
296 real_from_string (&r, "-0.5");
297 neg = build_real (argtype, r);
299 tmp = gfc_build_const (argtype, integer_zero_node);
300 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
302 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
303 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
304 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
308 /* Convert a real to an integer using a specific rounding mode.
309 Ideally we would just build the corresponding GENERIC node,
310 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
313 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
314 enum rounding_mode op)
319 return build_fixbound_expr (pblock, arg, type, 0);
323 return build_fixbound_expr (pblock, arg, type, 1);
327 return build_round_expr (pblock, arg, type);
330 gcc_assert (op == RND_TRUNC);
331 return build1 (FIX_TRUNC_EXPR, type, arg);
336 /* Round a real value using the specified rounding mode.
337 We use a temporary integer of that same kind size as the result.
338 Values larger than those that can be represented by this kind are
339 unchanged, as they will not be accurate enough to represent the
341 huge = HUGE (KIND (a))
342 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
346 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
357 kind = expr->ts.kind;
360 /* We have builtin functions for some cases. */
403 /* Evaluate the argument. */
404 gcc_assert (expr->value.function.actual->expr);
405 arg = gfc_conv_intrinsic_function_args (se, expr);
407 /* Use a builtin function if one exists. */
408 if (n != END_BUILTINS)
410 tmp = built_in_decls[n];
411 se->expr = build_function_call_expr (tmp, arg);
415 /* This code is probably redundant, but we'll keep it lying around just
417 type = gfc_typenode_for_spec (&expr->ts);
418 arg = TREE_VALUE (arg);
419 arg = gfc_evaluate_now (arg, &se->pre);
421 /* Test if the value is too large to handle sensibly. */
422 gfc_set_model_kind (kind);
424 n = gfc_validate_kind (BT_INTEGER, kind, false);
425 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
426 tmp = gfc_conv_mpfr_to_tree (huge, kind);
427 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
429 mpfr_neg (huge, huge, GFC_RND_MODE);
430 tmp = gfc_conv_mpfr_to_tree (huge, kind);
431 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
432 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
433 itype = gfc_get_int_type (kind);
435 tmp = build_fix_expr (&se->pre, arg, itype, op);
436 tmp = convert (type, tmp);
437 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
442 /* Convert to an integer using the specified rounding mode. */
445 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
450 /* Evaluate the argument. */
451 type = gfc_typenode_for_spec (&expr->ts);
452 gcc_assert (expr->value.function.actual->expr);
453 arg = gfc_conv_intrinsic_function_args (se, expr);
454 arg = TREE_VALUE (arg);
456 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
458 /* Conversion to a different integer kind. */
459 se->expr = convert (type, arg);
463 /* Conversion from complex to non-complex involves taking the real
464 component of the value. */
465 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
466 && expr->ts.type != BT_COMPLEX)
470 artype = TREE_TYPE (TREE_TYPE (arg));
471 arg = build1 (REALPART_EXPR, artype, arg);
474 se->expr = build_fix_expr (&se->pre, arg, type, op);
479 /* Get the imaginary component of a value. */
482 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
486 arg = gfc_conv_intrinsic_function_args (se, expr);
487 arg = TREE_VALUE (arg);
488 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
492 /* Get the complex conjugate of a value. */
495 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
499 arg = gfc_conv_intrinsic_function_args (se, expr);
500 arg = TREE_VALUE (arg);
501 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
505 /* Initialize function decls for library functions. The external functions
506 are created as required. Builtin functions are added here. */
509 gfc_build_intrinsic_lib_fndecls (void)
511 gfc_intrinsic_map_t *m;
513 /* Add GCC builtin functions. */
514 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
516 if (m->code_r4 != END_BUILTINS)
517 m->real4_decl = built_in_decls[m->code_r4];
518 if (m->code_r8 != END_BUILTINS)
519 m->real8_decl = built_in_decls[m->code_r8];
520 if (m->code_r10 != END_BUILTINS)
521 m->real10_decl = built_in_decls[m->code_r10];
522 if (m->code_r16 != END_BUILTINS)
523 m->real16_decl = built_in_decls[m->code_r16];
524 if (m->code_c4 != END_BUILTINS)
525 m->complex4_decl = built_in_decls[m->code_c4];
526 if (m->code_c8 != END_BUILTINS)
527 m->complex8_decl = built_in_decls[m->code_c8];
528 if (m->code_c10 != END_BUILTINS)
529 m->complex10_decl = built_in_decls[m->code_c10];
530 if (m->code_c16 != END_BUILTINS)
531 m->complex16_decl = built_in_decls[m->code_c16];
536 /* Create a fndecl for a simple intrinsic library function. */
539 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
544 gfc_actual_arglist *actual;
547 char name[GFC_MAX_SYMBOL_LEN + 3];
550 if (ts->type == BT_REAL)
555 pdecl = &m->real4_decl;
558 pdecl = &m->real8_decl;
561 pdecl = &m->real10_decl;
564 pdecl = &m->real16_decl;
570 else if (ts->type == BT_COMPLEX)
572 gcc_assert (m->complex_available);
577 pdecl = &m->complex4_decl;
580 pdecl = &m->complex8_decl;
583 pdecl = &m->complex10_decl;
586 pdecl = &m->complex16_decl;
601 snprintf (name, sizeof (name), "%s%s%s",
602 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
603 else if (ts->kind == 8)
604 snprintf (name, sizeof (name), "%s%s",
605 ts->type == BT_COMPLEX ? "c" : "", m->name);
608 gcc_assert (ts->kind == 10 || ts->kind == 16);
609 snprintf (name, sizeof (name), "%s%s%s",
610 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
615 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
616 ts->type == BT_COMPLEX ? 'c' : 'r',
620 argtypes = NULL_TREE;
621 for (actual = expr->value.function.actual; actual; actual = actual->next)
623 type = gfc_typenode_for_spec (&actual->expr->ts);
624 argtypes = gfc_chainon_list (argtypes, type);
626 argtypes = gfc_chainon_list (argtypes, void_type_node);
627 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
628 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
630 /* Mark the decl as external. */
631 DECL_EXTERNAL (fndecl) = 1;
632 TREE_PUBLIC (fndecl) = 1;
634 /* Mark it __attribute__((const)), if possible. */
635 TREE_READONLY (fndecl) = m->is_constant;
637 rest_of_decl_compilation (fndecl, 1, 0);
644 /* Convert an intrinsic function into an external or builtin call. */
647 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
649 gfc_intrinsic_map_t *m;
654 id = expr->value.function.isym->id;
655 /* Find the entry for this function. */
656 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
662 if (m->id == GFC_ISYM_NONE)
664 internal_error ("Intrinsic function %s(%d) not recognized",
665 expr->value.function.name, id);
668 /* Get the decl and generate the call. */
669 args = gfc_conv_intrinsic_function_args (se, expr);
670 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
671 se->expr = build_function_call_expr (fndecl, args);
674 /* Generate code for EXPONENT(X) intrinsic function. */
677 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
682 args = gfc_conv_intrinsic_function_args (se, expr);
684 a1 = expr->value.function.actual->expr;
688 fndecl = gfor_fndecl_math_exponent4;
691 fndecl = gfor_fndecl_math_exponent8;
694 fndecl = gfor_fndecl_math_exponent10;
697 fndecl = gfor_fndecl_math_exponent16;
703 se->expr = build_function_call_expr (fndecl, args);
706 /* Evaluate a single upper or lower bound. */
707 /* TODO: bound intrinsic generates way too much unnecessary code. */
710 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
712 gfc_actual_arglist *arg;
713 gfc_actual_arglist *arg2;
718 tree cond, cond1, cond2, cond3, cond4, size;
726 arg = expr->value.function.actual;
731 /* Create an implicit second parameter from the loop variable. */
732 gcc_assert (!arg2->expr);
733 gcc_assert (se->loop->dimen == 1);
734 gcc_assert (se->ss->expr == expr);
735 gfc_advance_se_ss_chain (se);
736 bound = se->loop->loopvar[0];
737 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
742 /* use the passed argument. */
743 gcc_assert (arg->next->expr);
744 gfc_init_se (&argse, NULL);
745 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
746 gfc_add_block_to_block (&se->pre, &argse.pre);
748 /* Convert from one based to zero based. */
749 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
753 /* TODO: don't re-evaluate the descriptor on each iteration. */
754 /* Get a descriptor for the first parameter. */
755 ss = gfc_walk_expr (arg->expr);
756 gcc_assert (ss != gfc_ss_terminator);
757 gfc_init_se (&argse, NULL);
758 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
759 gfc_add_block_to_block (&se->pre, &argse.pre);
760 gfc_add_block_to_block (&se->post, &argse.post);
764 if (INTEGER_CST_P (bound))
768 hi = TREE_INT_CST_HIGH (bound);
769 low = TREE_INT_CST_LOW (bound);
770 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
771 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
772 "dimension index", upper ? "UBOUND" : "LBOUND",
777 if (flag_bounds_check)
779 bound = gfc_evaluate_now (bound, &se->pre);
780 cond = fold_build2 (LT_EXPR, boolean_type_node,
781 bound, build_int_cst (TREE_TYPE (bound), 0));
782 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
783 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
784 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
785 gfc_trans_runtime_check (cond, gfc_msg_fault, &se->pre, &expr->where);
789 ubound = gfc_conv_descriptor_ubound (desc, bound);
790 lbound = gfc_conv_descriptor_lbound (desc, bound);
792 /* Follow any component references. */
793 if (arg->expr->expr_type == EXPR_VARIABLE
794 || arg->expr->expr_type == EXPR_CONSTANT)
796 as = arg->expr->symtree->n.sym->as;
797 for (ref = arg->expr->ref; ref; ref = ref->next)
802 as = ref->u.c.component->as;
810 switch (ref->u.ar.type)
828 /* 13.14.53: Result value for LBOUND
830 Case (i): For an array section or for an array expression other than a
831 whole array or array structure component, LBOUND(ARRAY, DIM)
832 has the value 1. For a whole array or array structure
833 component, LBOUND(ARRAY, DIM) has the value:
834 (a) equal to the lower bound for subscript DIM of ARRAY if
835 dimension DIM of ARRAY does not have extent zero
836 or if ARRAY is an assumed-size array of rank DIM,
839 13.14.113: Result value for UBOUND
841 Case (i): For an array section or for an array expression other than a
842 whole array or array structure component, UBOUND(ARRAY, DIM)
843 has the value equal to the number of elements in the given
844 dimension; otherwise, it has a value equal to the upper bound
845 for subscript DIM of ARRAY if dimension DIM of ARRAY does
846 not have size zero and has value zero if dimension DIM has
851 tree stride = gfc_conv_descriptor_stride (desc, bound);
853 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
854 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
856 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
857 gfc_index_zero_node);
858 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
860 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
861 gfc_index_zero_node);
862 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
866 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
868 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
869 ubound, gfc_index_zero_node);
873 if (as->type == AS_ASSUMED_SIZE)
874 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
875 build_int_cst (TREE_TYPE (bound),
876 arg->expr->rank - 1));
878 cond = boolean_false_node;
880 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
881 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
883 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
884 lbound, gfc_index_one_node);
891 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
892 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
896 se->expr = gfc_index_one_node;
899 type = gfc_typenode_for_spec (&expr->ts);
900 se->expr = convert (type, se->expr);
905 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
911 args = gfc_conv_intrinsic_function_args (se, expr);
912 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
913 val = TREE_VALUE (args);
915 switch (expr->value.function.actual->expr->ts.type)
919 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
923 switch (expr->ts.kind)
938 se->expr = build_function_call_expr (built_in_decls[n], args);
947 /* Create a complex value from one or two real components. */
950 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
957 type = gfc_typenode_for_spec (&expr->ts);
958 arg = gfc_conv_intrinsic_function_args (se, expr);
959 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
961 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
962 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
964 arg = TREE_VALUE (arg);
965 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
966 imag = convert (TREE_TYPE (type), imag);
969 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
971 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
974 /* Remainder function MOD(A, P) = A - INT(A / P) * P
975 MODULO(A, P) = A - FLOOR (A / P) * P */
976 /* TODO: MOD(x, 0) */
979 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
991 arg = gfc_conv_intrinsic_function_args (se, expr);
993 switch (expr->ts.type)
996 /* Integer case is easy, we've got a builtin op. */
997 arg2 = TREE_VALUE (TREE_CHAIN (arg));
998 arg = TREE_VALUE (arg);
999 type = TREE_TYPE (arg);
1002 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
1004 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
1009 /* Check if we have a builtin fmod. */
1010 switch (expr->ts.kind)
1029 /* Use it if it exists. */
1030 if (n != END_BUILTINS)
1032 tmp = built_in_decls[n];
1033 se->expr = build_function_call_expr (tmp, arg);
1038 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1039 arg = TREE_VALUE (arg);
1040 type = TREE_TYPE (arg);
1042 arg = gfc_evaluate_now (arg, &se->pre);
1043 arg2 = gfc_evaluate_now (arg2, &se->pre);
1046 modulo = arg - floor (arg/arg2) * arg2, so
1047 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1049 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1050 thereby avoiding another division and retaining the accuracy
1051 of the builtin function. */
1052 if (n != END_BUILTINS && modulo)
1054 tree zero = gfc_build_const (type, integer_zero_node);
1055 tmp = gfc_evaluate_now (se->expr, &se->pre);
1056 test = build2 (LT_EXPR, boolean_type_node, arg, zero);
1057 test2 = build2 (LT_EXPR, boolean_type_node, arg2, zero);
1058 test2 = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1059 test = build2 (NE_EXPR, boolean_type_node, tmp, zero);
1060 test = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1061 test = gfc_evaluate_now (test, &se->pre);
1062 se->expr = build3 (COND_EXPR, type, test,
1063 build2 (PLUS_EXPR, type, tmp, arg2), tmp);
1067 /* If we do not have a built_in fmod, the calculation is going to
1068 have to be done longhand. */
1069 tmp = build2 (RDIV_EXPR, type, arg, arg2);
1071 /* Test if the value is too large to handle sensibly. */
1072 gfc_set_model_kind (expr->ts.kind);
1074 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1075 ikind = expr->ts.kind;
1078 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1079 ikind = gfc_max_integer_kind;
1081 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1082 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1083 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
1085 mpfr_neg (huge, huge, GFC_RND_MODE);
1086 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1087 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
1088 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1090 itype = gfc_get_int_type (ikind);
1092 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1094 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1095 tmp = convert (type, tmp);
1096 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
1097 tmp = build2 (MULT_EXPR, type, tmp, arg2);
1098 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
1107 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1110 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1119 arg = gfc_conv_intrinsic_function_args (se, expr);
1120 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1121 arg = TREE_VALUE (arg);
1122 type = TREE_TYPE (arg);
1124 val = build2 (MINUS_EXPR, type, arg, arg2);
1125 val = gfc_evaluate_now (val, &se->pre);
1127 zero = gfc_build_const (type, integer_zero_node);
1128 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
1129 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
1133 /* SIGN(A, B) is absolute value of A times sign of B.
1134 The real value versions use library functions to ensure the correct
1135 handling of negative zero. Integer case implemented as:
1136 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1140 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1147 arg = gfc_conv_intrinsic_function_args (se, expr);
1148 if (expr->ts.type == BT_REAL)
1150 switch (expr->ts.kind)
1153 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1156 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1160 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1165 se->expr = build_function_call_expr (tmp, arg);
1169 /* Having excluded floating point types, we know we are now dealing
1170 with signed integer types. */
1171 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1172 arg = TREE_VALUE (arg);
1173 type = TREE_TYPE (arg);
1175 /* Arg is used multiple times below. */
1176 arg = gfc_evaluate_now (arg, &se->pre);
1178 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1179 the signs of A and B are the same, and of all ones if they differ. */
1180 tmp = fold_build2 (BIT_XOR_EXPR, type, arg, arg2);
1181 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1182 build_int_cst (type, TYPE_PRECISION (type) - 1));
1183 tmp = gfc_evaluate_now (tmp, &se->pre);
1185 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1186 is all ones (i.e. -1). */
1187 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1188 fold_build2 (PLUS_EXPR, type, arg, tmp),
1193 /* Test for the presence of an optional argument. */
1196 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1200 arg = expr->value.function.actual->expr;
1201 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1202 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1203 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1207 /* Calculate the double precision product of two single precision values. */
1210 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1216 arg = gfc_conv_intrinsic_function_args (se, expr);
1217 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1218 arg = TREE_VALUE (arg);
1220 /* Convert the args to double precision before multiplying. */
1221 type = gfc_typenode_for_spec (&expr->ts);
1222 arg = convert (type, arg);
1223 arg2 = convert (type, arg2);
1224 se->expr = build2 (MULT_EXPR, type, arg, arg2);
1228 /* Return a length one character string containing an ascii character. */
1231 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1237 arg = gfc_conv_intrinsic_function_args (se, expr);
1238 arg = TREE_VALUE (arg);
1240 /* We currently don't support character types != 1. */
1241 gcc_assert (expr->ts.kind == 1);
1242 type = gfc_character1_type_node;
1243 var = gfc_create_var (type, "char");
1245 arg = convert (type, arg);
1246 gfc_add_modify_expr (&se->pre, var, arg);
1247 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1248 se->string_length = integer_one_node;
1253 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1261 tree gfc_int8_type_node = gfc_get_int_type (8);
1263 type = build_pointer_type (gfc_character1_type_node);
1264 var = gfc_create_var (type, "pstr");
1265 len = gfc_create_var (gfc_int8_type_node, "len");
1267 tmp = gfc_conv_intrinsic_function_args (se, expr);
1268 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1269 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1270 arglist = chainon (arglist, tmp);
1272 tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
1273 gfc_add_expr_to_block (&se->pre, tmp);
1275 /* Free the temporary afterwards, if necessary. */
1276 cond = build2 (GT_EXPR, boolean_type_node, len,
1277 build_int_cst (TREE_TYPE (len), 0));
1278 tmp = gfc_call_free (var);
1279 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1280 gfc_add_expr_to_block (&se->post, tmp);
1283 se->string_length = len;
1288 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1296 tree gfc_int4_type_node = gfc_get_int_type (4);
1298 type = build_pointer_type (gfc_character1_type_node);
1299 var = gfc_create_var (type, "pstr");
1300 len = gfc_create_var (gfc_int4_type_node, "len");
1302 tmp = gfc_conv_intrinsic_function_args (se, expr);
1303 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1304 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1305 arglist = chainon (arglist, tmp);
1307 tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
1308 gfc_add_expr_to_block (&se->pre, tmp);
1310 /* Free the temporary afterwards, if necessary. */
1311 cond = build2 (GT_EXPR, boolean_type_node, len,
1312 build_int_cst (TREE_TYPE (len), 0));
1313 tmp = gfc_call_free (var);
1314 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1315 gfc_add_expr_to_block (&se->post, tmp);
1318 se->string_length = len;
1322 /* Return a character string containing the tty name. */
1325 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1333 tree gfc_int4_type_node = gfc_get_int_type (4);
1335 type = build_pointer_type (gfc_character1_type_node);
1336 var = gfc_create_var (type, "pstr");
1337 len = gfc_create_var (gfc_int4_type_node, "len");
1339 tmp = gfc_conv_intrinsic_function_args (se, expr);
1340 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1341 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1342 arglist = chainon (arglist, tmp);
1344 tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
1345 gfc_add_expr_to_block (&se->pre, tmp);
1347 /* Free the temporary afterwards, if necessary. */
1348 cond = build2 (GT_EXPR, boolean_type_node, len,
1349 build_int_cst (TREE_TYPE (len), 0));
1350 tmp = gfc_call_free (var);
1351 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1352 gfc_add_expr_to_block (&se->post, tmp);
1355 se->string_length = len;
1359 /* Get the minimum/maximum value of all the parameters.
1360 minmax (a1, a2, a3, ...)
1373 /* TODO: Mismatching types can occur when specific names are used.
1374 These should be handled during resolution. */
1376 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1387 arg = gfc_conv_intrinsic_function_args (se, expr);
1388 type = gfc_typenode_for_spec (&expr->ts);
1390 limit = TREE_VALUE (arg);
1391 if (TREE_TYPE (limit) != type)
1392 limit = convert (type, limit);
1393 /* Only evaluate the argument once. */
1394 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1395 limit = gfc_evaluate_now (limit, &se->pre);
1397 mvar = gfc_create_var (type, "M");
1398 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1399 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1401 val = TREE_VALUE (arg);
1402 if (TREE_TYPE (val) != type)
1403 val = convert (type, val);
1405 /* Only evaluate the argument once. */
1406 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1407 val = gfc_evaluate_now (val, &se->pre);
1409 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1411 tmp = build2 (op, boolean_type_node, val, limit);
1412 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1413 gfc_add_expr_to_block (&se->pre, tmp);
1414 elsecase = build_empty_stmt ();
1421 /* Create a symbol node for this intrinsic. The symbol from the frontend
1422 has the generic name. */
1425 gfc_get_symbol_for_expr (gfc_expr * expr)
1429 /* TODO: Add symbols for intrinsic function to the global namespace. */
1430 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1431 sym = gfc_new_symbol (expr->value.function.name, NULL);
1434 sym->attr.external = 1;
1435 sym->attr.function = 1;
1436 sym->attr.always_explicit = 1;
1437 sym->attr.proc = PROC_INTRINSIC;
1438 sym->attr.flavor = FL_PROCEDURE;
1442 sym->attr.dimension = 1;
1443 sym->as = gfc_get_array_spec ();
1444 sym->as->type = AS_ASSUMED_SHAPE;
1445 sym->as->rank = expr->rank;
1448 /* TODO: proper argument lists for external intrinsics. */
1452 /* Generate a call to an external intrinsic function. */
1454 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1459 gcc_assert (!se->ss || se->ss->expr == expr);
1462 gcc_assert (expr->rank > 0);
1464 gcc_assert (expr->rank == 0);
1466 sym = gfc_get_symbol_for_expr (expr);
1468 /* Calls to libgfortran_matmul need to be appended special arguments,
1469 to be able to call the BLAS ?gemm functions if required and possible. */
1470 append_args = NULL_TREE;
1471 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1472 && sym->ts.type != BT_LOGICAL)
1474 tree cint = gfc_get_int_type (gfc_c_int_kind);
1476 if (gfc_option.flag_external_blas
1477 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1478 && (sym->ts.kind == gfc_default_real_kind
1479 || sym->ts.kind == gfc_default_double_kind))
1483 if (sym->ts.type == BT_REAL)
1485 if (sym->ts.kind == gfc_default_real_kind)
1486 gemm_fndecl = gfor_fndecl_sgemm;
1488 gemm_fndecl = gfor_fndecl_dgemm;
1492 if (sym->ts.kind == gfc_default_real_kind)
1493 gemm_fndecl = gfor_fndecl_cgemm;
1495 gemm_fndecl = gfor_fndecl_zgemm;
1498 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1499 append_args = gfc_chainon_list
1500 (append_args, build_int_cst
1501 (cint, gfc_option.blas_matmul_limit));
1502 append_args = gfc_chainon_list (append_args,
1503 gfc_build_addr_expr (NULL_TREE,
1508 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1509 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1510 append_args = gfc_chainon_list (append_args, null_pointer_node);
1514 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1518 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1538 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1547 gfc_actual_arglist *actual;
1554 gfc_conv_intrinsic_funcall (se, expr);
1558 actual = expr->value.function.actual;
1559 type = gfc_typenode_for_spec (&expr->ts);
1560 /* Initialize the result. */
1561 resvar = gfc_create_var (type, "test");
1563 tmp = convert (type, boolean_true_node);
1565 tmp = convert (type, boolean_false_node);
1566 gfc_add_modify_expr (&se->pre, resvar, tmp);
1568 /* Walk the arguments. */
1569 arrayss = gfc_walk_expr (actual->expr);
1570 gcc_assert (arrayss != gfc_ss_terminator);
1572 /* Initialize the scalarizer. */
1573 gfc_init_loopinfo (&loop);
1574 exit_label = gfc_build_label_decl (NULL_TREE);
1575 TREE_USED (exit_label) = 1;
1576 gfc_add_ss_to_loop (&loop, arrayss);
1578 /* Initialize the loop. */
1579 gfc_conv_ss_startstride (&loop);
1580 gfc_conv_loop_setup (&loop);
1582 gfc_mark_ss_chain_used (arrayss, 1);
1583 /* Generate the loop body. */
1584 gfc_start_scalarized_body (&loop, &body);
1586 /* If the condition matches then set the return value. */
1587 gfc_start_block (&block);
1589 tmp = convert (type, boolean_false_node);
1591 tmp = convert (type, boolean_true_node);
1592 gfc_add_modify_expr (&block, resvar, tmp);
1594 /* And break out of the loop. */
1595 tmp = build1_v (GOTO_EXPR, exit_label);
1596 gfc_add_expr_to_block (&block, tmp);
1598 found = gfc_finish_block (&block);
1600 /* Check this element. */
1601 gfc_init_se (&arrayse, NULL);
1602 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1603 arrayse.ss = arrayss;
1604 gfc_conv_expr_val (&arrayse, actual->expr);
1606 gfc_add_block_to_block (&body, &arrayse.pre);
1607 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1608 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1609 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1610 gfc_add_expr_to_block (&body, tmp);
1611 gfc_add_block_to_block (&body, &arrayse.post);
1613 gfc_trans_scalarizing_loops (&loop, &body);
1615 /* Add the exit label. */
1616 tmp = build1_v (LABEL_EXPR, exit_label);
1617 gfc_add_expr_to_block (&loop.pre, tmp);
1619 gfc_add_block_to_block (&se->pre, &loop.pre);
1620 gfc_add_block_to_block (&se->pre, &loop.post);
1621 gfc_cleanup_loop (&loop);
1626 /* COUNT(A) = Number of true elements in A. */
1628 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1635 gfc_actual_arglist *actual;
1641 gfc_conv_intrinsic_funcall (se, expr);
1645 actual = expr->value.function.actual;
1647 type = gfc_typenode_for_spec (&expr->ts);
1648 /* Initialize the result. */
1649 resvar = gfc_create_var (type, "count");
1650 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1652 /* Walk the arguments. */
1653 arrayss = gfc_walk_expr (actual->expr);
1654 gcc_assert (arrayss != gfc_ss_terminator);
1656 /* Initialize the scalarizer. */
1657 gfc_init_loopinfo (&loop);
1658 gfc_add_ss_to_loop (&loop, arrayss);
1660 /* Initialize the loop. */
1661 gfc_conv_ss_startstride (&loop);
1662 gfc_conv_loop_setup (&loop);
1664 gfc_mark_ss_chain_used (arrayss, 1);
1665 /* Generate the loop body. */
1666 gfc_start_scalarized_body (&loop, &body);
1668 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1669 build_int_cst (TREE_TYPE (resvar), 1));
1670 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1672 gfc_init_se (&arrayse, NULL);
1673 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1674 arrayse.ss = arrayss;
1675 gfc_conv_expr_val (&arrayse, actual->expr);
1676 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1678 gfc_add_block_to_block (&body, &arrayse.pre);
1679 gfc_add_expr_to_block (&body, tmp);
1680 gfc_add_block_to_block (&body, &arrayse.post);
1682 gfc_trans_scalarizing_loops (&loop, &body);
1684 gfc_add_block_to_block (&se->pre, &loop.pre);
1685 gfc_add_block_to_block (&se->pre, &loop.post);
1686 gfc_cleanup_loop (&loop);
1691 /* Inline implementation of the sum and product intrinsics. */
1693 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1701 gfc_actual_arglist *actual;
1706 gfc_expr *arrayexpr;
1711 gfc_conv_intrinsic_funcall (se, expr);
1715 type = gfc_typenode_for_spec (&expr->ts);
1716 /* Initialize the result. */
1717 resvar = gfc_create_var (type, "val");
1718 if (op == PLUS_EXPR)
1719 tmp = gfc_build_const (type, integer_zero_node);
1721 tmp = gfc_build_const (type, integer_one_node);
1723 gfc_add_modify_expr (&se->pre, resvar, tmp);
1725 /* Walk the arguments. */
1726 actual = expr->value.function.actual;
1727 arrayexpr = actual->expr;
1728 arrayss = gfc_walk_expr (arrayexpr);
1729 gcc_assert (arrayss != gfc_ss_terminator);
1731 actual = actual->next->next;
1732 gcc_assert (actual);
1733 maskexpr = actual->expr;
1734 if (maskexpr && maskexpr->rank != 0)
1736 maskss = gfc_walk_expr (maskexpr);
1737 gcc_assert (maskss != gfc_ss_terminator);
1742 /* Initialize the scalarizer. */
1743 gfc_init_loopinfo (&loop);
1744 gfc_add_ss_to_loop (&loop, arrayss);
1746 gfc_add_ss_to_loop (&loop, maskss);
1748 /* Initialize the loop. */
1749 gfc_conv_ss_startstride (&loop);
1750 gfc_conv_loop_setup (&loop);
1752 gfc_mark_ss_chain_used (arrayss, 1);
1754 gfc_mark_ss_chain_used (maskss, 1);
1755 /* Generate the loop body. */
1756 gfc_start_scalarized_body (&loop, &body);
1758 /* If we have a mask, only add this element if the mask is set. */
1761 gfc_init_se (&maskse, NULL);
1762 gfc_copy_loopinfo_to_se (&maskse, &loop);
1764 gfc_conv_expr_val (&maskse, maskexpr);
1765 gfc_add_block_to_block (&body, &maskse.pre);
1767 gfc_start_block (&block);
1770 gfc_init_block (&block);
1772 /* Do the actual summation/product. */
1773 gfc_init_se (&arrayse, NULL);
1774 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1775 arrayse.ss = arrayss;
1776 gfc_conv_expr_val (&arrayse, arrayexpr);
1777 gfc_add_block_to_block (&block, &arrayse.pre);
1779 tmp = build2 (op, type, resvar, arrayse.expr);
1780 gfc_add_modify_expr (&block, resvar, tmp);
1781 gfc_add_block_to_block (&block, &arrayse.post);
1785 /* We enclose the above in if (mask) {...} . */
1786 tmp = gfc_finish_block (&block);
1788 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1791 tmp = gfc_finish_block (&block);
1792 gfc_add_expr_to_block (&body, tmp);
1794 gfc_trans_scalarizing_loops (&loop, &body);
1796 /* For a scalar mask, enclose the loop in an if statement. */
1797 if (maskexpr && maskss == NULL)
1799 gfc_init_se (&maskse, NULL);
1800 gfc_conv_expr_val (&maskse, maskexpr);
1801 gfc_init_block (&block);
1802 gfc_add_block_to_block (&block, &loop.pre);
1803 gfc_add_block_to_block (&block, &loop.post);
1804 tmp = gfc_finish_block (&block);
1806 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1807 gfc_add_expr_to_block (&block, tmp);
1808 gfc_add_block_to_block (&se->pre, &block);
1812 gfc_add_block_to_block (&se->pre, &loop.pre);
1813 gfc_add_block_to_block (&se->pre, &loop.post);
1816 gfc_cleanup_loop (&loop);
1822 /* Inline implementation of the dot_product intrinsic. This function
1823 is based on gfc_conv_intrinsic_arith (the previous function). */
1825 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1833 gfc_actual_arglist *actual;
1834 gfc_ss *arrayss1, *arrayss2;
1835 gfc_se arrayse1, arrayse2;
1836 gfc_expr *arrayexpr1, *arrayexpr2;
1838 type = gfc_typenode_for_spec (&expr->ts);
1840 /* Initialize the result. */
1841 resvar = gfc_create_var (type, "val");
1842 if (expr->ts.type == BT_LOGICAL)
1843 tmp = build_int_cst (type, 0);
1845 tmp = gfc_build_const (type, integer_zero_node);
1847 gfc_add_modify_expr (&se->pre, resvar, tmp);
1849 /* Walk argument #1. */
1850 actual = expr->value.function.actual;
1851 arrayexpr1 = actual->expr;
1852 arrayss1 = gfc_walk_expr (arrayexpr1);
1853 gcc_assert (arrayss1 != gfc_ss_terminator);
1855 /* Walk argument #2. */
1856 actual = actual->next;
1857 arrayexpr2 = actual->expr;
1858 arrayss2 = gfc_walk_expr (arrayexpr2);
1859 gcc_assert (arrayss2 != gfc_ss_terminator);
1861 /* Initialize the scalarizer. */
1862 gfc_init_loopinfo (&loop);
1863 gfc_add_ss_to_loop (&loop, arrayss1);
1864 gfc_add_ss_to_loop (&loop, arrayss2);
1866 /* Initialize the loop. */
1867 gfc_conv_ss_startstride (&loop);
1868 gfc_conv_loop_setup (&loop);
1870 gfc_mark_ss_chain_used (arrayss1, 1);
1871 gfc_mark_ss_chain_used (arrayss2, 1);
1873 /* Generate the loop body. */
1874 gfc_start_scalarized_body (&loop, &body);
1875 gfc_init_block (&block);
1877 /* Make the tree expression for [conjg(]array1[)]. */
1878 gfc_init_se (&arrayse1, NULL);
1879 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1880 arrayse1.ss = arrayss1;
1881 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1882 if (expr->ts.type == BT_COMPLEX)
1883 arrayse1.expr = build1 (CONJ_EXPR, type, arrayse1.expr);
1884 gfc_add_block_to_block (&block, &arrayse1.pre);
1886 /* Make the tree expression for array2. */
1887 gfc_init_se (&arrayse2, NULL);
1888 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
1889 arrayse2.ss = arrayss2;
1890 gfc_conv_expr_val (&arrayse2, arrayexpr2);
1891 gfc_add_block_to_block (&block, &arrayse2.pre);
1893 /* Do the actual product and sum. */
1894 if (expr->ts.type == BT_LOGICAL)
1896 tmp = build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
1897 tmp = build2 (TRUTH_OR_EXPR, type, resvar, tmp);
1901 tmp = build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
1902 tmp = build2 (PLUS_EXPR, type, resvar, tmp);
1904 gfc_add_modify_expr (&block, resvar, tmp);
1906 /* Finish up the loop block and the loop. */
1907 tmp = gfc_finish_block (&block);
1908 gfc_add_expr_to_block (&body, tmp);
1910 gfc_trans_scalarizing_loops (&loop, &body);
1911 gfc_add_block_to_block (&se->pre, &loop.pre);
1912 gfc_add_block_to_block (&se->pre, &loop.post);
1913 gfc_cleanup_loop (&loop);
1920 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1924 stmtblock_t ifblock;
1925 stmtblock_t elseblock;
1933 gfc_actual_arglist *actual;
1938 gfc_expr *arrayexpr;
1945 gfc_conv_intrinsic_funcall (se, expr);
1949 /* Initialize the result. */
1950 pos = gfc_create_var (gfc_array_index_type, "pos");
1951 offset = gfc_create_var (gfc_array_index_type, "offset");
1952 type = gfc_typenode_for_spec (&expr->ts);
1954 /* Walk the arguments. */
1955 actual = expr->value.function.actual;
1956 arrayexpr = actual->expr;
1957 arrayss = gfc_walk_expr (arrayexpr);
1958 gcc_assert (arrayss != gfc_ss_terminator);
1960 actual = actual->next->next;
1961 gcc_assert (actual);
1962 maskexpr = actual->expr;
1963 if (maskexpr && maskexpr->rank != 0)
1965 maskss = gfc_walk_expr (maskexpr);
1966 gcc_assert (maskss != gfc_ss_terminator);
1971 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1972 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1973 switch (arrayexpr->ts.type)
1976 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1980 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1981 arrayexpr->ts.kind);
1988 /* We start with the most negative possible value for MAXLOC, and the most
1989 positive possible value for MINLOC. The most negative possible value is
1990 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
1991 possible value is HUGE in both cases. */
1993 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1994 gfc_add_modify_expr (&se->pre, limit, tmp);
1996 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
1997 tmp = build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
1998 build_int_cst (type, 1));
2000 /* Initialize the scalarizer. */
2001 gfc_init_loopinfo (&loop);
2002 gfc_add_ss_to_loop (&loop, arrayss);
2004 gfc_add_ss_to_loop (&loop, maskss);
2006 /* Initialize the loop. */
2007 gfc_conv_ss_startstride (&loop);
2008 gfc_conv_loop_setup (&loop);
2010 gcc_assert (loop.dimen == 1);
2012 /* Initialize the position to zero, following Fortran 2003. We are free
2013 to do this because Fortran 95 allows the result of an entirely false
2014 mask to be processor dependent. */
2015 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2017 gfc_mark_ss_chain_used (arrayss, 1);
2019 gfc_mark_ss_chain_used (maskss, 1);
2020 /* Generate the loop body. */
2021 gfc_start_scalarized_body (&loop, &body);
2023 /* If we have a mask, only check this element if the mask is set. */
2026 gfc_init_se (&maskse, NULL);
2027 gfc_copy_loopinfo_to_se (&maskse, &loop);
2029 gfc_conv_expr_val (&maskse, maskexpr);
2030 gfc_add_block_to_block (&body, &maskse.pre);
2032 gfc_start_block (&block);
2035 gfc_init_block (&block);
2037 /* Compare with the current limit. */
2038 gfc_init_se (&arrayse, NULL);
2039 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2040 arrayse.ss = arrayss;
2041 gfc_conv_expr_val (&arrayse, arrayexpr);
2042 gfc_add_block_to_block (&block, &arrayse.pre);
2044 /* We do the following if this is a more extreme value. */
2045 gfc_start_block (&ifblock);
2047 /* Assign the value to the limit... */
2048 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2050 /* Remember where we are. An offset must be added to the loop
2051 counter to obtain the required position. */
2053 tmp = build_int_cst (gfc_array_index_type, 1);
2055 tmp =fold_build2 (MINUS_EXPR, gfc_array_index_type,
2056 gfc_index_one_node, loop.from[0]);
2057 gfc_add_modify_expr (&block, offset, tmp);
2059 tmp = build2 (PLUS_EXPR, TREE_TYPE (pos),
2060 loop.loopvar[0], offset);
2061 gfc_add_modify_expr (&ifblock, pos, tmp);
2063 ifbody = gfc_finish_block (&ifblock);
2065 /* If it is a more extreme value or pos is still zero and the value
2066 equal to the limit. */
2067 tmp = build2 (TRUTH_AND_EXPR, boolean_type_node,
2068 build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node),
2069 build2 (EQ_EXPR, boolean_type_node, arrayse.expr, limit));
2070 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node,
2071 build2 (op, boolean_type_node, arrayse.expr, limit), tmp);
2072 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2073 gfc_add_expr_to_block (&block, tmp);
2077 /* We enclose the above in if (mask) {...}. */
2078 tmp = gfc_finish_block (&block);
2080 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2083 tmp = gfc_finish_block (&block);
2084 gfc_add_expr_to_block (&body, tmp);
2086 gfc_trans_scalarizing_loops (&loop, &body);
2088 /* For a scalar mask, enclose the loop in an if statement. */
2089 if (maskexpr && maskss == NULL)
2091 gfc_init_se (&maskse, NULL);
2092 gfc_conv_expr_val (&maskse, maskexpr);
2093 gfc_init_block (&block);
2094 gfc_add_block_to_block (&block, &loop.pre);
2095 gfc_add_block_to_block (&block, &loop.post);
2096 tmp = gfc_finish_block (&block);
2098 /* For the else part of the scalar mask, just initialize
2099 the pos variable the same way as above. */
2101 gfc_init_block (&elseblock);
2102 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2103 elsetmp = gfc_finish_block (&elseblock);
2105 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2106 gfc_add_expr_to_block (&block, tmp);
2107 gfc_add_block_to_block (&se->pre, &block);
2111 gfc_add_block_to_block (&se->pre, &loop.pre);
2112 gfc_add_block_to_block (&se->pre, &loop.post);
2114 gfc_cleanup_loop (&loop);
2116 se->expr = convert (type, pos);
2120 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2129 gfc_actual_arglist *actual;
2134 gfc_expr *arrayexpr;
2140 gfc_conv_intrinsic_funcall (se, expr);
2144 type = gfc_typenode_for_spec (&expr->ts);
2145 /* Initialize the result. */
2146 limit = gfc_create_var (type, "limit");
2147 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2148 switch (expr->ts.type)
2151 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2155 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2162 /* We start with the most negative possible value for MAXVAL, and the most
2163 positive possible value for MINVAL. The most negative possible value is
2164 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2165 possible value is HUGE in both cases. */
2167 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2169 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2170 tmp = build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2171 build_int_cst (type, 1));
2173 gfc_add_modify_expr (&se->pre, limit, tmp);
2175 /* Walk the arguments. */
2176 actual = expr->value.function.actual;
2177 arrayexpr = actual->expr;
2178 arrayss = gfc_walk_expr (arrayexpr);
2179 gcc_assert (arrayss != gfc_ss_terminator);
2181 actual = actual->next->next;
2182 gcc_assert (actual);
2183 maskexpr = actual->expr;
2184 if (maskexpr && maskexpr->rank != 0)
2186 maskss = gfc_walk_expr (maskexpr);
2187 gcc_assert (maskss != gfc_ss_terminator);
2192 /* Initialize the scalarizer. */
2193 gfc_init_loopinfo (&loop);
2194 gfc_add_ss_to_loop (&loop, arrayss);
2196 gfc_add_ss_to_loop (&loop, maskss);
2198 /* Initialize the loop. */
2199 gfc_conv_ss_startstride (&loop);
2200 gfc_conv_loop_setup (&loop);
2202 gfc_mark_ss_chain_used (arrayss, 1);
2204 gfc_mark_ss_chain_used (maskss, 1);
2205 /* Generate the loop body. */
2206 gfc_start_scalarized_body (&loop, &body);
2208 /* If we have a mask, only add this element if the mask is set. */
2211 gfc_init_se (&maskse, NULL);
2212 gfc_copy_loopinfo_to_se (&maskse, &loop);
2214 gfc_conv_expr_val (&maskse, maskexpr);
2215 gfc_add_block_to_block (&body, &maskse.pre);
2217 gfc_start_block (&block);
2220 gfc_init_block (&block);
2222 /* Compare with the current limit. */
2223 gfc_init_se (&arrayse, NULL);
2224 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2225 arrayse.ss = arrayss;
2226 gfc_conv_expr_val (&arrayse, arrayexpr);
2227 gfc_add_block_to_block (&block, &arrayse.pre);
2229 /* Assign the value to the limit... */
2230 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2232 /* If it is a more extreme value. */
2233 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
2234 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2235 gfc_add_expr_to_block (&block, tmp);
2236 gfc_add_block_to_block (&block, &arrayse.post);
2238 tmp = gfc_finish_block (&block);
2240 /* We enclose the above in if (mask) {...}. */
2241 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2242 gfc_add_expr_to_block (&body, tmp);
2244 gfc_trans_scalarizing_loops (&loop, &body);
2246 /* For a scalar mask, enclose the loop in an if statement. */
2247 if (maskexpr && maskss == NULL)
2249 gfc_init_se (&maskse, NULL);
2250 gfc_conv_expr_val (&maskse, maskexpr);
2251 gfc_init_block (&block);
2252 gfc_add_block_to_block (&block, &loop.pre);
2253 gfc_add_block_to_block (&block, &loop.post);
2254 tmp = gfc_finish_block (&block);
2256 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2257 gfc_add_expr_to_block (&block, tmp);
2258 gfc_add_block_to_block (&se->pre, &block);
2262 gfc_add_block_to_block (&se->pre, &loop.pre);
2263 gfc_add_block_to_block (&se->pre, &loop.post);
2266 gfc_cleanup_loop (&loop);
2271 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2273 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2280 arg = gfc_conv_intrinsic_function_args (se, expr);
2281 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2282 arg = TREE_VALUE (arg);
2283 type = TREE_TYPE (arg);
2285 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2286 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
2287 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2288 build_int_cst (type, 0));
2289 type = gfc_typenode_for_spec (&expr->ts);
2290 se->expr = convert (type, tmp);
2293 /* Generate code to perform the specified operation. */
2295 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2301 arg = gfc_conv_intrinsic_function_args (se, expr);
2302 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2303 arg = TREE_VALUE (arg);
2304 type = TREE_TYPE (arg);
2306 se->expr = fold_build2 (op, type, arg, arg2);
2311 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2315 arg = gfc_conv_intrinsic_function_args (se, expr);
2316 arg = TREE_VALUE (arg);
2318 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2321 /* Set or clear a single bit. */
2323 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2331 arg = gfc_conv_intrinsic_function_args (se, expr);
2332 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2333 arg = TREE_VALUE (arg);
2334 type = TREE_TYPE (arg);
2336 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2342 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2344 se->expr = fold_build2 (op, type, arg, tmp);
2347 /* Extract a sequence of bits.
2348 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2350 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2359 arg = gfc_conv_intrinsic_function_args (se, expr);
2360 arg2 = TREE_CHAIN (arg);
2361 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
2362 arg = TREE_VALUE (arg);
2363 arg2 = TREE_VALUE (arg2);
2364 type = TREE_TYPE (arg);
2366 mask = build_int_cst (type, -1);
2367 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
2368 mask = build1 (BIT_NOT_EXPR, type, mask);
2370 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
2372 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2375 /* RSHIFT (I, SHIFT) = I >> SHIFT
2376 LSHIFT (I, SHIFT) = I << SHIFT */
2378 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2383 arg = gfc_conv_intrinsic_function_args (se, expr);
2384 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2385 arg = TREE_VALUE (arg);
2387 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2388 TREE_TYPE (arg), arg, arg2);
2391 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2393 : ((shift >= 0) ? i << shift : i >> -shift)
2394 where all shifts are logical shifts. */
2396 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2409 arg = gfc_conv_intrinsic_function_args (se, expr);
2410 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2411 arg = TREE_VALUE (arg);
2412 type = TREE_TYPE (arg);
2413 utype = unsigned_type_for (type);
2415 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
2417 /* Left shift if positive. */
2418 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
2420 /* Right shift if negative.
2421 We convert to an unsigned type because we want a logical shift.
2422 The standard doesn't define the case of shifting negative
2423 numbers, and we try to be compatible with other compilers, most
2424 notably g77, here. */
2425 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
2426 convert (utype, arg), width));
2428 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
2429 build_int_cst (TREE_TYPE (arg2), 0));
2430 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2432 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2433 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2435 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
2436 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2438 se->expr = fold_build3 (COND_EXPR, type, cond,
2439 build_int_cst (type, 0), tmp);
2442 /* Circular shift. AKA rotate or barrel shift. */
2444 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2455 arg = gfc_conv_intrinsic_function_args (se, expr);
2456 arg2 = TREE_CHAIN (arg);
2457 arg3 = TREE_CHAIN (arg2);
2460 /* Use a library function for the 3 parameter version. */
2461 tree int4type = gfc_get_int_type (4);
2463 type = TREE_TYPE (TREE_VALUE (arg));
2464 /* We convert the first argument to at least 4 bytes, and
2465 convert back afterwards. This removes the need for library
2466 functions for all argument sizes, and function will be
2467 aligned to at least 32 bits, so there's no loss. */
2468 if (expr->ts.kind < 4)
2470 tmp = convert (int4type, TREE_VALUE (arg));
2471 TREE_VALUE (arg) = tmp;
2473 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2474 need loads of library functions. They cannot have values >
2475 BIT_SIZE (I) so the conversion is safe. */
2476 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
2477 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
2479 switch (expr->ts.kind)
2484 tmp = gfor_fndecl_math_ishftc4;
2487 tmp = gfor_fndecl_math_ishftc8;
2490 tmp = gfor_fndecl_math_ishftc16;
2495 se->expr = build_function_call_expr (tmp, arg);
2496 /* Convert the result back to the original type, if we extended
2497 the first argument's width above. */
2498 if (expr->ts.kind < 4)
2499 se->expr = convert (type, se->expr);
2503 arg = TREE_VALUE (arg);
2504 arg2 = TREE_VALUE (arg2);
2505 type = TREE_TYPE (arg);
2507 /* Rotate left if positive. */
2508 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
2510 /* Rotate right if negative. */
2511 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
2512 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
2514 zero = build_int_cst (TREE_TYPE (arg2), 0);
2515 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
2516 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2518 /* Do nothing if shift == 0. */
2519 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
2520 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
2523 /* The length of a character string. */
2525 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2535 gcc_assert (!se->ss);
2537 arg = expr->value.function.actual->expr;
2539 type = gfc_typenode_for_spec (&expr->ts);
2540 switch (arg->expr_type)
2543 len = build_int_cst (NULL_TREE, arg->value.character.length);
2547 /* Obtain the string length from the function used by
2548 trans-array.c(gfc_trans_array_constructor). */
2550 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2554 if (arg->ref == NULL
2555 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2557 /* This doesn't catch all cases.
2558 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2559 and the surrounding thread. */
2560 sym = arg->symtree->n.sym;
2561 decl = gfc_get_symbol_decl (sym);
2562 if (decl == current_function_decl && sym->attr.function
2563 && (sym->result == sym))
2564 decl = gfc_get_fake_result_decl (sym, 0);
2566 len = sym->ts.cl->backend_decl;
2571 /* Otherwise fall through. */
2574 /* Anybody stupid enough to do this deserves inefficient code. */
2575 ss = gfc_walk_expr (arg);
2576 gfc_init_se (&argse, se);
2577 if (ss == gfc_ss_terminator)
2578 gfc_conv_expr (&argse, arg);
2580 gfc_conv_expr_descriptor (&argse, arg, ss);
2581 gfc_add_block_to_block (&se->pre, &argse.pre);
2582 gfc_add_block_to_block (&se->post, &argse.post);
2583 len = argse.string_length;
2586 se->expr = convert (type, len);
2589 /* The length of a character string not including trailing blanks. */
2591 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2596 args = gfc_conv_intrinsic_function_args (se, expr);
2597 type = gfc_typenode_for_spec (&expr->ts);
2598 se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
2599 se->expr = convert (type, se->expr);
2603 /* Returns the starting position of a substring within a string. */
2606 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2608 tree logical4_type_node = gfc_get_logical_type (4);
2614 args = gfc_conv_intrinsic_function_args (se, expr);
2615 type = gfc_typenode_for_spec (&expr->ts);
2616 tmp = gfc_advance_chain (args, 3);
2617 if (TREE_CHAIN (tmp) == NULL_TREE)
2619 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2621 TREE_CHAIN (tmp) = back;
2625 back = TREE_CHAIN (tmp);
2626 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2629 se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
2630 se->expr = convert (type, se->expr);
2633 /* The ascii value for a single character. */
2635 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2640 arg = gfc_conv_intrinsic_function_args (se, expr);
2641 arg = TREE_VALUE (TREE_CHAIN (arg));
2642 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2643 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2644 type = gfc_typenode_for_spec (&expr->ts);
2646 se->expr = build_fold_indirect_ref (arg);
2647 se->expr = convert (type, se->expr);
2651 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2654 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2663 arg = gfc_conv_intrinsic_function_args (se, expr);
2664 if (expr->ts.type != BT_CHARACTER)
2666 tsource = TREE_VALUE (arg);
2667 arg = TREE_CHAIN (arg);
2668 fsource = TREE_VALUE (arg);
2669 mask = TREE_VALUE (TREE_CHAIN (arg));
2673 /* We do the same as in the non-character case, but the argument
2674 list is different because of the string length arguments. We
2675 also have to set the string length for the result. */
2676 len = TREE_VALUE (arg);
2677 arg = TREE_CHAIN (arg);
2678 tsource = TREE_VALUE (arg);
2679 arg = TREE_CHAIN (TREE_CHAIN (arg));
2680 fsource = TREE_VALUE (arg);
2681 mask = TREE_VALUE (TREE_CHAIN (arg));
2683 se->string_length = len;
2685 type = TREE_TYPE (tsource);
2686 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2691 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2693 gfc_actual_arglist *actual;
2701 gfc_init_se (&argse, NULL);
2702 actual = expr->value.function.actual;
2704 ss = gfc_walk_expr (actual->expr);
2705 gcc_assert (ss != gfc_ss_terminator);
2706 argse.want_pointer = 1;
2707 argse.data_not_needed = 1;
2708 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2709 gfc_add_block_to_block (&se->pre, &argse.pre);
2710 gfc_add_block_to_block (&se->post, &argse.post);
2711 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
2713 /* Build the call to size0. */
2714 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
2716 actual = actual->next;
2720 gfc_init_se (&argse, NULL);
2721 gfc_conv_expr_type (&argse, actual->expr,
2722 gfc_array_index_type);
2723 gfc_add_block_to_block (&se->pre, &argse.pre);
2725 /* Build the call to size1. */
2726 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
2729 /* Unusually, for an intrinsic, size does not exclude
2730 an optional arg2, so we must test for it. */
2731 if (actual->expr->expr_type == EXPR_VARIABLE
2732 && actual->expr->symtree->n.sym->attr.dummy
2733 && actual->expr->symtree->n.sym->attr.optional)
2736 gfc_init_se (&argse, NULL);
2737 argse.want_pointer = 1;
2738 argse.data_not_needed = 1;
2739 gfc_conv_expr (&argse, actual->expr);
2740 gfc_add_block_to_block (&se->pre, &argse.pre);
2741 tmp = build2 (NE_EXPR, boolean_type_node, argse.expr,
2743 tmp = gfc_evaluate_now (tmp, &se->pre);
2744 se->expr = build3 (COND_EXPR, pvoid_type_node,
2745 tmp, fncall1, fncall0);
2753 type = gfc_typenode_for_spec (&expr->ts);
2754 se->expr = convert (type, se->expr);
2759 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
2773 arg = expr->value.function.actual->expr;
2775 gfc_init_se (&argse, NULL);
2776 ss = gfc_walk_expr (arg);
2778 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
2780 if (ss == gfc_ss_terminator)
2782 gfc_conv_expr_reference (&argse, arg);
2783 source = argse.expr;
2785 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
2787 /* Obtain the source word length. */
2788 if (arg->ts.type == BT_CHARACTER)
2789 source_bytes = fold_convert (gfc_array_index_type,
2790 argse.string_length);
2792 source_bytes = fold_convert (gfc_array_index_type,
2793 size_in_bytes (type));
2797 argse.want_pointer = 0;
2798 gfc_conv_expr_descriptor (&argse, arg, ss);
2799 source = gfc_conv_descriptor_data_get (argse.expr);
2800 type = gfc_get_element_type (TREE_TYPE (argse.expr));
2802 /* Obtain the argument's word length. */
2803 if (arg->ts.type == BT_CHARACTER)
2804 tmp = fold_convert (gfc_array_index_type, argse.string_length);
2806 tmp = fold_convert (gfc_array_index_type,
2807 size_in_bytes (type));
2808 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2810 /* Obtain the size of the array in bytes. */
2811 for (n = 0; n < arg->rank; n++)
2814 idx = gfc_rank_cst[n];
2815 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2816 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2817 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2819 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2820 tmp, gfc_index_one_node);
2821 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2823 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2827 gfc_add_block_to_block (&se->pre, &argse.pre);
2828 se->expr = source_bytes;
2832 /* Intrinsic string comparison functions. */
2835 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2841 args = gfc_conv_intrinsic_function_args (se, expr);
2842 arg2 = TREE_CHAIN (TREE_CHAIN (args));
2844 se->expr = gfc_build_compare_string (TREE_VALUE (args),
2845 TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
2846 TREE_VALUE (TREE_CHAIN (arg2)));
2848 type = gfc_typenode_for_spec (&expr->ts);
2849 se->expr = fold_build2 (op, type, se->expr,
2850 build_int_cst (TREE_TYPE (se->expr), 0));
2853 /* Generate a call to the adjustl/adjustr library function. */
2855 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2863 args = gfc_conv_intrinsic_function_args (se, expr);
2864 len = TREE_VALUE (args);
2866 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2867 var = gfc_conv_string_tmp (se, type, len);
2868 args = tree_cons (NULL_TREE, var, args);
2870 tmp = build_function_call_expr (fndecl, args);
2871 gfc_add_expr_to_block (&se->pre, tmp);
2873 se->string_length = len;
2877 /* Array transfer statement.
2878 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
2880 typeof<DEST> = typeof<MOLD>
2882 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
2883 sizeof (DEST(0) * SIZE). */
2886 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
2901 gfc_actual_arglist *arg;
2908 gcc_assert (se->loop);
2909 info = &se->ss->data.info;
2911 /* Convert SOURCE. The output from this stage is:-
2912 source_bytes = length of the source in bytes
2913 source = pointer to the source data. */
2914 arg = expr->value.function.actual;
2915 gfc_init_se (&argse, NULL);
2916 ss = gfc_walk_expr (arg->expr);
2918 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
2920 /* Obtain the pointer to source and the length of source in bytes. */
2921 if (ss == gfc_ss_terminator)
2923 gfc_conv_expr_reference (&argse, arg->expr);
2924 source = argse.expr;
2926 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
2928 /* Obtain the source word length. */
2929 if (arg->expr->ts.type == BT_CHARACTER)
2930 tmp = fold_convert (gfc_array_index_type, argse.string_length);
2932 tmp = fold_convert (gfc_array_index_type,
2933 size_in_bytes (source_type));
2937 argse.want_pointer = 0;
2938 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2939 source = gfc_conv_descriptor_data_get (argse.expr);
2940 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
2942 /* Repack the source if not a full variable array. */
2943 if (!(arg->expr->expr_type == EXPR_VARIABLE
2944 && arg->expr->ref->u.ar.type == AR_FULL))
2946 tmp = build_fold_addr_expr (argse.expr);
2947 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
2948 source = gfc_evaluate_now (source, &argse.pre);
2950 /* Free the temporary. */
2951 gfc_start_block (&block);
2952 tmp = gfc_call_free (convert (pvoid_type_node, source));
2953 gfc_add_expr_to_block (&block, tmp);
2954 stmt = gfc_finish_block (&block);
2956 /* Clean up if it was repacked. */
2957 gfc_init_block (&block);
2958 tmp = gfc_conv_array_data (argse.expr);
2959 tmp = build2 (NE_EXPR, boolean_type_node, source, tmp);
2960 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
2961 gfc_add_expr_to_block (&block, tmp);
2962 gfc_add_block_to_block (&block, &se->post);
2963 gfc_init_block (&se->post);
2964 gfc_add_block_to_block (&se->post, &block);
2967 /* Obtain the source word length. */
2968 if (arg->expr->ts.type == BT_CHARACTER)
2969 tmp = fold_convert (gfc_array_index_type, argse.string_length);
2971 tmp = fold_convert (gfc_array_index_type,
2972 size_in_bytes (source_type));
2974 /* Obtain the size of the array in bytes. */
2975 extent = gfc_create_var (gfc_array_index_type, NULL);
2976 for (n = 0; n < arg->expr->rank; n++)
2979 idx = gfc_rank_cst[n];
2980 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2981 stride = gfc_conv_descriptor_stride (argse.expr, idx);
2982 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2983 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2984 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2986 gfc_add_modify_expr (&argse.pre, extent, tmp);
2987 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2988 extent, gfc_index_one_node);
2989 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2994 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2995 gfc_add_block_to_block (&se->pre, &argse.pre);
2996 gfc_add_block_to_block (&se->post, &argse.post);
2998 /* Now convert MOLD. The outputs are:
2999 mold_type = the TREE type of MOLD
3000 dest_word_len = destination word length in bytes. */
3003 gfc_init_se (&argse, NULL);
3004 ss = gfc_walk_expr (arg->expr);
3006 if (ss == gfc_ss_terminator)
3008 gfc_conv_expr_reference (&argse, arg->expr);
3009 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3013 gfc_init_se (&argse, NULL);
3014 argse.want_pointer = 0;
3015 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3016 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3019 if (arg->expr->ts.type == BT_CHARACTER)
3021 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3022 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3025 tmp = fold_convert (gfc_array_index_type,
3026 size_in_bytes (mold_type));
3028 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3029 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
3031 /* Finally convert SIZE, if it is present. */
3033 size_words = gfc_create_var (gfc_array_index_type, NULL);
3037 gfc_init_se (&argse, NULL);
3038 gfc_conv_expr_reference (&argse, arg->expr);
3039 tmp = convert (gfc_array_index_type,
3040 build_fold_indirect_ref (argse.expr));
3041 gfc_add_block_to_block (&se->pre, &argse.pre);
3042 gfc_add_block_to_block (&se->post, &argse.post);
3047 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3048 if (tmp != NULL_TREE)
3050 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3051 tmp, dest_word_len);
3052 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3058 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
3059 gfc_add_modify_expr (&se->pre, size_words,
3060 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3061 size_bytes, dest_word_len));
3063 /* Evaluate the bounds of the result. If the loop range exists, we have
3064 to check if it is too large. If so, we modify loop->to be consistent
3065 with min(size, size(source)). Otherwise, size is made consistent with
3066 the loop range, so that the right number of bytes is transferred.*/
3067 n = se->loop->order[0];
3068 if (se->loop->to[n] != NULL_TREE)
3070 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3071 se->loop->to[n], se->loop->from[n]);
3072 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3073 tmp, gfc_index_one_node);
3074 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3076 gfc_add_modify_expr (&se->pre, size_words, tmp);
3077 gfc_add_modify_expr (&se->pre, size_bytes,
3078 fold_build2 (MULT_EXPR, gfc_array_index_type,
3079 size_words, dest_word_len));
3080 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3081 size_words, se->loop->from[n]);
3082 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3083 upper, gfc_index_one_node);
3087 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3088 size_words, gfc_index_one_node);
3089 se->loop->from[n] = gfc_index_zero_node;
3092 se->loop->to[n] = upper;
3094 /* Build a destination descriptor, using the pointer, source, as the
3095 data field. This is already allocated so set callee_alloc.
3096 FIXME callee_alloc is not set! */
3098 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3099 info, mold_type, false, true, false);
3101 /* Cast the pointer to the result. */
3102 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3103 tmp = fold_convert (pvoid_type_node, tmp);
3105 /* Use memcpy to do the transfer. */
3106 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3109 fold_convert (pvoid_type_node, source),
3111 gfc_add_expr_to_block (&se->pre, tmp);
3113 se->expr = info->descriptor;
3114 if (expr->ts.type == BT_CHARACTER)
3115 se->string_length = dest_word_len;
3119 /* Scalar transfer statement.
3120 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3123 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3125 gfc_actual_arglist *arg;
3132 /* Get a pointer to the source. */
3133 arg = expr->value.function.actual;
3134 ss = gfc_walk_expr (arg->expr);
3135 gfc_init_se (&argse, NULL);
3136 if (ss == gfc_ss_terminator)
3137 gfc_conv_expr_reference (&argse, arg->expr);
3139 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3140 gfc_add_block_to_block (&se->pre, &argse.pre);
3141 gfc_add_block_to_block (&se->post, &argse.post);
3145 type = gfc_typenode_for_spec (&expr->ts);
3147 if (expr->ts.type == BT_CHARACTER)
3149 ptr = convert (build_pointer_type (type), ptr);
3150 gfc_init_se (&argse, NULL);
3151 gfc_conv_expr (&argse, arg->expr);
3152 gfc_add_block_to_block (&se->pre, &argse.pre);
3153 gfc_add_block_to_block (&se->post, &argse.post);
3155 se->string_length = argse.string_length;
3160 tmpdecl = gfc_create_var (type, "transfer");
3161 moldsize = size_in_bytes (type);
3163 /* Use memcpy to do the transfer. */
3164 tmp = build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3165 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3166 fold_convert (pvoid_type_node, tmp),
3167 fold_convert (pvoid_type_node, ptr),
3169 gfc_add_expr_to_block (&se->pre, tmp);
3176 /* Generate code for the ALLOCATED intrinsic.
3177 Generate inline code that directly check the address of the argument. */
3180 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3182 gfc_actual_arglist *arg1;
3187 gfc_init_se (&arg1se, NULL);
3188 arg1 = expr->value.function.actual;
3189 ss1 = gfc_walk_expr (arg1->expr);
3190 arg1se.descriptor_only = 1;
3191 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3193 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3194 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
3195 fold_convert (TREE_TYPE (tmp), null_pointer_node));
3196 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3200 /* Generate code for the ASSOCIATED intrinsic.
3201 If both POINTER and TARGET are arrays, generate a call to library function
3202 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3203 In other cases, generate inline code that directly compare the address of
3204 POINTER with the address of TARGET. */
3207 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3209 gfc_actual_arglist *arg1;
3210 gfc_actual_arglist *arg2;
3216 tree nonzero_charlen;
3217 tree nonzero_arraylen;
3220 gfc_init_se (&arg1se, NULL);
3221 gfc_init_se (&arg2se, NULL);
3222 arg1 = expr->value.function.actual;
3224 ss1 = gfc_walk_expr (arg1->expr);
3228 /* No optional target. */
3229 if (ss1 == gfc_ss_terminator)
3231 /* A pointer to a scalar. */
3232 arg1se.want_pointer = 1;
3233 gfc_conv_expr (&arg1se, arg1->expr);
3238 /* A pointer to an array. */
3239 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3240 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3242 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3243 gfc_add_block_to_block (&se->post, &arg1se.post);
3244 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
3245 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3250 /* An optional target. */
3251 ss2 = gfc_walk_expr (arg2->expr);
3253 nonzero_charlen = NULL_TREE;
3254 if (arg1->expr->ts.type == BT_CHARACTER)
3255 nonzero_charlen = build2 (NE_EXPR, boolean_type_node,
3256 arg1->expr->ts.cl->backend_decl,
3259 if (ss1 == gfc_ss_terminator)
3261 /* A pointer to a scalar. */
3262 gcc_assert (ss2 == gfc_ss_terminator);
3263 arg1se.want_pointer = 1;
3264 gfc_conv_expr (&arg1se, arg1->expr);
3265 arg2se.want_pointer = 1;
3266 gfc_conv_expr (&arg2se, arg2->expr);
3267 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3268 gfc_add_block_to_block (&se->post, &arg1se.post);
3269 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
3270 tmp2 = build2 (NE_EXPR, boolean_type_node, arg1se.expr,
3272 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node, tmp, tmp2);
3277 /* An array pointer of zero length is not associated if target is
3279 arg1se.descriptor_only = 1;
3280 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3281 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3282 gfc_rank_cst[arg1->expr->rank - 1]);
3283 nonzero_arraylen = build2 (NE_EXPR, boolean_type_node,
3284 tmp, build_int_cst (TREE_TYPE (tmp), 0));
3286 /* A pointer to an array, call library function _gfor_associated. */
3287 gcc_assert (ss2 != gfc_ss_terminator);
3288 arg1se.want_pointer = 1;
3289 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3291 arg2se.want_pointer = 1;
3292 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3293 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3294 gfc_add_block_to_block (&se->post, &arg2se.post);
3295 fndecl = gfor_fndecl_associated;
3296 se->expr = build_call_expr (fndecl, 2, arg1se.expr, arg2se.expr);
3297 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3298 se->expr, nonzero_arraylen);
3302 /* If target is present zero character length pointers cannot
3304 if (nonzero_charlen != NULL_TREE)
3305 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3306 se->expr, nonzero_charlen);
3309 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3313 /* Scan a string for any one of the characters in a set of characters. */
3316 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
3318 tree logical4_type_node = gfc_get_logical_type (4);
3324 args = gfc_conv_intrinsic_function_args (se, expr);
3325 type = gfc_typenode_for_spec (&expr->ts);
3326 tmp = gfc_advance_chain (args, 3);
3327 if (TREE_CHAIN (tmp) == NULL_TREE)
3329 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3331 TREE_CHAIN (tmp) = back;
3335 back = TREE_CHAIN (tmp);
3336 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3339 se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
3340 se->expr = convert (type, se->expr);
3344 /* Verify that a set of characters contains all the characters in a string
3345 by identifying the position of the first character in a string of
3346 characters that does not appear in a given set of characters. */
3349 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
3351 tree logical4_type_node = gfc_get_logical_type (4);
3357 args = gfc_conv_intrinsic_function_args (se, expr);
3358 type = gfc_typenode_for_spec (&expr->ts);
3359 tmp = gfc_advance_chain (args, 3);
3360 if (TREE_CHAIN (tmp) == NULL_TREE)
3362 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3364 TREE_CHAIN (tmp) = back;
3368 back = TREE_CHAIN (tmp);
3369 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3372 se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
3373 se->expr = convert (type, se->expr);
3377 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3380 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
3384 args = gfc_conv_intrinsic_function_args (se, expr);
3385 args = TREE_VALUE (args);
3386 args = build_fold_addr_expr (args);
3387 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, args);
3390 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3393 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
3395 gfc_actual_arglist *actual;
3400 for (actual = expr->value.function.actual; actual; actual = actual->next)
3402 gfc_init_se (&argse, se);
3404 /* Pass a NULL pointer for an absent arg. */
3405 if (actual->expr == NULL)
3406 argse.expr = null_pointer_node;
3408 gfc_conv_expr_reference (&argse, actual->expr);
3410 gfc_add_block_to_block (&se->pre, &argse.pre);
3411 gfc_add_block_to_block (&se->post, &argse.post);
3412 args = gfc_chainon_list (args, argse.expr);
3414 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3418 /* Generate code for TRIM (A) intrinsic function. */
3421 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3423 tree gfc_int4_type_node = gfc_get_int_type (4);
3432 arglist = NULL_TREE;
3434 type = build_pointer_type (gfc_character1_type_node);
3435 var = gfc_create_var (type, "pstr");
3436 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3437 len = gfc_create_var (gfc_int4_type_node, "len");
3439 tmp = gfc_conv_intrinsic_function_args (se, expr);
3440 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
3441 arglist = gfc_chainon_list (arglist, addr);
3442 arglist = chainon (arglist, tmp);
3444 tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
3445 gfc_add_expr_to_block (&se->pre, tmp);
3447 /* Free the temporary afterwards, if necessary. */
3448 cond = build2 (GT_EXPR, boolean_type_node, len,
3449 build_int_cst (TREE_TYPE (len), 0));
3450 tmp = gfc_call_free (var);
3451 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3452 gfc_add_expr_to_block (&se->post, tmp);
3455 se->string_length = len;
3459 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3462 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3464 tree args, ncopies, dest, dlen, src, slen, ncopies_type;
3465 tree type, cond, tmp, count, exit_label, n, max, largest;
3466 stmtblock_t block, body;
3469 /* Get the arguments. */
3470 args = gfc_conv_intrinsic_function_args (se, expr);
3471 slen = fold_convert (size_type_node, gfc_evaluate_now (TREE_VALUE (args),
3473 src = TREE_VALUE (TREE_CHAIN (args));
3474 ncopies = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
3475 ncopies = gfc_evaluate_now (ncopies, &se->pre);
3476 ncopies_type = TREE_TYPE (ncopies);
3478 /* Check that NCOPIES is not negative. */
3479 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3480 build_int_cst (ncopies_type, 0));
3481 gfc_trans_runtime_check (cond,
3482 "Argument NCOPIES of REPEAT intrinsic is negative",
3483 &se->pre, &expr->where);
3485 /* If the source length is zero, any non negative value of NCOPIES
3486 is valid, and nothing happens. */
3487 n = gfc_create_var (ncopies_type, "ncopies");
3488 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3489 build_int_cst (size_type_node, 0));
3490 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
3491 build_int_cst (ncopies_type, 0), ncopies);
3492 gfc_add_modify_expr (&se->pre, n, tmp);
3495 /* Check that ncopies is not too large: ncopies should be less than
3496 (or equal to) MAX / slen, where MAX is the maximal integer of
3497 the gfc_charlen_type_node type. If slen == 0, we need a special
3498 case to avoid the division by zero. */
3499 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
3500 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
3501 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
3502 fold_convert (size_type_node, max), slen);
3503 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
3504 ? size_type_node : ncopies_type;
3505 cond = fold_build2 (GT_EXPR, boolean_type_node,
3506 fold_convert (largest, ncopies),
3507 fold_convert (largest, max));
3508 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3509 build_int_cst (size_type_node, 0));
3510 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
3512 gfc_trans_runtime_check (cond,
3513 "Argument NCOPIES of REPEAT intrinsic is too large",
3514 &se->pre, &expr->where);
3516 /* Compute the destination length. */
3517 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node, slen, ncopies);
3518 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3519 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
3521 /* Generate the code to do the repeat operation:
3522 for (i = 0; i < ncopies; i++)
3523 memmove (dest + (i * slen), src, slen); */
3524 gfc_start_block (&block);
3525 count = gfc_create_var (ncopies_type, "count");
3526 gfc_add_modify_expr (&block, count, build_int_cst (ncopies_type, 0));
3527 exit_label = gfc_build_label_decl (NULL_TREE);
3529 /* Start the loop body. */
3530 gfc_start_block (&body);
3532 /* Exit the loop if count >= ncopies. */
3533 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
3534 tmp = build1_v (GOTO_EXPR, exit_label);
3535 TREE_USED (exit_label) = 1;
3536 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3537 build_empty_stmt ());
3538 gfc_add_expr_to_block (&body, tmp);
3540 /* Call memmove (dest + (i*slen), src, slen). */
3541 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node, slen,
3542 fold_convert (gfc_charlen_type_node, count));
3543 tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node, dest,
3544 fold_convert (sizetype, tmp));
3545 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3,
3547 gfc_add_expr_to_block (&body, tmp);
3549 /* Increment count. */
3550 tmp = build2 (PLUS_EXPR, ncopies_type, count,
3551 build_int_cst (TREE_TYPE (count), 1));
3552 gfc_add_modify_expr (&body, count, tmp);
3554 /* Build the loop. */
3555 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
3556 gfc_add_expr_to_block (&block, tmp);
3558 /* Add the exit label. */
3559 tmp = build1_v (LABEL_EXPR, exit_label);
3560 gfc_add_expr_to_block (&block, tmp);
3562 /* Finish the block. */
3563 tmp = gfc_finish_block (&block);
3564 gfc_add_expr_to_block (&se->pre, tmp);
3566 /* Set the result value. */
3568 se->string_length = dlen;
3572 /* Generate code for the IARGC intrinsic. */
3575 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3581 /* Call the library function. This always returns an INTEGER(4). */
3582 fndecl = gfor_fndecl_iargc;
3583 tmp = build_call_expr (fndecl, 0);
3585 /* Convert it to the required type. */
3586 type = gfc_typenode_for_spec (&expr->ts);
3587 tmp = fold_convert (type, tmp);
3593 /* The loc intrinsic returns the address of its argument as
3594 gfc_index_integer_kind integer. */
3597 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3603 gcc_assert (!se->ss);
3605 arg_expr = expr->value.function.actual->expr;
3606 ss = gfc_walk_expr (arg_expr);
3607 if (ss == gfc_ss_terminator)
3608 gfc_conv_expr_reference (se, arg_expr);
3610 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3611 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
3613 /* Create a temporary variable for loc return value. Without this,
3614 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3615 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
3616 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3617 se->expr = temp_var;
3620 /* Generate code for an intrinsic function. Some map directly to library
3621 calls, others get special handling. In some cases the name of the function
3622 used depends on the type specifiers. */
3625 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
3627 gfc_intrinsic_sym *isym;
3631 isym = expr->value.function.isym;
3633 name = &expr->value.function.name[2];
3635 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
3637 lib = gfc_is_intrinsic_libcall (expr);
3641 se->ignore_optional = 1;
3642 gfc_conv_intrinsic_funcall (se, expr);
3647 switch (expr->value.function.isym->id)
3652 case GFC_ISYM_REPEAT:
3653 gfc_conv_intrinsic_repeat (se, expr);
3657 gfc_conv_intrinsic_trim (se, expr);
3660 case GFC_ISYM_SI_KIND:
3661 gfc_conv_intrinsic_si_kind (se, expr);
3664 case GFC_ISYM_SR_KIND:
3665 gfc_conv_intrinsic_sr_kind (se, expr);
3668 case GFC_ISYM_EXPONENT:
3669 gfc_conv_intrinsic_exponent (se, expr);
3673 gfc_conv_intrinsic_scan (se, expr);
3676 case GFC_ISYM_VERIFY:
3677 gfc_conv_intrinsic_verify (se, expr);
3680 case GFC_ISYM_ALLOCATED:
3681 gfc_conv_allocated (se, expr);
3684 case GFC_ISYM_ASSOCIATED:
3685 gfc_conv_associated(se, expr);
3689 gfc_conv_intrinsic_abs (se, expr);
3692 case GFC_ISYM_ADJUSTL:
3693 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
3696 case GFC_ISYM_ADJUSTR:
3697 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
3700 case GFC_ISYM_AIMAG:
3701 gfc_conv_intrinsic_imagpart (se, expr);
3705 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
3709 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
3712 case GFC_ISYM_ANINT:
3713 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
3717 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3721 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
3724 case GFC_ISYM_BTEST:
3725 gfc_conv_intrinsic_btest (se, expr);
3728 case GFC_ISYM_ACHAR:
3730 gfc_conv_intrinsic_char (se, expr);
3733 case GFC_ISYM_CONVERSION:
3735 case GFC_ISYM_LOGICAL:
3737 gfc_conv_intrinsic_conversion (se, expr);
3740 /* Integer conversions are handled separately to make sure we get the
3741 correct rounding mode. */
3746 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
3750 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
3753 case GFC_ISYM_CEILING:
3754 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
3757 case GFC_ISYM_FLOOR:
3758 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
3762 gfc_conv_intrinsic_mod (se, expr, 0);
3765 case GFC_ISYM_MODULO:
3766 gfc_conv_intrinsic_mod (se, expr, 1);
3769 case GFC_ISYM_CMPLX:
3770 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3773 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3774 gfc_conv_intrinsic_iargc (se, expr);
3777 case GFC_ISYM_COMPLEX:
3778 gfc_conv_intrinsic_cmplx (se, expr, 1);
3781 case GFC_ISYM_CONJG:
3782 gfc_conv_intrinsic_conjg (se, expr);
3785 case GFC_ISYM_COUNT:
3786 gfc_conv_intrinsic_count (se, expr);
3789 case GFC_ISYM_CTIME:
3790 gfc_conv_intrinsic_ctime (se, expr);
3794 gfc_conv_intrinsic_dim (se, expr);
3797 case GFC_ISYM_DOT_PRODUCT:
3798 gfc_conv_intrinsic_dot_product (se, expr);
3801 case GFC_ISYM_DPROD:
3802 gfc_conv_intrinsic_dprod (se, expr);
3805 case GFC_ISYM_FDATE:
3806 gfc_conv_intrinsic_fdate (se, expr);
3810 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3813 case GFC_ISYM_IBCLR:
3814 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3817 case GFC_ISYM_IBITS:
3818 gfc_conv_intrinsic_ibits (se, expr);
3821 case GFC_ISYM_IBSET:
3822 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3825 case GFC_ISYM_IACHAR:
3826 case GFC_ISYM_ICHAR:
3827 /* We assume ASCII character sequence. */
3828 gfc_conv_intrinsic_ichar (se, expr);
3831 case GFC_ISYM_IARGC:
3832 gfc_conv_intrinsic_iargc (se, expr);
3836 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3839 case GFC_ISYM_INDEX:
3840 gfc_conv_intrinsic_index (se, expr);
3844 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3847 case GFC_ISYM_LSHIFT:
3848 gfc_conv_intrinsic_rlshift (se, expr, 0);
3851 case GFC_ISYM_RSHIFT:
3852 gfc_conv_intrinsic_rlshift (se, expr, 1);
3855 case GFC_ISYM_ISHFT:
3856 gfc_conv_intrinsic_ishft (se, expr);
3859 case GFC_ISYM_ISHFTC:
3860 gfc_conv_intrinsic_ishftc (se, expr);
3863 case GFC_ISYM_LBOUND:
3864 gfc_conv_intrinsic_bound (se, expr, 0);
3867 case GFC_ISYM_TRANSPOSE:
3868 if (se->ss && se->ss->useflags)
3870 gfc_conv_tmp_array_ref (se);
3871 gfc_advance_se_ss_chain (se);
3874 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3878 gfc_conv_intrinsic_len (se, expr);
3881 case GFC_ISYM_LEN_TRIM:
3882 gfc_conv_intrinsic_len_trim (se, expr);
3886 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3890 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3894 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3898 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3902 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3905 case GFC_ISYM_MAXLOC:
3906 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3909 case GFC_ISYM_MAXVAL:
3910 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3913 case GFC_ISYM_MERGE:
3914 gfc_conv_intrinsic_merge (se, expr);
3918 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3921 case GFC_ISYM_MINLOC:
3922 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3925 case GFC_ISYM_MINVAL:
3926 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3930 gfc_conv_intrinsic_not (se, expr);
3934 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3937 case GFC_ISYM_PRESENT:
3938 gfc_conv_intrinsic_present (se, expr);
3941 case GFC_ISYM_PRODUCT:
3942 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3946 gfc_conv_intrinsic_sign (se, expr);
3950 gfc_conv_intrinsic_size (se, expr);
3953 case GFC_ISYM_SIZEOF:
3954 gfc_conv_intrinsic_sizeof (se, expr);
3958 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3961 case GFC_ISYM_TRANSFER:
3964 if (se->ss->useflags)
3966 /* Access the previously obtained result. */
3967 gfc_conv_tmp_array_ref (se);
3968 gfc_advance_se_ss_chain (se);
3972 gfc_conv_intrinsic_array_transfer (se, expr);
3975 gfc_conv_intrinsic_transfer (se, expr);
3978 case GFC_ISYM_TTYNAM:
3979 gfc_conv_intrinsic_ttynam (se, expr);
3982 case GFC_ISYM_UBOUND:
3983 gfc_conv_intrinsic_bound (se, expr, 1);
3987 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3991 gfc_conv_intrinsic_loc (se, expr);
3994 case GFC_ISYM_ACCESS:
3995 case GFC_ISYM_CHDIR:
3996 case GFC_ISYM_CHMOD:
3997 case GFC_ISYM_ETIME:
3999 case GFC_ISYM_FGETC:
4002 case GFC_ISYM_FPUTC:
4003 case GFC_ISYM_FSTAT:
4004 case GFC_ISYM_FTELL:
4005 case GFC_ISYM_GETCWD:
4006 case GFC_ISYM_GETGID:
4007 case GFC_ISYM_GETPID:
4008 case GFC_ISYM_GETUID:
4009 case GFC_ISYM_HOSTNM:
4011 case GFC_ISYM_IERRNO:
4012 case GFC_ISYM_IRAND:
4013 case GFC_ISYM_ISATTY:
4015 case GFC_ISYM_LSTAT:
4016 case GFC_ISYM_MALLOC:
4017 case GFC_ISYM_MATMUL:
4018 case GFC_ISYM_MCLOCK:
4019 case GFC_ISYM_MCLOCK8:
4021 case GFC_ISYM_RENAME:
4022 case GFC_ISYM_SECOND:
4023 case GFC_ISYM_SECNDS:
4024 case GFC_ISYM_SIGNAL:
4026 case GFC_ISYM_SYMLNK:
4027 case GFC_ISYM_SYSTEM:
4029 case GFC_ISYM_TIME8:
4030 case GFC_ISYM_UMASK:
4031 case GFC_ISYM_UNLINK:
4032 gfc_conv_intrinsic_funcall (se, expr);
4036 gfc_conv_intrinsic_lib_function (se, expr);
4042 /* This generates code to execute before entering the scalarization loop.
4043 Currently does nothing. */
4046 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4048 switch (ss->expr->value.function.isym->id)
4050 case GFC_ISYM_UBOUND:
4051 case GFC_ISYM_LBOUND:
4060 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4061 inside the scalarization loop. */
4064 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4068 /* The two argument version returns a scalar. */
4069 if (expr->value.function.actual->next->expr)
4072 newss = gfc_get_ss ();
4073 newss->type = GFC_SS_INTRINSIC;
4076 newss->data.info.dimen = 1;
4082 /* Walk an intrinsic array libcall. */
4085 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4089 gcc_assert (expr->rank > 0);
4091 newss = gfc_get_ss ();
4092 newss->type = GFC_SS_FUNCTION;
4095 newss->data.info.dimen = expr->rank;
4101 /* Returns nonzero if the specified intrinsic function call maps directly to a
4102 an external library call. Should only be used for functions that return
4106 gfc_is_intrinsic_libcall (gfc_expr * expr)
4108 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4109 gcc_assert (expr->rank > 0);
4111 switch (expr->value.function.isym->id)
4115 case GFC_ISYM_COUNT:
4116 case GFC_ISYM_MATMUL:
4117 case GFC_ISYM_MAXLOC:
4118 case GFC_ISYM_MAXVAL:
4119 case GFC_ISYM_MINLOC:
4120 case GFC_ISYM_MINVAL:
4121 case GFC_ISYM_PRODUCT:
4123 case GFC_ISYM_SHAPE:
4124 case GFC_ISYM_SPREAD:
4125 case GFC_ISYM_TRANSPOSE:
4126 /* Ignore absent optional parameters. */
4129 case GFC_ISYM_RESHAPE:
4130 case GFC_ISYM_CSHIFT:
4131 case GFC_ISYM_EOSHIFT:
4133 case GFC_ISYM_UNPACK:
4134 /* Pass absent optional parameters. */
4142 /* Walk an intrinsic function. */
4144 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
4145 gfc_intrinsic_sym * isym)
4149 if (isym->elemental)
4150 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
4152 if (expr->rank == 0)
4155 if (gfc_is_intrinsic_libcall (expr))
4156 return gfc_walk_intrinsic_libfunc (ss, expr);
4158 /* Special cases. */
4161 case GFC_ISYM_LBOUND:
4162 case GFC_ISYM_UBOUND:
4163 return gfc_walk_intrinsic_bound (ss, expr);
4165 case GFC_ISYM_TRANSFER:
4166 return gfc_walk_intrinsic_libfunc (ss, expr);
4169 /* This probably meant someone forgot to add an intrinsic to the above
4170 list(s) when they implemented it, or something's gone horribly wrong.
4172 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
4173 expr->value.function.name);
4177 #include "gt-fortran-trans-intrinsic.h"