1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
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 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
109 /* Functions built into gcc itself. */
110 #include "mathbuiltins.def"
113 { GFC_ISYM_NONE, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS,
114 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS,
115 true, false, true, NULL, NULL_TREE, NULL_TREE, NULL_TREE,
116 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
118 #undef DEFINE_MATH_BUILTIN
119 #undef DEFINE_MATH_BUILTIN_C
121 /* Structure for storing components of a floating number to be used by
122 elemental functions to manipulate reals. */
125 tree arg; /* Variable tree to view convert to integer. */
126 tree expn; /* Variable tree to save exponent. */
127 tree frac; /* Variable tree to save fraction. */
128 tree smask; /* Constant tree of sign's mask. */
129 tree emask; /* Constant tree of exponent's mask. */
130 tree fmask; /* Constant tree of fraction's mask. */
131 tree edigits; /* Constant tree of the number of exponent bits. */
132 tree fdigits; /* Constant tree of the number of fraction bits. */
133 tree f1; /* Constant tree of the f1 defined in the real model. */
134 tree bias; /* Constant tree of the bias of exponent in the memory. */
135 tree type; /* Type tree of arg1. */
136 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
140 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
142 /* Evaluate the arguments to an intrinsic function. The value
143 of NARGS may be less than the actual number of arguments in EXPR
144 to allow optional "KIND" arguments that are not included in the
145 generated code to be ignored. */
148 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
149 tree *argarray, int nargs)
151 gfc_actual_arglist *actual;
153 gfc_intrinsic_arg *formal;
157 formal = expr->value.function.isym->formal;
158 actual = expr->value.function.actual;
160 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
161 actual = actual->next,
162 formal = formal ? formal->next : NULL)
166 /* Skip omitted optional arguments. */
173 /* Evaluate the parameter. This will substitute scalarized
174 references automatically. */
175 gfc_init_se (&argse, se);
177 if (e->ts.type == BT_CHARACTER)
179 gfc_conv_expr (&argse, e);
180 gfc_conv_string_parameter (&argse);
181 argarray[curr_arg++] = argse.string_length;
182 gcc_assert (curr_arg < nargs);
185 gfc_conv_expr_val (&argse, e);
187 /* If an optional argument is itself an optional dummy argument,
188 check its presence and substitute a null if absent. */
189 if (e->expr_type == EXPR_VARIABLE
190 && e->symtree->n.sym->attr.optional
193 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
195 gfc_add_block_to_block (&se->pre, &argse.pre);
196 gfc_add_block_to_block (&se->post, &argse.post);
197 argarray[curr_arg] = argse.expr;
201 /* Count the number of actual arguments to the intrinsic function EXPR
202 including any "hidden" string length arguments. */
205 gfc_intrinsic_argument_list_length (gfc_expr *expr)
208 gfc_actual_arglist *actual;
210 for (actual = expr->value.function.actual; actual; actual = actual->next)
215 if (actual->expr->ts.type == BT_CHARACTER)
225 /* Conversions between different types are output by the frontend as
226 intrinsic functions. We implement these directly with inline code. */
229 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
235 nargs = gfc_intrinsic_argument_list_length (expr);
236 args = alloca (sizeof (tree) * nargs);
238 /* Evaluate all the arguments passed. Whilst we're only interested in the
239 first one here, there are other parts of the front-end that assume this
240 and will trigger an ICE if it's not the case. */
241 type = gfc_typenode_for_spec (&expr->ts);
242 gcc_assert (expr->value.function.actual->expr);
243 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
245 /* Conversion from complex to non-complex involves taking the real
246 component of the value. */
247 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
248 && expr->ts.type != BT_COMPLEX)
252 artype = TREE_TYPE (TREE_TYPE (args[0]));
253 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
256 se->expr = convert (type, args[0]);
259 /* This is needed because the gcc backend only implements
260 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
261 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
262 Similarly for CEILING. */
265 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
272 argtype = TREE_TYPE (arg);
273 arg = gfc_evaluate_now (arg, pblock);
275 intval = convert (type, arg);
276 intval = gfc_evaluate_now (intval, pblock);
278 tmp = convert (argtype, intval);
279 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
281 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
282 build_int_cst (type, 1));
283 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
288 /* Round to nearest integer, away from zero. */
291 build_round_expr (tree arg, tree restype)
296 int argprec, resprec;
298 argtype = TREE_TYPE (arg);
299 argprec = TYPE_PRECISION (argtype);
300 resprec = TYPE_PRECISION (restype);
302 /* Depending on the type of the result, choose the long int intrinsic
303 (lround family) or long long intrinsic (llround). We might also
304 need to convert the result afterwards. */
305 if (resprec <= LONG_TYPE_SIZE)
307 else if (resprec <= LONG_LONG_TYPE_SIZE)
312 /* Now, depending on the argument type, we choose between intrinsics. */
313 if (argprec == TYPE_PRECISION (float_type_node))
314 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
315 else if (argprec == TYPE_PRECISION (double_type_node))
316 fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
317 else if (argprec == TYPE_PRECISION (long_double_type_node))
318 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
322 return fold_convert (restype, build_call_expr (fn, 1, arg));
326 /* Convert a real to an integer using a specific rounding mode.
327 Ideally we would just build the corresponding GENERIC node,
328 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
331 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
332 enum rounding_mode op)
337 return build_fixbound_expr (pblock, arg, type, 0);
341 return build_fixbound_expr (pblock, arg, type, 1);
345 return build_round_expr (arg, type);
349 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
358 /* Round a real value using the specified rounding mode.
359 We use a temporary integer of that same kind size as the result.
360 Values larger than those that can be represented by this kind are
361 unchanged, as they will not be accurate enough to represent the
363 huge = HUGE (KIND (a))
364 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
368 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
379 kind = expr->ts.kind;
380 nargs = gfc_intrinsic_argument_list_length (expr);
383 /* We have builtin functions for some cases. */
426 /* Evaluate the argument. */
427 gcc_assert (expr->value.function.actual->expr);
428 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
430 /* Use a builtin function if one exists. */
431 if (n != END_BUILTINS)
433 tmp = built_in_decls[n];
434 se->expr = build_call_expr (tmp, 1, arg[0]);
438 /* This code is probably redundant, but we'll keep it lying around just
440 type = gfc_typenode_for_spec (&expr->ts);
441 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
443 /* Test if the value is too large to handle sensibly. */
444 gfc_set_model_kind (kind);
446 n = gfc_validate_kind (BT_INTEGER, kind, false);
447 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
448 tmp = gfc_conv_mpfr_to_tree (huge, kind);
449 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
451 mpfr_neg (huge, huge, GFC_RND_MODE);
452 tmp = gfc_conv_mpfr_to_tree (huge, kind);
453 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
454 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
455 itype = gfc_get_int_type (kind);
457 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
458 tmp = convert (type, tmp);
459 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
464 /* Convert to an integer using the specified rounding mode. */
467 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
473 nargs = gfc_intrinsic_argument_list_length (expr);
474 args = alloca (sizeof (tree) * nargs);
476 /* Evaluate the argument, we process all arguments even though we only
477 use the first one for code generation purposes. */
478 type = gfc_typenode_for_spec (&expr->ts);
479 gcc_assert (expr->value.function.actual->expr);
480 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
482 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
484 /* Conversion to a different integer kind. */
485 se->expr = convert (type, args[0]);
489 /* Conversion from complex to non-complex involves taking the real
490 component of the value. */
491 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
492 && expr->ts.type != BT_COMPLEX)
496 artype = TREE_TYPE (TREE_TYPE (args[0]));
497 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
500 se->expr = build_fix_expr (&se->pre, args[0], type, op);
505 /* Get the imaginary component of a value. */
508 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
512 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
513 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
517 /* Get the complex conjugate of a value. */
520 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
524 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
525 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
529 /* Initialize function decls for library functions. The external functions
530 are created as required. Builtin functions are added here. */
533 gfc_build_intrinsic_lib_fndecls (void)
535 gfc_intrinsic_map_t *m;
537 /* Add GCC builtin functions. */
538 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
540 if (m->code_r4 != END_BUILTINS)
541 m->real4_decl = built_in_decls[m->code_r4];
542 if (m->code_r8 != END_BUILTINS)
543 m->real8_decl = built_in_decls[m->code_r8];
544 if (m->code_r10 != END_BUILTINS)
545 m->real10_decl = built_in_decls[m->code_r10];
546 if (m->code_r16 != END_BUILTINS)
547 m->real16_decl = built_in_decls[m->code_r16];
548 if (m->code_c4 != END_BUILTINS)
549 m->complex4_decl = built_in_decls[m->code_c4];
550 if (m->code_c8 != END_BUILTINS)
551 m->complex8_decl = built_in_decls[m->code_c8];
552 if (m->code_c10 != END_BUILTINS)
553 m->complex10_decl = built_in_decls[m->code_c10];
554 if (m->code_c16 != END_BUILTINS)
555 m->complex16_decl = built_in_decls[m->code_c16];
560 /* Create a fndecl for a simple intrinsic library function. */
563 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
568 gfc_actual_arglist *actual;
571 char name[GFC_MAX_SYMBOL_LEN + 3];
574 if (ts->type == BT_REAL)
579 pdecl = &m->real4_decl;
582 pdecl = &m->real8_decl;
585 pdecl = &m->real10_decl;
588 pdecl = &m->real16_decl;
594 else if (ts->type == BT_COMPLEX)
596 gcc_assert (m->complex_available);
601 pdecl = &m->complex4_decl;
604 pdecl = &m->complex8_decl;
607 pdecl = &m->complex10_decl;
610 pdecl = &m->complex16_decl;
625 snprintf (name, sizeof (name), "%s%s%s",
626 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
627 else if (ts->kind == 8)
628 snprintf (name, sizeof (name), "%s%s",
629 ts->type == BT_COMPLEX ? "c" : "", m->name);
632 gcc_assert (ts->kind == 10 || ts->kind == 16);
633 snprintf (name, sizeof (name), "%s%s%s",
634 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
639 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
640 ts->type == BT_COMPLEX ? 'c' : 'r',
644 argtypes = NULL_TREE;
645 for (actual = expr->value.function.actual; actual; actual = actual->next)
647 type = gfc_typenode_for_spec (&actual->expr->ts);
648 argtypes = gfc_chainon_list (argtypes, type);
650 argtypes = gfc_chainon_list (argtypes, void_type_node);
651 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
652 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
654 /* Mark the decl as external. */
655 DECL_EXTERNAL (fndecl) = 1;
656 TREE_PUBLIC (fndecl) = 1;
658 /* Mark it __attribute__((const)), if possible. */
659 TREE_READONLY (fndecl) = m->is_constant;
661 rest_of_decl_compilation (fndecl, 1, 0);
668 /* Convert an intrinsic function into an external or builtin call. */
671 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
673 gfc_intrinsic_map_t *m;
677 unsigned int num_args;
680 id = expr->value.function.isym->id;
681 /* Find the entry for this function. */
682 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
688 if (m->id == GFC_ISYM_NONE)
690 internal_error ("Intrinsic function %s(%d) not recognized",
691 expr->value.function.name, id);
694 /* Get the decl and generate the call. */
695 num_args = gfc_intrinsic_argument_list_length (expr);
696 args = alloca (sizeof (tree) * num_args);
698 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
699 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
700 rettype = TREE_TYPE (TREE_TYPE (fndecl));
702 fndecl = build_addr (fndecl, current_function_decl);
703 se->expr = build_call_array (rettype, fndecl, num_args, args);
706 /* The EXPONENT(s) intrinsic function is translated into
713 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
715 tree arg, type, res, tmp;
718 switch (expr->value.function.actual->expr->ts.kind)
721 frexp = BUILT_IN_FREXPF;
724 frexp = BUILT_IN_FREXP;
728 frexp = BUILT_IN_FREXPL;
734 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
736 res = gfc_create_var (integer_type_node, NULL);
737 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
738 build_fold_addr_expr (res));
739 gfc_add_expr_to_block (&se->pre, tmp);
741 type = gfc_typenode_for_spec (&expr->ts);
742 se->expr = fold_convert (type, res);
745 /* Evaluate a single upper or lower bound. */
746 /* TODO: bound intrinsic generates way too much unnecessary code. */
749 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
751 gfc_actual_arglist *arg;
752 gfc_actual_arglist *arg2;
757 tree cond, cond1, cond2, cond3, cond4, size;
765 arg = expr->value.function.actual;
770 /* Create an implicit second parameter from the loop variable. */
771 gcc_assert (!arg2->expr);
772 gcc_assert (se->loop->dimen == 1);
773 gcc_assert (se->ss->expr == expr);
774 gfc_advance_se_ss_chain (se);
775 bound = se->loop->loopvar[0];
776 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
781 /* use the passed argument. */
782 gcc_assert (arg->next->expr);
783 gfc_init_se (&argse, NULL);
784 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
785 gfc_add_block_to_block (&se->pre, &argse.pre);
787 /* Convert from one based to zero based. */
788 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
792 /* TODO: don't re-evaluate the descriptor on each iteration. */
793 /* Get a descriptor for the first parameter. */
794 ss = gfc_walk_expr (arg->expr);
795 gcc_assert (ss != gfc_ss_terminator);
796 gfc_init_se (&argse, NULL);
797 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
798 gfc_add_block_to_block (&se->pre, &argse.pre);
799 gfc_add_block_to_block (&se->post, &argse.post);
803 if (INTEGER_CST_P (bound))
807 hi = TREE_INT_CST_HIGH (bound);
808 low = TREE_INT_CST_LOW (bound);
809 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
810 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
811 "dimension index", upper ? "UBOUND" : "LBOUND",
816 if (flag_bounds_check)
818 bound = gfc_evaluate_now (bound, &se->pre);
819 cond = fold_build2 (LT_EXPR, boolean_type_node,
820 bound, build_int_cst (TREE_TYPE (bound), 0));
821 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
822 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
823 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
824 gfc_trans_runtime_check (cond, &se->pre, &expr->where, gfc_msg_fault);
828 ubound = gfc_conv_descriptor_ubound (desc, bound);
829 lbound = gfc_conv_descriptor_lbound (desc, bound);
831 /* Follow any component references. */
832 if (arg->expr->expr_type == EXPR_VARIABLE
833 || arg->expr->expr_type == EXPR_CONSTANT)
835 as = arg->expr->symtree->n.sym->as;
836 for (ref = arg->expr->ref; ref; ref = ref->next)
841 as = ref->u.c.component->as;
849 switch (ref->u.ar.type)
867 /* 13.14.53: Result value for LBOUND
869 Case (i): For an array section or for an array expression other than a
870 whole array or array structure component, LBOUND(ARRAY, DIM)
871 has the value 1. For a whole array or array structure
872 component, LBOUND(ARRAY, DIM) has the value:
873 (a) equal to the lower bound for subscript DIM of ARRAY if
874 dimension DIM of ARRAY does not have extent zero
875 or if ARRAY is an assumed-size array of rank DIM,
878 13.14.113: Result value for UBOUND
880 Case (i): For an array section or for an array expression other than a
881 whole array or array structure component, UBOUND(ARRAY, DIM)
882 has the value equal to the number of elements in the given
883 dimension; otherwise, it has a value equal to the upper bound
884 for subscript DIM of ARRAY if dimension DIM of ARRAY does
885 not have size zero and has value zero if dimension DIM has
890 tree stride = gfc_conv_descriptor_stride (desc, bound);
892 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
893 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
895 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
896 gfc_index_zero_node);
897 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
899 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
900 gfc_index_zero_node);
901 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
905 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
907 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
908 ubound, gfc_index_zero_node);
912 if (as->type == AS_ASSUMED_SIZE)
913 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
914 build_int_cst (TREE_TYPE (bound),
915 arg->expr->rank - 1));
917 cond = boolean_false_node;
919 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
920 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
922 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
923 lbound, gfc_index_one_node);
930 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
931 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
935 se->expr = gfc_index_one_node;
938 type = gfc_typenode_for_spec (&expr->ts);
939 se->expr = convert (type, se->expr);
944 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
949 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
951 switch (expr->value.function.actual->expr->ts.type)
955 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
959 switch (expr->ts.kind)
974 se->expr = build_call_expr (built_in_decls[n], 1, arg);
983 /* Create a complex value from one or two real components. */
986 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
992 unsigned int num_args;
994 num_args = gfc_intrinsic_argument_list_length (expr);
995 args = alloca (sizeof (tree) * num_args);
997 type = gfc_typenode_for_spec (&expr->ts);
998 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
999 real = convert (TREE_TYPE (type), args[0]);
1001 imag = convert (TREE_TYPE (type), args[1]);
1002 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1004 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1006 imag = convert (TREE_TYPE (type), imag);
1009 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1011 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1014 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1015 MODULO(A, P) = A - FLOOR (A / P) * P */
1016 /* TODO: MOD(x, 0) */
1019 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1030 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1032 switch (expr->ts.type)
1035 /* Integer case is easy, we've got a builtin op. */
1036 type = TREE_TYPE (args[0]);
1039 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1041 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1046 /* Check if we have a builtin fmod. */
1047 switch (expr->ts.kind)
1066 /* Use it if it exists. */
1067 if (n != END_BUILTINS)
1069 tmp = build_addr (built_in_decls[n], current_function_decl);
1070 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1076 type = TREE_TYPE (args[0]);
1078 args[0] = gfc_evaluate_now (args[0], &se->pre);
1079 args[1] = gfc_evaluate_now (args[1], &se->pre);
1082 modulo = arg - floor (arg/arg2) * arg2, so
1083 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1085 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1086 thereby avoiding another division and retaining the accuracy
1087 of the builtin function. */
1088 if (n != END_BUILTINS && modulo)
1090 tree zero = gfc_build_const (type, integer_zero_node);
1091 tmp = gfc_evaluate_now (se->expr, &se->pre);
1092 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1093 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1094 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1095 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1096 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1097 test = gfc_evaluate_now (test, &se->pre);
1098 se->expr = fold_build3 (COND_EXPR, type, test,
1099 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1104 /* If we do not have a built_in fmod, the calculation is going to
1105 have to be done longhand. */
1106 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1108 /* Test if the value is too large to handle sensibly. */
1109 gfc_set_model_kind (expr->ts.kind);
1111 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1112 ikind = expr->ts.kind;
1115 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1116 ikind = gfc_max_integer_kind;
1118 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1119 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1120 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1122 mpfr_neg (huge, huge, GFC_RND_MODE);
1123 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1124 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1125 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1127 itype = gfc_get_int_type (ikind);
1129 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1131 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1132 tmp = convert (type, tmp);
1133 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1134 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1135 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1144 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1147 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1155 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1156 type = TREE_TYPE (args[0]);
1158 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1159 val = gfc_evaluate_now (val, &se->pre);
1161 zero = gfc_build_const (type, integer_zero_node);
1162 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1163 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1167 /* SIGN(A, B) is absolute value of A times sign of B.
1168 The real value versions use library functions to ensure the correct
1169 handling of negative zero. Integer case implemented as:
1170 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1174 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1180 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1181 if (expr->ts.type == BT_REAL)
1183 switch (expr->ts.kind)
1186 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1189 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1193 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1198 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1202 /* Having excluded floating point types, we know we are now dealing
1203 with signed integer types. */
1204 type = TREE_TYPE (args[0]);
1206 /* Args[0] is used multiple times below. */
1207 args[0] = gfc_evaluate_now (args[0], &se->pre);
1209 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1210 the signs of A and B are the same, and of all ones if they differ. */
1211 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1212 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1213 build_int_cst (type, TYPE_PRECISION (type) - 1));
1214 tmp = gfc_evaluate_now (tmp, &se->pre);
1216 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1217 is all ones (i.e. -1). */
1218 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1219 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1224 /* Test for the presence of an optional argument. */
1227 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1231 arg = expr->value.function.actual->expr;
1232 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1233 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1234 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1238 /* Calculate the double precision product of two single precision values. */
1241 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1246 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1248 /* Convert the args to double precision before multiplying. */
1249 type = gfc_typenode_for_spec (&expr->ts);
1250 args[0] = convert (type, args[0]);
1251 args[1] = convert (type, args[1]);
1252 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1256 /* Return a length one character string containing an ascii character. */
1259 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1265 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1267 /* We currently don't support character types != 1. */
1268 gcc_assert (expr->ts.kind == 1);
1269 type = gfc_character1_type_node;
1270 var = gfc_create_var (type, "char");
1272 arg = convert (type, arg);
1273 gfc_add_modify_expr (&se->pre, var, arg);
1274 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1275 se->string_length = integer_one_node;
1280 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1287 tree gfc_int8_type_node = gfc_get_int_type (8);
1290 unsigned int num_args;
1292 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1293 args = alloca (sizeof (tree) * num_args);
1295 type = build_pointer_type (gfc_character1_type_node);
1296 var = gfc_create_var (type, "pstr");
1297 len = gfc_create_var (gfc_int8_type_node, "len");
1299 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1300 args[0] = build_fold_addr_expr (var);
1301 args[1] = build_fold_addr_expr (len);
1303 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1304 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1305 fndecl, num_args, args);
1306 gfc_add_expr_to_block (&se->pre, tmp);
1308 /* Free the temporary afterwards, if necessary. */
1309 cond = fold_build2 (GT_EXPR, boolean_type_node,
1310 len, build_int_cst (TREE_TYPE (len), 0));
1311 tmp = gfc_call_free (var);
1312 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1313 gfc_add_expr_to_block (&se->post, tmp);
1316 se->string_length = len;
1321 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1328 tree gfc_int4_type_node = gfc_get_int_type (4);
1331 unsigned int num_args;
1333 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1334 args = alloca (sizeof (tree) * num_args);
1336 type = build_pointer_type (gfc_character1_type_node);
1337 var = gfc_create_var (type, "pstr");
1338 len = gfc_create_var (gfc_int4_type_node, "len");
1340 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1341 args[0] = build_fold_addr_expr (var);
1342 args[1] = build_fold_addr_expr (len);
1344 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1345 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1346 fndecl, num_args, args);
1347 gfc_add_expr_to_block (&se->pre, tmp);
1349 /* Free the temporary afterwards, if necessary. */
1350 cond = fold_build2 (GT_EXPR, boolean_type_node,
1351 len, build_int_cst (TREE_TYPE (len), 0));
1352 tmp = gfc_call_free (var);
1353 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1354 gfc_add_expr_to_block (&se->post, tmp);
1357 se->string_length = len;
1361 /* Return a character string containing the tty name. */
1364 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1372 tree gfc_int4_type_node = gfc_get_int_type (4);
1374 unsigned int num_args;
1376 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1377 args = alloca (sizeof (tree) * num_args);
1379 type = build_pointer_type (gfc_character1_type_node);
1380 var = gfc_create_var (type, "pstr");
1381 len = gfc_create_var (gfc_int4_type_node, "len");
1383 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1384 args[0] = build_fold_addr_expr (var);
1385 args[1] = build_fold_addr_expr (len);
1387 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1388 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1389 fndecl, num_args, args);
1390 gfc_add_expr_to_block (&se->pre, tmp);
1392 /* Free the temporary afterwards, if necessary. */
1393 cond = fold_build2 (GT_EXPR, boolean_type_node,
1394 len, build_int_cst (TREE_TYPE (len), 0));
1395 tmp = gfc_call_free (var);
1396 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1397 gfc_add_expr_to_block (&se->post, tmp);
1400 se->string_length = len;
1404 /* Get the minimum/maximum value of all the parameters.
1405 minmax (a1, a2, a3, ...)
1408 if (a2 .op. mvar || isnan(mvar))
1410 if (a3 .op. mvar || isnan(mvar))
1417 /* TODO: Mismatching types can occur when specific names are used.
1418 These should be handled during resolution. */
1420 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1428 gfc_actual_arglist *argexpr;
1429 unsigned int i, nargs;
1431 nargs = gfc_intrinsic_argument_list_length (expr);
1432 args = alloca (sizeof (tree) * nargs);
1434 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1435 type = gfc_typenode_for_spec (&expr->ts);
1437 argexpr = expr->value.function.actual;
1438 if (TREE_TYPE (args[0]) != type)
1439 args[0] = convert (type, args[0]);
1440 /* Only evaluate the argument once. */
1441 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1442 args[0] = gfc_evaluate_now (args[0], &se->pre);
1444 mvar = gfc_create_var (type, "M");
1445 gfc_add_modify_expr (&se->pre, mvar, args[0]);
1446 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1452 /* Handle absent optional arguments by ignoring the comparison. */
1453 if (argexpr->expr->expr_type == EXPR_VARIABLE
1454 && argexpr->expr->symtree->n.sym->attr.optional
1455 && TREE_CODE (val) == INDIRECT_REF)
1457 (NE_EXPR, boolean_type_node, TREE_OPERAND (val, 0),
1458 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1463 /* Only evaluate the argument once. */
1464 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1465 val = gfc_evaluate_now (val, &se->pre);
1468 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1470 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1472 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1473 __builtin_isnan might be made dependent on that module being loaded,
1474 to help performance of programs that don't rely on IEEE semantics. */
1475 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1477 isnan = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1478 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1479 fold_convert (boolean_type_node, isnan));
1481 tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
1483 if (cond != NULL_TREE)
1484 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1486 gfc_add_expr_to_block (&se->pre, tmp);
1487 argexpr = argexpr->next;
1493 /* Generate library calls for MIN and MAX intrinsics for character
1496 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1499 tree var, len, fndecl, tmp, cond;
1502 nargs = gfc_intrinsic_argument_list_length (expr);
1503 args = alloca (sizeof (tree) * (nargs + 4));
1504 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1506 /* Create the result variables. */
1507 len = gfc_create_var (gfc_charlen_type_node, "len");
1508 args[0] = build_fold_addr_expr (len);
1509 var = gfc_create_var (build_pointer_type (gfc_character1_type_node), "pstr");
1510 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1511 args[2] = build_int_cst (NULL_TREE, op);
1512 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1514 /* Make the function call. */
1515 fndecl = build_addr (gfor_fndecl_string_minmax, current_function_decl);
1516 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_minmax)),
1517 fndecl, nargs + 4, args);
1518 gfc_add_expr_to_block (&se->pre, tmp);
1520 /* Free the temporary afterwards, if necessary. */
1521 cond = fold_build2 (GT_EXPR, boolean_type_node,
1522 len, build_int_cst (TREE_TYPE (len), 0));
1523 tmp = gfc_call_free (var);
1524 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1525 gfc_add_expr_to_block (&se->post, tmp);
1528 se->string_length = len;
1532 /* Create a symbol node for this intrinsic. The symbol from the frontend
1533 has the generic name. */
1536 gfc_get_symbol_for_expr (gfc_expr * expr)
1540 /* TODO: Add symbols for intrinsic function to the global namespace. */
1541 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1542 sym = gfc_new_symbol (expr->value.function.name, NULL);
1545 sym->attr.external = 1;
1546 sym->attr.function = 1;
1547 sym->attr.always_explicit = 1;
1548 sym->attr.proc = PROC_INTRINSIC;
1549 sym->attr.flavor = FL_PROCEDURE;
1553 sym->attr.dimension = 1;
1554 sym->as = gfc_get_array_spec ();
1555 sym->as->type = AS_ASSUMED_SHAPE;
1556 sym->as->rank = expr->rank;
1559 /* TODO: proper argument lists for external intrinsics. */
1563 /* Generate a call to an external intrinsic function. */
1565 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1570 gcc_assert (!se->ss || se->ss->expr == expr);
1573 gcc_assert (expr->rank > 0);
1575 gcc_assert (expr->rank == 0);
1577 sym = gfc_get_symbol_for_expr (expr);
1579 /* Calls to libgfortran_matmul need to be appended special arguments,
1580 to be able to call the BLAS ?gemm functions if required and possible. */
1581 append_args = NULL_TREE;
1582 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1583 && sym->ts.type != BT_LOGICAL)
1585 tree cint = gfc_get_int_type (gfc_c_int_kind);
1587 if (gfc_option.flag_external_blas
1588 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1589 && (sym->ts.kind == gfc_default_real_kind
1590 || sym->ts.kind == gfc_default_double_kind))
1594 if (sym->ts.type == BT_REAL)
1596 if (sym->ts.kind == gfc_default_real_kind)
1597 gemm_fndecl = gfor_fndecl_sgemm;
1599 gemm_fndecl = gfor_fndecl_dgemm;
1603 if (sym->ts.kind == gfc_default_real_kind)
1604 gemm_fndecl = gfor_fndecl_cgemm;
1606 gemm_fndecl = gfor_fndecl_zgemm;
1609 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1610 append_args = gfc_chainon_list
1611 (append_args, build_int_cst
1612 (cint, gfc_option.blas_matmul_limit));
1613 append_args = gfc_chainon_list (append_args,
1614 gfc_build_addr_expr (NULL_TREE,
1619 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1620 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1621 append_args = gfc_chainon_list (append_args, null_pointer_node);
1625 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1629 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1649 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1658 gfc_actual_arglist *actual;
1665 gfc_conv_intrinsic_funcall (se, expr);
1669 actual = expr->value.function.actual;
1670 type = gfc_typenode_for_spec (&expr->ts);
1671 /* Initialize the result. */
1672 resvar = gfc_create_var (type, "test");
1674 tmp = convert (type, boolean_true_node);
1676 tmp = convert (type, boolean_false_node);
1677 gfc_add_modify_expr (&se->pre, resvar, tmp);
1679 /* Walk the arguments. */
1680 arrayss = gfc_walk_expr (actual->expr);
1681 gcc_assert (arrayss != gfc_ss_terminator);
1683 /* Initialize the scalarizer. */
1684 gfc_init_loopinfo (&loop);
1685 exit_label = gfc_build_label_decl (NULL_TREE);
1686 TREE_USED (exit_label) = 1;
1687 gfc_add_ss_to_loop (&loop, arrayss);
1689 /* Initialize the loop. */
1690 gfc_conv_ss_startstride (&loop);
1691 gfc_conv_loop_setup (&loop);
1693 gfc_mark_ss_chain_used (arrayss, 1);
1694 /* Generate the loop body. */
1695 gfc_start_scalarized_body (&loop, &body);
1697 /* If the condition matches then set the return value. */
1698 gfc_start_block (&block);
1700 tmp = convert (type, boolean_false_node);
1702 tmp = convert (type, boolean_true_node);
1703 gfc_add_modify_expr (&block, resvar, tmp);
1705 /* And break out of the loop. */
1706 tmp = build1_v (GOTO_EXPR, exit_label);
1707 gfc_add_expr_to_block (&block, tmp);
1709 found = gfc_finish_block (&block);
1711 /* Check this element. */
1712 gfc_init_se (&arrayse, NULL);
1713 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1714 arrayse.ss = arrayss;
1715 gfc_conv_expr_val (&arrayse, actual->expr);
1717 gfc_add_block_to_block (&body, &arrayse.pre);
1718 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1719 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1720 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1721 gfc_add_expr_to_block (&body, tmp);
1722 gfc_add_block_to_block (&body, &arrayse.post);
1724 gfc_trans_scalarizing_loops (&loop, &body);
1726 /* Add the exit label. */
1727 tmp = build1_v (LABEL_EXPR, exit_label);
1728 gfc_add_expr_to_block (&loop.pre, tmp);
1730 gfc_add_block_to_block (&se->pre, &loop.pre);
1731 gfc_add_block_to_block (&se->pre, &loop.post);
1732 gfc_cleanup_loop (&loop);
1737 /* COUNT(A) = Number of true elements in A. */
1739 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1746 gfc_actual_arglist *actual;
1752 gfc_conv_intrinsic_funcall (se, expr);
1756 actual = expr->value.function.actual;
1758 type = gfc_typenode_for_spec (&expr->ts);
1759 /* Initialize the result. */
1760 resvar = gfc_create_var (type, "count");
1761 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1763 /* Walk the arguments. */
1764 arrayss = gfc_walk_expr (actual->expr);
1765 gcc_assert (arrayss != gfc_ss_terminator);
1767 /* Initialize the scalarizer. */
1768 gfc_init_loopinfo (&loop);
1769 gfc_add_ss_to_loop (&loop, arrayss);
1771 /* Initialize the loop. */
1772 gfc_conv_ss_startstride (&loop);
1773 gfc_conv_loop_setup (&loop);
1775 gfc_mark_ss_chain_used (arrayss, 1);
1776 /* Generate the loop body. */
1777 gfc_start_scalarized_body (&loop, &body);
1779 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1780 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1781 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1783 gfc_init_se (&arrayse, NULL);
1784 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1785 arrayse.ss = arrayss;
1786 gfc_conv_expr_val (&arrayse, actual->expr);
1787 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1789 gfc_add_block_to_block (&body, &arrayse.pre);
1790 gfc_add_expr_to_block (&body, tmp);
1791 gfc_add_block_to_block (&body, &arrayse.post);
1793 gfc_trans_scalarizing_loops (&loop, &body);
1795 gfc_add_block_to_block (&se->pre, &loop.pre);
1796 gfc_add_block_to_block (&se->pre, &loop.post);
1797 gfc_cleanup_loop (&loop);
1802 /* Inline implementation of the sum and product intrinsics. */
1804 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1812 gfc_actual_arglist *actual;
1817 gfc_expr *arrayexpr;
1822 gfc_conv_intrinsic_funcall (se, expr);
1826 type = gfc_typenode_for_spec (&expr->ts);
1827 /* Initialize the result. */
1828 resvar = gfc_create_var (type, "val");
1829 if (op == PLUS_EXPR)
1830 tmp = gfc_build_const (type, integer_zero_node);
1832 tmp = gfc_build_const (type, integer_one_node);
1834 gfc_add_modify_expr (&se->pre, resvar, tmp);
1836 /* Walk the arguments. */
1837 actual = expr->value.function.actual;
1838 arrayexpr = actual->expr;
1839 arrayss = gfc_walk_expr (arrayexpr);
1840 gcc_assert (arrayss != gfc_ss_terminator);
1842 actual = actual->next->next;
1843 gcc_assert (actual);
1844 maskexpr = actual->expr;
1845 if (maskexpr && maskexpr->rank != 0)
1847 maskss = gfc_walk_expr (maskexpr);
1848 gcc_assert (maskss != gfc_ss_terminator);
1853 /* Initialize the scalarizer. */
1854 gfc_init_loopinfo (&loop);
1855 gfc_add_ss_to_loop (&loop, arrayss);
1857 gfc_add_ss_to_loop (&loop, maskss);
1859 /* Initialize the loop. */
1860 gfc_conv_ss_startstride (&loop);
1861 gfc_conv_loop_setup (&loop);
1863 gfc_mark_ss_chain_used (arrayss, 1);
1865 gfc_mark_ss_chain_used (maskss, 1);
1866 /* Generate the loop body. */
1867 gfc_start_scalarized_body (&loop, &body);
1869 /* If we have a mask, only add this element if the mask is set. */
1872 gfc_init_se (&maskse, NULL);
1873 gfc_copy_loopinfo_to_se (&maskse, &loop);
1875 gfc_conv_expr_val (&maskse, maskexpr);
1876 gfc_add_block_to_block (&body, &maskse.pre);
1878 gfc_start_block (&block);
1881 gfc_init_block (&block);
1883 /* Do the actual summation/product. */
1884 gfc_init_se (&arrayse, NULL);
1885 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1886 arrayse.ss = arrayss;
1887 gfc_conv_expr_val (&arrayse, arrayexpr);
1888 gfc_add_block_to_block (&block, &arrayse.pre);
1890 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1891 gfc_add_modify_expr (&block, resvar, tmp);
1892 gfc_add_block_to_block (&block, &arrayse.post);
1896 /* We enclose the above in if (mask) {...} . */
1897 tmp = gfc_finish_block (&block);
1899 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1902 tmp = gfc_finish_block (&block);
1903 gfc_add_expr_to_block (&body, tmp);
1905 gfc_trans_scalarizing_loops (&loop, &body);
1907 /* For a scalar mask, enclose the loop in an if statement. */
1908 if (maskexpr && maskss == NULL)
1910 gfc_init_se (&maskse, NULL);
1911 gfc_conv_expr_val (&maskse, maskexpr);
1912 gfc_init_block (&block);
1913 gfc_add_block_to_block (&block, &loop.pre);
1914 gfc_add_block_to_block (&block, &loop.post);
1915 tmp = gfc_finish_block (&block);
1917 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1918 gfc_add_expr_to_block (&block, tmp);
1919 gfc_add_block_to_block (&se->pre, &block);
1923 gfc_add_block_to_block (&se->pre, &loop.pre);
1924 gfc_add_block_to_block (&se->pre, &loop.post);
1927 gfc_cleanup_loop (&loop);
1933 /* Inline implementation of the dot_product intrinsic. This function
1934 is based on gfc_conv_intrinsic_arith (the previous function). */
1936 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1944 gfc_actual_arglist *actual;
1945 gfc_ss *arrayss1, *arrayss2;
1946 gfc_se arrayse1, arrayse2;
1947 gfc_expr *arrayexpr1, *arrayexpr2;
1949 type = gfc_typenode_for_spec (&expr->ts);
1951 /* Initialize the result. */
1952 resvar = gfc_create_var (type, "val");
1953 if (expr->ts.type == BT_LOGICAL)
1954 tmp = build_int_cst (type, 0);
1956 tmp = gfc_build_const (type, integer_zero_node);
1958 gfc_add_modify_expr (&se->pre, resvar, tmp);
1960 /* Walk argument #1. */
1961 actual = expr->value.function.actual;
1962 arrayexpr1 = actual->expr;
1963 arrayss1 = gfc_walk_expr (arrayexpr1);
1964 gcc_assert (arrayss1 != gfc_ss_terminator);
1966 /* Walk argument #2. */
1967 actual = actual->next;
1968 arrayexpr2 = actual->expr;
1969 arrayss2 = gfc_walk_expr (arrayexpr2);
1970 gcc_assert (arrayss2 != gfc_ss_terminator);
1972 /* Initialize the scalarizer. */
1973 gfc_init_loopinfo (&loop);
1974 gfc_add_ss_to_loop (&loop, arrayss1);
1975 gfc_add_ss_to_loop (&loop, arrayss2);
1977 /* Initialize the loop. */
1978 gfc_conv_ss_startstride (&loop);
1979 gfc_conv_loop_setup (&loop);
1981 gfc_mark_ss_chain_used (arrayss1, 1);
1982 gfc_mark_ss_chain_used (arrayss2, 1);
1984 /* Generate the loop body. */
1985 gfc_start_scalarized_body (&loop, &body);
1986 gfc_init_block (&block);
1988 /* Make the tree expression for [conjg(]array1[)]. */
1989 gfc_init_se (&arrayse1, NULL);
1990 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1991 arrayse1.ss = arrayss1;
1992 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1993 if (expr->ts.type == BT_COMPLEX)
1994 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
1995 gfc_add_block_to_block (&block, &arrayse1.pre);
1997 /* Make the tree expression for array2. */
1998 gfc_init_se (&arrayse2, NULL);
1999 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2000 arrayse2.ss = arrayss2;
2001 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2002 gfc_add_block_to_block (&block, &arrayse2.pre);
2004 /* Do the actual product and sum. */
2005 if (expr->ts.type == BT_LOGICAL)
2007 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2008 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2012 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2013 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2015 gfc_add_modify_expr (&block, resvar, tmp);
2017 /* Finish up the loop block and the loop. */
2018 tmp = gfc_finish_block (&block);
2019 gfc_add_expr_to_block (&body, tmp);
2021 gfc_trans_scalarizing_loops (&loop, &body);
2022 gfc_add_block_to_block (&se->pre, &loop.pre);
2023 gfc_add_block_to_block (&se->pre, &loop.post);
2024 gfc_cleanup_loop (&loop);
2031 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
2035 stmtblock_t ifblock;
2036 stmtblock_t elseblock;
2044 gfc_actual_arglist *actual;
2049 gfc_expr *arrayexpr;
2056 gfc_conv_intrinsic_funcall (se, expr);
2060 /* Initialize the result. */
2061 pos = gfc_create_var (gfc_array_index_type, "pos");
2062 offset = gfc_create_var (gfc_array_index_type, "offset");
2063 type = gfc_typenode_for_spec (&expr->ts);
2065 /* Walk the arguments. */
2066 actual = expr->value.function.actual;
2067 arrayexpr = actual->expr;
2068 arrayss = gfc_walk_expr (arrayexpr);
2069 gcc_assert (arrayss != gfc_ss_terminator);
2071 actual = actual->next->next;
2072 gcc_assert (actual);
2073 maskexpr = actual->expr;
2074 if (maskexpr && maskexpr->rank != 0)
2076 maskss = gfc_walk_expr (maskexpr);
2077 gcc_assert (maskss != gfc_ss_terminator);
2082 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2083 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2084 switch (arrayexpr->ts.type)
2087 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
2091 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2092 arrayexpr->ts.kind);
2099 /* We start with the most negative possible value for MAXLOC, and the most
2100 positive possible value for MINLOC. The most negative possible value is
2101 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2102 possible value is HUGE in both cases. */
2104 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2105 gfc_add_modify_expr (&se->pre, limit, tmp);
2107 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2108 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2109 build_int_cst (type, 1));
2111 /* Initialize the scalarizer. */
2112 gfc_init_loopinfo (&loop);
2113 gfc_add_ss_to_loop (&loop, arrayss);
2115 gfc_add_ss_to_loop (&loop, maskss);
2117 /* Initialize the loop. */
2118 gfc_conv_ss_startstride (&loop);
2119 gfc_conv_loop_setup (&loop);
2121 gcc_assert (loop.dimen == 1);
2123 /* Initialize the position to zero, following Fortran 2003. We are free
2124 to do this because Fortran 95 allows the result of an entirely false
2125 mask to be processor dependent. */
2126 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2128 gfc_mark_ss_chain_used (arrayss, 1);
2130 gfc_mark_ss_chain_used (maskss, 1);
2131 /* Generate the loop body. */
2132 gfc_start_scalarized_body (&loop, &body);
2134 /* If we have a mask, only check this element if the mask is set. */
2137 gfc_init_se (&maskse, NULL);
2138 gfc_copy_loopinfo_to_se (&maskse, &loop);
2140 gfc_conv_expr_val (&maskse, maskexpr);
2141 gfc_add_block_to_block (&body, &maskse.pre);
2143 gfc_start_block (&block);
2146 gfc_init_block (&block);
2148 /* Compare with the current limit. */
2149 gfc_init_se (&arrayse, NULL);
2150 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2151 arrayse.ss = arrayss;
2152 gfc_conv_expr_val (&arrayse, arrayexpr);
2153 gfc_add_block_to_block (&block, &arrayse.pre);
2155 /* We do the following if this is a more extreme value. */
2156 gfc_start_block (&ifblock);
2158 /* Assign the value to the limit... */
2159 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2161 /* Remember where we are. An offset must be added to the loop
2162 counter to obtain the required position. */
2164 tmp = build_int_cst (gfc_array_index_type, 1);
2166 tmp =fold_build2 (MINUS_EXPR, gfc_array_index_type,
2167 gfc_index_one_node, loop.from[0]);
2168 gfc_add_modify_expr (&block, offset, tmp);
2170 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2171 loop.loopvar[0], offset);
2172 gfc_add_modify_expr (&ifblock, pos, tmp);
2174 ifbody = gfc_finish_block (&ifblock);
2176 /* If it is a more extreme value or pos is still zero and the value
2177 equal to the limit. */
2178 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2179 fold_build2 (EQ_EXPR, boolean_type_node,
2180 pos, gfc_index_zero_node),
2181 fold_build2 (EQ_EXPR, boolean_type_node,
2182 arrayse.expr, limit));
2183 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2184 fold_build2 (op, boolean_type_node,
2185 arrayse.expr, limit), tmp);
2186 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2187 gfc_add_expr_to_block (&block, tmp);
2191 /* We enclose the above in if (mask) {...}. */
2192 tmp = gfc_finish_block (&block);
2194 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2197 tmp = gfc_finish_block (&block);
2198 gfc_add_expr_to_block (&body, tmp);
2200 gfc_trans_scalarizing_loops (&loop, &body);
2202 /* For a scalar mask, enclose the loop in an if statement. */
2203 if (maskexpr && maskss == NULL)
2205 gfc_init_se (&maskse, NULL);
2206 gfc_conv_expr_val (&maskse, maskexpr);
2207 gfc_init_block (&block);
2208 gfc_add_block_to_block (&block, &loop.pre);
2209 gfc_add_block_to_block (&block, &loop.post);
2210 tmp = gfc_finish_block (&block);
2212 /* For the else part of the scalar mask, just initialize
2213 the pos variable the same way as above. */
2215 gfc_init_block (&elseblock);
2216 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2217 elsetmp = gfc_finish_block (&elseblock);
2219 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2220 gfc_add_expr_to_block (&block, tmp);
2221 gfc_add_block_to_block (&se->pre, &block);
2225 gfc_add_block_to_block (&se->pre, &loop.pre);
2226 gfc_add_block_to_block (&se->pre, &loop.post);
2228 gfc_cleanup_loop (&loop);
2230 se->expr = convert (type, pos);
2234 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2243 gfc_actual_arglist *actual;
2248 gfc_expr *arrayexpr;
2254 gfc_conv_intrinsic_funcall (se, expr);
2258 type = gfc_typenode_for_spec (&expr->ts);
2259 /* Initialize the result. */
2260 limit = gfc_create_var (type, "limit");
2261 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2262 switch (expr->ts.type)
2265 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2269 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2276 /* We start with the most negative possible value for MAXVAL, and the most
2277 positive possible value for MINVAL. The most negative possible value is
2278 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2279 possible value is HUGE in both cases. */
2281 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2283 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2284 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2285 tmp, build_int_cst (type, 1));
2287 gfc_add_modify_expr (&se->pre, limit, tmp);
2289 /* Walk the arguments. */
2290 actual = expr->value.function.actual;
2291 arrayexpr = actual->expr;
2292 arrayss = gfc_walk_expr (arrayexpr);
2293 gcc_assert (arrayss != gfc_ss_terminator);
2295 actual = actual->next->next;
2296 gcc_assert (actual);
2297 maskexpr = actual->expr;
2298 if (maskexpr && maskexpr->rank != 0)
2300 maskss = gfc_walk_expr (maskexpr);
2301 gcc_assert (maskss != gfc_ss_terminator);
2306 /* Initialize the scalarizer. */
2307 gfc_init_loopinfo (&loop);
2308 gfc_add_ss_to_loop (&loop, arrayss);
2310 gfc_add_ss_to_loop (&loop, maskss);
2312 /* Initialize the loop. */
2313 gfc_conv_ss_startstride (&loop);
2314 gfc_conv_loop_setup (&loop);
2316 gfc_mark_ss_chain_used (arrayss, 1);
2318 gfc_mark_ss_chain_used (maskss, 1);
2319 /* Generate the loop body. */
2320 gfc_start_scalarized_body (&loop, &body);
2322 /* If we have a mask, only add this element if the mask is set. */
2325 gfc_init_se (&maskse, NULL);
2326 gfc_copy_loopinfo_to_se (&maskse, &loop);
2328 gfc_conv_expr_val (&maskse, maskexpr);
2329 gfc_add_block_to_block (&body, &maskse.pre);
2331 gfc_start_block (&block);
2334 gfc_init_block (&block);
2336 /* Compare with the current limit. */
2337 gfc_init_se (&arrayse, NULL);
2338 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2339 arrayse.ss = arrayss;
2340 gfc_conv_expr_val (&arrayse, arrayexpr);
2341 gfc_add_block_to_block (&block, &arrayse.pre);
2343 /* Assign the value to the limit... */
2344 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2346 /* If it is a more extreme value. */
2347 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2348 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2349 gfc_add_expr_to_block (&block, tmp);
2350 gfc_add_block_to_block (&block, &arrayse.post);
2352 tmp = gfc_finish_block (&block);
2354 /* We enclose the above in if (mask) {...}. */
2355 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2356 gfc_add_expr_to_block (&body, tmp);
2358 gfc_trans_scalarizing_loops (&loop, &body);
2360 /* For a scalar mask, enclose the loop in an if statement. */
2361 if (maskexpr && maskss == NULL)
2363 gfc_init_se (&maskse, NULL);
2364 gfc_conv_expr_val (&maskse, maskexpr);
2365 gfc_init_block (&block);
2366 gfc_add_block_to_block (&block, &loop.pre);
2367 gfc_add_block_to_block (&block, &loop.post);
2368 tmp = gfc_finish_block (&block);
2370 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2371 gfc_add_expr_to_block (&block, tmp);
2372 gfc_add_block_to_block (&se->pre, &block);
2376 gfc_add_block_to_block (&se->pre, &loop.pre);
2377 gfc_add_block_to_block (&se->pre, &loop.post);
2380 gfc_cleanup_loop (&loop);
2385 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2387 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2393 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2394 type = TREE_TYPE (args[0]);
2396 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2397 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2398 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2399 build_int_cst (type, 0));
2400 type = gfc_typenode_for_spec (&expr->ts);
2401 se->expr = convert (type, tmp);
2404 /* Generate code to perform the specified operation. */
2406 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2410 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2411 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2416 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2420 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2421 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2424 /* Set or clear a single bit. */
2426 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2433 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2434 type = TREE_TYPE (args[0]);
2436 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2442 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2444 se->expr = fold_build2 (op, type, args[0], tmp);
2447 /* Extract a sequence of bits.
2448 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2450 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2457 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2458 type = TREE_TYPE (args[0]);
2460 mask = build_int_cst (type, -1);
2461 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2462 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2464 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2466 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2469 /* RSHIFT (I, SHIFT) = I >> SHIFT
2470 LSHIFT (I, SHIFT) = I << SHIFT */
2472 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2476 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2478 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2479 TREE_TYPE (args[0]), args[0], args[1]);
2482 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2484 : ((shift >= 0) ? i << shift : i >> -shift)
2485 where all shifts are logical shifts. */
2487 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2499 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2500 type = TREE_TYPE (args[0]);
2501 utype = unsigned_type_for (type);
2503 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2505 /* Left shift if positive. */
2506 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2508 /* Right shift if negative.
2509 We convert to an unsigned type because we want a logical shift.
2510 The standard doesn't define the case of shifting negative
2511 numbers, and we try to be compatible with other compilers, most
2512 notably g77, here. */
2513 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2514 convert (utype, args[0]), width));
2516 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2517 build_int_cst (TREE_TYPE (args[1]), 0));
2518 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2520 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2521 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2523 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2524 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2526 se->expr = fold_build3 (COND_EXPR, type, cond,
2527 build_int_cst (type, 0), tmp);
2531 /* Circular shift. AKA rotate or barrel shift. */
2534 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2542 unsigned int num_args;
2544 num_args = gfc_intrinsic_argument_list_length (expr);
2545 args = alloca (sizeof (tree) * num_args);
2547 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2551 /* Use a library function for the 3 parameter version. */
2552 tree int4type = gfc_get_int_type (4);
2554 type = TREE_TYPE (args[0]);
2555 /* We convert the first argument to at least 4 bytes, and
2556 convert back afterwards. This removes the need for library
2557 functions for all argument sizes, and function will be
2558 aligned to at least 32 bits, so there's no loss. */
2559 if (expr->ts.kind < 4)
2560 args[0] = convert (int4type, args[0]);
2562 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2563 need loads of library functions. They cannot have values >
2564 BIT_SIZE (I) so the conversion is safe. */
2565 args[1] = convert (int4type, args[1]);
2566 args[2] = convert (int4type, args[2]);
2568 switch (expr->ts.kind)
2573 tmp = gfor_fndecl_math_ishftc4;
2576 tmp = gfor_fndecl_math_ishftc8;
2579 tmp = gfor_fndecl_math_ishftc16;
2584 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2585 /* Convert the result back to the original type, if we extended
2586 the first argument's width above. */
2587 if (expr->ts.kind < 4)
2588 se->expr = convert (type, se->expr);
2592 type = TREE_TYPE (args[0]);
2594 /* Rotate left if positive. */
2595 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2597 /* Rotate right if negative. */
2598 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2599 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2601 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2602 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2603 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2605 /* Do nothing if shift == 0. */
2606 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2607 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2610 /* The length of a character string. */
2612 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2622 gcc_assert (!se->ss);
2624 arg = expr->value.function.actual->expr;
2626 type = gfc_typenode_for_spec (&expr->ts);
2627 switch (arg->expr_type)
2630 len = build_int_cst (NULL_TREE, arg->value.character.length);
2634 /* Obtain the string length from the function used by
2635 trans-array.c(gfc_trans_array_constructor). */
2637 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2641 if (arg->ref == NULL
2642 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2644 /* This doesn't catch all cases.
2645 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2646 and the surrounding thread. */
2647 sym = arg->symtree->n.sym;
2648 decl = gfc_get_symbol_decl (sym);
2649 if (decl == current_function_decl && sym->attr.function
2650 && (sym->result == sym))
2651 decl = gfc_get_fake_result_decl (sym, 0);
2653 len = sym->ts.cl->backend_decl;
2658 /* Otherwise fall through. */
2661 /* Anybody stupid enough to do this deserves inefficient code. */
2662 ss = gfc_walk_expr (arg);
2663 gfc_init_se (&argse, se);
2664 if (ss == gfc_ss_terminator)
2665 gfc_conv_expr (&argse, arg);
2667 gfc_conv_expr_descriptor (&argse, arg, ss);
2668 gfc_add_block_to_block (&se->pre, &argse.pre);
2669 gfc_add_block_to_block (&se->post, &argse.post);
2670 len = argse.string_length;
2673 se->expr = convert (type, len);
2676 /* The length of a character string not including trailing blanks. */
2678 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2683 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2684 type = gfc_typenode_for_spec (&expr->ts);
2685 se->expr = build_call_expr (gfor_fndecl_string_len_trim, 2, args[0], args[1]);
2686 se->expr = convert (type, se->expr);
2690 /* Returns the starting position of a substring within a string. */
2693 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2696 tree logical4_type_node = gfc_get_logical_type (4);
2700 unsigned int num_args;
2702 num_args = gfc_intrinsic_argument_list_length (expr);
2703 args = alloca (sizeof (tree) * 5);
2705 gfc_conv_intrinsic_function_args (se, expr, args,
2706 num_args >= 5 ? 5 : num_args);
2707 type = gfc_typenode_for_spec (&expr->ts);
2710 args[4] = build_int_cst (logical4_type_node, 0);
2712 args[4] = convert (logical4_type_node, args[4]);
2714 fndecl = build_addr (function, current_function_decl);
2715 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
2717 se->expr = convert (type, se->expr);
2721 /* The ascii value for a single character. */
2723 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2728 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2729 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
2730 args[1] = fold_build1 (NOP_EXPR, pchar_type_node, args[1]);
2731 type = gfc_typenode_for_spec (&expr->ts);
2733 se->expr = build_fold_indirect_ref (args[1]);
2734 se->expr = convert (type, se->expr);
2738 /* Intrinsic ISNAN calls __builtin_isnan. */
2741 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
2745 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2746 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
2747 STRIP_TYPE_NOPS (se->expr);
2748 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2752 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
2753 their argument against a constant integer value. */
2756 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
2760 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2761 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
2762 arg, build_int_cst (TREE_TYPE (arg), value));
2767 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2770 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2778 unsigned int num_args;
2780 num_args = gfc_intrinsic_argument_list_length (expr);
2781 args = alloca (sizeof (tree) * num_args);
2783 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2784 if (expr->ts.type != BT_CHARACTER)
2792 /* We do the same as in the non-character case, but the argument
2793 list is different because of the string length arguments. We
2794 also have to set the string length for the result. */
2800 se->string_length = len;
2802 type = TREE_TYPE (tsource);
2803 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2807 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
2809 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
2811 tree arg, type, tmp;
2814 switch (expr->ts.kind)
2817 frexp = BUILT_IN_FREXPF;
2820 frexp = BUILT_IN_FREXP;
2824 frexp = BUILT_IN_FREXPL;
2830 type = gfc_typenode_for_spec (&expr->ts);
2831 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2832 tmp = gfc_create_var (integer_type_node, NULL);
2833 se->expr = build_call_expr (built_in_decls[frexp], 2,
2834 fold_convert (type, arg),
2835 build_fold_addr_expr (tmp));
2836 se->expr = fold_convert (type, se->expr);
2840 /* NEAREST (s, dir) is translated into
2841 tmp = copysign (INF, dir);
2842 return nextafter (s, tmp);
2845 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
2847 tree args[2], type, tmp;
2848 int nextafter, copysign, inf;
2850 switch (expr->ts.kind)
2853 nextafter = BUILT_IN_NEXTAFTERF;
2854 copysign = BUILT_IN_COPYSIGNF;
2855 inf = BUILT_IN_INFF;
2858 nextafter = BUILT_IN_NEXTAFTER;
2859 copysign = BUILT_IN_COPYSIGN;
2864 nextafter = BUILT_IN_NEXTAFTERL;
2865 copysign = BUILT_IN_COPYSIGNL;
2866 inf = BUILT_IN_INFL;
2872 type = gfc_typenode_for_spec (&expr->ts);
2873 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2874 tmp = build_call_expr (built_in_decls[copysign], 2,
2875 build_call_expr (built_in_decls[inf], 0),
2876 fold_convert (type, args[1]));
2877 se->expr = build_call_expr (built_in_decls[nextafter], 2,
2878 fold_convert (type, args[0]), tmp);
2879 se->expr = fold_convert (type, se->expr);
2883 /* SPACING (s) is translated into
2891 e = MAX_EXPR (e, emin);
2892 res = scalbn (1., e);
2896 where prec is the precision of s, gfc_real_kinds[k].digits,
2897 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
2898 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
2901 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2903 tree arg, type, prec, emin, tiny, res, e;
2905 int frexp, scalbn, k;
2908 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
2909 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
2910 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
2911 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind);
2913 switch (expr->ts.kind)
2916 frexp = BUILT_IN_FREXPF;
2917 scalbn = BUILT_IN_SCALBNF;
2920 frexp = BUILT_IN_FREXP;
2921 scalbn = BUILT_IN_SCALBN;
2925 frexp = BUILT_IN_FREXPL;
2926 scalbn = BUILT_IN_SCALBNL;
2932 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2933 arg = gfc_evaluate_now (arg, &se->pre);
2935 type = gfc_typenode_for_spec (&expr->ts);
2936 e = gfc_create_var (integer_type_node, NULL);
2937 res = gfc_create_var (type, NULL);
2940 /* Build the block for s /= 0. */
2941 gfc_start_block (&block);
2942 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
2943 build_fold_addr_expr (e));
2944 gfc_add_expr_to_block (&block, tmp);
2946 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
2947 gfc_add_modify_expr (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
2950 tmp = build_call_expr (built_in_decls[scalbn], 2,
2951 build_real_from_int_cst (type, integer_one_node), e);
2952 gfc_add_modify_expr (&block, res, tmp);
2954 /* Finish by building the IF statement. */
2955 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
2956 build_real_from_int_cst (type, integer_zero_node));
2957 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
2958 gfc_finish_block (&block));
2960 gfc_add_expr_to_block (&se->pre, tmp);
2965 /* RRSPACING (s) is translated into
2972 x = scalbn (x, precision - e);
2976 where precision is gfc_real_kinds[k].digits. */
2979 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2981 tree arg, type, e, x, cond, stmt, tmp;
2982 int frexp, scalbn, fabs, prec, k;
2985 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
2986 prec = gfc_real_kinds[k].digits;
2987 switch (expr->ts.kind)
2990 frexp = BUILT_IN_FREXPF;
2991 scalbn = BUILT_IN_SCALBNF;
2992 fabs = BUILT_IN_FABSF;
2995 frexp = BUILT_IN_FREXP;
2996 scalbn = BUILT_IN_SCALBN;
2997 fabs = BUILT_IN_FABS;
3001 frexp = BUILT_IN_FREXPL;
3002 scalbn = BUILT_IN_SCALBNL;
3003 fabs = BUILT_IN_FABSL;
3009 type = gfc_typenode_for_spec (&expr->ts);
3010 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3011 arg = gfc_evaluate_now (arg, &se->pre);
3013 e = gfc_create_var (integer_type_node, NULL);
3014 x = gfc_create_var (type, NULL);
3015 gfc_add_modify_expr (&se->pre, x,
3016 build_call_expr (built_in_decls[fabs], 1, arg));
3019 gfc_start_block (&block);
3020 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3021 build_fold_addr_expr (e));
3022 gfc_add_expr_to_block (&block, tmp);
3024 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3025 build_int_cst (NULL_TREE, prec), e);
3026 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3027 gfc_add_modify_expr (&block, x, tmp);
3028 stmt = gfc_finish_block (&block);
3030 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3031 build_real_from_int_cst (type, integer_zero_node));
3032 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3033 gfc_add_expr_to_block (&se->pre, tmp);
3035 se->expr = fold_convert (type, x);
3039 /* SCALE (s, i) is translated into scalbn (s, i). */
3041 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3046 switch (expr->ts.kind)
3049 scalbn = BUILT_IN_SCALBNF;
3052 scalbn = BUILT_IN_SCALBN;
3056 scalbn = BUILT_IN_SCALBNL;
3062 type = gfc_typenode_for_spec (&expr->ts);
3063 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3064 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3065 fold_convert (type, args[0]),
3066 fold_convert (integer_type_node, args[1]));
3067 se->expr = fold_convert (type, se->expr);
3071 /* SET_EXPONENT (s, i) is translated into
3072 scalbn (frexp (s, &dummy_int), i). */
3074 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3076 tree args[2], type, tmp;
3079 switch (expr->ts.kind)
3082 frexp = BUILT_IN_FREXPF;
3083 scalbn = BUILT_IN_SCALBNF;
3086 frexp = BUILT_IN_FREXP;
3087 scalbn = BUILT_IN_SCALBN;
3091 frexp = BUILT_IN_FREXPL;
3092 scalbn = BUILT_IN_SCALBNL;
3098 type = gfc_typenode_for_spec (&expr->ts);
3099 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3101 tmp = gfc_create_var (integer_type_node, NULL);
3102 tmp = build_call_expr (built_in_decls[frexp], 2,
3103 fold_convert (type, args[0]),
3104 build_fold_addr_expr (tmp));
3105 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3106 fold_convert (integer_type_node, args[1]));
3107 se->expr = fold_convert (type, se->expr);
3112 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3114 gfc_actual_arglist *actual;
3122 gfc_init_se (&argse, NULL);
3123 actual = expr->value.function.actual;
3125 ss = gfc_walk_expr (actual->expr);
3126 gcc_assert (ss != gfc_ss_terminator);
3127 argse.want_pointer = 1;
3128 argse.data_not_needed = 1;
3129 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3130 gfc_add_block_to_block (&se->pre, &argse.pre);
3131 gfc_add_block_to_block (&se->post, &argse.post);
3132 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3134 /* Build the call to size0. */
3135 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3137 actual = actual->next;
3141 gfc_init_se (&argse, NULL);
3142 gfc_conv_expr_type (&argse, actual->expr,
3143 gfc_array_index_type);
3144 gfc_add_block_to_block (&se->pre, &argse.pre);
3146 /* Build the call to size1. */
3147 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3150 /* Unusually, for an intrinsic, size does not exclude
3151 an optional arg2, so we must test for it. */
3152 if (actual->expr->expr_type == EXPR_VARIABLE
3153 && actual->expr->symtree->n.sym->attr.dummy
3154 && actual->expr->symtree->n.sym->attr.optional)
3157 gfc_init_se (&argse, NULL);
3158 argse.want_pointer = 1;
3159 argse.data_not_needed = 1;
3160 gfc_conv_expr (&argse, actual->expr);
3161 gfc_add_block_to_block (&se->pre, &argse.pre);
3162 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3163 argse.expr, null_pointer_node);
3164 tmp = gfc_evaluate_now (tmp, &se->pre);
3165 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3166 tmp, fncall1, fncall0);
3174 type = gfc_typenode_for_spec (&expr->ts);
3175 se->expr = convert (type, se->expr);
3180 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3194 arg = expr->value.function.actual->expr;
3196 gfc_init_se (&argse, NULL);
3197 ss = gfc_walk_expr (arg);
3199 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3201 if (ss == gfc_ss_terminator)
3203 gfc_conv_expr_reference (&argse, arg);
3204 source = argse.expr;
3206 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3208 /* Obtain the source word length. */
3209 if (arg->ts.type == BT_CHARACTER)
3210 source_bytes = fold_convert (gfc_array_index_type,
3211 argse.string_length);
3213 source_bytes = fold_convert (gfc_array_index_type,
3214 size_in_bytes (type));
3218 argse.want_pointer = 0;
3219 gfc_conv_expr_descriptor (&argse, arg, ss);
3220 source = gfc_conv_descriptor_data_get (argse.expr);
3221 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3223 /* Obtain the argument's word length. */
3224 if (arg->ts.type == BT_CHARACTER)
3225 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3227 tmp = fold_convert (gfc_array_index_type,
3228 size_in_bytes (type));
3229 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3231 /* Obtain the size of the array in bytes. */
3232 for (n = 0; n < arg->rank; n++)
3235 idx = gfc_rank_cst[n];
3236 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3237 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3238 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3240 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3241 tmp, gfc_index_one_node);
3242 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3244 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3248 gfc_add_block_to_block (&se->pre, &argse.pre);
3249 se->expr = source_bytes;
3253 /* Intrinsic string comparison functions. */
3256 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
3260 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3262 se->expr = gfc_build_compare_string (args[0], args[1], args[2], args[3]);
3263 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3264 build_int_cst (TREE_TYPE (se->expr), 0));
3267 /* Generate a call to the adjustl/adjustr library function. */
3269 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3277 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3280 type = TREE_TYPE (args[2]);
3281 var = gfc_conv_string_tmp (se, type, len);
3284 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3285 gfc_add_expr_to_block (&se->pre, tmp);
3287 se->string_length = len;
3291 /* Array transfer statement.
3292 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3294 typeof<DEST> = typeof<MOLD>
3296 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3297 sizeof (DEST(0) * SIZE). */
3300 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
3315 gfc_actual_arglist *arg;
3322 gcc_assert (se->loop);
3323 info = &se->ss->data.info;
3325 /* Convert SOURCE. The output from this stage is:-
3326 source_bytes = length of the source in bytes
3327 source = pointer to the source data. */
3328 arg = expr->value.function.actual;
3329 gfc_init_se (&argse, NULL);
3330 ss = gfc_walk_expr (arg->expr);
3332 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3334 /* Obtain the pointer to source and the length of source in bytes. */
3335 if (ss == gfc_ss_terminator)
3337 gfc_conv_expr_reference (&argse, arg->expr);
3338 source = argse.expr;
3340 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3342 /* Obtain the source word length. */
3343 if (arg->expr->ts.type == BT_CHARACTER)
3344 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3346 tmp = fold_convert (gfc_array_index_type,
3347 size_in_bytes (source_type));
3351 argse.want_pointer = 0;
3352 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3353 source = gfc_conv_descriptor_data_get (argse.expr);
3354 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3356 /* Repack the source if not a full variable array. */
3357 if (!(arg->expr->expr_type == EXPR_VARIABLE
3358 && arg->expr->ref->u.ar.type == AR_FULL))
3360 tmp = build_fold_addr_expr (argse.expr);
3361 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3362 source = gfc_evaluate_now (source, &argse.pre);
3364 /* Free the temporary. */
3365 gfc_start_block (&block);
3366 tmp = gfc_call_free (convert (pvoid_type_node, source));
3367 gfc_add_expr_to_block (&block, tmp);
3368 stmt = gfc_finish_block (&block);
3370 /* Clean up if it was repacked. */
3371 gfc_init_block (&block);
3372 tmp = gfc_conv_array_data (argse.expr);
3373 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3374 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3375 gfc_add_expr_to_block (&block, tmp);
3376 gfc_add_block_to_block (&block, &se->post);
3377 gfc_init_block (&se->post);
3378 gfc_add_block_to_block (&se->post, &block);
3381 /* Obtain the source word length. */
3382 if (arg->expr->ts.type == BT_CHARACTER)
3383 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3385 tmp = fold_convert (gfc_array_index_type,
3386 size_in_bytes (source_type));
3388 /* Obtain the size of the array in bytes. */
3389 extent = gfc_create_var (gfc_array_index_type, NULL);
3390 for (n = 0; n < arg->expr->rank; n++)
3393 idx = gfc_rank_cst[n];
3394 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3395 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3396 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3397 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3398 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3400 gfc_add_modify_expr (&argse.pre, extent, tmp);
3401 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3402 extent, gfc_index_one_node);
3403 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3408 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3409 gfc_add_block_to_block (&se->pre, &argse.pre);
3410 gfc_add_block_to_block (&se->post, &argse.post);
3412 /* Now convert MOLD. The outputs are:
3413 mold_type = the TREE type of MOLD
3414 dest_word_len = destination word length in bytes. */
3417 gfc_init_se (&argse, NULL);
3418 ss = gfc_walk_expr (arg->expr);
3420 if (ss == gfc_ss_terminator)
3422 gfc_conv_expr_reference (&argse, arg->expr);
3423 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3427 gfc_init_se (&argse, NULL);
3428 argse.want_pointer = 0;
3429 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3430 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3433 if (arg->expr->ts.type == BT_CHARACTER)
3435 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3436 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3439 tmp = fold_convert (gfc_array_index_type,
3440 size_in_bytes (mold_type));
3442 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3443 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
3445 /* Finally convert SIZE, if it is present. */
3447 size_words = gfc_create_var (gfc_array_index_type, NULL);
3451 gfc_init_se (&argse, NULL);
3452 gfc_conv_expr_reference (&argse, arg->expr);
3453 tmp = convert (gfc_array_index_type,
3454 build_fold_indirect_ref (argse.expr));
3455 gfc_add_block_to_block (&se->pre, &argse.pre);
3456 gfc_add_block_to_block (&se->post, &argse.post);
3461 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3462 if (tmp != NULL_TREE)
3464 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3465 tmp, dest_word_len);
3466 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3472 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
3473 gfc_add_modify_expr (&se->pre, size_words,
3474 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3475 size_bytes, dest_word_len));
3477 /* Evaluate the bounds of the result. If the loop range exists, we have
3478 to check if it is too large. If so, we modify loop->to be consistent
3479 with min(size, size(source)). Otherwise, size is made consistent with
3480 the loop range, so that the right number of bytes is transferred.*/
3481 n = se->loop->order[0];
3482 if (se->loop->to[n] != NULL_TREE)
3484 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3485 se->loop->to[n], se->loop->from[n]);
3486 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3487 tmp, gfc_index_one_node);
3488 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3490 gfc_add_modify_expr (&se->pre, size_words, tmp);
3491 gfc_add_modify_expr (&se->pre, size_bytes,
3492 fold_build2 (MULT_EXPR, gfc_array_index_type,
3493 size_words, dest_word_len));
3494 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3495 size_words, se->loop->from[n]);
3496 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3497 upper, gfc_index_one_node);
3501 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3502 size_words, gfc_index_one_node);
3503 se->loop->from[n] = gfc_index_zero_node;
3506 se->loop->to[n] = upper;
3508 /* Build a destination descriptor, using the pointer, source, as the
3509 data field. This is already allocated so set callee_alloc.
3510 FIXME callee_alloc is not set! */
3512 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3513 info, mold_type, false, true, false);
3515 /* Cast the pointer to the result. */
3516 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3517 tmp = fold_convert (pvoid_type_node, tmp);
3519 /* Use memcpy to do the transfer. */
3520 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3523 fold_convert (pvoid_type_node, source),
3525 gfc_add_expr_to_block (&se->pre, tmp);
3527 se->expr = info->descriptor;
3528 if (expr->ts.type == BT_CHARACTER)
3529 se->string_length = dest_word_len;
3533 /* Scalar transfer statement.
3534 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3537 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3539 gfc_actual_arglist *arg;
3546 /* Get a pointer to the source. */
3547 arg = expr->value.function.actual;
3548 ss = gfc_walk_expr (arg->expr);
3549 gfc_init_se (&argse, NULL);
3550 if (ss == gfc_ss_terminator)
3551 gfc_conv_expr_reference (&argse, arg->expr);
3553 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3554 gfc_add_block_to_block (&se->pre, &argse.pre);
3555 gfc_add_block_to_block (&se->post, &argse.post);
3559 type = gfc_typenode_for_spec (&expr->ts);
3561 if (expr->ts.type == BT_CHARACTER)
3563 ptr = convert (build_pointer_type (type), ptr);
3564 gfc_init_se (&argse, NULL);
3565 gfc_conv_expr (&argse, arg->expr);
3566 gfc_add_block_to_block (&se->pre, &argse.pre);
3567 gfc_add_block_to_block (&se->post, &argse.post);
3569 se->string_length = argse.string_length;
3574 tmpdecl = gfc_create_var (type, "transfer");
3575 moldsize = size_in_bytes (type);
3577 /* Use memcpy to do the transfer. */
3578 tmp = fold_build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3579 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3580 fold_convert (pvoid_type_node, tmp),
3581 fold_convert (pvoid_type_node, ptr),
3583 gfc_add_expr_to_block (&se->pre, tmp);
3590 /* Generate code for the ALLOCATED intrinsic.
3591 Generate inline code that directly check the address of the argument. */
3594 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3596 gfc_actual_arglist *arg1;
3601 gfc_init_se (&arg1se, NULL);
3602 arg1 = expr->value.function.actual;
3603 ss1 = gfc_walk_expr (arg1->expr);
3604 arg1se.descriptor_only = 1;
3605 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3607 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3608 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3609 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3610 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3614 /* Generate code for the ASSOCIATED intrinsic.
3615 If both POINTER and TARGET are arrays, generate a call to library function
3616 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3617 In other cases, generate inline code that directly compare the address of
3618 POINTER with the address of TARGET. */
3621 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3623 gfc_actual_arglist *arg1;
3624 gfc_actual_arglist *arg2;
3629 tree nonzero_charlen;
3630 tree nonzero_arraylen;
3633 gfc_init_se (&arg1se, NULL);
3634 gfc_init_se (&arg2se, NULL);
3635 arg1 = expr->value.function.actual;
3637 ss1 = gfc_walk_expr (arg1->expr);
3641 /* No optional target. */
3642 if (ss1 == gfc_ss_terminator)
3644 /* A pointer to a scalar. */
3645 arg1se.want_pointer = 1;
3646 gfc_conv_expr (&arg1se, arg1->expr);
3651 /* A pointer to an array. */
3652 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3653 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3655 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3656 gfc_add_block_to_block (&se->post, &arg1se.post);
3657 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
3658 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3663 /* An optional target. */
3664 ss2 = gfc_walk_expr (arg2->expr);
3666 nonzero_charlen = NULL_TREE;
3667 if (arg1->expr->ts.type == BT_CHARACTER)
3668 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
3669 arg1->expr->ts.cl->backend_decl,
3672 if (ss1 == gfc_ss_terminator)
3674 /* A pointer to a scalar. */
3675 gcc_assert (ss2 == gfc_ss_terminator);
3676 arg1se.want_pointer = 1;
3677 gfc_conv_expr (&arg1se, arg1->expr);
3678 arg2se.want_pointer = 1;
3679 gfc_conv_expr (&arg2se, arg2->expr);
3680 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3681 gfc_add_block_to_block (&se->post, &arg1se.post);
3682 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
3683 arg1se.expr, arg2se.expr);
3684 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
3685 arg1se.expr, null_pointer_node);
3686 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3691 /* An array pointer of zero length is not associated if target is
3693 arg1se.descriptor_only = 1;
3694 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3695 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3696 gfc_rank_cst[arg1->expr->rank - 1]);
3697 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
3698 build_int_cst (TREE_TYPE (tmp), 0));
3700 /* A pointer to an array, call library function _gfor_associated. */
3701 gcc_assert (ss2 != gfc_ss_terminator);
3702 arg1se.want_pointer = 1;
3703 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3705 arg2se.want_pointer = 1;
3706 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3707 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3708 gfc_add_block_to_block (&se->post, &arg2se.post);
3709 se->expr = build_call_expr (gfor_fndecl_associated, 2,
3710 arg1se.expr, arg2se.expr);
3711 se->expr = convert (boolean_type_node, se->expr);
3712 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3713 se->expr, nonzero_arraylen);
3716 /* If target is present zero character length pointers cannot
3718 if (nonzero_charlen != NULL_TREE)
3719 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3720 se->expr, nonzero_charlen);
3723 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3727 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3730 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
3734 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3736 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
3737 type = gfc_get_int_type (4);
3738 arg = build_fold_addr_expr (fold_convert (type, arg));
3740 /* Convert it to the required type. */
3741 type = gfc_typenode_for_spec (&expr->ts);
3742 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
3743 se->expr = fold_convert (type, se->expr);
3747 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3750 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
3752 gfc_actual_arglist *actual;
3757 for (actual = expr->value.function.actual; actual; actual = actual->next)
3759 gfc_init_se (&argse, se);
3761 /* Pass a NULL pointer for an absent arg. */
3762 if (actual->expr == NULL)
3763 argse.expr = null_pointer_node;
3767 if (actual->expr->ts.kind != gfc_c_int_kind)
3769 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
3770 ts.type = BT_INTEGER;
3771 ts.kind = gfc_c_int_kind;
3772 gfc_convert_type (actual->expr, &ts, 2);
3774 gfc_conv_expr_reference (&argse, actual->expr);
3777 gfc_add_block_to_block (&se->pre, &argse.pre);
3778 gfc_add_block_to_block (&se->post, &argse.post);
3779 args = gfc_chainon_list (args, argse.expr);
3782 /* Convert it to the required type. */
3783 type = gfc_typenode_for_spec (&expr->ts);
3784 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3785 se->expr = fold_convert (type, se->expr);
3789 /* Generate code for TRIM (A) intrinsic function. */
3792 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3794 tree gfc_int4_type_node = gfc_get_int_type (4);
3803 unsigned int num_args;
3805 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
3806 args = alloca (sizeof (tree) * num_args);
3808 type = build_pointer_type (gfc_character1_type_node);
3809 var = gfc_create_var (type, "pstr");
3810 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3811 len = gfc_create_var (gfc_int4_type_node, "len");
3813 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
3814 args[0] = build_fold_addr_expr (len);
3817 fndecl = build_addr (gfor_fndecl_string_trim, current_function_decl);
3818 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_trim)),
3819 fndecl, num_args, args);
3820 gfc_add_expr_to_block (&se->pre, tmp);
3822 /* Free the temporary afterwards, if necessary. */
3823 cond = fold_build2 (GT_EXPR, boolean_type_node,
3824 len, build_int_cst (TREE_TYPE (len), 0));
3825 tmp = gfc_call_free (var);
3826 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3827 gfc_add_expr_to_block (&se->post, tmp);
3830 se->string_length = len;
3834 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3837 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3839 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
3840 tree type, cond, tmp, count, exit_label, n, max, largest;
3841 stmtblock_t block, body;
3844 /* Get the arguments. */
3845 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3846 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
3848 ncopies = gfc_evaluate_now (args[2], &se->pre);
3849 ncopies_type = TREE_TYPE (ncopies);
3851 /* Check that NCOPIES is not negative. */
3852 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3853 build_int_cst (ncopies_type, 0));
3854 gfc_trans_runtime_check (cond, &se->pre, &expr->where,
3855 "Argument NCOPIES of REPEAT intrinsic is negative "
3856 "(its value is %lld)",
3857 fold_convert (long_integer_type_node, ncopies));
3859 /* If the source length is zero, any non negative value of NCOPIES
3860 is valid, and nothing happens. */
3861 n = gfc_create_var (ncopies_type, "ncopies");
3862 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3863 build_int_cst (size_type_node, 0));
3864 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
3865 build_int_cst (ncopies_type, 0), ncopies);
3866 gfc_add_modify_expr (&se->pre, n, tmp);
3869 /* Check that ncopies is not too large: ncopies should be less than
3870 (or equal to) MAX / slen, where MAX is the maximal integer of
3871 the gfc_charlen_type_node type. If slen == 0, we need a special
3872 case to avoid the division by zero. */
3873 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
3874 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
3875 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
3876 fold_convert (size_type_node, max), slen);
3877 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
3878 ? size_type_node : ncopies_type;
3879 cond = fold_build2 (GT_EXPR, boolean_type_node,
3880 fold_convert (largest, ncopies),
3881 fold_convert (largest, max));
3882 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3883 build_int_cst (size_type_node, 0));
3884 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
3886 gfc_trans_runtime_check (cond, &se->pre, &expr->where,
3887 "Argument NCOPIES of REPEAT intrinsic is too large");
3890 /* Compute the destination length. */
3891 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
3892 fold_convert (gfc_charlen_type_node, slen),
3893 fold_convert (gfc_charlen_type_node, ncopies));
3894 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3895 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
3897 /* Generate the code to do the repeat operation:
3898 for (i = 0; i < ncopies; i++)
3899 memmove (dest + (i * slen), src, slen); */
3900 gfc_start_block (&block);
3901 count = gfc_create_var (ncopies_type, "count");
3902 gfc_add_modify_expr (&block, count, build_int_cst (ncopies_type, 0));
3903 exit_label = gfc_build_label_decl (NULL_TREE);
3905 /* Start the loop body. */
3906 gfc_start_block (&body);
3908 /* Exit the loop if count >= ncopies. */
3909 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
3910 tmp = build1_v (GOTO_EXPR, exit_label);
3911 TREE_USED (exit_label) = 1;
3912 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3913 build_empty_stmt ());
3914 gfc_add_expr_to_block (&body, tmp);
3916 /* Call memmove (dest + (i*slen), src, slen). */
3917 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
3918 fold_convert (gfc_charlen_type_node, slen),
3919 fold_convert (gfc_charlen_type_node, count));
3920 tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node,
3921 fold_convert (pchar_type_node, dest),
3922 fold_convert (sizetype, tmp));
3923 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3,
3925 gfc_add_expr_to_block (&body, tmp);
3927 /* Increment count. */
3928 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
3929 count, build_int_cst (TREE_TYPE (count), 1));
3930 gfc_add_modify_expr (&body, count, tmp);
3932 /* Build the loop. */
3933 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
3934 gfc_add_expr_to_block (&block, tmp);
3936 /* Add the exit label. */
3937 tmp = build1_v (LABEL_EXPR, exit_label);
3938 gfc_add_expr_to_block (&block, tmp);
3940 /* Finish the block. */
3941 tmp = gfc_finish_block (&block);
3942 gfc_add_expr_to_block (&se->pre, tmp);
3944 /* Set the result value. */
3946 se->string_length = dlen;
3950 /* Generate code for the IARGC intrinsic. */
3953 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3959 /* Call the library function. This always returns an INTEGER(4). */
3960 fndecl = gfor_fndecl_iargc;
3961 tmp = build_call_expr (fndecl, 0);
3963 /* Convert it to the required type. */
3964 type = gfc_typenode_for_spec (&expr->ts);
3965 tmp = fold_convert (type, tmp);
3971 /* The loc intrinsic returns the address of its argument as
3972 gfc_index_integer_kind integer. */
3975 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3981 gcc_assert (!se->ss);
3983 arg_expr = expr->value.function.actual->expr;
3984 ss = gfc_walk_expr (arg_expr);
3985 if (ss == gfc_ss_terminator)
3986 gfc_conv_expr_reference (se, arg_expr);
3988 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3989 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
3991 /* Create a temporary variable for loc return value. Without this,
3992 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3993 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
3994 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3995 se->expr = temp_var;
3998 /* Generate code for an intrinsic function. Some map directly to library
3999 calls, others get special handling. In some cases the name of the function
4000 used depends on the type specifiers. */
4003 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4005 gfc_intrinsic_sym *isym;
4009 isym = expr->value.function.isym;
4011 name = &expr->value.function.name[2];
4013 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4015 lib = gfc_is_intrinsic_libcall (expr);
4019 se->ignore_optional = 1;
4020 gfc_conv_intrinsic_funcall (se, expr);
4025 switch (expr->value.function.isym->id)
4030 case GFC_ISYM_REPEAT:
4031 gfc_conv_intrinsic_repeat (se, expr);
4035 gfc_conv_intrinsic_trim (se, expr);
4038 case GFC_ISYM_SI_KIND:
4039 gfc_conv_intrinsic_si_kind (se, expr);
4042 case GFC_ISYM_SR_KIND:
4043 gfc_conv_intrinsic_sr_kind (se, expr);
4046 case GFC_ISYM_EXPONENT:
4047 gfc_conv_intrinsic_exponent (se, expr);
4051 gfc_conv_intrinsic_index_scan_verify (se, expr, gfor_fndecl_string_scan);
4054 case GFC_ISYM_VERIFY:
4055 gfc_conv_intrinsic_index_scan_verify (se, expr, gfor_fndecl_string_verify);
4058 case GFC_ISYM_ALLOCATED:
4059 gfc_conv_allocated (se, expr);
4062 case GFC_ISYM_ASSOCIATED:
4063 gfc_conv_associated(se, expr);
4067 gfc_conv_intrinsic_abs (se, expr);
4070 case GFC_ISYM_ADJUSTL:
4071 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
4074 case GFC_ISYM_ADJUSTR:
4075 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
4078 case GFC_ISYM_AIMAG:
4079 gfc_conv_intrinsic_imagpart (se, expr);
4083 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4087 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4090 case GFC_ISYM_ANINT:
4091 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4095 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4099 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4102 case GFC_ISYM_BTEST:
4103 gfc_conv_intrinsic_btest (se, expr);
4106 case GFC_ISYM_ACHAR:
4108 gfc_conv_intrinsic_char (se, expr);
4111 case GFC_ISYM_CONVERSION:
4113 case GFC_ISYM_LOGICAL:
4115 gfc_conv_intrinsic_conversion (se, expr);
4118 /* Integer conversions are handled separately to make sure we get the
4119 correct rounding mode. */
4124 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4128 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4131 case GFC_ISYM_CEILING:
4132 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4135 case GFC_ISYM_FLOOR:
4136 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4140 gfc_conv_intrinsic_mod (se, expr, 0);
4143 case GFC_ISYM_MODULO:
4144 gfc_conv_intrinsic_mod (se, expr, 1);
4147 case GFC_ISYM_CMPLX:
4148 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4151 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4152 gfc_conv_intrinsic_iargc (se, expr);
4155 case GFC_ISYM_COMPLEX:
4156 gfc_conv_intrinsic_cmplx (se, expr, 1);
4159 case GFC_ISYM_CONJG:
4160 gfc_conv_intrinsic_conjg (se, expr);
4163 case GFC_ISYM_COUNT:
4164 gfc_conv_intrinsic_count (se, expr);
4167 case GFC_ISYM_CTIME:
4168 gfc_conv_intrinsic_ctime (se, expr);
4172 gfc_conv_intrinsic_dim (se, expr);
4175 case GFC_ISYM_DOT_PRODUCT:
4176 gfc_conv_intrinsic_dot_product (se, expr);
4179 case GFC_ISYM_DPROD:
4180 gfc_conv_intrinsic_dprod (se, expr);
4183 case GFC_ISYM_FDATE:
4184 gfc_conv_intrinsic_fdate (se, expr);
4187 case GFC_ISYM_FRACTION:
4188 gfc_conv_intrinsic_fraction (se, expr);
4192 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4195 case GFC_ISYM_IBCLR:
4196 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4199 case GFC_ISYM_IBITS:
4200 gfc_conv_intrinsic_ibits (se, expr);
4203 case GFC_ISYM_IBSET:
4204 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4207 case GFC_ISYM_IACHAR:
4208 case GFC_ISYM_ICHAR:
4209 /* We assume ASCII character sequence. */
4210 gfc_conv_intrinsic_ichar (se, expr);
4213 case GFC_ISYM_IARGC:
4214 gfc_conv_intrinsic_iargc (se, expr);
4218 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4221 case GFC_ISYM_INDEX:
4222 gfc_conv_intrinsic_index_scan_verify (se, expr, gfor_fndecl_string_index);
4226 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4229 case GFC_ISYM_IS_IOSTAT_END:
4230 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4233 case GFC_ISYM_IS_IOSTAT_EOR:
4234 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4237 case GFC_ISYM_ISNAN:
4238 gfc_conv_intrinsic_isnan (se, expr);
4241 case GFC_ISYM_LSHIFT:
4242 gfc_conv_intrinsic_rlshift (se, expr, 0);
4245 case GFC_ISYM_RSHIFT:
4246 gfc_conv_intrinsic_rlshift (se, expr, 1);
4249 case GFC_ISYM_ISHFT:
4250 gfc_conv_intrinsic_ishft (se, expr);
4253 case GFC_ISYM_ISHFTC:
4254 gfc_conv_intrinsic_ishftc (se, expr);
4257 case GFC_ISYM_LBOUND:
4258 gfc_conv_intrinsic_bound (se, expr, 0);
4261 case GFC_ISYM_TRANSPOSE:
4262 if (se->ss && se->ss->useflags)
4264 gfc_conv_tmp_array_ref (se);
4265 gfc_advance_se_ss_chain (se);
4268 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4272 gfc_conv_intrinsic_len (se, expr);
4275 case GFC_ISYM_LEN_TRIM:
4276 gfc_conv_intrinsic_len_trim (se, expr);
4280 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4284 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4288 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4292 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4296 if (expr->ts.type == BT_CHARACTER)
4297 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4299 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4302 case GFC_ISYM_MAXLOC:
4303 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4306 case GFC_ISYM_MAXVAL:
4307 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4310 case GFC_ISYM_MERGE:
4311 gfc_conv_intrinsic_merge (se, expr);
4315 if (expr->ts.type == BT_CHARACTER)
4316 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4318 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4321 case GFC_ISYM_MINLOC:
4322 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4325 case GFC_ISYM_MINVAL:
4326 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4329 case GFC_ISYM_NEAREST:
4330 gfc_conv_intrinsic_nearest (se, expr);
4334 gfc_conv_intrinsic_not (se, expr);
4338 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4341 case GFC_ISYM_PRESENT:
4342 gfc_conv_intrinsic_present (se, expr);
4345 case GFC_ISYM_PRODUCT:
4346 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4349 case GFC_ISYM_RRSPACING:
4350 gfc_conv_intrinsic_rrspacing (se, expr);
4353 case GFC_ISYM_SET_EXPONENT:
4354 gfc_conv_intrinsic_set_exponent (se, expr);
4357 case GFC_ISYM_SCALE:
4358 gfc_conv_intrinsic_scale (se, expr);
4362 gfc_conv_intrinsic_sign (se, expr);
4366 gfc_conv_intrinsic_size (se, expr);
4369 case GFC_ISYM_SIZEOF:
4370 gfc_conv_intrinsic_sizeof (se, expr);
4373 case GFC_ISYM_SPACING:
4374 gfc_conv_intrinsic_spacing (se, expr);
4378 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4381 case GFC_ISYM_TRANSFER:
4384 if (se->ss->useflags)
4386 /* Access the previously obtained result. */
4387 gfc_conv_tmp_array_ref (se);
4388 gfc_advance_se_ss_chain (se);
4392 gfc_conv_intrinsic_array_transfer (se, expr);
4395 gfc_conv_intrinsic_transfer (se, expr);
4398 case GFC_ISYM_TTYNAM:
4399 gfc_conv_intrinsic_ttynam (se, expr);
4402 case GFC_ISYM_UBOUND:
4403 gfc_conv_intrinsic_bound (se, expr, 1);
4407 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4411 gfc_conv_intrinsic_loc (se, expr);
4414 case GFC_ISYM_ACCESS:
4415 case GFC_ISYM_CHDIR:
4416 case GFC_ISYM_CHMOD:
4417 case GFC_ISYM_DTIME:
4418 case GFC_ISYM_ETIME:
4420 case GFC_ISYM_FGETC:
4423 case GFC_ISYM_FPUTC:
4424 case GFC_ISYM_FSTAT:
4425 case GFC_ISYM_FTELL:
4426 case GFC_ISYM_GETCWD:
4427 case GFC_ISYM_GETGID:
4428 case GFC_ISYM_GETPID:
4429 case GFC_ISYM_GETUID:
4430 case GFC_ISYM_HOSTNM:
4432 case GFC_ISYM_IERRNO:
4433 case GFC_ISYM_IRAND:
4434 case GFC_ISYM_ISATTY:
4436 case GFC_ISYM_LSTAT:
4437 case GFC_ISYM_MALLOC:
4438 case GFC_ISYM_MATMUL:
4439 case GFC_ISYM_MCLOCK:
4440 case GFC_ISYM_MCLOCK8:
4442 case GFC_ISYM_RENAME:
4443 case GFC_ISYM_SECOND:
4444 case GFC_ISYM_SECNDS:
4445 case GFC_ISYM_SIGNAL:
4447 case GFC_ISYM_SYMLNK:
4448 case GFC_ISYM_SYSTEM:
4450 case GFC_ISYM_TIME8:
4451 case GFC_ISYM_UMASK:
4452 case GFC_ISYM_UNLINK:
4453 gfc_conv_intrinsic_funcall (se, expr);
4457 gfc_conv_intrinsic_lib_function (se, expr);
4463 /* This generates code to execute before entering the scalarization loop.
4464 Currently does nothing. */
4467 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4469 switch (ss->expr->value.function.isym->id)
4471 case GFC_ISYM_UBOUND:
4472 case GFC_ISYM_LBOUND:
4481 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4482 inside the scalarization loop. */
4485 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4489 /* The two argument version returns a scalar. */
4490 if (expr->value.function.actual->next->expr)
4493 newss = gfc_get_ss ();
4494 newss->type = GFC_SS_INTRINSIC;
4497 newss->data.info.dimen = 1;
4503 /* Walk an intrinsic array libcall. */
4506 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4510 gcc_assert (expr->rank > 0);
4512 newss = gfc_get_ss ();
4513 newss->type = GFC_SS_FUNCTION;
4516 newss->data.info.dimen = expr->rank;
4522 /* Returns nonzero if the specified intrinsic function call maps directly to a
4523 an external library call. Should only be used for functions that return
4527 gfc_is_intrinsic_libcall (gfc_expr * expr)
4529 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4530 gcc_assert (expr->rank > 0);
4532 switch (expr->value.function.isym->id)
4536 case GFC_ISYM_COUNT:
4537 case GFC_ISYM_MATMUL:
4538 case GFC_ISYM_MAXLOC:
4539 case GFC_ISYM_MAXVAL:
4540 case GFC_ISYM_MINLOC:
4541 case GFC_ISYM_MINVAL:
4542 case GFC_ISYM_PRODUCT:
4544 case GFC_ISYM_SHAPE:
4545 case GFC_ISYM_SPREAD:
4546 case GFC_ISYM_TRANSPOSE:
4547 /* Ignore absent optional parameters. */
4550 case GFC_ISYM_RESHAPE:
4551 case GFC_ISYM_CSHIFT:
4552 case GFC_ISYM_EOSHIFT:
4554 case GFC_ISYM_UNPACK:
4555 /* Pass absent optional parameters. */
4563 /* Walk an intrinsic function. */
4565 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
4566 gfc_intrinsic_sym * isym)
4570 if (isym->elemental)
4571 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
4573 if (expr->rank == 0)
4576 if (gfc_is_intrinsic_libcall (expr))
4577 return gfc_walk_intrinsic_libfunc (ss, expr);
4579 /* Special cases. */
4582 case GFC_ISYM_LBOUND:
4583 case GFC_ISYM_UBOUND:
4584 return gfc_walk_intrinsic_bound (ss, expr);
4586 case GFC_ISYM_TRANSFER:
4587 return gfc_walk_intrinsic_libfunc (ss, expr);
4590 /* This probably meant someone forgot to add an intrinsic to the above
4591 list(s) when they implemented it, or something's gone horribly
4597 #include "gt-fortran-trans-intrinsic.h"