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 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
108 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
111 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
113 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
115 /* Functions built into gcc itself. */
116 #include "mathbuiltins.def"
118 /* Functions in libgfortran. */
119 LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
122 LIB_FUNCTION (NONE, NULL, false)
126 #undef DEFINE_MATH_BUILTIN
127 #undef DEFINE_MATH_BUILTIN_C
129 /* Structure for storing components of a floating number to be used by
130 elemental functions to manipulate reals. */
133 tree arg; /* Variable tree to view convert to integer. */
134 tree expn; /* Variable tree to save exponent. */
135 tree frac; /* Variable tree to save fraction. */
136 tree smask; /* Constant tree of sign's mask. */
137 tree emask; /* Constant tree of exponent's mask. */
138 tree fmask; /* Constant tree of fraction's mask. */
139 tree edigits; /* Constant tree of the number of exponent bits. */
140 tree fdigits; /* Constant tree of the number of fraction bits. */
141 tree f1; /* Constant tree of the f1 defined in the real model. */
142 tree bias; /* Constant tree of the bias of exponent in the memory. */
143 tree type; /* Type tree of arg1. */
144 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
148 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
150 /* Evaluate the arguments to an intrinsic function. The value
151 of NARGS may be less than the actual number of arguments in EXPR
152 to allow optional "KIND" arguments that are not included in the
153 generated code to be ignored. */
156 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
157 tree *argarray, int nargs)
159 gfc_actual_arglist *actual;
161 gfc_intrinsic_arg *formal;
165 formal = expr->value.function.isym->formal;
166 actual = expr->value.function.actual;
168 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
169 actual = actual->next,
170 formal = formal ? formal->next : NULL)
174 /* Skip omitted optional arguments. */
181 /* Evaluate the parameter. This will substitute scalarized
182 references automatically. */
183 gfc_init_se (&argse, se);
185 if (e->ts.type == BT_CHARACTER)
187 gfc_conv_expr (&argse, e);
188 gfc_conv_string_parameter (&argse);
189 argarray[curr_arg++] = argse.string_length;
190 gcc_assert (curr_arg < nargs);
193 gfc_conv_expr_val (&argse, e);
195 /* If an optional argument is itself an optional dummy argument,
196 check its presence and substitute a null if absent. */
197 if (e->expr_type == EXPR_VARIABLE
198 && e->symtree->n.sym->attr.optional
201 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
203 gfc_add_block_to_block (&se->pre, &argse.pre);
204 gfc_add_block_to_block (&se->post, &argse.post);
205 argarray[curr_arg] = argse.expr;
209 /* Count the number of actual arguments to the intrinsic function EXPR
210 including any "hidden" string length arguments. */
213 gfc_intrinsic_argument_list_length (gfc_expr *expr)
216 gfc_actual_arglist *actual;
218 for (actual = expr->value.function.actual; actual; actual = actual->next)
223 if (actual->expr->ts.type == BT_CHARACTER)
233 /* Conversions between different types are output by the frontend as
234 intrinsic functions. We implement these directly with inline code. */
237 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
243 nargs = gfc_intrinsic_argument_list_length (expr);
244 args = alloca (sizeof (tree) * nargs);
246 /* Evaluate all the arguments passed. Whilst we're only interested in the
247 first one here, there are other parts of the front-end that assume this
248 and will trigger an ICE if it's not the case. */
249 type = gfc_typenode_for_spec (&expr->ts);
250 gcc_assert (expr->value.function.actual->expr);
251 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
253 /* Conversion from complex to non-complex involves taking the real
254 component of the value. */
255 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
256 && expr->ts.type != BT_COMPLEX)
260 artype = TREE_TYPE (TREE_TYPE (args[0]));
261 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
264 se->expr = convert (type, args[0]);
267 /* This is needed because the gcc backend only implements
268 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
269 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
270 Similarly for CEILING. */
273 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
280 argtype = TREE_TYPE (arg);
281 arg = gfc_evaluate_now (arg, pblock);
283 intval = convert (type, arg);
284 intval = gfc_evaluate_now (intval, pblock);
286 tmp = convert (argtype, intval);
287 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
289 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
290 build_int_cst (type, 1));
291 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
296 /* Round to nearest integer, away from zero. */
299 build_round_expr (tree arg, tree restype)
304 int argprec, resprec;
306 argtype = TREE_TYPE (arg);
307 argprec = TYPE_PRECISION (argtype);
308 resprec = TYPE_PRECISION (restype);
310 /* Depending on the type of the result, choose the long int intrinsic
311 (lround family) or long long intrinsic (llround). We might also
312 need to convert the result afterwards. */
313 if (resprec <= LONG_TYPE_SIZE)
315 else if (resprec <= LONG_LONG_TYPE_SIZE)
320 /* Now, depending on the argument type, we choose between intrinsics. */
321 if (argprec == TYPE_PRECISION (float_type_node))
322 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
323 else if (argprec == TYPE_PRECISION (double_type_node))
324 fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
325 else if (argprec == TYPE_PRECISION (long_double_type_node))
326 fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
330 return fold_convert (restype, build_call_expr (fn, 1, arg));
334 /* Convert a real to an integer using a specific rounding mode.
335 Ideally we would just build the corresponding GENERIC node,
336 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
339 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
340 enum rounding_mode op)
345 return build_fixbound_expr (pblock, arg, type, 0);
349 return build_fixbound_expr (pblock, arg, type, 1);
353 return build_round_expr (arg, type);
357 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
366 /* Round a real value using the specified rounding mode.
367 We use a temporary integer of that same kind size as the result.
368 Values larger than those that can be represented by this kind are
369 unchanged, as they will not be accurate enough to represent the
371 huge = HUGE (KIND (a))
372 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
376 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
387 kind = expr->ts.kind;
388 nargs = gfc_intrinsic_argument_list_length (expr);
391 /* We have builtin functions for some cases. */
434 /* Evaluate the argument. */
435 gcc_assert (expr->value.function.actual->expr);
436 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
438 /* Use a builtin function if one exists. */
439 if (n != END_BUILTINS)
441 tmp = built_in_decls[n];
442 se->expr = build_call_expr (tmp, 1, arg[0]);
446 /* This code is probably redundant, but we'll keep it lying around just
448 type = gfc_typenode_for_spec (&expr->ts);
449 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
451 /* Test if the value is too large to handle sensibly. */
452 gfc_set_model_kind (kind);
454 n = gfc_validate_kind (BT_INTEGER, kind, false);
455 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
456 tmp = gfc_conv_mpfr_to_tree (huge, kind);
457 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
459 mpfr_neg (huge, huge, GFC_RND_MODE);
460 tmp = gfc_conv_mpfr_to_tree (huge, kind);
461 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
462 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
463 itype = gfc_get_int_type (kind);
465 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
466 tmp = convert (type, tmp);
467 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
472 /* Convert to an integer using the specified rounding mode. */
475 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
481 nargs = gfc_intrinsic_argument_list_length (expr);
482 args = alloca (sizeof (tree) * nargs);
484 /* Evaluate the argument, we process all arguments even though we only
485 use the first one for code generation purposes. */
486 type = gfc_typenode_for_spec (&expr->ts);
487 gcc_assert (expr->value.function.actual->expr);
488 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
490 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
492 /* Conversion to a different integer kind. */
493 se->expr = convert (type, args[0]);
497 /* Conversion from complex to non-complex involves taking the real
498 component of the value. */
499 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
500 && expr->ts.type != BT_COMPLEX)
504 artype = TREE_TYPE (TREE_TYPE (args[0]));
505 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
508 se->expr = build_fix_expr (&se->pre, args[0], type, op);
513 /* Get the imaginary component of a value. */
516 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
520 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
521 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
525 /* Get the complex conjugate of a value. */
528 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
532 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
533 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
537 /* Initialize function decls for library functions. The external functions
538 are created as required. Builtin functions are added here. */
541 gfc_build_intrinsic_lib_fndecls (void)
543 gfc_intrinsic_map_t *m;
545 /* Add GCC builtin functions. */
546 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
548 if (m->code_r4 != END_BUILTINS)
549 m->real4_decl = built_in_decls[m->code_r4];
550 if (m->code_r8 != END_BUILTINS)
551 m->real8_decl = built_in_decls[m->code_r8];
552 if (m->code_r10 != END_BUILTINS)
553 m->real10_decl = built_in_decls[m->code_r10];
554 if (m->code_r16 != END_BUILTINS)
555 m->real16_decl = built_in_decls[m->code_r16];
556 if (m->code_c4 != END_BUILTINS)
557 m->complex4_decl = built_in_decls[m->code_c4];
558 if (m->code_c8 != END_BUILTINS)
559 m->complex8_decl = built_in_decls[m->code_c8];
560 if (m->code_c10 != END_BUILTINS)
561 m->complex10_decl = built_in_decls[m->code_c10];
562 if (m->code_c16 != END_BUILTINS)
563 m->complex16_decl = built_in_decls[m->code_c16];
568 /* Create a fndecl for a simple intrinsic library function. */
571 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
576 gfc_actual_arglist *actual;
579 char name[GFC_MAX_SYMBOL_LEN + 3];
582 if (ts->type == BT_REAL)
587 pdecl = &m->real4_decl;
590 pdecl = &m->real8_decl;
593 pdecl = &m->real10_decl;
596 pdecl = &m->real16_decl;
602 else if (ts->type == BT_COMPLEX)
604 gcc_assert (m->complex_available);
609 pdecl = &m->complex4_decl;
612 pdecl = &m->complex8_decl;
615 pdecl = &m->complex10_decl;
618 pdecl = &m->complex16_decl;
633 snprintf (name, sizeof (name), "%s%s%s",
634 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
635 else if (ts->kind == 8)
636 snprintf (name, sizeof (name), "%s%s",
637 ts->type == BT_COMPLEX ? "c" : "", m->name);
640 gcc_assert (ts->kind == 10 || ts->kind == 16);
641 snprintf (name, sizeof (name), "%s%s%s",
642 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
647 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
648 ts->type == BT_COMPLEX ? 'c' : 'r',
652 argtypes = NULL_TREE;
653 for (actual = expr->value.function.actual; actual; actual = actual->next)
655 type = gfc_typenode_for_spec (&actual->expr->ts);
656 argtypes = gfc_chainon_list (argtypes, type);
658 argtypes = gfc_chainon_list (argtypes, void_type_node);
659 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
660 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
662 /* Mark the decl as external. */
663 DECL_EXTERNAL (fndecl) = 1;
664 TREE_PUBLIC (fndecl) = 1;
666 /* Mark it __attribute__((const)), if possible. */
667 TREE_READONLY (fndecl) = m->is_constant;
669 rest_of_decl_compilation (fndecl, 1, 0);
676 /* Convert an intrinsic function into an external or builtin call. */
679 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
681 gfc_intrinsic_map_t *m;
685 unsigned int num_args;
688 id = expr->value.function.isym->id;
689 /* Find the entry for this function. */
690 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
696 if (m->id == GFC_ISYM_NONE)
698 internal_error ("Intrinsic function %s(%d) not recognized",
699 expr->value.function.name, id);
702 /* Get the decl and generate the call. */
703 num_args = gfc_intrinsic_argument_list_length (expr);
704 args = alloca (sizeof (tree) * num_args);
706 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
707 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
708 rettype = TREE_TYPE (TREE_TYPE (fndecl));
710 fndecl = build_addr (fndecl, current_function_decl);
711 se->expr = build_call_array (rettype, fndecl, num_args, args);
714 /* The EXPONENT(s) intrinsic function is translated into
721 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
723 tree arg, type, res, tmp;
726 switch (expr->value.function.actual->expr->ts.kind)
729 frexp = BUILT_IN_FREXPF;
732 frexp = BUILT_IN_FREXP;
736 frexp = BUILT_IN_FREXPL;
742 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
744 res = gfc_create_var (integer_type_node, NULL);
745 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
746 build_fold_addr_expr (res));
747 gfc_add_expr_to_block (&se->pre, tmp);
749 type = gfc_typenode_for_spec (&expr->ts);
750 se->expr = fold_convert (type, res);
753 /* Evaluate a single upper or lower bound. */
754 /* TODO: bound intrinsic generates way too much unnecessary code. */
757 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
759 gfc_actual_arglist *arg;
760 gfc_actual_arglist *arg2;
765 tree cond, cond1, cond2, cond3, cond4, size;
773 arg = expr->value.function.actual;
778 /* Create an implicit second parameter from the loop variable. */
779 gcc_assert (!arg2->expr);
780 gcc_assert (se->loop->dimen == 1);
781 gcc_assert (se->ss->expr == expr);
782 gfc_advance_se_ss_chain (se);
783 bound = se->loop->loopvar[0];
784 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
789 /* use the passed argument. */
790 gcc_assert (arg->next->expr);
791 gfc_init_se (&argse, NULL);
792 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
793 gfc_add_block_to_block (&se->pre, &argse.pre);
795 /* Convert from one based to zero based. */
796 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
800 /* TODO: don't re-evaluate the descriptor on each iteration. */
801 /* Get a descriptor for the first parameter. */
802 ss = gfc_walk_expr (arg->expr);
803 gcc_assert (ss != gfc_ss_terminator);
804 gfc_init_se (&argse, NULL);
805 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
806 gfc_add_block_to_block (&se->pre, &argse.pre);
807 gfc_add_block_to_block (&se->post, &argse.post);
811 if (INTEGER_CST_P (bound))
815 hi = TREE_INT_CST_HIGH (bound);
816 low = TREE_INT_CST_LOW (bound);
817 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
818 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
819 "dimension index", upper ? "UBOUND" : "LBOUND",
824 if (flag_bounds_check)
826 bound = gfc_evaluate_now (bound, &se->pre);
827 cond = fold_build2 (LT_EXPR, boolean_type_node,
828 bound, build_int_cst (TREE_TYPE (bound), 0));
829 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
830 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
831 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
832 gfc_trans_runtime_check (cond, &se->pre, &expr->where, gfc_msg_fault);
836 ubound = gfc_conv_descriptor_ubound (desc, bound);
837 lbound = gfc_conv_descriptor_lbound (desc, bound);
839 /* Follow any component references. */
840 if (arg->expr->expr_type == EXPR_VARIABLE
841 || arg->expr->expr_type == EXPR_CONSTANT)
843 as = arg->expr->symtree->n.sym->as;
844 for (ref = arg->expr->ref; ref; ref = ref->next)
849 as = ref->u.c.component->as;
857 switch (ref->u.ar.type)
875 /* 13.14.53: Result value for LBOUND
877 Case (i): For an array section or for an array expression other than a
878 whole array or array structure component, LBOUND(ARRAY, DIM)
879 has the value 1. For a whole array or array structure
880 component, LBOUND(ARRAY, DIM) has the value:
881 (a) equal to the lower bound for subscript DIM of ARRAY if
882 dimension DIM of ARRAY does not have extent zero
883 or if ARRAY is an assumed-size array of rank DIM,
886 13.14.113: Result value for UBOUND
888 Case (i): For an array section or for an array expression other than a
889 whole array or array structure component, UBOUND(ARRAY, DIM)
890 has the value equal to the number of elements in the given
891 dimension; otherwise, it has a value equal to the upper bound
892 for subscript DIM of ARRAY if dimension DIM of ARRAY does
893 not have size zero and has value zero if dimension DIM has
898 tree stride = gfc_conv_descriptor_stride (desc, bound);
900 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
901 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
903 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
904 gfc_index_zero_node);
905 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
907 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
908 gfc_index_zero_node);
909 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
913 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
915 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
916 ubound, gfc_index_zero_node);
920 if (as->type == AS_ASSUMED_SIZE)
921 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
922 build_int_cst (TREE_TYPE (bound),
923 arg->expr->rank - 1));
925 cond = boolean_false_node;
927 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
928 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
930 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
931 lbound, gfc_index_one_node);
938 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
939 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
943 se->expr = gfc_index_one_node;
946 type = gfc_typenode_for_spec (&expr->ts);
947 se->expr = convert (type, se->expr);
952 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
957 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
959 switch (expr->value.function.actual->expr->ts.type)
963 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
967 switch (expr->ts.kind)
982 se->expr = build_call_expr (built_in_decls[n], 1, arg);
991 /* Create a complex value from one or two real components. */
994 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1000 unsigned int num_args;
1002 num_args = gfc_intrinsic_argument_list_length (expr);
1003 args = alloca (sizeof (tree) * num_args);
1005 type = gfc_typenode_for_spec (&expr->ts);
1006 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1007 real = convert (TREE_TYPE (type), args[0]);
1009 imag = convert (TREE_TYPE (type), args[1]);
1010 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1012 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1014 imag = convert (TREE_TYPE (type), imag);
1017 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1019 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1022 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1023 MODULO(A, P) = A - FLOOR (A / P) * P */
1024 /* TODO: MOD(x, 0) */
1027 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1038 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1040 switch (expr->ts.type)
1043 /* Integer case is easy, we've got a builtin op. */
1044 type = TREE_TYPE (args[0]);
1047 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1049 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1054 /* Check if we have a builtin fmod. */
1055 switch (expr->ts.kind)
1074 /* Use it if it exists. */
1075 if (n != END_BUILTINS)
1077 tmp = build_addr (built_in_decls[n], current_function_decl);
1078 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1084 type = TREE_TYPE (args[0]);
1086 args[0] = gfc_evaluate_now (args[0], &se->pre);
1087 args[1] = gfc_evaluate_now (args[1], &se->pre);
1090 modulo = arg - floor (arg/arg2) * arg2, so
1091 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1093 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1094 thereby avoiding another division and retaining the accuracy
1095 of the builtin function. */
1096 if (n != END_BUILTINS && modulo)
1098 tree zero = gfc_build_const (type, integer_zero_node);
1099 tmp = gfc_evaluate_now (se->expr, &se->pre);
1100 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1101 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1102 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1103 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1104 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1105 test = gfc_evaluate_now (test, &se->pre);
1106 se->expr = fold_build3 (COND_EXPR, type, test,
1107 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1112 /* If we do not have a built_in fmod, the calculation is going to
1113 have to be done longhand. */
1114 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1116 /* Test if the value is too large to handle sensibly. */
1117 gfc_set_model_kind (expr->ts.kind);
1119 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1120 ikind = expr->ts.kind;
1123 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1124 ikind = gfc_max_integer_kind;
1126 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1127 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1128 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1130 mpfr_neg (huge, huge, GFC_RND_MODE);
1131 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1132 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1133 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1135 itype = gfc_get_int_type (ikind);
1137 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1139 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1140 tmp = convert (type, tmp);
1141 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1142 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1143 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1152 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1155 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1163 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1164 type = TREE_TYPE (args[0]);
1166 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1167 val = gfc_evaluate_now (val, &se->pre);
1169 zero = gfc_build_const (type, integer_zero_node);
1170 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1171 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1175 /* SIGN(A, B) is absolute value of A times sign of B.
1176 The real value versions use library functions to ensure the correct
1177 handling of negative zero. Integer case implemented as:
1178 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1182 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1188 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1189 if (expr->ts.type == BT_REAL)
1191 switch (expr->ts.kind)
1194 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1197 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1201 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1206 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1210 /* Having excluded floating point types, we know we are now dealing
1211 with signed integer types. */
1212 type = TREE_TYPE (args[0]);
1214 /* Args[0] is used multiple times below. */
1215 args[0] = gfc_evaluate_now (args[0], &se->pre);
1217 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1218 the signs of A and B are the same, and of all ones if they differ. */
1219 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1220 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1221 build_int_cst (type, TYPE_PRECISION (type) - 1));
1222 tmp = gfc_evaluate_now (tmp, &se->pre);
1224 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1225 is all ones (i.e. -1). */
1226 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1227 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1232 /* Test for the presence of an optional argument. */
1235 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1239 arg = expr->value.function.actual->expr;
1240 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1241 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1242 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1246 /* Calculate the double precision product of two single precision values. */
1249 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1254 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1256 /* Convert the args to double precision before multiplying. */
1257 type = gfc_typenode_for_spec (&expr->ts);
1258 args[0] = convert (type, args[0]);
1259 args[1] = convert (type, args[1]);
1260 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1264 /* Return a length one character string containing an ascii character. */
1267 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1273 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1275 /* We currently don't support character types != 1. */
1276 gcc_assert (expr->ts.kind == 1);
1277 type = gfc_character1_type_node;
1278 var = gfc_create_var (type, "char");
1280 arg = convert (type, arg);
1281 gfc_add_modify_expr (&se->pre, var, arg);
1282 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1283 se->string_length = integer_one_node;
1288 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1295 tree gfc_int8_type_node = gfc_get_int_type (8);
1298 unsigned int num_args;
1300 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1301 args = alloca (sizeof (tree) * num_args);
1303 type = build_pointer_type (gfc_character1_type_node);
1304 var = gfc_create_var (type, "pstr");
1305 len = gfc_create_var (gfc_int8_type_node, "len");
1307 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1308 args[0] = build_fold_addr_expr (var);
1309 args[1] = build_fold_addr_expr (len);
1311 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1312 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1313 fndecl, num_args, args);
1314 gfc_add_expr_to_block (&se->pre, tmp);
1316 /* Free the temporary afterwards, if necessary. */
1317 cond = fold_build2 (GT_EXPR, boolean_type_node,
1318 len, build_int_cst (TREE_TYPE (len), 0));
1319 tmp = gfc_call_free (var);
1320 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1321 gfc_add_expr_to_block (&se->post, tmp);
1324 se->string_length = len;
1329 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1336 tree gfc_int4_type_node = gfc_get_int_type (4);
1339 unsigned int num_args;
1341 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1342 args = alloca (sizeof (tree) * num_args);
1344 type = build_pointer_type (gfc_character1_type_node);
1345 var = gfc_create_var (type, "pstr");
1346 len = gfc_create_var (gfc_int4_type_node, "len");
1348 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1349 args[0] = build_fold_addr_expr (var);
1350 args[1] = build_fold_addr_expr (len);
1352 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1353 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1354 fndecl, num_args, args);
1355 gfc_add_expr_to_block (&se->pre, tmp);
1357 /* Free the temporary afterwards, if necessary. */
1358 cond = fold_build2 (GT_EXPR, boolean_type_node,
1359 len, build_int_cst (TREE_TYPE (len), 0));
1360 tmp = gfc_call_free (var);
1361 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1362 gfc_add_expr_to_block (&se->post, tmp);
1365 se->string_length = len;
1369 /* Return a character string containing the tty name. */
1372 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1380 tree gfc_int4_type_node = gfc_get_int_type (4);
1382 unsigned int num_args;
1384 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1385 args = alloca (sizeof (tree) * num_args);
1387 type = build_pointer_type (gfc_character1_type_node);
1388 var = gfc_create_var (type, "pstr");
1389 len = gfc_create_var (gfc_int4_type_node, "len");
1391 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1392 args[0] = build_fold_addr_expr (var);
1393 args[1] = build_fold_addr_expr (len);
1395 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1396 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1397 fndecl, num_args, args);
1398 gfc_add_expr_to_block (&se->pre, tmp);
1400 /* Free the temporary afterwards, if necessary. */
1401 cond = fold_build2 (GT_EXPR, boolean_type_node,
1402 len, build_int_cst (TREE_TYPE (len), 0));
1403 tmp = gfc_call_free (var);
1404 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1405 gfc_add_expr_to_block (&se->post, tmp);
1408 se->string_length = len;
1412 /* Get the minimum/maximum value of all the parameters.
1413 minmax (a1, a2, a3, ...)
1416 if (a2 .op. mvar || isnan(mvar))
1418 if (a3 .op. mvar || isnan(mvar))
1425 /* TODO: Mismatching types can occur when specific names are used.
1426 These should be handled during resolution. */
1428 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1436 gfc_actual_arglist *argexpr;
1437 unsigned int i, nargs;
1439 nargs = gfc_intrinsic_argument_list_length (expr);
1440 args = alloca (sizeof (tree) * nargs);
1442 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1443 type = gfc_typenode_for_spec (&expr->ts);
1445 argexpr = expr->value.function.actual;
1446 if (TREE_TYPE (args[0]) != type)
1447 args[0] = convert (type, args[0]);
1448 /* Only evaluate the argument once. */
1449 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1450 args[0] = gfc_evaluate_now (args[0], &se->pre);
1452 mvar = gfc_create_var (type, "M");
1453 gfc_add_modify_expr (&se->pre, mvar, args[0]);
1454 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1460 /* Handle absent optional arguments by ignoring the comparison. */
1461 if (argexpr->expr->expr_type == EXPR_VARIABLE
1462 && argexpr->expr->symtree->n.sym->attr.optional
1463 && TREE_CODE (val) == INDIRECT_REF)
1465 (NE_EXPR, boolean_type_node, TREE_OPERAND (val, 0),
1466 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1471 /* Only evaluate the argument once. */
1472 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1473 val = gfc_evaluate_now (val, &se->pre);
1476 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1478 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1480 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1481 __builtin_isnan might be made dependent on that module being loaded,
1482 to help performance of programs that don't rely on IEEE semantics. */
1483 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1485 isnan = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1486 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1487 fold_convert (boolean_type_node, isnan));
1489 tmp = build3_v (COND_EXPR, tmp, thencase, build_empty_stmt ());
1491 if (cond != NULL_TREE)
1492 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1494 gfc_add_expr_to_block (&se->pre, tmp);
1495 argexpr = argexpr->next;
1501 /* Generate library calls for MIN and MAX intrinsics for character
1504 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1507 tree var, len, fndecl, tmp, cond;
1510 nargs = gfc_intrinsic_argument_list_length (expr);
1511 args = alloca (sizeof (tree) * (nargs + 4));
1512 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1514 /* Create the result variables. */
1515 len = gfc_create_var (gfc_charlen_type_node, "len");
1516 args[0] = build_fold_addr_expr (len);
1517 var = gfc_create_var (build_pointer_type (gfc_character1_type_node), "pstr");
1518 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1519 args[2] = build_int_cst (NULL_TREE, op);
1520 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1522 /* Make the function call. */
1523 fndecl = build_addr (gfor_fndecl_string_minmax, current_function_decl);
1524 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_minmax)),
1525 fndecl, nargs + 4, args);
1526 gfc_add_expr_to_block (&se->pre, tmp);
1528 /* Free the temporary afterwards, if necessary. */
1529 cond = fold_build2 (GT_EXPR, boolean_type_node,
1530 len, build_int_cst (TREE_TYPE (len), 0));
1531 tmp = gfc_call_free (var);
1532 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1533 gfc_add_expr_to_block (&se->post, tmp);
1536 se->string_length = len;
1540 /* Create a symbol node for this intrinsic. The symbol from the frontend
1541 has the generic name. */
1544 gfc_get_symbol_for_expr (gfc_expr * expr)
1548 /* TODO: Add symbols for intrinsic function to the global namespace. */
1549 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1550 sym = gfc_new_symbol (expr->value.function.name, NULL);
1553 sym->attr.external = 1;
1554 sym->attr.function = 1;
1555 sym->attr.always_explicit = 1;
1556 sym->attr.proc = PROC_INTRINSIC;
1557 sym->attr.flavor = FL_PROCEDURE;
1561 sym->attr.dimension = 1;
1562 sym->as = gfc_get_array_spec ();
1563 sym->as->type = AS_ASSUMED_SHAPE;
1564 sym->as->rank = expr->rank;
1567 /* TODO: proper argument lists for external intrinsics. */
1571 /* Generate a call to an external intrinsic function. */
1573 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1578 gcc_assert (!se->ss || se->ss->expr == expr);
1581 gcc_assert (expr->rank > 0);
1583 gcc_assert (expr->rank == 0);
1585 sym = gfc_get_symbol_for_expr (expr);
1587 /* Calls to libgfortran_matmul need to be appended special arguments,
1588 to be able to call the BLAS ?gemm functions if required and possible. */
1589 append_args = NULL_TREE;
1590 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1591 && sym->ts.type != BT_LOGICAL)
1593 tree cint = gfc_get_int_type (gfc_c_int_kind);
1595 if (gfc_option.flag_external_blas
1596 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1597 && (sym->ts.kind == gfc_default_real_kind
1598 || sym->ts.kind == gfc_default_double_kind))
1602 if (sym->ts.type == BT_REAL)
1604 if (sym->ts.kind == gfc_default_real_kind)
1605 gemm_fndecl = gfor_fndecl_sgemm;
1607 gemm_fndecl = gfor_fndecl_dgemm;
1611 if (sym->ts.kind == gfc_default_real_kind)
1612 gemm_fndecl = gfor_fndecl_cgemm;
1614 gemm_fndecl = gfor_fndecl_zgemm;
1617 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1618 append_args = gfc_chainon_list
1619 (append_args, build_int_cst
1620 (cint, gfc_option.blas_matmul_limit));
1621 append_args = gfc_chainon_list (append_args,
1622 gfc_build_addr_expr (NULL_TREE,
1627 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1628 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1629 append_args = gfc_chainon_list (append_args, null_pointer_node);
1633 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1637 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1657 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1666 gfc_actual_arglist *actual;
1673 gfc_conv_intrinsic_funcall (se, expr);
1677 actual = expr->value.function.actual;
1678 type = gfc_typenode_for_spec (&expr->ts);
1679 /* Initialize the result. */
1680 resvar = gfc_create_var (type, "test");
1682 tmp = convert (type, boolean_true_node);
1684 tmp = convert (type, boolean_false_node);
1685 gfc_add_modify_expr (&se->pre, resvar, tmp);
1687 /* Walk the arguments. */
1688 arrayss = gfc_walk_expr (actual->expr);
1689 gcc_assert (arrayss != gfc_ss_terminator);
1691 /* Initialize the scalarizer. */
1692 gfc_init_loopinfo (&loop);
1693 exit_label = gfc_build_label_decl (NULL_TREE);
1694 TREE_USED (exit_label) = 1;
1695 gfc_add_ss_to_loop (&loop, arrayss);
1697 /* Initialize the loop. */
1698 gfc_conv_ss_startstride (&loop);
1699 gfc_conv_loop_setup (&loop);
1701 gfc_mark_ss_chain_used (arrayss, 1);
1702 /* Generate the loop body. */
1703 gfc_start_scalarized_body (&loop, &body);
1705 /* If the condition matches then set the return value. */
1706 gfc_start_block (&block);
1708 tmp = convert (type, boolean_false_node);
1710 tmp = convert (type, boolean_true_node);
1711 gfc_add_modify_expr (&block, resvar, tmp);
1713 /* And break out of the loop. */
1714 tmp = build1_v (GOTO_EXPR, exit_label);
1715 gfc_add_expr_to_block (&block, tmp);
1717 found = gfc_finish_block (&block);
1719 /* Check this element. */
1720 gfc_init_se (&arrayse, NULL);
1721 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1722 arrayse.ss = arrayss;
1723 gfc_conv_expr_val (&arrayse, actual->expr);
1725 gfc_add_block_to_block (&body, &arrayse.pre);
1726 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1727 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1728 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1729 gfc_add_expr_to_block (&body, tmp);
1730 gfc_add_block_to_block (&body, &arrayse.post);
1732 gfc_trans_scalarizing_loops (&loop, &body);
1734 /* Add the exit label. */
1735 tmp = build1_v (LABEL_EXPR, exit_label);
1736 gfc_add_expr_to_block (&loop.pre, tmp);
1738 gfc_add_block_to_block (&se->pre, &loop.pre);
1739 gfc_add_block_to_block (&se->pre, &loop.post);
1740 gfc_cleanup_loop (&loop);
1745 /* COUNT(A) = Number of true elements in A. */
1747 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1754 gfc_actual_arglist *actual;
1760 gfc_conv_intrinsic_funcall (se, expr);
1764 actual = expr->value.function.actual;
1766 type = gfc_typenode_for_spec (&expr->ts);
1767 /* Initialize the result. */
1768 resvar = gfc_create_var (type, "count");
1769 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1771 /* Walk the arguments. */
1772 arrayss = gfc_walk_expr (actual->expr);
1773 gcc_assert (arrayss != gfc_ss_terminator);
1775 /* Initialize the scalarizer. */
1776 gfc_init_loopinfo (&loop);
1777 gfc_add_ss_to_loop (&loop, arrayss);
1779 /* Initialize the loop. */
1780 gfc_conv_ss_startstride (&loop);
1781 gfc_conv_loop_setup (&loop);
1783 gfc_mark_ss_chain_used (arrayss, 1);
1784 /* Generate the loop body. */
1785 gfc_start_scalarized_body (&loop, &body);
1787 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1788 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1789 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1791 gfc_init_se (&arrayse, NULL);
1792 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1793 arrayse.ss = arrayss;
1794 gfc_conv_expr_val (&arrayse, actual->expr);
1795 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1797 gfc_add_block_to_block (&body, &arrayse.pre);
1798 gfc_add_expr_to_block (&body, tmp);
1799 gfc_add_block_to_block (&body, &arrayse.post);
1801 gfc_trans_scalarizing_loops (&loop, &body);
1803 gfc_add_block_to_block (&se->pre, &loop.pre);
1804 gfc_add_block_to_block (&se->pre, &loop.post);
1805 gfc_cleanup_loop (&loop);
1810 /* Inline implementation of the sum and product intrinsics. */
1812 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1820 gfc_actual_arglist *actual;
1825 gfc_expr *arrayexpr;
1830 gfc_conv_intrinsic_funcall (se, expr);
1834 type = gfc_typenode_for_spec (&expr->ts);
1835 /* Initialize the result. */
1836 resvar = gfc_create_var (type, "val");
1837 if (op == PLUS_EXPR)
1838 tmp = gfc_build_const (type, integer_zero_node);
1840 tmp = gfc_build_const (type, integer_one_node);
1842 gfc_add_modify_expr (&se->pre, resvar, tmp);
1844 /* Walk the arguments. */
1845 actual = expr->value.function.actual;
1846 arrayexpr = actual->expr;
1847 arrayss = gfc_walk_expr (arrayexpr);
1848 gcc_assert (arrayss != gfc_ss_terminator);
1850 actual = actual->next->next;
1851 gcc_assert (actual);
1852 maskexpr = actual->expr;
1853 if (maskexpr && maskexpr->rank != 0)
1855 maskss = gfc_walk_expr (maskexpr);
1856 gcc_assert (maskss != gfc_ss_terminator);
1861 /* Initialize the scalarizer. */
1862 gfc_init_loopinfo (&loop);
1863 gfc_add_ss_to_loop (&loop, arrayss);
1865 gfc_add_ss_to_loop (&loop, maskss);
1867 /* Initialize the loop. */
1868 gfc_conv_ss_startstride (&loop);
1869 gfc_conv_loop_setup (&loop);
1871 gfc_mark_ss_chain_used (arrayss, 1);
1873 gfc_mark_ss_chain_used (maskss, 1);
1874 /* Generate the loop body. */
1875 gfc_start_scalarized_body (&loop, &body);
1877 /* If we have a mask, only add this element if the mask is set. */
1880 gfc_init_se (&maskse, NULL);
1881 gfc_copy_loopinfo_to_se (&maskse, &loop);
1883 gfc_conv_expr_val (&maskse, maskexpr);
1884 gfc_add_block_to_block (&body, &maskse.pre);
1886 gfc_start_block (&block);
1889 gfc_init_block (&block);
1891 /* Do the actual summation/product. */
1892 gfc_init_se (&arrayse, NULL);
1893 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1894 arrayse.ss = arrayss;
1895 gfc_conv_expr_val (&arrayse, arrayexpr);
1896 gfc_add_block_to_block (&block, &arrayse.pre);
1898 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1899 gfc_add_modify_expr (&block, resvar, tmp);
1900 gfc_add_block_to_block (&block, &arrayse.post);
1904 /* We enclose the above in if (mask) {...} . */
1905 tmp = gfc_finish_block (&block);
1907 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1910 tmp = gfc_finish_block (&block);
1911 gfc_add_expr_to_block (&body, tmp);
1913 gfc_trans_scalarizing_loops (&loop, &body);
1915 /* For a scalar mask, enclose the loop in an if statement. */
1916 if (maskexpr && maskss == NULL)
1918 gfc_init_se (&maskse, NULL);
1919 gfc_conv_expr_val (&maskse, maskexpr);
1920 gfc_init_block (&block);
1921 gfc_add_block_to_block (&block, &loop.pre);
1922 gfc_add_block_to_block (&block, &loop.post);
1923 tmp = gfc_finish_block (&block);
1925 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1926 gfc_add_expr_to_block (&block, tmp);
1927 gfc_add_block_to_block (&se->pre, &block);
1931 gfc_add_block_to_block (&se->pre, &loop.pre);
1932 gfc_add_block_to_block (&se->pre, &loop.post);
1935 gfc_cleanup_loop (&loop);
1941 /* Inline implementation of the dot_product intrinsic. This function
1942 is based on gfc_conv_intrinsic_arith (the previous function). */
1944 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1952 gfc_actual_arglist *actual;
1953 gfc_ss *arrayss1, *arrayss2;
1954 gfc_se arrayse1, arrayse2;
1955 gfc_expr *arrayexpr1, *arrayexpr2;
1957 type = gfc_typenode_for_spec (&expr->ts);
1959 /* Initialize the result. */
1960 resvar = gfc_create_var (type, "val");
1961 if (expr->ts.type == BT_LOGICAL)
1962 tmp = build_int_cst (type, 0);
1964 tmp = gfc_build_const (type, integer_zero_node);
1966 gfc_add_modify_expr (&se->pre, resvar, tmp);
1968 /* Walk argument #1. */
1969 actual = expr->value.function.actual;
1970 arrayexpr1 = actual->expr;
1971 arrayss1 = gfc_walk_expr (arrayexpr1);
1972 gcc_assert (arrayss1 != gfc_ss_terminator);
1974 /* Walk argument #2. */
1975 actual = actual->next;
1976 arrayexpr2 = actual->expr;
1977 arrayss2 = gfc_walk_expr (arrayexpr2);
1978 gcc_assert (arrayss2 != gfc_ss_terminator);
1980 /* Initialize the scalarizer. */
1981 gfc_init_loopinfo (&loop);
1982 gfc_add_ss_to_loop (&loop, arrayss1);
1983 gfc_add_ss_to_loop (&loop, arrayss2);
1985 /* Initialize the loop. */
1986 gfc_conv_ss_startstride (&loop);
1987 gfc_conv_loop_setup (&loop);
1989 gfc_mark_ss_chain_used (arrayss1, 1);
1990 gfc_mark_ss_chain_used (arrayss2, 1);
1992 /* Generate the loop body. */
1993 gfc_start_scalarized_body (&loop, &body);
1994 gfc_init_block (&block);
1996 /* Make the tree expression for [conjg(]array1[)]. */
1997 gfc_init_se (&arrayse1, NULL);
1998 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1999 arrayse1.ss = arrayss1;
2000 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2001 if (expr->ts.type == BT_COMPLEX)
2002 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2003 gfc_add_block_to_block (&block, &arrayse1.pre);
2005 /* Make the tree expression for array2. */
2006 gfc_init_se (&arrayse2, NULL);
2007 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2008 arrayse2.ss = arrayss2;
2009 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2010 gfc_add_block_to_block (&block, &arrayse2.pre);
2012 /* Do the actual product and sum. */
2013 if (expr->ts.type == BT_LOGICAL)
2015 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2016 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2020 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2021 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2023 gfc_add_modify_expr (&block, resvar, tmp);
2025 /* Finish up the loop block and the loop. */
2026 tmp = gfc_finish_block (&block);
2027 gfc_add_expr_to_block (&body, tmp);
2029 gfc_trans_scalarizing_loops (&loop, &body);
2030 gfc_add_block_to_block (&se->pre, &loop.pre);
2031 gfc_add_block_to_block (&se->pre, &loop.post);
2032 gfc_cleanup_loop (&loop);
2039 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
2043 stmtblock_t ifblock;
2044 stmtblock_t elseblock;
2052 gfc_actual_arglist *actual;
2057 gfc_expr *arrayexpr;
2064 gfc_conv_intrinsic_funcall (se, expr);
2068 /* Initialize the result. */
2069 pos = gfc_create_var (gfc_array_index_type, "pos");
2070 offset = gfc_create_var (gfc_array_index_type, "offset");
2071 type = gfc_typenode_for_spec (&expr->ts);
2073 /* Walk the arguments. */
2074 actual = expr->value.function.actual;
2075 arrayexpr = actual->expr;
2076 arrayss = gfc_walk_expr (arrayexpr);
2077 gcc_assert (arrayss != gfc_ss_terminator);
2079 actual = actual->next->next;
2080 gcc_assert (actual);
2081 maskexpr = actual->expr;
2082 if (maskexpr && maskexpr->rank != 0)
2084 maskss = gfc_walk_expr (maskexpr);
2085 gcc_assert (maskss != gfc_ss_terminator);
2090 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2091 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2092 switch (arrayexpr->ts.type)
2095 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
2099 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2100 arrayexpr->ts.kind);
2107 /* We start with the most negative possible value for MAXLOC, and the most
2108 positive possible value for MINLOC. The most negative possible value is
2109 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2110 possible value is HUGE in both cases. */
2112 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2113 gfc_add_modify_expr (&se->pre, limit, tmp);
2115 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2116 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2117 build_int_cst (type, 1));
2119 /* Initialize the scalarizer. */
2120 gfc_init_loopinfo (&loop);
2121 gfc_add_ss_to_loop (&loop, arrayss);
2123 gfc_add_ss_to_loop (&loop, maskss);
2125 /* Initialize the loop. */
2126 gfc_conv_ss_startstride (&loop);
2127 gfc_conv_loop_setup (&loop);
2129 gcc_assert (loop.dimen == 1);
2131 /* Initialize the position to zero, following Fortran 2003. We are free
2132 to do this because Fortran 95 allows the result of an entirely false
2133 mask to be processor dependent. */
2134 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2136 gfc_mark_ss_chain_used (arrayss, 1);
2138 gfc_mark_ss_chain_used (maskss, 1);
2139 /* Generate the loop body. */
2140 gfc_start_scalarized_body (&loop, &body);
2142 /* If we have a mask, only check this element if the mask is set. */
2145 gfc_init_se (&maskse, NULL);
2146 gfc_copy_loopinfo_to_se (&maskse, &loop);
2148 gfc_conv_expr_val (&maskse, maskexpr);
2149 gfc_add_block_to_block (&body, &maskse.pre);
2151 gfc_start_block (&block);
2154 gfc_init_block (&block);
2156 /* Compare with the current limit. */
2157 gfc_init_se (&arrayse, NULL);
2158 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2159 arrayse.ss = arrayss;
2160 gfc_conv_expr_val (&arrayse, arrayexpr);
2161 gfc_add_block_to_block (&block, &arrayse.pre);
2163 /* We do the following if this is a more extreme value. */
2164 gfc_start_block (&ifblock);
2166 /* Assign the value to the limit... */
2167 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2169 /* Remember where we are. An offset must be added to the loop
2170 counter to obtain the required position. */
2172 tmp = build_int_cst (gfc_array_index_type, 1);
2174 tmp =fold_build2 (MINUS_EXPR, gfc_array_index_type,
2175 gfc_index_one_node, loop.from[0]);
2176 gfc_add_modify_expr (&block, offset, tmp);
2178 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2179 loop.loopvar[0], offset);
2180 gfc_add_modify_expr (&ifblock, pos, tmp);
2182 ifbody = gfc_finish_block (&ifblock);
2184 /* If it is a more extreme value or pos is still zero and the value
2185 equal to the limit. */
2186 tmp = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
2187 fold_build2 (EQ_EXPR, boolean_type_node,
2188 pos, gfc_index_zero_node),
2189 fold_build2 (EQ_EXPR, boolean_type_node,
2190 arrayse.expr, limit));
2191 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
2192 fold_build2 (op, boolean_type_node,
2193 arrayse.expr, limit), tmp);
2194 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2195 gfc_add_expr_to_block (&block, tmp);
2199 /* We enclose the above in if (mask) {...}. */
2200 tmp = gfc_finish_block (&block);
2202 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2205 tmp = gfc_finish_block (&block);
2206 gfc_add_expr_to_block (&body, tmp);
2208 gfc_trans_scalarizing_loops (&loop, &body);
2210 /* For a scalar mask, enclose the loop in an if statement. */
2211 if (maskexpr && maskss == NULL)
2213 gfc_init_se (&maskse, NULL);
2214 gfc_conv_expr_val (&maskse, maskexpr);
2215 gfc_init_block (&block);
2216 gfc_add_block_to_block (&block, &loop.pre);
2217 gfc_add_block_to_block (&block, &loop.post);
2218 tmp = gfc_finish_block (&block);
2220 /* For the else part of the scalar mask, just initialize
2221 the pos variable the same way as above. */
2223 gfc_init_block (&elseblock);
2224 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2225 elsetmp = gfc_finish_block (&elseblock);
2227 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2228 gfc_add_expr_to_block (&block, tmp);
2229 gfc_add_block_to_block (&se->pre, &block);
2233 gfc_add_block_to_block (&se->pre, &loop.pre);
2234 gfc_add_block_to_block (&se->pre, &loop.post);
2236 gfc_cleanup_loop (&loop);
2238 se->expr = convert (type, pos);
2242 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2251 gfc_actual_arglist *actual;
2256 gfc_expr *arrayexpr;
2262 gfc_conv_intrinsic_funcall (se, expr);
2266 type = gfc_typenode_for_spec (&expr->ts);
2267 /* Initialize the result. */
2268 limit = gfc_create_var (type, "limit");
2269 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2270 switch (expr->ts.type)
2273 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2277 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2284 /* We start with the most negative possible value for MAXVAL, and the most
2285 positive possible value for MINVAL. The most negative possible value is
2286 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2287 possible value is HUGE in both cases. */
2289 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2291 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2292 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2293 tmp, build_int_cst (type, 1));
2295 gfc_add_modify_expr (&se->pre, limit, tmp);
2297 /* Walk the arguments. */
2298 actual = expr->value.function.actual;
2299 arrayexpr = actual->expr;
2300 arrayss = gfc_walk_expr (arrayexpr);
2301 gcc_assert (arrayss != gfc_ss_terminator);
2303 actual = actual->next->next;
2304 gcc_assert (actual);
2305 maskexpr = actual->expr;
2306 if (maskexpr && maskexpr->rank != 0)
2308 maskss = gfc_walk_expr (maskexpr);
2309 gcc_assert (maskss != gfc_ss_terminator);
2314 /* Initialize the scalarizer. */
2315 gfc_init_loopinfo (&loop);
2316 gfc_add_ss_to_loop (&loop, arrayss);
2318 gfc_add_ss_to_loop (&loop, maskss);
2320 /* Initialize the loop. */
2321 gfc_conv_ss_startstride (&loop);
2322 gfc_conv_loop_setup (&loop);
2324 gfc_mark_ss_chain_used (arrayss, 1);
2326 gfc_mark_ss_chain_used (maskss, 1);
2327 /* Generate the loop body. */
2328 gfc_start_scalarized_body (&loop, &body);
2330 /* If we have a mask, only add this element if the mask is set. */
2333 gfc_init_se (&maskse, NULL);
2334 gfc_copy_loopinfo_to_se (&maskse, &loop);
2336 gfc_conv_expr_val (&maskse, maskexpr);
2337 gfc_add_block_to_block (&body, &maskse.pre);
2339 gfc_start_block (&block);
2342 gfc_init_block (&block);
2344 /* Compare with the current limit. */
2345 gfc_init_se (&arrayse, NULL);
2346 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2347 arrayse.ss = arrayss;
2348 gfc_conv_expr_val (&arrayse, arrayexpr);
2349 gfc_add_block_to_block (&block, &arrayse.pre);
2351 /* Assign the value to the limit... */
2352 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2354 /* If it is a more extreme value. */
2355 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2356 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2357 gfc_add_expr_to_block (&block, tmp);
2358 gfc_add_block_to_block (&block, &arrayse.post);
2360 tmp = gfc_finish_block (&block);
2362 /* We enclose the above in if (mask) {...}. */
2363 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2364 gfc_add_expr_to_block (&body, tmp);
2366 gfc_trans_scalarizing_loops (&loop, &body);
2368 /* For a scalar mask, enclose the loop in an if statement. */
2369 if (maskexpr && maskss == NULL)
2371 gfc_init_se (&maskse, NULL);
2372 gfc_conv_expr_val (&maskse, maskexpr);
2373 gfc_init_block (&block);
2374 gfc_add_block_to_block (&block, &loop.pre);
2375 gfc_add_block_to_block (&block, &loop.post);
2376 tmp = gfc_finish_block (&block);
2378 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2379 gfc_add_expr_to_block (&block, tmp);
2380 gfc_add_block_to_block (&se->pre, &block);
2384 gfc_add_block_to_block (&se->pre, &loop.pre);
2385 gfc_add_block_to_block (&se->pre, &loop.post);
2388 gfc_cleanup_loop (&loop);
2393 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2395 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2401 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2402 type = TREE_TYPE (args[0]);
2404 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2405 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2406 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2407 build_int_cst (type, 0));
2408 type = gfc_typenode_for_spec (&expr->ts);
2409 se->expr = convert (type, tmp);
2412 /* Generate code to perform the specified operation. */
2414 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2418 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2419 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2424 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2428 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2429 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2432 /* Set or clear a single bit. */
2434 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2441 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2442 type = TREE_TYPE (args[0]);
2444 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2450 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2452 se->expr = fold_build2 (op, type, args[0], tmp);
2455 /* Extract a sequence of bits.
2456 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2458 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2465 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2466 type = TREE_TYPE (args[0]);
2468 mask = build_int_cst (type, -1);
2469 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2470 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2472 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2474 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2477 /* RSHIFT (I, SHIFT) = I >> SHIFT
2478 LSHIFT (I, SHIFT) = I << SHIFT */
2480 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2484 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2486 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2487 TREE_TYPE (args[0]), args[0], args[1]);
2490 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2492 : ((shift >= 0) ? i << shift : i >> -shift)
2493 where all shifts are logical shifts. */
2495 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2507 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2508 type = TREE_TYPE (args[0]);
2509 utype = unsigned_type_for (type);
2511 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2513 /* Left shift if positive. */
2514 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2516 /* Right shift if negative.
2517 We convert to an unsigned type because we want a logical shift.
2518 The standard doesn't define the case of shifting negative
2519 numbers, and we try to be compatible with other compilers, most
2520 notably g77, here. */
2521 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
2522 convert (utype, args[0]), width));
2524 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2525 build_int_cst (TREE_TYPE (args[1]), 0));
2526 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2528 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2529 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2531 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
2532 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2534 se->expr = fold_build3 (COND_EXPR, type, cond,
2535 build_int_cst (type, 0), tmp);
2539 /* Circular shift. AKA rotate or barrel shift. */
2542 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2550 unsigned int num_args;
2552 num_args = gfc_intrinsic_argument_list_length (expr);
2553 args = alloca (sizeof (tree) * num_args);
2555 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2559 /* Use a library function for the 3 parameter version. */
2560 tree int4type = gfc_get_int_type (4);
2562 type = TREE_TYPE (args[0]);
2563 /* We convert the first argument to at least 4 bytes, and
2564 convert back afterwards. This removes the need for library
2565 functions for all argument sizes, and function will be
2566 aligned to at least 32 bits, so there's no loss. */
2567 if (expr->ts.kind < 4)
2568 args[0] = convert (int4type, args[0]);
2570 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2571 need loads of library functions. They cannot have values >
2572 BIT_SIZE (I) so the conversion is safe. */
2573 args[1] = convert (int4type, args[1]);
2574 args[2] = convert (int4type, args[2]);
2576 switch (expr->ts.kind)
2581 tmp = gfor_fndecl_math_ishftc4;
2584 tmp = gfor_fndecl_math_ishftc8;
2587 tmp = gfor_fndecl_math_ishftc16;
2592 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2593 /* Convert the result back to the original type, if we extended
2594 the first argument's width above. */
2595 if (expr->ts.kind < 4)
2596 se->expr = convert (type, se->expr);
2600 type = TREE_TYPE (args[0]);
2602 /* Rotate left if positive. */
2603 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2605 /* Rotate right if negative. */
2606 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2607 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2609 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2610 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2611 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2613 /* Do nothing if shift == 0. */
2614 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2615 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2618 /* The length of a character string. */
2620 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2630 gcc_assert (!se->ss);
2632 arg = expr->value.function.actual->expr;
2634 type = gfc_typenode_for_spec (&expr->ts);
2635 switch (arg->expr_type)
2638 len = build_int_cst (NULL_TREE, arg->value.character.length);
2642 /* Obtain the string length from the function used by
2643 trans-array.c(gfc_trans_array_constructor). */
2645 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2649 if (arg->ref == NULL
2650 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2652 /* This doesn't catch all cases.
2653 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2654 and the surrounding thread. */
2655 sym = arg->symtree->n.sym;
2656 decl = gfc_get_symbol_decl (sym);
2657 if (decl == current_function_decl && sym->attr.function
2658 && (sym->result == sym))
2659 decl = gfc_get_fake_result_decl (sym, 0);
2661 len = sym->ts.cl->backend_decl;
2666 /* Otherwise fall through. */
2669 /* Anybody stupid enough to do this deserves inefficient code. */
2670 ss = gfc_walk_expr (arg);
2671 gfc_init_se (&argse, se);
2672 if (ss == gfc_ss_terminator)
2673 gfc_conv_expr (&argse, arg);
2675 gfc_conv_expr_descriptor (&argse, arg, ss);
2676 gfc_add_block_to_block (&se->pre, &argse.pre);
2677 gfc_add_block_to_block (&se->post, &argse.post);
2678 len = argse.string_length;
2681 se->expr = convert (type, len);
2684 /* The length of a character string not including trailing blanks. */
2686 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2691 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2692 type = gfc_typenode_for_spec (&expr->ts);
2693 se->expr = build_call_expr (gfor_fndecl_string_len_trim, 2, args[0], args[1]);
2694 se->expr = convert (type, se->expr);
2698 /* Returns the starting position of a substring within a string. */
2701 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
2704 tree logical4_type_node = gfc_get_logical_type (4);
2708 unsigned int num_args;
2710 num_args = gfc_intrinsic_argument_list_length (expr);
2711 args = alloca (sizeof (tree) * 5);
2713 gfc_conv_intrinsic_function_args (se, expr, args,
2714 num_args >= 5 ? 5 : num_args);
2715 type = gfc_typenode_for_spec (&expr->ts);
2718 args[4] = build_int_cst (logical4_type_node, 0);
2720 args[4] = convert (logical4_type_node, args[4]);
2722 fndecl = build_addr (function, current_function_decl);
2723 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (function)), fndecl,
2725 se->expr = convert (type, se->expr);
2729 /* The ascii value for a single character. */
2731 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2736 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2737 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
2738 args[1] = fold_build1 (NOP_EXPR, pchar_type_node, args[1]);
2739 type = gfc_typenode_for_spec (&expr->ts);
2741 se->expr = build_fold_indirect_ref (args[1]);
2742 se->expr = convert (type, se->expr);
2746 /* Intrinsic ISNAN calls __builtin_isnan. */
2749 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
2753 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2754 se->expr = build_call_expr (built_in_decls[BUILT_IN_ISNAN], 1, arg);
2755 STRIP_TYPE_NOPS (se->expr);
2756 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2760 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
2761 their argument against a constant integer value. */
2764 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
2768 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2769 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
2770 arg, build_int_cst (TREE_TYPE (arg), value));
2775 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2778 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2786 unsigned int num_args;
2788 num_args = gfc_intrinsic_argument_list_length (expr);
2789 args = alloca (sizeof (tree) * num_args);
2791 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2792 if (expr->ts.type != BT_CHARACTER)
2800 /* We do the same as in the non-character case, but the argument
2801 list is different because of the string length arguments. We
2802 also have to set the string length for the result. */
2808 se->string_length = len;
2810 type = TREE_TYPE (tsource);
2811 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2815 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
2817 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
2819 tree arg, type, tmp;
2822 switch (expr->ts.kind)
2825 frexp = BUILT_IN_FREXPF;
2828 frexp = BUILT_IN_FREXP;
2832 frexp = BUILT_IN_FREXPL;
2838 type = gfc_typenode_for_spec (&expr->ts);
2839 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2840 tmp = gfc_create_var (integer_type_node, NULL);
2841 se->expr = build_call_expr (built_in_decls[frexp], 2,
2842 fold_convert (type, arg),
2843 build_fold_addr_expr (tmp));
2844 se->expr = fold_convert (type, se->expr);
2848 /* NEAREST (s, dir) is translated into
2849 tmp = copysign (INF, dir);
2850 return nextafter (s, tmp);
2853 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
2855 tree args[2], type, tmp;
2856 int nextafter, copysign, inf;
2858 switch (expr->ts.kind)
2861 nextafter = BUILT_IN_NEXTAFTERF;
2862 copysign = BUILT_IN_COPYSIGNF;
2863 inf = BUILT_IN_INFF;
2866 nextafter = BUILT_IN_NEXTAFTER;
2867 copysign = BUILT_IN_COPYSIGN;
2872 nextafter = BUILT_IN_NEXTAFTERL;
2873 copysign = BUILT_IN_COPYSIGNL;
2874 inf = BUILT_IN_INFL;
2880 type = gfc_typenode_for_spec (&expr->ts);
2881 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2882 tmp = build_call_expr (built_in_decls[copysign], 2,
2883 build_call_expr (built_in_decls[inf], 0),
2884 fold_convert (type, args[1]));
2885 se->expr = build_call_expr (built_in_decls[nextafter], 2,
2886 fold_convert (type, args[0]), tmp);
2887 se->expr = fold_convert (type, se->expr);
2891 /* SPACING (s) is translated into
2899 e = MAX_EXPR (e, emin);
2900 res = scalbn (1., e);
2904 where prec is the precision of s, gfc_real_kinds[k].digits,
2905 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
2906 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
2909 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2911 tree arg, type, prec, emin, tiny, res, e;
2913 int frexp, scalbn, k;
2916 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
2917 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
2918 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
2919 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind);
2921 switch (expr->ts.kind)
2924 frexp = BUILT_IN_FREXPF;
2925 scalbn = BUILT_IN_SCALBNF;
2928 frexp = BUILT_IN_FREXP;
2929 scalbn = BUILT_IN_SCALBN;
2933 frexp = BUILT_IN_FREXPL;
2934 scalbn = BUILT_IN_SCALBNL;
2940 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2941 arg = gfc_evaluate_now (arg, &se->pre);
2943 type = gfc_typenode_for_spec (&expr->ts);
2944 e = gfc_create_var (integer_type_node, NULL);
2945 res = gfc_create_var (type, NULL);
2948 /* Build the block for s /= 0. */
2949 gfc_start_block (&block);
2950 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
2951 build_fold_addr_expr (e));
2952 gfc_add_expr_to_block (&block, tmp);
2954 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
2955 gfc_add_modify_expr (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
2958 tmp = build_call_expr (built_in_decls[scalbn], 2,
2959 build_real_from_int_cst (type, integer_one_node), e);
2960 gfc_add_modify_expr (&block, res, tmp);
2962 /* Finish by building the IF statement. */
2963 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
2964 build_real_from_int_cst (type, integer_zero_node));
2965 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
2966 gfc_finish_block (&block));
2968 gfc_add_expr_to_block (&se->pre, tmp);
2973 /* RRSPACING (s) is translated into
2980 x = scalbn (x, precision - e);
2984 where precision is gfc_real_kinds[k].digits. */
2987 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2989 tree arg, type, e, x, cond, stmt, tmp;
2990 int frexp, scalbn, fabs, prec, k;
2993 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
2994 prec = gfc_real_kinds[k].digits;
2995 switch (expr->ts.kind)
2998 frexp = BUILT_IN_FREXPF;
2999 scalbn = BUILT_IN_SCALBNF;
3000 fabs = BUILT_IN_FABSF;
3003 frexp = BUILT_IN_FREXP;
3004 scalbn = BUILT_IN_SCALBN;
3005 fabs = BUILT_IN_FABS;
3009 frexp = BUILT_IN_FREXPL;
3010 scalbn = BUILT_IN_SCALBNL;
3011 fabs = BUILT_IN_FABSL;
3017 type = gfc_typenode_for_spec (&expr->ts);
3018 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3019 arg = gfc_evaluate_now (arg, &se->pre);
3021 e = gfc_create_var (integer_type_node, NULL);
3022 x = gfc_create_var (type, NULL);
3023 gfc_add_modify_expr (&se->pre, x,
3024 build_call_expr (built_in_decls[fabs], 1, arg));
3027 gfc_start_block (&block);
3028 tmp = build_call_expr (built_in_decls[frexp], 2, arg,
3029 build_fold_addr_expr (e));
3030 gfc_add_expr_to_block (&block, tmp);
3032 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3033 build_int_cst (NULL_TREE, prec), e);
3034 tmp = build_call_expr (built_in_decls[scalbn], 2, x, tmp);
3035 gfc_add_modify_expr (&block, x, tmp);
3036 stmt = gfc_finish_block (&block);
3038 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3039 build_real_from_int_cst (type, integer_zero_node));
3040 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt ());
3041 gfc_add_expr_to_block (&se->pre, tmp);
3043 se->expr = fold_convert (type, x);
3047 /* SCALE (s, i) is translated into scalbn (s, i). */
3049 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3054 switch (expr->ts.kind)
3057 scalbn = BUILT_IN_SCALBNF;
3060 scalbn = BUILT_IN_SCALBN;
3064 scalbn = BUILT_IN_SCALBNL;
3070 type = gfc_typenode_for_spec (&expr->ts);
3071 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3072 se->expr = build_call_expr (built_in_decls[scalbn], 2,
3073 fold_convert (type, args[0]),
3074 fold_convert (integer_type_node, args[1]));
3075 se->expr = fold_convert (type, se->expr);
3079 /* SET_EXPONENT (s, i) is translated into
3080 scalbn (frexp (s, &dummy_int), i). */
3082 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3084 tree args[2], type, tmp;
3087 switch (expr->ts.kind)
3090 frexp = BUILT_IN_FREXPF;
3091 scalbn = BUILT_IN_SCALBNF;
3094 frexp = BUILT_IN_FREXP;
3095 scalbn = BUILT_IN_SCALBN;
3099 frexp = BUILT_IN_FREXPL;
3100 scalbn = BUILT_IN_SCALBNL;
3106 type = gfc_typenode_for_spec (&expr->ts);
3107 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3109 tmp = gfc_create_var (integer_type_node, NULL);
3110 tmp = build_call_expr (built_in_decls[frexp], 2,
3111 fold_convert (type, args[0]),
3112 build_fold_addr_expr (tmp));
3113 se->expr = build_call_expr (built_in_decls[scalbn], 2, tmp,
3114 fold_convert (integer_type_node, args[1]));
3115 se->expr = fold_convert (type, se->expr);
3120 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3122 gfc_actual_arglist *actual;
3130 gfc_init_se (&argse, NULL);
3131 actual = expr->value.function.actual;
3133 ss = gfc_walk_expr (actual->expr);
3134 gcc_assert (ss != gfc_ss_terminator);
3135 argse.want_pointer = 1;
3136 argse.data_not_needed = 1;
3137 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3138 gfc_add_block_to_block (&se->pre, &argse.pre);
3139 gfc_add_block_to_block (&se->post, &argse.post);
3140 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3142 /* Build the call to size0. */
3143 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
3145 actual = actual->next;
3149 gfc_init_se (&argse, NULL);
3150 gfc_conv_expr_type (&argse, actual->expr,
3151 gfc_array_index_type);
3152 gfc_add_block_to_block (&se->pre, &argse.pre);
3154 /* Build the call to size1. */
3155 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
3158 /* Unusually, for an intrinsic, size does not exclude
3159 an optional arg2, so we must test for it. */
3160 if (actual->expr->expr_type == EXPR_VARIABLE
3161 && actual->expr->symtree->n.sym->attr.dummy
3162 && actual->expr->symtree->n.sym->attr.optional)
3165 gfc_init_se (&argse, NULL);
3166 argse.want_pointer = 1;
3167 argse.data_not_needed = 1;
3168 gfc_conv_expr (&argse, actual->expr);
3169 gfc_add_block_to_block (&se->pre, &argse.pre);
3170 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3171 argse.expr, null_pointer_node);
3172 tmp = gfc_evaluate_now (tmp, &se->pre);
3173 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3174 tmp, fncall1, fncall0);
3182 type = gfc_typenode_for_spec (&expr->ts);
3183 se->expr = convert (type, se->expr);
3188 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3202 arg = expr->value.function.actual->expr;
3204 gfc_init_se (&argse, NULL);
3205 ss = gfc_walk_expr (arg);
3207 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3209 if (ss == gfc_ss_terminator)
3211 gfc_conv_expr_reference (&argse, arg);
3212 source = argse.expr;
3214 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3216 /* Obtain the source word length. */
3217 if (arg->ts.type == BT_CHARACTER)
3218 source_bytes = fold_convert (gfc_array_index_type,
3219 argse.string_length);
3221 source_bytes = fold_convert (gfc_array_index_type,
3222 size_in_bytes (type));
3226 argse.want_pointer = 0;
3227 gfc_conv_expr_descriptor (&argse, arg, ss);
3228 source = gfc_conv_descriptor_data_get (argse.expr);
3229 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3231 /* Obtain the argument's word length. */
3232 if (arg->ts.type == BT_CHARACTER)
3233 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3235 tmp = fold_convert (gfc_array_index_type,
3236 size_in_bytes (type));
3237 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3239 /* Obtain the size of the array in bytes. */
3240 for (n = 0; n < arg->rank; n++)
3243 idx = gfc_rank_cst[n];
3244 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3245 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3246 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3248 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3249 tmp, gfc_index_one_node);
3250 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3252 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3256 gfc_add_block_to_block (&se->pre, &argse.pre);
3257 se->expr = source_bytes;
3261 /* Intrinsic string comparison functions. */
3264 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
3268 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3270 se->expr = gfc_build_compare_string (args[0], args[1], args[2], args[3]);
3271 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3272 build_int_cst (TREE_TYPE (se->expr), 0));
3275 /* Generate a call to the adjustl/adjustr library function. */
3277 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3285 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3288 type = TREE_TYPE (args[2]);
3289 var = gfc_conv_string_tmp (se, type, len);
3292 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
3293 gfc_add_expr_to_block (&se->pre, tmp);
3295 se->string_length = len;
3299 /* Array transfer statement.
3300 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3302 typeof<DEST> = typeof<MOLD>
3304 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3305 sizeof (DEST(0) * SIZE). */
3308 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
3323 gfc_actual_arglist *arg;
3330 gcc_assert (se->loop);
3331 info = &se->ss->data.info;
3333 /* Convert SOURCE. The output from this stage is:-
3334 source_bytes = length of the source in bytes
3335 source = pointer to the source data. */
3336 arg = expr->value.function.actual;
3337 gfc_init_se (&argse, NULL);
3338 ss = gfc_walk_expr (arg->expr);
3340 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
3342 /* Obtain the pointer to source and the length of source in bytes. */
3343 if (ss == gfc_ss_terminator)
3345 gfc_conv_expr_reference (&argse, arg->expr);
3346 source = argse.expr;
3348 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3350 /* Obtain the source word length. */
3351 if (arg->expr->ts.type == BT_CHARACTER)
3352 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3354 tmp = fold_convert (gfc_array_index_type,
3355 size_in_bytes (source_type));
3359 argse.want_pointer = 0;
3360 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3361 source = gfc_conv_descriptor_data_get (argse.expr);
3362 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3364 /* Repack the source if not a full variable array. */
3365 if (!(arg->expr->expr_type == EXPR_VARIABLE
3366 && arg->expr->ref->u.ar.type == AR_FULL))
3368 tmp = build_fold_addr_expr (argse.expr);
3369 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
3370 source = gfc_evaluate_now (source, &argse.pre);
3372 /* Free the temporary. */
3373 gfc_start_block (&block);
3374 tmp = gfc_call_free (convert (pvoid_type_node, source));
3375 gfc_add_expr_to_block (&block, tmp);
3376 stmt = gfc_finish_block (&block);
3378 /* Clean up if it was repacked. */
3379 gfc_init_block (&block);
3380 tmp = gfc_conv_array_data (argse.expr);
3381 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
3382 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
3383 gfc_add_expr_to_block (&block, tmp);
3384 gfc_add_block_to_block (&block, &se->post);
3385 gfc_init_block (&se->post);
3386 gfc_add_block_to_block (&se->post, &block);
3389 /* Obtain the source word length. */
3390 if (arg->expr->ts.type == BT_CHARACTER)
3391 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3393 tmp = fold_convert (gfc_array_index_type,
3394 size_in_bytes (source_type));
3396 /* Obtain the size of the array in bytes. */
3397 extent = gfc_create_var (gfc_array_index_type, NULL);
3398 for (n = 0; n < arg->expr->rank; n++)
3401 idx = gfc_rank_cst[n];
3402 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3403 stride = gfc_conv_descriptor_stride (argse.expr, idx);
3404 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
3405 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
3406 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3408 gfc_add_modify_expr (&argse.pre, extent, tmp);
3409 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3410 extent, gfc_index_one_node);
3411 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3416 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
3417 gfc_add_block_to_block (&se->pre, &argse.pre);
3418 gfc_add_block_to_block (&se->post, &argse.post);
3420 /* Now convert MOLD. The outputs are:
3421 mold_type = the TREE type of MOLD
3422 dest_word_len = destination word length in bytes. */
3425 gfc_init_se (&argse, NULL);
3426 ss = gfc_walk_expr (arg->expr);
3428 if (ss == gfc_ss_terminator)
3430 gfc_conv_expr_reference (&argse, arg->expr);
3431 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3435 gfc_init_se (&argse, NULL);
3436 argse.want_pointer = 0;
3437 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3438 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3441 if (arg->expr->ts.type == BT_CHARACTER)
3443 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3444 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3447 tmp = fold_convert (gfc_array_index_type,
3448 size_in_bytes (mold_type));
3450 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3451 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
3453 /* Finally convert SIZE, if it is present. */
3455 size_words = gfc_create_var (gfc_array_index_type, NULL);
3459 gfc_init_se (&argse, NULL);
3460 gfc_conv_expr_reference (&argse, arg->expr);
3461 tmp = convert (gfc_array_index_type,
3462 build_fold_indirect_ref (argse.expr));
3463 gfc_add_block_to_block (&se->pre, &argse.pre);
3464 gfc_add_block_to_block (&se->post, &argse.post);
3469 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3470 if (tmp != NULL_TREE)
3472 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3473 tmp, dest_word_len);
3474 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3480 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
3481 gfc_add_modify_expr (&se->pre, size_words,
3482 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3483 size_bytes, dest_word_len));
3485 /* Evaluate the bounds of the result. If the loop range exists, we have
3486 to check if it is too large. If so, we modify loop->to be consistent
3487 with min(size, size(source)). Otherwise, size is made consistent with
3488 the loop range, so that the right number of bytes is transferred.*/
3489 n = se->loop->order[0];
3490 if (se->loop->to[n] != NULL_TREE)
3492 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3493 se->loop->to[n], se->loop->from[n]);
3494 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3495 tmp, gfc_index_one_node);
3496 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3498 gfc_add_modify_expr (&se->pre, size_words, tmp);
3499 gfc_add_modify_expr (&se->pre, size_bytes,
3500 fold_build2 (MULT_EXPR, gfc_array_index_type,
3501 size_words, dest_word_len));
3502 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3503 size_words, se->loop->from[n]);
3504 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3505 upper, gfc_index_one_node);
3509 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3510 size_words, gfc_index_one_node);
3511 se->loop->from[n] = gfc_index_zero_node;
3514 se->loop->to[n] = upper;
3516 /* Build a destination descriptor, using the pointer, source, as the
3517 data field. This is already allocated so set callee_alloc.
3518 FIXME callee_alloc is not set! */
3520 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3521 info, mold_type, false, true, false);
3523 /* Cast the pointer to the result. */
3524 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3525 tmp = fold_convert (pvoid_type_node, tmp);
3527 /* Use memcpy to do the transfer. */
3528 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3531 fold_convert (pvoid_type_node, source),
3533 gfc_add_expr_to_block (&se->pre, tmp);
3535 se->expr = info->descriptor;
3536 if (expr->ts.type == BT_CHARACTER)
3537 se->string_length = dest_word_len;
3541 /* Scalar transfer statement.
3542 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3545 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3547 gfc_actual_arglist *arg;
3554 /* Get a pointer to the source. */
3555 arg = expr->value.function.actual;
3556 ss = gfc_walk_expr (arg->expr);
3557 gfc_init_se (&argse, NULL);
3558 if (ss == gfc_ss_terminator)
3559 gfc_conv_expr_reference (&argse, arg->expr);
3561 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3562 gfc_add_block_to_block (&se->pre, &argse.pre);
3563 gfc_add_block_to_block (&se->post, &argse.post);
3567 type = gfc_typenode_for_spec (&expr->ts);
3569 if (expr->ts.type == BT_CHARACTER)
3571 ptr = convert (build_pointer_type (type), ptr);
3572 gfc_init_se (&argse, NULL);
3573 gfc_conv_expr (&argse, arg->expr);
3574 gfc_add_block_to_block (&se->pre, &argse.pre);
3575 gfc_add_block_to_block (&se->post, &argse.post);
3577 se->string_length = argse.string_length;
3582 tmpdecl = gfc_create_var (type, "transfer");
3583 moldsize = size_in_bytes (type);
3585 /* Use memcpy to do the transfer. */
3586 tmp = fold_build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3587 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3588 fold_convert (pvoid_type_node, tmp),
3589 fold_convert (pvoid_type_node, ptr),
3591 gfc_add_expr_to_block (&se->pre, tmp);
3598 /* Generate code for the ALLOCATED intrinsic.
3599 Generate inline code that directly check the address of the argument. */
3602 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3604 gfc_actual_arglist *arg1;
3609 gfc_init_se (&arg1se, NULL);
3610 arg1 = expr->value.function.actual;
3611 ss1 = gfc_walk_expr (arg1->expr);
3612 arg1se.descriptor_only = 1;
3613 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3615 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3616 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3617 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
3618 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3622 /* Generate code for the ASSOCIATED intrinsic.
3623 If both POINTER and TARGET are arrays, generate a call to library function
3624 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3625 In other cases, generate inline code that directly compare the address of
3626 POINTER with the address of TARGET. */
3629 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3631 gfc_actual_arglist *arg1;
3632 gfc_actual_arglist *arg2;
3637 tree nonzero_charlen;
3638 tree nonzero_arraylen;
3641 gfc_init_se (&arg1se, NULL);
3642 gfc_init_se (&arg2se, NULL);
3643 arg1 = expr->value.function.actual;
3645 ss1 = gfc_walk_expr (arg1->expr);
3649 /* No optional target. */
3650 if (ss1 == gfc_ss_terminator)
3652 /* A pointer to a scalar. */
3653 arg1se.want_pointer = 1;
3654 gfc_conv_expr (&arg1se, arg1->expr);
3659 /* A pointer to an array. */
3660 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3661 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3663 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3664 gfc_add_block_to_block (&se->post, &arg1se.post);
3665 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
3666 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3671 /* An optional target. */
3672 ss2 = gfc_walk_expr (arg2->expr);
3674 nonzero_charlen = NULL_TREE;
3675 if (arg1->expr->ts.type == BT_CHARACTER)
3676 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
3677 arg1->expr->ts.cl->backend_decl,
3680 if (ss1 == gfc_ss_terminator)
3682 /* A pointer to a scalar. */
3683 gcc_assert (ss2 == gfc_ss_terminator);
3684 arg1se.want_pointer = 1;
3685 gfc_conv_expr (&arg1se, arg1->expr);
3686 arg2se.want_pointer = 1;
3687 gfc_conv_expr (&arg2se, arg2->expr);
3688 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3689 gfc_add_block_to_block (&se->post, &arg1se.post);
3690 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
3691 arg1se.expr, arg2se.expr);
3692 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
3693 arg1se.expr, null_pointer_node);
3694 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3699 /* An array pointer of zero length is not associated if target is
3701 arg1se.descriptor_only = 1;
3702 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3703 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3704 gfc_rank_cst[arg1->expr->rank - 1]);
3705 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
3706 build_int_cst (TREE_TYPE (tmp), 0));
3708 /* A pointer to an array, call library function _gfor_associated. */
3709 gcc_assert (ss2 != gfc_ss_terminator);
3710 arg1se.want_pointer = 1;
3711 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3713 arg2se.want_pointer = 1;
3714 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3715 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3716 gfc_add_block_to_block (&se->post, &arg2se.post);
3717 se->expr = build_call_expr (gfor_fndecl_associated, 2,
3718 arg1se.expr, arg2se.expr);
3719 se->expr = convert (boolean_type_node, se->expr);
3720 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3721 se->expr, nonzero_arraylen);
3724 /* If target is present zero character length pointers cannot
3726 if (nonzero_charlen != NULL_TREE)
3727 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
3728 se->expr, nonzero_charlen);
3731 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3735 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3738 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
3742 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3744 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
3745 type = gfc_get_int_type (4);
3746 arg = build_fold_addr_expr (fold_convert (type, arg));
3748 /* Convert it to the required type. */
3749 type = gfc_typenode_for_spec (&expr->ts);
3750 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
3751 se->expr = fold_convert (type, se->expr);
3755 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3758 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
3760 gfc_actual_arglist *actual;
3765 for (actual = expr->value.function.actual; actual; actual = actual->next)
3767 gfc_init_se (&argse, se);
3769 /* Pass a NULL pointer for an absent arg. */
3770 if (actual->expr == NULL)
3771 argse.expr = null_pointer_node;
3777 if (actual->expr->ts.kind != gfc_c_int_kind)
3779 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
3780 ts.type = BT_INTEGER;
3781 ts.kind = gfc_c_int_kind;
3782 gfc_convert_type (actual->expr, &ts, 2);
3784 gfc_conv_expr_reference (&argse, actual->expr);
3787 gfc_add_block_to_block (&se->pre, &argse.pre);
3788 gfc_add_block_to_block (&se->post, &argse.post);
3789 args = gfc_chainon_list (args, argse.expr);
3792 /* Convert it to the required type. */
3793 type = gfc_typenode_for_spec (&expr->ts);
3794 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3795 se->expr = fold_convert (type, se->expr);
3799 /* Generate code for TRIM (A) intrinsic function. */
3802 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3804 tree gfc_int4_type_node = gfc_get_int_type (4);
3813 unsigned int num_args;
3815 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
3816 args = alloca (sizeof (tree) * num_args);
3818 type = build_pointer_type (gfc_character1_type_node);
3819 var = gfc_create_var (type, "pstr");
3820 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3821 len = gfc_create_var (gfc_int4_type_node, "len");
3823 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
3824 args[0] = build_fold_addr_expr (len);
3827 fndecl = build_addr (gfor_fndecl_string_trim, current_function_decl);
3828 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_trim)),
3829 fndecl, num_args, args);
3830 gfc_add_expr_to_block (&se->pre, tmp);
3832 /* Free the temporary afterwards, if necessary. */
3833 cond = fold_build2 (GT_EXPR, boolean_type_node,
3834 len, build_int_cst (TREE_TYPE (len), 0));
3835 tmp = gfc_call_free (var);
3836 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3837 gfc_add_expr_to_block (&se->post, tmp);
3840 se->string_length = len;
3844 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3847 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3849 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
3850 tree type, cond, tmp, count, exit_label, n, max, largest;
3851 stmtblock_t block, body;
3854 /* Get the arguments. */
3855 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3856 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
3858 ncopies = gfc_evaluate_now (args[2], &se->pre);
3859 ncopies_type = TREE_TYPE (ncopies);
3861 /* Check that NCOPIES is not negative. */
3862 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3863 build_int_cst (ncopies_type, 0));
3864 gfc_trans_runtime_check (cond, &se->pre, &expr->where,
3865 "Argument NCOPIES of REPEAT intrinsic is negative "
3866 "(its value is %lld)",
3867 fold_convert (long_integer_type_node, ncopies));
3869 /* If the source length is zero, any non negative value of NCOPIES
3870 is valid, and nothing happens. */
3871 n = gfc_create_var (ncopies_type, "ncopies");
3872 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3873 build_int_cst (size_type_node, 0));
3874 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
3875 build_int_cst (ncopies_type, 0), ncopies);
3876 gfc_add_modify_expr (&se->pre, n, tmp);
3879 /* Check that ncopies is not too large: ncopies should be less than
3880 (or equal to) MAX / slen, where MAX is the maximal integer of
3881 the gfc_charlen_type_node type. If slen == 0, we need a special
3882 case to avoid the division by zero. */
3883 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
3884 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
3885 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
3886 fold_convert (size_type_node, max), slen);
3887 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
3888 ? size_type_node : ncopies_type;
3889 cond = fold_build2 (GT_EXPR, boolean_type_node,
3890 fold_convert (largest, ncopies),
3891 fold_convert (largest, max));
3892 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3893 build_int_cst (size_type_node, 0));
3894 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
3896 gfc_trans_runtime_check (cond, &se->pre, &expr->where,
3897 "Argument NCOPIES of REPEAT intrinsic is too large");
3900 /* Compute the destination length. */
3901 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
3902 fold_convert (gfc_charlen_type_node, slen),
3903 fold_convert (gfc_charlen_type_node, ncopies));
3904 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3905 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
3907 /* Generate the code to do the repeat operation:
3908 for (i = 0; i < ncopies; i++)
3909 memmove (dest + (i * slen), src, slen); */
3910 gfc_start_block (&block);
3911 count = gfc_create_var (ncopies_type, "count");
3912 gfc_add_modify_expr (&block, count, build_int_cst (ncopies_type, 0));
3913 exit_label = gfc_build_label_decl (NULL_TREE);
3915 /* Start the loop body. */
3916 gfc_start_block (&body);
3918 /* Exit the loop if count >= ncopies. */
3919 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
3920 tmp = build1_v (GOTO_EXPR, exit_label);
3921 TREE_USED (exit_label) = 1;
3922 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3923 build_empty_stmt ());
3924 gfc_add_expr_to_block (&body, tmp);
3926 /* Call memmove (dest + (i*slen), src, slen). */
3927 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
3928 fold_convert (gfc_charlen_type_node, slen),
3929 fold_convert (gfc_charlen_type_node, count));
3930 tmp = fold_build2 (POINTER_PLUS_EXPR, pchar_type_node,
3931 fold_convert (pchar_type_node, dest),
3932 fold_convert (sizetype, tmp));
3933 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3,
3935 gfc_add_expr_to_block (&body, tmp);
3937 /* Increment count. */
3938 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
3939 count, build_int_cst (TREE_TYPE (count), 1));
3940 gfc_add_modify_expr (&body, count, tmp);
3942 /* Build the loop. */
3943 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
3944 gfc_add_expr_to_block (&block, tmp);
3946 /* Add the exit label. */
3947 tmp = build1_v (LABEL_EXPR, exit_label);
3948 gfc_add_expr_to_block (&block, tmp);
3950 /* Finish the block. */
3951 tmp = gfc_finish_block (&block);
3952 gfc_add_expr_to_block (&se->pre, tmp);
3954 /* Set the result value. */
3956 se->string_length = dlen;
3960 /* Generate code for the IARGC intrinsic. */
3963 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3969 /* Call the library function. This always returns an INTEGER(4). */
3970 fndecl = gfor_fndecl_iargc;
3971 tmp = build_call_expr (fndecl, 0);
3973 /* Convert it to the required type. */
3974 type = gfc_typenode_for_spec (&expr->ts);
3975 tmp = fold_convert (type, tmp);
3981 /* The loc intrinsic returns the address of its argument as
3982 gfc_index_integer_kind integer. */
3985 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3991 gcc_assert (!se->ss);
3993 arg_expr = expr->value.function.actual->expr;
3994 ss = gfc_walk_expr (arg_expr);
3995 if (ss == gfc_ss_terminator)
3996 gfc_conv_expr_reference (se, arg_expr);
3998 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3999 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4001 /* Create a temporary variable for loc return value. Without this,
4002 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4003 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4004 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
4005 se->expr = temp_var;
4008 /* Generate code for an intrinsic function. Some map directly to library
4009 calls, others get special handling. In some cases the name of the function
4010 used depends on the type specifiers. */
4013 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4015 gfc_intrinsic_sym *isym;
4019 isym = expr->value.function.isym;
4021 name = &expr->value.function.name[2];
4023 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4025 lib = gfc_is_intrinsic_libcall (expr);
4029 se->ignore_optional = 1;
4030 gfc_conv_intrinsic_funcall (se, expr);
4035 switch (expr->value.function.isym->id)
4040 case GFC_ISYM_REPEAT:
4041 gfc_conv_intrinsic_repeat (se, expr);
4045 gfc_conv_intrinsic_trim (se, expr);
4048 case GFC_ISYM_SI_KIND:
4049 gfc_conv_intrinsic_si_kind (se, expr);
4052 case GFC_ISYM_SR_KIND:
4053 gfc_conv_intrinsic_sr_kind (se, expr);
4056 case GFC_ISYM_EXPONENT:
4057 gfc_conv_intrinsic_exponent (se, expr);
4061 gfc_conv_intrinsic_index_scan_verify (se, expr, gfor_fndecl_string_scan);
4064 case GFC_ISYM_VERIFY:
4065 gfc_conv_intrinsic_index_scan_verify (se, expr, gfor_fndecl_string_verify);
4068 case GFC_ISYM_ALLOCATED:
4069 gfc_conv_allocated (se, expr);
4072 case GFC_ISYM_ASSOCIATED:
4073 gfc_conv_associated(se, expr);
4077 gfc_conv_intrinsic_abs (se, expr);
4080 case GFC_ISYM_ADJUSTL:
4081 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
4084 case GFC_ISYM_ADJUSTR:
4085 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
4088 case GFC_ISYM_AIMAG:
4089 gfc_conv_intrinsic_imagpart (se, expr);
4093 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4097 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4100 case GFC_ISYM_ANINT:
4101 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4105 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4109 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4112 case GFC_ISYM_BTEST:
4113 gfc_conv_intrinsic_btest (se, expr);
4116 case GFC_ISYM_ACHAR:
4118 gfc_conv_intrinsic_char (se, expr);
4121 case GFC_ISYM_CONVERSION:
4123 case GFC_ISYM_LOGICAL:
4125 gfc_conv_intrinsic_conversion (se, expr);
4128 /* Integer conversions are handled separately to make sure we get the
4129 correct rounding mode. */
4134 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
4138 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
4141 case GFC_ISYM_CEILING:
4142 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
4145 case GFC_ISYM_FLOOR:
4146 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
4150 gfc_conv_intrinsic_mod (se, expr, 0);
4153 case GFC_ISYM_MODULO:
4154 gfc_conv_intrinsic_mod (se, expr, 1);
4157 case GFC_ISYM_CMPLX:
4158 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
4161 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
4162 gfc_conv_intrinsic_iargc (se, expr);
4165 case GFC_ISYM_COMPLEX:
4166 gfc_conv_intrinsic_cmplx (se, expr, 1);
4169 case GFC_ISYM_CONJG:
4170 gfc_conv_intrinsic_conjg (se, expr);
4173 case GFC_ISYM_COUNT:
4174 gfc_conv_intrinsic_count (se, expr);
4177 case GFC_ISYM_CTIME:
4178 gfc_conv_intrinsic_ctime (se, expr);
4182 gfc_conv_intrinsic_dim (se, expr);
4185 case GFC_ISYM_DOT_PRODUCT:
4186 gfc_conv_intrinsic_dot_product (se, expr);
4189 case GFC_ISYM_DPROD:
4190 gfc_conv_intrinsic_dprod (se, expr);
4193 case GFC_ISYM_FDATE:
4194 gfc_conv_intrinsic_fdate (se, expr);
4197 case GFC_ISYM_FRACTION:
4198 gfc_conv_intrinsic_fraction (se, expr);
4202 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4205 case GFC_ISYM_IBCLR:
4206 gfc_conv_intrinsic_singlebitop (se, expr, 0);
4209 case GFC_ISYM_IBITS:
4210 gfc_conv_intrinsic_ibits (se, expr);
4213 case GFC_ISYM_IBSET:
4214 gfc_conv_intrinsic_singlebitop (se, expr, 1);
4217 case GFC_ISYM_IACHAR:
4218 case GFC_ISYM_ICHAR:
4219 /* We assume ASCII character sequence. */
4220 gfc_conv_intrinsic_ichar (se, expr);
4223 case GFC_ISYM_IARGC:
4224 gfc_conv_intrinsic_iargc (se, expr);
4228 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4231 case GFC_ISYM_INDEX:
4232 gfc_conv_intrinsic_index_scan_verify (se, expr, gfor_fndecl_string_index);
4236 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4239 case GFC_ISYM_IS_IOSTAT_END:
4240 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
4243 case GFC_ISYM_IS_IOSTAT_EOR:
4244 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
4247 case GFC_ISYM_ISNAN:
4248 gfc_conv_intrinsic_isnan (se, expr);
4251 case GFC_ISYM_LSHIFT:
4252 gfc_conv_intrinsic_rlshift (se, expr, 0);
4255 case GFC_ISYM_RSHIFT:
4256 gfc_conv_intrinsic_rlshift (se, expr, 1);
4259 case GFC_ISYM_ISHFT:
4260 gfc_conv_intrinsic_ishft (se, expr);
4263 case GFC_ISYM_ISHFTC:
4264 gfc_conv_intrinsic_ishftc (se, expr);
4267 case GFC_ISYM_LBOUND:
4268 gfc_conv_intrinsic_bound (se, expr, 0);
4271 case GFC_ISYM_TRANSPOSE:
4272 if (se->ss && se->ss->useflags)
4274 gfc_conv_tmp_array_ref (se);
4275 gfc_advance_se_ss_chain (se);
4278 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
4282 gfc_conv_intrinsic_len (se, expr);
4285 case GFC_ISYM_LEN_TRIM:
4286 gfc_conv_intrinsic_len_trim (se, expr);
4290 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
4294 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
4298 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
4302 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
4306 if (expr->ts.type == BT_CHARACTER)
4307 gfc_conv_intrinsic_minmax_char (se, expr, 1);
4309 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
4312 case GFC_ISYM_MAXLOC:
4313 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
4316 case GFC_ISYM_MAXVAL:
4317 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
4320 case GFC_ISYM_MERGE:
4321 gfc_conv_intrinsic_merge (se, expr);
4325 if (expr->ts.type == BT_CHARACTER)
4326 gfc_conv_intrinsic_minmax_char (se, expr, -1);
4328 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
4331 case GFC_ISYM_MINLOC:
4332 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
4335 case GFC_ISYM_MINVAL:
4336 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
4339 case GFC_ISYM_NEAREST:
4340 gfc_conv_intrinsic_nearest (se, expr);
4344 gfc_conv_intrinsic_not (se, expr);
4348 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
4351 case GFC_ISYM_PRESENT:
4352 gfc_conv_intrinsic_present (se, expr);
4355 case GFC_ISYM_PRODUCT:
4356 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
4359 case GFC_ISYM_RRSPACING:
4360 gfc_conv_intrinsic_rrspacing (se, expr);
4363 case GFC_ISYM_SET_EXPONENT:
4364 gfc_conv_intrinsic_set_exponent (se, expr);
4367 case GFC_ISYM_SCALE:
4368 gfc_conv_intrinsic_scale (se, expr);
4372 gfc_conv_intrinsic_sign (se, expr);
4376 gfc_conv_intrinsic_size (se, expr);
4379 case GFC_ISYM_SIZEOF:
4380 gfc_conv_intrinsic_sizeof (se, expr);
4383 case GFC_ISYM_SPACING:
4384 gfc_conv_intrinsic_spacing (se, expr);
4388 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
4391 case GFC_ISYM_TRANSFER:
4394 if (se->ss->useflags)
4396 /* Access the previously obtained result. */
4397 gfc_conv_tmp_array_ref (se);
4398 gfc_advance_se_ss_chain (se);
4402 gfc_conv_intrinsic_array_transfer (se, expr);
4405 gfc_conv_intrinsic_transfer (se, expr);
4408 case GFC_ISYM_TTYNAM:
4409 gfc_conv_intrinsic_ttynam (se, expr);
4412 case GFC_ISYM_UBOUND:
4413 gfc_conv_intrinsic_bound (se, expr, 1);
4417 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
4421 gfc_conv_intrinsic_loc (se, expr);
4424 case GFC_ISYM_ACCESS:
4425 case GFC_ISYM_CHDIR:
4426 case GFC_ISYM_CHMOD:
4427 case GFC_ISYM_DTIME:
4428 case GFC_ISYM_ETIME:
4430 case GFC_ISYM_FGETC:
4433 case GFC_ISYM_FPUTC:
4434 case GFC_ISYM_FSTAT:
4435 case GFC_ISYM_FTELL:
4436 case GFC_ISYM_GETCWD:
4437 case GFC_ISYM_GETGID:
4438 case GFC_ISYM_GETPID:
4439 case GFC_ISYM_GETUID:
4440 case GFC_ISYM_HOSTNM:
4442 case GFC_ISYM_IERRNO:
4443 case GFC_ISYM_IRAND:
4444 case GFC_ISYM_ISATTY:
4446 case GFC_ISYM_LSTAT:
4447 case GFC_ISYM_MALLOC:
4448 case GFC_ISYM_MATMUL:
4449 case GFC_ISYM_MCLOCK:
4450 case GFC_ISYM_MCLOCK8:
4452 case GFC_ISYM_RENAME:
4453 case GFC_ISYM_SECOND:
4454 case GFC_ISYM_SECNDS:
4455 case GFC_ISYM_SIGNAL:
4457 case GFC_ISYM_SYMLNK:
4458 case GFC_ISYM_SYSTEM:
4460 case GFC_ISYM_TIME8:
4461 case GFC_ISYM_UMASK:
4462 case GFC_ISYM_UNLINK:
4463 gfc_conv_intrinsic_funcall (se, expr);
4467 gfc_conv_intrinsic_lib_function (se, expr);
4473 /* This generates code to execute before entering the scalarization loop.
4474 Currently does nothing. */
4477 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4479 switch (ss->expr->value.function.isym->id)
4481 case GFC_ISYM_UBOUND:
4482 case GFC_ISYM_LBOUND:
4491 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4492 inside the scalarization loop. */
4495 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4499 /* The two argument version returns a scalar. */
4500 if (expr->value.function.actual->next->expr)
4503 newss = gfc_get_ss ();
4504 newss->type = GFC_SS_INTRINSIC;
4507 newss->data.info.dimen = 1;
4513 /* Walk an intrinsic array libcall. */
4516 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4520 gcc_assert (expr->rank > 0);
4522 newss = gfc_get_ss ();
4523 newss->type = GFC_SS_FUNCTION;
4526 newss->data.info.dimen = expr->rank;
4532 /* Returns nonzero if the specified intrinsic function call maps directly to a
4533 an external library call. Should only be used for functions that return
4537 gfc_is_intrinsic_libcall (gfc_expr * expr)
4539 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4540 gcc_assert (expr->rank > 0);
4542 switch (expr->value.function.isym->id)
4546 case GFC_ISYM_COUNT:
4547 case GFC_ISYM_MATMUL:
4548 case GFC_ISYM_MAXLOC:
4549 case GFC_ISYM_MAXVAL:
4550 case GFC_ISYM_MINLOC:
4551 case GFC_ISYM_MINVAL:
4552 case GFC_ISYM_PRODUCT:
4554 case GFC_ISYM_SHAPE:
4555 case GFC_ISYM_SPREAD:
4556 case GFC_ISYM_TRANSPOSE:
4557 /* Ignore absent optional parameters. */
4560 case GFC_ISYM_RESHAPE:
4561 case GFC_ISYM_CSHIFT:
4562 case GFC_ISYM_EOSHIFT:
4564 case GFC_ISYM_UNPACK:
4565 /* Pass absent optional parameters. */
4573 /* Walk an intrinsic function. */
4575 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
4576 gfc_intrinsic_sym * isym)
4580 if (isym->elemental)
4581 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
4583 if (expr->rank == 0)
4586 if (gfc_is_intrinsic_libcall (expr))
4587 return gfc_walk_intrinsic_libfunc (ss, expr);
4589 /* Special cases. */
4592 case GFC_ISYM_LBOUND:
4593 case GFC_ISYM_UBOUND:
4594 return gfc_walk_intrinsic_bound (ss, expr);
4596 case GFC_ISYM_TRANSFER:
4597 return gfc_walk_intrinsic_libfunc (ss, expr);
4600 /* This probably meant someone forgot to add an intrinsic to the above
4601 list(s) when they implemented it, or something's gone horribly
4607 #include "gt-fortran-trans-intrinsic.h"