1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
24 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
28 #include "coretypes.h"
33 #include "tree-gimple.h"
37 #include "intrinsic.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
44 #include "trans-stmt.h"
46 /* This maps fortran intrinsic math functions to external library or GCC
48 typedef struct gfc_intrinsic_map_t GTY(())
50 /* The explicit enum is required to work around inadequacies in the
51 garbage collection/gengtype parsing mechanism. */
54 /* Enum value from the "language-independent", aka C-centric, part
55 of gcc, or END_BUILTINS of no such value set. */
56 enum built_in_function code_r4;
57 enum built_in_function code_r8;
58 enum built_in_function code_r10;
59 enum built_in_function code_r16;
60 enum built_in_function code_c4;
61 enum built_in_function code_c8;
62 enum built_in_function code_c10;
63 enum built_in_function code_c16;
65 /* True if the naming pattern is to prepend "c" for complex and
66 append "f" for kind=4. False if the naming pattern is to
67 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
70 /* True if a complex version of the function exists. */
71 bool complex_available;
73 /* True if the function should be marked const. */
76 /* The base library name of this function. */
79 /* Cache decls created for the various operand types. */
91 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
92 defines complex variants of all of the entries in mathbuiltins.def
94 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
95 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
96 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, 0, 0, 0, 0, true, \
97 false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
98 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
100 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
101 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
102 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
103 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
104 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
105 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
107 #define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
108 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 true, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
111 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
113 #define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
114 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
115 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
116 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
117 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
119 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
121 /* Functions built into gcc itself. */
122 #include "mathbuiltins.def"
124 /* Functions in libm. */
125 /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
126 pattern for other mathbuiltins.def entries. At present we have no
127 optimizations for this in the common sources. */
128 LIBM_FUNCTION (SCALE, "scalbn", false),
130 /* Functions in libgfortran. */
131 LIBF_FUNCTION (FRACTION, "fraction", false),
132 LIBF_FUNCTION (NEAREST, "nearest", false),
133 LIBF_FUNCTION (RRSPACING, "rrspacing", false),
134 LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
135 LIBF_FUNCTION (SPACING, "spacing", false),
138 LIBF_FUNCTION (NONE, NULL, false)
140 #undef DEFINE_MATH_BUILTIN
141 #undef DEFINE_MATH_BUILTIN_C
145 /* Structure for storing components of a floating number to be used by
146 elemental functions to manipulate reals. */
149 tree arg; /* Variable tree to view convert to integer. */
150 tree expn; /* Variable tree to save exponent. */
151 tree frac; /* Variable tree to save fraction. */
152 tree smask; /* Constant tree of sign's mask. */
153 tree emask; /* Constant tree of exponent's mask. */
154 tree fmask; /* Constant tree of fraction's mask. */
155 tree edigits; /* Constant tree of the number of exponent bits. */
156 tree fdigits; /* Constant tree of the number of fraction bits. */
157 tree f1; /* Constant tree of the f1 defined in the real model. */
158 tree bias; /* Constant tree of the bias of exponent in the memory. */
159 tree type; /* Type tree of arg1. */
160 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
164 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
166 /* Evaluate the arguments to an intrinsic function. The value
167 of NARGS may be less than the actual number of arguments in EXPR
168 to allow optional "KIND" arguments that are not included in the
169 generated code to be ignored. */
172 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
173 tree *argarray, int nargs)
175 gfc_actual_arglist *actual;
177 gfc_intrinsic_arg *formal;
181 formal = expr->value.function.isym->formal;
182 actual = expr->value.function.actual;
184 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
185 actual = actual->next,
186 formal = formal ? formal->next : NULL)
190 /* Skip omitted optional arguments. */
194 /* Evaluate the parameter. This will substitute scalarized
195 references automatically. */
196 gfc_init_se (&argse, se);
198 if (e->ts.type == BT_CHARACTER)
200 gfc_conv_expr (&argse, e);
201 gfc_conv_string_parameter (&argse);
202 argarray[curr_arg++] = argse.string_length;
203 gcc_assert (curr_arg < nargs);
206 gfc_conv_expr_val (&argse, e);
208 /* If an optional argument is itself an optional dummy argument,
209 check its presence and substitute a null if absent. */
210 if (e->expr_type ==EXPR_VARIABLE
211 && e->symtree->n.sym->attr.optional
214 gfc_conv_missing_dummy (&argse, e, formal->ts);
216 gfc_add_block_to_block (&se->pre, &argse.pre);
217 gfc_add_block_to_block (&se->post, &argse.post);
218 argarray[curr_arg] = argse.expr;
222 /* Count the number of actual arguments to the intrinsic function EXPR
223 including any "hidden" string length arguments. */
226 gfc_intrinsic_argument_list_length (gfc_expr *expr)
229 gfc_actual_arglist *actual;
231 for (actual = expr->value.function.actual; actual; actual = actual->next)
236 if (actual->expr->ts.type == BT_CHARACTER)
246 /* Conversions between different types are output by the frontend as
247 intrinsic functions. We implement these directly with inline code. */
250 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
255 /* Evaluate the argument. */
256 type = gfc_typenode_for_spec (&expr->ts);
257 gcc_assert (expr->value.function.actual->expr);
258 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
260 /* Conversion from complex to non-complex involves taking the real
261 component of the value. */
262 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
263 && expr->ts.type != BT_COMPLEX)
267 artype = TREE_TYPE (TREE_TYPE (arg));
268 arg = build1 (REALPART_EXPR, artype, arg);
271 se->expr = convert (type, arg);
274 /* This is needed because the gcc backend only implements
275 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
276 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
277 Similarly for CEILING. */
280 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
287 argtype = TREE_TYPE (arg);
288 arg = gfc_evaluate_now (arg, pblock);
290 intval = convert (type, arg);
291 intval = gfc_evaluate_now (intval, pblock);
293 tmp = convert (argtype, intval);
294 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
296 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
297 build_int_cst (type, 1));
298 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
303 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
304 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
307 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
316 argtype = TREE_TYPE (arg);
317 arg = gfc_evaluate_now (arg, pblock);
319 real_from_string (&r, "0.5");
320 pos = build_real (argtype, r);
322 real_from_string (&r, "-0.5");
323 neg = build_real (argtype, r);
325 tmp = gfc_build_const (argtype, integer_zero_node);
326 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
328 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
329 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
330 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
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 (pblock, arg, type);
356 gcc_assert (op == RND_TRUNC);
357 return build1 (FIX_TRUNC_EXPR, type, arg);
362 /* Round a real value using the specified rounding mode.
363 We use a temporary integer of that same kind size as the result.
364 Values larger than those that can be represented by this kind are
365 unchanged, as they will not be accurate enough to represent the
367 huge = HUGE (KIND (a))
368 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
372 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
383 kind = expr->ts.kind;
386 /* We have builtin functions for some cases. */
429 /* Evaluate the argument. */
430 gcc_assert (expr->value.function.actual->expr);
431 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
433 /* Use a builtin function if one exists. */
434 if (n != END_BUILTINS)
436 tmp = built_in_decls[n];
437 se->expr = build_call_expr (tmp, 1, arg);
441 /* This code is probably redundant, but we'll keep it lying around just
443 type = gfc_typenode_for_spec (&expr->ts);
444 arg = gfc_evaluate_now (arg, &se->pre);
446 /* Test if the value is too large to handle sensibly. */
447 gfc_set_model_kind (kind);
449 n = gfc_validate_kind (BT_INTEGER, kind, false);
450 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
451 tmp = gfc_conv_mpfr_to_tree (huge, kind);
452 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
454 mpfr_neg (huge, huge, GFC_RND_MODE);
455 tmp = gfc_conv_mpfr_to_tree (huge, kind);
456 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
457 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
458 itype = gfc_get_int_type (kind);
460 tmp = build_fix_expr (&se->pre, arg, itype, op);
461 tmp = convert (type, tmp);
462 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
467 /* Convert to an integer using the specified rounding mode. */
470 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
475 /* Evaluate the argument. */
476 type = gfc_typenode_for_spec (&expr->ts);
477 gcc_assert (expr->value.function.actual->expr);
478 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
480 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
482 /* Conversion to a different integer kind. */
483 se->expr = convert (type, arg);
487 /* Conversion from complex to non-complex involves taking the real
488 component of the value. */
489 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
490 && expr->ts.type != BT_COMPLEX)
494 artype = TREE_TYPE (TREE_TYPE (arg));
495 arg = build1 (REALPART_EXPR, artype, arg);
498 se->expr = build_fix_expr (&se->pre, arg, type, op);
503 /* Get the imaginary component of a value. */
506 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
510 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
511 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
515 /* Get the complex conjugate of a value. */
518 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
522 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
523 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
527 /* Initialize function decls for library functions. The external functions
528 are created as required. Builtin functions are added here. */
531 gfc_build_intrinsic_lib_fndecls (void)
533 gfc_intrinsic_map_t *m;
535 /* Add GCC builtin functions. */
536 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
538 if (m->code_r4 != END_BUILTINS)
539 m->real4_decl = built_in_decls[m->code_r4];
540 if (m->code_r8 != END_BUILTINS)
541 m->real8_decl = built_in_decls[m->code_r8];
542 if (m->code_r10 != END_BUILTINS)
543 m->real10_decl = built_in_decls[m->code_r10];
544 if (m->code_r16 != END_BUILTINS)
545 m->real16_decl = built_in_decls[m->code_r16];
546 if (m->code_c4 != END_BUILTINS)
547 m->complex4_decl = built_in_decls[m->code_c4];
548 if (m->code_c8 != END_BUILTINS)
549 m->complex8_decl = built_in_decls[m->code_c8];
550 if (m->code_c10 != END_BUILTINS)
551 m->complex10_decl = built_in_decls[m->code_c10];
552 if (m->code_c16 != END_BUILTINS)
553 m->complex16_decl = built_in_decls[m->code_c16];
558 /* Create a fndecl for a simple intrinsic library function. */
561 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
566 gfc_actual_arglist *actual;
569 char name[GFC_MAX_SYMBOL_LEN + 3];
572 if (ts->type == BT_REAL)
577 pdecl = &m->real4_decl;
580 pdecl = &m->real8_decl;
583 pdecl = &m->real10_decl;
586 pdecl = &m->real16_decl;
592 else if (ts->type == BT_COMPLEX)
594 gcc_assert (m->complex_available);
599 pdecl = &m->complex4_decl;
602 pdecl = &m->complex8_decl;
605 pdecl = &m->complex10_decl;
608 pdecl = &m->complex16_decl;
623 snprintf (name, sizeof (name), "%s%s%s",
624 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
625 else if (ts->kind == 8)
626 snprintf (name, sizeof (name), "%s%s",
627 ts->type == BT_COMPLEX ? "c" : "", m->name);
630 gcc_assert (ts->kind == 10 || ts->kind == 16);
631 snprintf (name, sizeof (name), "%s%s%s",
632 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
637 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
638 ts->type == BT_COMPLEX ? 'c' : 'r',
642 argtypes = NULL_TREE;
643 for (actual = expr->value.function.actual; actual; actual = actual->next)
645 type = gfc_typenode_for_spec (&actual->expr->ts);
646 argtypes = gfc_chainon_list (argtypes, type);
648 argtypes = gfc_chainon_list (argtypes, void_type_node);
649 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
650 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
652 /* Mark the decl as external. */
653 DECL_EXTERNAL (fndecl) = 1;
654 TREE_PUBLIC (fndecl) = 1;
656 /* Mark it __attribute__((const)), if possible. */
657 TREE_READONLY (fndecl) = m->is_constant;
659 rest_of_decl_compilation (fndecl, 1, 0);
666 /* Convert an intrinsic function into an external or builtin call. */
669 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
671 gfc_intrinsic_map_t *m;
675 unsigned int num_args;
678 id = expr->value.function.isym->id;
679 /* Find the entry for this function. */
680 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
686 if (m->id == GFC_ISYM_NONE)
688 internal_error ("Intrinsic function %s(%d) not recognized",
689 expr->value.function.name, id);
692 /* Get the decl and generate the call. */
693 num_args = gfc_intrinsic_argument_list_length (expr);
694 args = alloca (sizeof (tree) * num_args);
696 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
697 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
698 rettype = TREE_TYPE (TREE_TYPE (fndecl));
700 fndecl = build_addr (fndecl, current_function_decl);
701 se->expr = build_call_array (rettype, fndecl, num_args, args);
704 /* Generate code for EXPONENT(X) intrinsic function. */
707 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
712 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
714 a1 = expr->value.function.actual->expr;
718 fndecl = gfor_fndecl_math_exponent4;
721 fndecl = gfor_fndecl_math_exponent8;
724 fndecl = gfor_fndecl_math_exponent10;
727 fndecl = gfor_fndecl_math_exponent16;
733 se->expr = build_call_expr (fndecl, 1, arg);
736 /* Evaluate a single upper or lower bound. */
737 /* TODO: bound intrinsic generates way too much unnecessary code. */
740 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
742 gfc_actual_arglist *arg;
743 gfc_actual_arglist *arg2;
748 tree cond, cond1, cond2, cond3, cond4, size;
756 arg = expr->value.function.actual;
761 /* Create an implicit second parameter from the loop variable. */
762 gcc_assert (!arg2->expr);
763 gcc_assert (se->loop->dimen == 1);
764 gcc_assert (se->ss->expr == expr);
765 gfc_advance_se_ss_chain (se);
766 bound = se->loop->loopvar[0];
767 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
772 /* use the passed argument. */
773 gcc_assert (arg->next->expr);
774 gfc_init_se (&argse, NULL);
775 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
776 gfc_add_block_to_block (&se->pre, &argse.pre);
778 /* Convert from one based to zero based. */
779 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
783 /* TODO: don't re-evaluate the descriptor on each iteration. */
784 /* Get a descriptor for the first parameter. */
785 ss = gfc_walk_expr (arg->expr);
786 gcc_assert (ss != gfc_ss_terminator);
787 gfc_init_se (&argse, NULL);
788 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
789 gfc_add_block_to_block (&se->pre, &argse.pre);
790 gfc_add_block_to_block (&se->post, &argse.post);
794 if (INTEGER_CST_P (bound))
798 hi = TREE_INT_CST_HIGH (bound);
799 low = TREE_INT_CST_LOW (bound);
800 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
801 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
802 "dimension index", upper ? "UBOUND" : "LBOUND",
807 if (flag_bounds_check)
809 bound = gfc_evaluate_now (bound, &se->pre);
810 cond = fold_build2 (LT_EXPR, boolean_type_node,
811 bound, build_int_cst (TREE_TYPE (bound), 0));
812 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
813 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
814 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
815 gfc_trans_runtime_check (cond, gfc_msg_fault, &se->pre, &expr->where);
819 ubound = gfc_conv_descriptor_ubound (desc, bound);
820 lbound = gfc_conv_descriptor_lbound (desc, bound);
822 /* Follow any component references. */
823 if (arg->expr->expr_type == EXPR_VARIABLE
824 || arg->expr->expr_type == EXPR_CONSTANT)
826 as = arg->expr->symtree->n.sym->as;
827 for (ref = arg->expr->ref; ref; ref = ref->next)
832 as = ref->u.c.component->as;
840 switch (ref->u.ar.type)
858 /* 13.14.53: Result value for LBOUND
860 Case (i): For an array section or for an array expression other than a
861 whole array or array structure component, LBOUND(ARRAY, DIM)
862 has the value 1. For a whole array or array structure
863 component, LBOUND(ARRAY, DIM) has the value:
864 (a) equal to the lower bound for subscript DIM of ARRAY if
865 dimension DIM of ARRAY does not have extent zero
866 or if ARRAY is an assumed-size array of rank DIM,
869 13.14.113: Result value for UBOUND
871 Case (i): For an array section or for an array expression other than a
872 whole array or array structure component, UBOUND(ARRAY, DIM)
873 has the value equal to the number of elements in the given
874 dimension; otherwise, it has a value equal to the upper bound
875 for subscript DIM of ARRAY if dimension DIM of ARRAY does
876 not have size zero and has value zero if dimension DIM has
881 tree stride = gfc_conv_descriptor_stride (desc, bound);
883 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
884 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
886 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
887 gfc_index_zero_node);
888 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
890 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
891 gfc_index_zero_node);
892 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
896 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
898 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
899 ubound, gfc_index_zero_node);
903 if (as->type == AS_ASSUMED_SIZE)
904 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
905 build_int_cst (TREE_TYPE (bound),
906 arg->expr->rank - 1));
908 cond = boolean_false_node;
910 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
911 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
913 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
914 lbound, gfc_index_one_node);
921 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
922 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
926 se->expr = gfc_index_one_node;
929 type = gfc_typenode_for_spec (&expr->ts);
930 se->expr = convert (type, se->expr);
935 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
940 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
942 switch (expr->value.function.actual->expr->ts.type)
946 se->expr = build1 (ABS_EXPR, TREE_TYPE (arg), arg);
950 switch (expr->ts.kind)
965 se->expr = build_call_expr (built_in_decls[n], 1, arg);
974 /* Create a complex value from one or two real components. */
977 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
983 unsigned int num_args;
985 num_args = gfc_intrinsic_argument_list_length (expr);
986 args = alloca (sizeof (tree) * num_args);
988 type = gfc_typenode_for_spec (&expr->ts);
989 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
990 real = convert (TREE_TYPE (type), args[0]);
992 imag = convert (TREE_TYPE (type), args[1]);
993 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
995 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])), args[0]);
996 imag = convert (TREE_TYPE (type), imag);
999 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1001 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1004 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1005 MODULO(A, P) = A - FLOOR (A / P) * P */
1006 /* TODO: MOD(x, 0) */
1009 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1020 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1022 switch (expr->ts.type)
1025 /* Integer case is easy, we've got a builtin op. */
1026 type = TREE_TYPE (args[0]);
1029 se->expr = build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1031 se->expr = build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1036 /* Check if we have a builtin fmod. */
1037 switch (expr->ts.kind)
1056 /* Use it if it exists. */
1057 if (n != END_BUILTINS)
1059 tmp = build_addr (built_in_decls[n], current_function_decl);
1060 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (built_in_decls[n])),
1066 type = TREE_TYPE (args[0]);
1068 args[0] = gfc_evaluate_now (args[0], &se->pre);
1069 args[1] = gfc_evaluate_now (args[1], &se->pre);
1072 modulo = arg - floor (arg/arg2) * arg2, so
1073 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1075 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1076 thereby avoiding another division and retaining the accuracy
1077 of the builtin function. */
1078 if (n != END_BUILTINS && modulo)
1080 tree zero = gfc_build_const (type, integer_zero_node);
1081 tmp = gfc_evaluate_now (se->expr, &se->pre);
1082 test = build2 (LT_EXPR, boolean_type_node, args[0], zero);
1083 test2 = build2 (LT_EXPR, boolean_type_node, args[1], zero);
1084 test2 = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1085 test = build2 (NE_EXPR, boolean_type_node, tmp, zero);
1086 test = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1087 test = gfc_evaluate_now (test, &se->pre);
1088 se->expr = build3 (COND_EXPR, type, test,
1089 build2 (PLUS_EXPR, type, tmp, args[1]), tmp);
1093 /* If we do not have a built_in fmod, the calculation is going to
1094 have to be done longhand. */
1095 tmp = build2 (RDIV_EXPR, type, args[0], args[1]);
1097 /* Test if the value is too large to handle sensibly. */
1098 gfc_set_model_kind (expr->ts.kind);
1100 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1101 ikind = expr->ts.kind;
1104 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1105 ikind = gfc_max_integer_kind;
1107 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1108 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1109 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
1111 mpfr_neg (huge, huge, GFC_RND_MODE);
1112 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1113 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
1114 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1116 itype = gfc_get_int_type (ikind);
1118 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1120 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1121 tmp = convert (type, tmp);
1122 tmp = build3 (COND_EXPR, type, test2, tmp, args[0]);
1123 tmp = build2 (MULT_EXPR, type, tmp, args[1]);
1124 se->expr = build2 (MINUS_EXPR, type, args[0], tmp);
1133 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1136 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1144 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1145 type = TREE_TYPE (args[0]);
1147 val = build2 (MINUS_EXPR, type, args[0], args[1]);
1148 val = gfc_evaluate_now (val, &se->pre);
1150 zero = gfc_build_const (type, integer_zero_node);
1151 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
1152 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
1156 /* SIGN(A, B) is absolute value of A times sign of B.
1157 The real value versions use library functions to ensure the correct
1158 handling of negative zero. Integer case implemented as:
1159 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1163 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1169 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1170 if (expr->ts.type == BT_REAL)
1172 switch (expr->ts.kind)
1175 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1178 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1182 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1187 se->expr = build_call_expr (tmp, 2, args[0], args[1]);
1191 /* Having excluded floating point types, we know we are now dealing
1192 with signed integer types. */
1193 type = TREE_TYPE (args[0]);
1195 /* Args[0] is used multiple times below. */
1196 args[0] = gfc_evaluate_now (args[0], &se->pre);
1198 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1199 the signs of A and B are the same, and of all ones if they differ. */
1200 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1201 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1202 build_int_cst (type, TYPE_PRECISION (type) - 1));
1203 tmp = gfc_evaluate_now (tmp, &se->pre);
1205 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1206 is all ones (i.e. -1). */
1207 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1208 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1213 /* Test for the presence of an optional argument. */
1216 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1220 arg = expr->value.function.actual->expr;
1221 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1222 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1223 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1227 /* Calculate the double precision product of two single precision values. */
1230 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1235 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1237 /* Convert the args to double precision before multiplying. */
1238 type = gfc_typenode_for_spec (&expr->ts);
1239 args[0] = convert (type, args[0]);
1240 args[1] = convert (type, args[1]);
1241 se->expr = build2 (MULT_EXPR, type, args[0], args[1]);
1245 /* Return a length one character string containing an ascii character. */
1248 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1254 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1256 /* We currently don't support character types != 1. */
1257 gcc_assert (expr->ts.kind == 1);
1258 type = gfc_character1_type_node;
1259 var = gfc_create_var (type, "char");
1261 arg = convert (type, arg);
1262 gfc_add_modify_expr (&se->pre, var, arg);
1263 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1264 se->string_length = integer_one_node;
1269 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1276 tree gfc_int8_type_node = gfc_get_int_type (8);
1279 unsigned int num_args;
1281 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1282 args = alloca (sizeof (tree) * num_args);
1284 type = build_pointer_type (gfc_character1_type_node);
1285 var = gfc_create_var (type, "pstr");
1286 len = gfc_create_var (gfc_int8_type_node, "len");
1288 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1289 args[0] = build_fold_addr_expr (var);
1290 args[1] = build_fold_addr_expr (len);
1292 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1293 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1294 fndecl, num_args, args);
1295 gfc_add_expr_to_block (&se->pre, tmp);
1297 /* Free the temporary afterwards, if necessary. */
1298 cond = build2 (GT_EXPR, boolean_type_node, len,
1299 build_int_cst (TREE_TYPE (len), 0));
1300 tmp = gfc_call_free (var);
1301 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1302 gfc_add_expr_to_block (&se->post, tmp);
1305 se->string_length = len;
1310 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1317 tree gfc_int4_type_node = gfc_get_int_type (4);
1320 unsigned int num_args;
1322 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1323 args = alloca (sizeof (tree) * num_args);
1325 type = build_pointer_type (gfc_character1_type_node);
1326 var = gfc_create_var (type, "pstr");
1327 len = gfc_create_var (gfc_int4_type_node, "len");
1329 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1330 args[0] = build_fold_addr_expr (var);
1331 args[1] = build_fold_addr_expr (len);
1333 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1334 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1335 fndecl, num_args, args);
1336 gfc_add_expr_to_block (&se->pre, tmp);
1338 /* Free the temporary afterwards, if necessary. */
1339 cond = build2 (GT_EXPR, boolean_type_node, len,
1340 build_int_cst (TREE_TYPE (len), 0));
1341 tmp = gfc_call_free (var);
1342 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1343 gfc_add_expr_to_block (&se->post, tmp);
1346 se->string_length = len;
1350 /* Return a character string containing the tty name. */
1353 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1361 tree gfc_int4_type_node = gfc_get_int_type (4);
1363 unsigned int num_args;
1365 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1366 args = alloca (sizeof (tree) * num_args);
1368 type = build_pointer_type (gfc_character1_type_node);
1369 var = gfc_create_var (type, "pstr");
1370 len = gfc_create_var (gfc_int4_type_node, "len");
1372 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1373 args[0] = build_fold_addr_expr (var);
1374 args[1] = build_fold_addr_expr (len);
1376 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1377 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1378 fndecl, num_args, args);
1379 gfc_add_expr_to_block (&se->pre, tmp);
1381 /* Free the temporary afterwards, if necessary. */
1382 cond = build2 (GT_EXPR, boolean_type_node, len,
1383 build_int_cst (TREE_TYPE (len), 0));
1384 tmp = gfc_call_free (var);
1385 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1386 gfc_add_expr_to_block (&se->post, tmp);
1389 se->string_length = len;
1393 /* Get the minimum/maximum value of all the parameters.
1394 minmax (a1, a2, a3, ...)
1407 /* TODO: Mismatching types can occur when specific names are used.
1408 These should be handled during resolution. */
1410 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1420 unsigned int num_args;
1423 num_args = gfc_intrinsic_argument_list_length (expr);
1424 args = alloca (sizeof (tree) * num_args);
1426 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1427 type = gfc_typenode_for_spec (&expr->ts);
1430 if (TREE_TYPE (limit) != type)
1431 limit = convert (type, limit);
1432 /* Only evaluate the argument once. */
1433 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1434 limit = gfc_evaluate_now (limit, &se->pre);
1436 mvar = gfc_create_var (type, "M");
1437 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1438 for (i = 1; i < num_args; i++)
1441 if (TREE_TYPE (val) != type)
1442 val = convert (type, val);
1444 /* Only evaluate the argument once. */
1445 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1446 val = gfc_evaluate_now (val, &se->pre);
1448 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1450 tmp = build2 (op, boolean_type_node, val, limit);
1451 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1452 gfc_add_expr_to_block (&se->pre, tmp);
1453 elsecase = build_empty_stmt ();
1460 /* Create a symbol node for this intrinsic. The symbol from the frontend
1461 has the generic name. */
1464 gfc_get_symbol_for_expr (gfc_expr * expr)
1468 /* TODO: Add symbols for intrinsic function to the global namespace. */
1469 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1470 sym = gfc_new_symbol (expr->value.function.name, NULL);
1473 sym->attr.external = 1;
1474 sym->attr.function = 1;
1475 sym->attr.always_explicit = 1;
1476 sym->attr.proc = PROC_INTRINSIC;
1477 sym->attr.flavor = FL_PROCEDURE;
1481 sym->attr.dimension = 1;
1482 sym->as = gfc_get_array_spec ();
1483 sym->as->type = AS_ASSUMED_SHAPE;
1484 sym->as->rank = expr->rank;
1487 /* TODO: proper argument lists for external intrinsics. */
1491 /* Generate a call to an external intrinsic function. */
1493 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1498 gcc_assert (!se->ss || se->ss->expr == expr);
1501 gcc_assert (expr->rank > 0);
1503 gcc_assert (expr->rank == 0);
1505 sym = gfc_get_symbol_for_expr (expr);
1507 /* Calls to libgfortran_matmul need to be appended special arguments,
1508 to be able to call the BLAS ?gemm functions if required and possible. */
1509 append_args = NULL_TREE;
1510 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1511 && sym->ts.type != BT_LOGICAL)
1513 tree cint = gfc_get_int_type (gfc_c_int_kind);
1515 if (gfc_option.flag_external_blas
1516 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1517 && (sym->ts.kind == gfc_default_real_kind
1518 || sym->ts.kind == gfc_default_double_kind))
1522 if (sym->ts.type == BT_REAL)
1524 if (sym->ts.kind == gfc_default_real_kind)
1525 gemm_fndecl = gfor_fndecl_sgemm;
1527 gemm_fndecl = gfor_fndecl_dgemm;
1531 if (sym->ts.kind == gfc_default_real_kind)
1532 gemm_fndecl = gfor_fndecl_cgemm;
1534 gemm_fndecl = gfor_fndecl_zgemm;
1537 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1538 append_args = gfc_chainon_list
1539 (append_args, build_int_cst
1540 (cint, gfc_option.blas_matmul_limit));
1541 append_args = gfc_chainon_list (append_args,
1542 gfc_build_addr_expr (NULL_TREE,
1547 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1548 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1549 append_args = gfc_chainon_list (append_args, null_pointer_node);
1553 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1557 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1577 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1586 gfc_actual_arglist *actual;
1593 gfc_conv_intrinsic_funcall (se, expr);
1597 actual = expr->value.function.actual;
1598 type = gfc_typenode_for_spec (&expr->ts);
1599 /* Initialize the result. */
1600 resvar = gfc_create_var (type, "test");
1602 tmp = convert (type, boolean_true_node);
1604 tmp = convert (type, boolean_false_node);
1605 gfc_add_modify_expr (&se->pre, resvar, tmp);
1607 /* Walk the arguments. */
1608 arrayss = gfc_walk_expr (actual->expr);
1609 gcc_assert (arrayss != gfc_ss_terminator);
1611 /* Initialize the scalarizer. */
1612 gfc_init_loopinfo (&loop);
1613 exit_label = gfc_build_label_decl (NULL_TREE);
1614 TREE_USED (exit_label) = 1;
1615 gfc_add_ss_to_loop (&loop, arrayss);
1617 /* Initialize the loop. */
1618 gfc_conv_ss_startstride (&loop);
1619 gfc_conv_loop_setup (&loop);
1621 gfc_mark_ss_chain_used (arrayss, 1);
1622 /* Generate the loop body. */
1623 gfc_start_scalarized_body (&loop, &body);
1625 /* If the condition matches then set the return value. */
1626 gfc_start_block (&block);
1628 tmp = convert (type, boolean_false_node);
1630 tmp = convert (type, boolean_true_node);
1631 gfc_add_modify_expr (&block, resvar, tmp);
1633 /* And break out of the loop. */
1634 tmp = build1_v (GOTO_EXPR, exit_label);
1635 gfc_add_expr_to_block (&block, tmp);
1637 found = gfc_finish_block (&block);
1639 /* Check this element. */
1640 gfc_init_se (&arrayse, NULL);
1641 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1642 arrayse.ss = arrayss;
1643 gfc_conv_expr_val (&arrayse, actual->expr);
1645 gfc_add_block_to_block (&body, &arrayse.pre);
1646 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1647 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1648 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1649 gfc_add_expr_to_block (&body, tmp);
1650 gfc_add_block_to_block (&body, &arrayse.post);
1652 gfc_trans_scalarizing_loops (&loop, &body);
1654 /* Add the exit label. */
1655 tmp = build1_v (LABEL_EXPR, exit_label);
1656 gfc_add_expr_to_block (&loop.pre, tmp);
1658 gfc_add_block_to_block (&se->pre, &loop.pre);
1659 gfc_add_block_to_block (&se->pre, &loop.post);
1660 gfc_cleanup_loop (&loop);
1665 /* COUNT(A) = Number of true elements in A. */
1667 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1674 gfc_actual_arglist *actual;
1680 gfc_conv_intrinsic_funcall (se, expr);
1684 actual = expr->value.function.actual;
1686 type = gfc_typenode_for_spec (&expr->ts);
1687 /* Initialize the result. */
1688 resvar = gfc_create_var (type, "count");
1689 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1691 /* Walk the arguments. */
1692 arrayss = gfc_walk_expr (actual->expr);
1693 gcc_assert (arrayss != gfc_ss_terminator);
1695 /* Initialize the scalarizer. */
1696 gfc_init_loopinfo (&loop);
1697 gfc_add_ss_to_loop (&loop, arrayss);
1699 /* Initialize the loop. */
1700 gfc_conv_ss_startstride (&loop);
1701 gfc_conv_loop_setup (&loop);
1703 gfc_mark_ss_chain_used (arrayss, 1);
1704 /* Generate the loop body. */
1705 gfc_start_scalarized_body (&loop, &body);
1707 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1708 build_int_cst (TREE_TYPE (resvar), 1));
1709 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1711 gfc_init_se (&arrayse, NULL);
1712 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1713 arrayse.ss = arrayss;
1714 gfc_conv_expr_val (&arrayse, actual->expr);
1715 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1717 gfc_add_block_to_block (&body, &arrayse.pre);
1718 gfc_add_expr_to_block (&body, tmp);
1719 gfc_add_block_to_block (&body, &arrayse.post);
1721 gfc_trans_scalarizing_loops (&loop, &body);
1723 gfc_add_block_to_block (&se->pre, &loop.pre);
1724 gfc_add_block_to_block (&se->pre, &loop.post);
1725 gfc_cleanup_loop (&loop);
1730 /* Inline implementation of the sum and product intrinsics. */
1732 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1740 gfc_actual_arglist *actual;
1745 gfc_expr *arrayexpr;
1750 gfc_conv_intrinsic_funcall (se, expr);
1754 type = gfc_typenode_for_spec (&expr->ts);
1755 /* Initialize the result. */
1756 resvar = gfc_create_var (type, "val");
1757 if (op == PLUS_EXPR)
1758 tmp = gfc_build_const (type, integer_zero_node);
1760 tmp = gfc_build_const (type, integer_one_node);
1762 gfc_add_modify_expr (&se->pre, resvar, tmp);
1764 /* Walk the arguments. */
1765 actual = expr->value.function.actual;
1766 arrayexpr = actual->expr;
1767 arrayss = gfc_walk_expr (arrayexpr);
1768 gcc_assert (arrayss != gfc_ss_terminator);
1770 actual = actual->next->next;
1771 gcc_assert (actual);
1772 maskexpr = actual->expr;
1773 if (maskexpr && maskexpr->rank != 0)
1775 maskss = gfc_walk_expr (maskexpr);
1776 gcc_assert (maskss != gfc_ss_terminator);
1781 /* Initialize the scalarizer. */
1782 gfc_init_loopinfo (&loop);
1783 gfc_add_ss_to_loop (&loop, arrayss);
1785 gfc_add_ss_to_loop (&loop, maskss);
1787 /* Initialize the loop. */
1788 gfc_conv_ss_startstride (&loop);
1789 gfc_conv_loop_setup (&loop);
1791 gfc_mark_ss_chain_used (arrayss, 1);
1793 gfc_mark_ss_chain_used (maskss, 1);
1794 /* Generate the loop body. */
1795 gfc_start_scalarized_body (&loop, &body);
1797 /* If we have a mask, only add this element if the mask is set. */
1800 gfc_init_se (&maskse, NULL);
1801 gfc_copy_loopinfo_to_se (&maskse, &loop);
1803 gfc_conv_expr_val (&maskse, maskexpr);
1804 gfc_add_block_to_block (&body, &maskse.pre);
1806 gfc_start_block (&block);
1809 gfc_init_block (&block);
1811 /* Do the actual summation/product. */
1812 gfc_init_se (&arrayse, NULL);
1813 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1814 arrayse.ss = arrayss;
1815 gfc_conv_expr_val (&arrayse, arrayexpr);
1816 gfc_add_block_to_block (&block, &arrayse.pre);
1818 tmp = build2 (op, type, resvar, arrayse.expr);
1819 gfc_add_modify_expr (&block, resvar, tmp);
1820 gfc_add_block_to_block (&block, &arrayse.post);
1824 /* We enclose the above in if (mask) {...} . */
1825 tmp = gfc_finish_block (&block);
1827 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1830 tmp = gfc_finish_block (&block);
1831 gfc_add_expr_to_block (&body, tmp);
1833 gfc_trans_scalarizing_loops (&loop, &body);
1835 /* For a scalar mask, enclose the loop in an if statement. */
1836 if (maskexpr && maskss == NULL)
1838 gfc_init_se (&maskse, NULL);
1839 gfc_conv_expr_val (&maskse, maskexpr);
1840 gfc_init_block (&block);
1841 gfc_add_block_to_block (&block, &loop.pre);
1842 gfc_add_block_to_block (&block, &loop.post);
1843 tmp = gfc_finish_block (&block);
1845 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1846 gfc_add_expr_to_block (&block, tmp);
1847 gfc_add_block_to_block (&se->pre, &block);
1851 gfc_add_block_to_block (&se->pre, &loop.pre);
1852 gfc_add_block_to_block (&se->pre, &loop.post);
1855 gfc_cleanup_loop (&loop);
1861 /* Inline implementation of the dot_product intrinsic. This function
1862 is based on gfc_conv_intrinsic_arith (the previous function). */
1864 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1872 gfc_actual_arglist *actual;
1873 gfc_ss *arrayss1, *arrayss2;
1874 gfc_se arrayse1, arrayse2;
1875 gfc_expr *arrayexpr1, *arrayexpr2;
1877 type = gfc_typenode_for_spec (&expr->ts);
1879 /* Initialize the result. */
1880 resvar = gfc_create_var (type, "val");
1881 if (expr->ts.type == BT_LOGICAL)
1882 tmp = build_int_cst (type, 0);
1884 tmp = gfc_build_const (type, integer_zero_node);
1886 gfc_add_modify_expr (&se->pre, resvar, tmp);
1888 /* Walk argument #1. */
1889 actual = expr->value.function.actual;
1890 arrayexpr1 = actual->expr;
1891 arrayss1 = gfc_walk_expr (arrayexpr1);
1892 gcc_assert (arrayss1 != gfc_ss_terminator);
1894 /* Walk argument #2. */
1895 actual = actual->next;
1896 arrayexpr2 = actual->expr;
1897 arrayss2 = gfc_walk_expr (arrayexpr2);
1898 gcc_assert (arrayss2 != gfc_ss_terminator);
1900 /* Initialize the scalarizer. */
1901 gfc_init_loopinfo (&loop);
1902 gfc_add_ss_to_loop (&loop, arrayss1);
1903 gfc_add_ss_to_loop (&loop, arrayss2);
1905 /* Initialize the loop. */
1906 gfc_conv_ss_startstride (&loop);
1907 gfc_conv_loop_setup (&loop);
1909 gfc_mark_ss_chain_used (arrayss1, 1);
1910 gfc_mark_ss_chain_used (arrayss2, 1);
1912 /* Generate the loop body. */
1913 gfc_start_scalarized_body (&loop, &body);
1914 gfc_init_block (&block);
1916 /* Make the tree expression for [conjg(]array1[)]. */
1917 gfc_init_se (&arrayse1, NULL);
1918 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1919 arrayse1.ss = arrayss1;
1920 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1921 if (expr->ts.type == BT_COMPLEX)
1922 arrayse1.expr = build1 (CONJ_EXPR, type, arrayse1.expr);
1923 gfc_add_block_to_block (&block, &arrayse1.pre);
1925 /* Make the tree expression for array2. */
1926 gfc_init_se (&arrayse2, NULL);
1927 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
1928 arrayse2.ss = arrayss2;
1929 gfc_conv_expr_val (&arrayse2, arrayexpr2);
1930 gfc_add_block_to_block (&block, &arrayse2.pre);
1932 /* Do the actual product and sum. */
1933 if (expr->ts.type == BT_LOGICAL)
1935 tmp = build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
1936 tmp = build2 (TRUTH_OR_EXPR, type, resvar, tmp);
1940 tmp = build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
1941 tmp = build2 (PLUS_EXPR, type, resvar, tmp);
1943 gfc_add_modify_expr (&block, resvar, tmp);
1945 /* Finish up the loop block and the loop. */
1946 tmp = gfc_finish_block (&block);
1947 gfc_add_expr_to_block (&body, tmp);
1949 gfc_trans_scalarizing_loops (&loop, &body);
1950 gfc_add_block_to_block (&se->pre, &loop.pre);
1951 gfc_add_block_to_block (&se->pre, &loop.post);
1952 gfc_cleanup_loop (&loop);
1959 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1963 stmtblock_t ifblock;
1964 stmtblock_t elseblock;
1971 gfc_actual_arglist *actual;
1976 gfc_expr *arrayexpr;
1983 gfc_conv_intrinsic_funcall (se, expr);
1987 /* Initialize the result. */
1988 pos = gfc_create_var (gfc_array_index_type, "pos");
1989 type = gfc_typenode_for_spec (&expr->ts);
1991 /* Walk the arguments. */
1992 actual = expr->value.function.actual;
1993 arrayexpr = actual->expr;
1994 arrayss = gfc_walk_expr (arrayexpr);
1995 gcc_assert (arrayss != gfc_ss_terminator);
1997 actual = actual->next->next;
1998 gcc_assert (actual);
1999 maskexpr = actual->expr;
2000 if (maskexpr && maskexpr->rank != 0)
2002 maskss = gfc_walk_expr (maskexpr);
2003 gcc_assert (maskss != gfc_ss_terminator);
2008 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2009 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2010 switch (arrayexpr->ts.type)
2013 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
2017 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2018 arrayexpr->ts.kind);
2025 /* We start with the most negative possible value for MAXLOC, and the most
2026 positive possible value for MINLOC. The most negative possible value is
2027 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2028 possible value is HUGE in both cases. */
2030 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2031 gfc_add_modify_expr (&se->pre, limit, tmp);
2033 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2034 tmp = build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2035 build_int_cst (type, 1));
2037 /* Initialize the scalarizer. */
2038 gfc_init_loopinfo (&loop);
2039 gfc_add_ss_to_loop (&loop, arrayss);
2041 gfc_add_ss_to_loop (&loop, maskss);
2043 /* Initialize the loop. */
2044 gfc_conv_ss_startstride (&loop);
2045 gfc_conv_loop_setup (&loop);
2047 gcc_assert (loop.dimen == 1);
2049 /* Initialize the position to zero, following Fortran 2003. We are free
2050 to do this because Fortran 95 allows the result of an entirely false
2051 mask to be processor dependent. */
2052 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2054 gfc_mark_ss_chain_used (arrayss, 1);
2056 gfc_mark_ss_chain_used (maskss, 1);
2057 /* Generate the loop body. */
2058 gfc_start_scalarized_body (&loop, &body);
2060 /* If we have a mask, only check this element if the mask is set. */
2063 gfc_init_se (&maskse, NULL);
2064 gfc_copy_loopinfo_to_se (&maskse, &loop);
2066 gfc_conv_expr_val (&maskse, maskexpr);
2067 gfc_add_block_to_block (&body, &maskse.pre);
2069 gfc_start_block (&block);
2072 gfc_init_block (&block);
2074 /* Compare with the current limit. */
2075 gfc_init_se (&arrayse, NULL);
2076 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2077 arrayse.ss = arrayss;
2078 gfc_conv_expr_val (&arrayse, arrayexpr);
2079 gfc_add_block_to_block (&block, &arrayse.pre);
2081 /* We do the following if this is a more extreme value. */
2082 gfc_start_block (&ifblock);
2084 /* Assign the value to the limit... */
2085 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2087 /* Remember where we are. */
2088 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
2090 ifbody = gfc_finish_block (&ifblock);
2092 /* If it is a more extreme value or pos is still zero. */
2093 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node,
2094 build2 (op, boolean_type_node, arrayse.expr, limit),
2095 build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node));
2096 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2097 gfc_add_expr_to_block (&block, tmp);
2101 /* We enclose the above in if (mask) {...}. */
2102 tmp = gfc_finish_block (&block);
2104 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2107 tmp = gfc_finish_block (&block);
2108 gfc_add_expr_to_block (&body, tmp);
2110 gfc_trans_scalarizing_loops (&loop, &body);
2112 /* For a scalar mask, enclose the loop in an if statement. */
2113 if (maskexpr && maskss == NULL)
2115 gfc_init_se (&maskse, NULL);
2116 gfc_conv_expr_val (&maskse, maskexpr);
2117 gfc_init_block (&block);
2118 gfc_add_block_to_block (&block, &loop.pre);
2119 gfc_add_block_to_block (&block, &loop.post);
2120 tmp = gfc_finish_block (&block);
2122 /* For the else part of the scalar mask, just initialize
2123 the pos variable the same way as above. */
2125 gfc_init_block (&elseblock);
2126 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2127 elsetmp = gfc_finish_block (&elseblock);
2129 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2130 gfc_add_expr_to_block (&block, tmp);
2131 gfc_add_block_to_block (&se->pre, &block);
2135 gfc_add_block_to_block (&se->pre, &loop.pre);
2136 gfc_add_block_to_block (&se->pre, &loop.post);
2138 gfc_cleanup_loop (&loop);
2140 /* Return a value in the range 1..SIZE(array). */
2141 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
2142 gfc_index_one_node);
2143 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
2144 /* And convert to the required type. */
2145 se->expr = convert (type, tmp);
2149 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2158 gfc_actual_arglist *actual;
2163 gfc_expr *arrayexpr;
2169 gfc_conv_intrinsic_funcall (se, expr);
2173 type = gfc_typenode_for_spec (&expr->ts);
2174 /* Initialize the result. */
2175 limit = gfc_create_var (type, "limit");
2176 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2177 switch (expr->ts.type)
2180 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2184 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2191 /* We start with the most negative possible value for MAXVAL, and the most
2192 positive possible value for MINVAL. The most negative possible value is
2193 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2194 possible value is HUGE in both cases. */
2196 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2198 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2199 tmp = build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2200 build_int_cst (type, 1));
2202 gfc_add_modify_expr (&se->pre, limit, tmp);
2204 /* Walk the arguments. */
2205 actual = expr->value.function.actual;
2206 arrayexpr = actual->expr;
2207 arrayss = gfc_walk_expr (arrayexpr);
2208 gcc_assert (arrayss != gfc_ss_terminator);
2210 actual = actual->next->next;
2211 gcc_assert (actual);
2212 maskexpr = actual->expr;
2213 if (maskexpr && maskexpr->rank != 0)
2215 maskss = gfc_walk_expr (maskexpr);
2216 gcc_assert (maskss != gfc_ss_terminator);
2221 /* Initialize the scalarizer. */
2222 gfc_init_loopinfo (&loop);
2223 gfc_add_ss_to_loop (&loop, arrayss);
2225 gfc_add_ss_to_loop (&loop, maskss);
2227 /* Initialize the loop. */
2228 gfc_conv_ss_startstride (&loop);
2229 gfc_conv_loop_setup (&loop);
2231 gfc_mark_ss_chain_used (arrayss, 1);
2233 gfc_mark_ss_chain_used (maskss, 1);
2234 /* Generate the loop body. */
2235 gfc_start_scalarized_body (&loop, &body);
2237 /* If we have a mask, only add this element if the mask is set. */
2240 gfc_init_se (&maskse, NULL);
2241 gfc_copy_loopinfo_to_se (&maskse, &loop);
2243 gfc_conv_expr_val (&maskse, maskexpr);
2244 gfc_add_block_to_block (&body, &maskse.pre);
2246 gfc_start_block (&block);
2249 gfc_init_block (&block);
2251 /* Compare with the current limit. */
2252 gfc_init_se (&arrayse, NULL);
2253 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2254 arrayse.ss = arrayss;
2255 gfc_conv_expr_val (&arrayse, arrayexpr);
2256 gfc_add_block_to_block (&block, &arrayse.pre);
2258 /* Assign the value to the limit... */
2259 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2261 /* If it is a more extreme value. */
2262 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
2263 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2264 gfc_add_expr_to_block (&block, tmp);
2265 gfc_add_block_to_block (&block, &arrayse.post);
2267 tmp = gfc_finish_block (&block);
2269 /* We enclose the above in if (mask) {...}. */
2270 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2271 gfc_add_expr_to_block (&body, tmp);
2273 gfc_trans_scalarizing_loops (&loop, &body);
2275 /* For a scalar mask, enclose the loop in an if statement. */
2276 if (maskexpr && maskss == NULL)
2278 gfc_init_se (&maskse, NULL);
2279 gfc_conv_expr_val (&maskse, maskexpr);
2280 gfc_init_block (&block);
2281 gfc_add_block_to_block (&block, &loop.pre);
2282 gfc_add_block_to_block (&block, &loop.post);
2283 tmp = gfc_finish_block (&block);
2285 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2286 gfc_add_expr_to_block (&block, tmp);
2287 gfc_add_block_to_block (&se->pre, &block);
2291 gfc_add_block_to_block (&se->pre, &loop.pre);
2292 gfc_add_block_to_block (&se->pre, &loop.post);
2295 gfc_cleanup_loop (&loop);
2300 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2302 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2308 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2309 type = TREE_TYPE (args[0]);
2311 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2312 tmp = build2 (BIT_AND_EXPR, type, args[0], tmp);
2313 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2314 build_int_cst (type, 0));
2315 type = gfc_typenode_for_spec (&expr->ts);
2316 se->expr = convert (type, tmp);
2319 /* Generate code to perform the specified operation. */
2321 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2325 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2326 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2331 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2335 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2336 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2339 /* Set or clear a single bit. */
2341 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2348 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2349 type = TREE_TYPE (args[0]);
2351 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2357 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2359 se->expr = fold_build2 (op, type, args[0], tmp);
2362 /* Extract a sequence of bits.
2363 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2365 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2372 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2373 type = TREE_TYPE (args[0]);
2375 mask = build_int_cst (type, -1);
2376 mask = build2 (LSHIFT_EXPR, type, mask, args[2]);
2377 mask = build1 (BIT_NOT_EXPR, type, mask);
2379 tmp = build2 (RSHIFT_EXPR, type, args[0], args[1]);
2381 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2384 /* RSHIFT (I, SHIFT) = I >> SHIFT
2385 LSHIFT (I, SHIFT) = I << SHIFT */
2387 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2391 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2393 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2394 TREE_TYPE (args[0]), args[0], args[1]);
2397 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2399 : ((shift >= 0) ? i << shift : i >> -shift)
2400 where all shifts are logical shifts. */
2402 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2414 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2415 type = TREE_TYPE (args[0]);
2416 utype = unsigned_type_for (type);
2418 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
2420 /* Left shift if positive. */
2421 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
2423 /* Right shift if negative.
2424 We convert to an unsigned type because we want a logical shift.
2425 The standard doesn't define the case of shifting negative
2426 numbers, and we try to be compatible with other compilers, most
2427 notably g77, here. */
2428 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
2429 convert (utype, args[0]), width));
2431 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
2432 build_int_cst (TREE_TYPE (args[1]), 0));
2433 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2435 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2436 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2438 num_bits = build_int_cst (TREE_TYPE (args[0]), TYPE_PRECISION (type));
2439 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2441 se->expr = fold_build3 (COND_EXPR, type, cond,
2442 build_int_cst (type, 0), tmp);
2445 /* Circular shift. AKA rotate or barrel shift. */
2447 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2455 unsigned int num_args;
2457 num_args = gfc_intrinsic_argument_list_length (expr);
2458 args = alloca (sizeof (tree) * num_args);
2460 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2464 /* Use a library function for the 3 parameter version. */
2465 tree int4type = gfc_get_int_type (4);
2467 type = TREE_TYPE (args[0]);
2468 /* We convert the first argument to at least 4 bytes, and
2469 convert back afterwards. This removes the need for library
2470 functions for all argument sizes, and function will be
2471 aligned to at least 32 bits, so there's no loss. */
2472 if (expr->ts.kind < 4)
2473 args[0] = convert (int4type, args[0]);
2475 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2476 need loads of library functions. They cannot have values >
2477 BIT_SIZE (I) so the conversion is safe. */
2478 args[1] = convert (int4type, args[1]);
2479 args[2] = convert (int4type, args[2]);
2481 switch (expr->ts.kind)
2486 tmp = gfor_fndecl_math_ishftc4;
2489 tmp = gfor_fndecl_math_ishftc8;
2492 tmp = gfor_fndecl_math_ishftc16;
2497 se->expr = build_call_expr (tmp, 3, args[0], args[1], args[2]);
2498 /* Convert the result back to the original type, if we extended
2499 the first argument's width above. */
2500 if (expr->ts.kind < 4)
2501 se->expr = convert (type, se->expr);
2505 type = TREE_TYPE (args[0]);
2507 /* Rotate left if positive. */
2508 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
2510 /* Rotate right if negative. */
2511 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
2512 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
2514 zero = build_int_cst (TREE_TYPE (args[1]), 0);
2515 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
2516 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2518 /* Do nothing if shift == 0. */
2519 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
2520 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
2523 /* The length of a character string. */
2525 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2535 gcc_assert (!se->ss);
2537 arg = expr->value.function.actual->expr;
2539 type = gfc_typenode_for_spec (&expr->ts);
2540 switch (arg->expr_type)
2543 len = build_int_cst (NULL_TREE, arg->value.character.length);
2547 /* Obtain the string length from the function used by
2548 trans-array.c(gfc_trans_array_constructor). */
2550 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
2554 if (arg->ref == NULL
2555 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2557 /* This doesn't catch all cases.
2558 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2559 and the surrounding thread. */
2560 sym = arg->symtree->n.sym;
2561 decl = gfc_get_symbol_decl (sym);
2562 if (decl == current_function_decl && sym->attr.function
2563 && (sym->result == sym))
2564 decl = gfc_get_fake_result_decl (sym, 0);
2566 len = sym->ts.cl->backend_decl;
2571 /* Otherwise fall through. */
2574 /* Anybody stupid enough to do this deserves inefficient code. */
2575 ss = gfc_walk_expr (arg);
2576 gfc_init_se (&argse, se);
2577 if (ss == gfc_ss_terminator)
2578 gfc_conv_expr (&argse, arg);
2580 gfc_conv_expr_descriptor (&argse, arg, ss);
2581 gfc_add_block_to_block (&se->pre, &argse.pre);
2582 gfc_add_block_to_block (&se->post, &argse.post);
2583 len = argse.string_length;
2586 se->expr = convert (type, len);
2589 /* The length of a character string not including trailing blanks. */
2591 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2596 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2597 type = gfc_typenode_for_spec (&expr->ts);
2598 se->expr = build_call_expr (gfor_fndecl_string_len_trim, 2, args[0], args[1]);
2599 se->expr = convert (type, se->expr);
2603 /* Returns the starting position of a substring within a string. */
2606 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2608 tree logical4_type_node = gfc_get_logical_type (4);
2612 unsigned int num_args;
2614 num_args = gfc_intrinsic_argument_list_length (expr);
2615 args = alloca (sizeof (tree) * 5);
2617 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2618 type = gfc_typenode_for_spec (&expr->ts);
2621 args[4] = build_int_cst (logical4_type_node, 0);
2624 gcc_assert (num_args == 5);
2625 args[4] = convert (logical4_type_node, args[4]);
2628 fndecl = build_addr (gfor_fndecl_string_index, current_function_decl);
2629 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_index)),
2631 se->expr = convert (type, se->expr);
2635 /* The ascii value for a single character. */
2637 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2642 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2643 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
2644 args[1] = build1 (NOP_EXPR, pchar_type_node, args[1]);
2645 type = gfc_typenode_for_spec (&expr->ts);
2647 se->expr = build_fold_indirect_ref (args[1]);
2648 se->expr = convert (type, se->expr);
2652 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2655 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2663 unsigned int num_args;
2665 num_args = gfc_intrinsic_argument_list_length (expr);
2666 args = alloca (sizeof (tree) * num_args);
2668 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
2669 if (expr->ts.type != BT_CHARACTER)
2677 /* We do the same as in the non-character case, but the argument
2678 list is different because of the string length arguments. We
2679 also have to set the string length for the result. */
2685 se->string_length = len;
2687 type = TREE_TYPE (tsource);
2688 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2693 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2695 gfc_actual_arglist *actual;
2703 gfc_init_se (&argse, NULL);
2704 actual = expr->value.function.actual;
2706 ss = gfc_walk_expr (actual->expr);
2707 gcc_assert (ss != gfc_ss_terminator);
2708 argse.want_pointer = 1;
2709 argse.data_not_needed = 1;
2710 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2711 gfc_add_block_to_block (&se->pre, &argse.pre);
2712 gfc_add_block_to_block (&se->post, &argse.post);
2713 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
2715 /* Build the call to size0. */
2716 fncall0 = build_call_expr (gfor_fndecl_size0, 1, arg1);
2718 actual = actual->next;
2722 gfc_init_se (&argse, NULL);
2723 gfc_conv_expr_type (&argse, actual->expr,
2724 gfc_array_index_type);
2725 gfc_add_block_to_block (&se->pre, &argse.pre);
2727 /* Build the call to size1. */
2728 fncall1 = build_call_expr (gfor_fndecl_size1, 2,
2731 /* Unusually, for an intrinsic, size does not exclude
2732 an optional arg2, so we must test for it. */
2733 if (actual->expr->expr_type == EXPR_VARIABLE
2734 && actual->expr->symtree->n.sym->attr.dummy
2735 && actual->expr->symtree->n.sym->attr.optional)
2738 gfc_init_se (&argse, NULL);
2739 argse.want_pointer = 1;
2740 argse.data_not_needed = 1;
2741 gfc_conv_expr (&argse, actual->expr);
2742 gfc_add_block_to_block (&se->pre, &argse.pre);
2743 tmp = build2 (NE_EXPR, boolean_type_node, argse.expr,
2745 tmp = gfc_evaluate_now (tmp, &se->pre);
2746 se->expr = build3 (COND_EXPR, pvoid_type_node,
2747 tmp, fncall1, fncall0);
2755 type = gfc_typenode_for_spec (&expr->ts);
2756 se->expr = convert (type, se->expr);
2761 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
2775 arg = expr->value.function.actual->expr;
2777 gfc_init_se (&argse, NULL);
2778 ss = gfc_walk_expr (arg);
2780 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
2782 if (ss == gfc_ss_terminator)
2784 gfc_conv_expr_reference (&argse, arg);
2785 source = argse.expr;
2787 type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
2789 /* Obtain the source word length. */
2790 if (arg->ts.type == BT_CHARACTER)
2791 source_bytes = fold_convert (gfc_array_index_type,
2792 argse.string_length);
2794 source_bytes = fold_convert (gfc_array_index_type,
2795 size_in_bytes (type));
2799 argse.want_pointer = 0;
2800 gfc_conv_expr_descriptor (&argse, arg, ss);
2801 source = gfc_conv_descriptor_data_get (argse.expr);
2802 type = gfc_get_element_type (TREE_TYPE (argse.expr));
2804 /* Obtain the argument's word length. */
2805 if (arg->ts.type == BT_CHARACTER)
2806 tmp = fold_convert (gfc_array_index_type, argse.string_length);
2808 tmp = fold_convert (gfc_array_index_type,
2809 size_in_bytes (type));
2810 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2812 /* Obtain the size of the array in bytes. */
2813 for (n = 0; n < arg->rank; n++)
2816 idx = gfc_rank_cst[n];
2817 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2818 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2819 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2821 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2822 tmp, gfc_index_one_node);
2823 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2825 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2829 gfc_add_block_to_block (&se->pre, &argse.pre);
2830 se->expr = source_bytes;
2834 /* Intrinsic string comparison functions. */
2837 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2842 gfc_conv_intrinsic_function_args (se, expr, args, 4);
2844 se->expr = gfc_build_compare_string (args[0], args[1], args[2], args[3]);
2845 type = gfc_typenode_for_spec (&expr->ts);
2846 se->expr = fold_build2 (op, type, se->expr,
2847 build_int_cst (TREE_TYPE (se->expr), 0));
2850 /* Generate a call to the adjustl/adjustr library function. */
2852 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2860 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
2863 type = TREE_TYPE (args[2]);
2864 var = gfc_conv_string_tmp (se, type, len);
2867 tmp = build_call_expr (fndecl, 3, args[0], args[1], args[2]);
2868 gfc_add_expr_to_block (&se->pre, tmp);
2870 se->string_length = len;
2874 /* Array transfer statement.
2875 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
2877 typeof<DEST> = typeof<MOLD>
2879 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
2880 sizeof (DEST(0) * SIZE). */
2883 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
2898 gfc_actual_arglist *arg;
2905 gcc_assert (se->loop);
2906 info = &se->ss->data.info;
2908 /* Convert SOURCE. The output from this stage is:-
2909 source_bytes = length of the source in bytes
2910 source = pointer to the source data. */
2911 arg = expr->value.function.actual;
2912 gfc_init_se (&argse, NULL);
2913 ss = gfc_walk_expr (arg->expr);
2915 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
2917 /* Obtain the pointer to source and the length of source in bytes. */
2918 if (ss == gfc_ss_terminator)
2920 gfc_conv_expr_reference (&argse, arg->expr);
2921 source = argse.expr;
2923 source_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
2925 /* Obtain the source word length. */
2926 if (arg->expr->ts.type == BT_CHARACTER)
2927 tmp = fold_convert (gfc_array_index_type, argse.string_length);
2929 tmp = fold_convert (gfc_array_index_type,
2930 size_in_bytes (source_type));
2934 argse.want_pointer = 0;
2935 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2936 source = gfc_conv_descriptor_data_get (argse.expr);
2937 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
2939 /* Repack the source if not a full variable array. */
2940 if (!(arg->expr->expr_type == EXPR_VARIABLE
2941 && arg->expr->ref->u.ar.type == AR_FULL))
2943 tmp = build_fold_addr_expr (argse.expr);
2944 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
2945 source = gfc_evaluate_now (source, &argse.pre);
2947 /* Free the temporary. */
2948 gfc_start_block (&block);
2949 tmp = gfc_call_free (convert (pvoid_type_node, source));
2950 gfc_add_expr_to_block (&block, tmp);
2951 stmt = gfc_finish_block (&block);
2953 /* Clean up if it was repacked. */
2954 gfc_init_block (&block);
2955 tmp = gfc_conv_array_data (argse.expr);
2956 tmp = build2 (NE_EXPR, boolean_type_node, source, tmp);
2957 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
2958 gfc_add_expr_to_block (&block, tmp);
2959 gfc_add_block_to_block (&block, &se->post);
2960 gfc_init_block (&se->post);
2961 gfc_add_block_to_block (&se->post, &block);
2964 /* Obtain the source word length. */
2965 if (arg->expr->ts.type == BT_CHARACTER)
2966 tmp = fold_convert (gfc_array_index_type, argse.string_length);
2968 tmp = fold_convert (gfc_array_index_type,
2969 size_in_bytes (source_type));
2971 /* Obtain the size of the array in bytes. */
2972 extent = gfc_create_var (gfc_array_index_type, NULL);
2973 for (n = 0; n < arg->expr->rank; n++)
2976 idx = gfc_rank_cst[n];
2977 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2978 stride = gfc_conv_descriptor_stride (argse.expr, idx);
2979 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2980 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2981 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2983 gfc_add_modify_expr (&argse.pre, extent, tmp);
2984 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
2985 extent, gfc_index_one_node);
2986 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
2991 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2992 gfc_add_block_to_block (&se->pre, &argse.pre);
2993 gfc_add_block_to_block (&se->post, &argse.post);
2995 /* Now convert MOLD. The outputs are:
2996 mold_type = the TREE type of MOLD
2997 dest_word_len = destination word length in bytes. */
3000 gfc_init_se (&argse, NULL);
3001 ss = gfc_walk_expr (arg->expr);
3003 if (ss == gfc_ss_terminator)
3005 gfc_conv_expr_reference (&argse, arg->expr);
3006 mold_type = TREE_TYPE (build_fold_indirect_ref (argse.expr));
3010 gfc_init_se (&argse, NULL);
3011 argse.want_pointer = 0;
3012 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
3013 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
3016 if (arg->expr->ts.type == BT_CHARACTER)
3018 tmp = fold_convert (gfc_array_index_type, argse.string_length);
3019 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
3022 tmp = fold_convert (gfc_array_index_type,
3023 size_in_bytes (mold_type));
3025 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
3026 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
3028 /* Finally convert SIZE, if it is present. */
3030 size_words = gfc_create_var (gfc_array_index_type, NULL);
3034 gfc_init_se (&argse, NULL);
3035 gfc_conv_expr_reference (&argse, arg->expr);
3036 tmp = convert (gfc_array_index_type,
3037 build_fold_indirect_ref (argse.expr));
3038 gfc_add_block_to_block (&se->pre, &argse.pre);
3039 gfc_add_block_to_block (&se->post, &argse.post);
3044 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
3045 if (tmp != NULL_TREE)
3047 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3048 tmp, dest_word_len);
3049 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3055 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
3056 gfc_add_modify_expr (&se->pre, size_words,
3057 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
3058 size_bytes, dest_word_len));
3060 /* Evaluate the bounds of the result. If the loop range exists, we have
3061 to check if it is too large. If so, we modify loop->to be consistent
3062 with min(size, size(source)). Otherwise, size is made consistent with
3063 the loop range, so that the right number of bytes is transferred.*/
3064 n = se->loop->order[0];
3065 if (se->loop->to[n] != NULL_TREE)
3067 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3068 se->loop->to[n], se->loop->from[n]);
3069 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3070 tmp, gfc_index_one_node);
3071 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
3073 gfc_add_modify_expr (&se->pre, size_words, tmp);
3074 gfc_add_modify_expr (&se->pre, size_bytes,
3075 fold_build2 (MULT_EXPR, gfc_array_index_type,
3076 size_words, dest_word_len));
3077 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3078 size_words, se->loop->from[n]);
3079 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3080 upper, gfc_index_one_node);
3084 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3085 size_words, gfc_index_one_node);
3086 se->loop->from[n] = gfc_index_zero_node;
3089 se->loop->to[n] = upper;
3091 /* Build a destination descriptor, using the pointer, source, as the
3092 data field. This is already allocated so set callee_alloc.
3093 FIXME callee_alloc is not set! */
3095 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
3096 info, mold_type, false, true, false);
3098 /* Cast the pointer to the result. */
3099 tmp = gfc_conv_descriptor_data_get (info->descriptor);
3100 tmp = fold_convert (pvoid_type_node, tmp);
3102 /* Use memcpy to do the transfer. */
3103 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
3106 fold_convert (pvoid_type_node, source),
3108 gfc_add_expr_to_block (&se->pre, tmp);
3110 se->expr = info->descriptor;
3111 if (expr->ts.type == BT_CHARACTER)
3112 se->string_length = dest_word_len;
3116 /* Scalar transfer statement.
3117 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3120 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3122 gfc_actual_arglist *arg;
3129 /* Get a pointer to the source. */
3130 arg = expr->value.function.actual;
3131 ss = gfc_walk_expr (arg->expr);
3132 gfc_init_se (&argse, NULL);
3133 if (ss == gfc_ss_terminator)
3134 gfc_conv_expr_reference (&argse, arg->expr);
3136 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3137 gfc_add_block_to_block (&se->pre, &argse.pre);
3138 gfc_add_block_to_block (&se->post, &argse.post);
3142 type = gfc_typenode_for_spec (&expr->ts);
3144 if (expr->ts.type == BT_CHARACTER)
3146 ptr = convert (build_pointer_type (type), ptr);
3147 gfc_init_se (&argse, NULL);
3148 gfc_conv_expr (&argse, arg->expr);
3149 gfc_add_block_to_block (&se->pre, &argse.pre);
3150 gfc_add_block_to_block (&se->post, &argse.post);
3152 se->string_length = argse.string_length;
3157 tmpdecl = gfc_create_var (type, "transfer");
3158 moldsize = size_in_bytes (type);
3160 /* Use memcpy to do the transfer. */
3161 tmp = build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3162 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3163 fold_convert (pvoid_type_node, tmp),
3164 fold_convert (pvoid_type_node, ptr),
3166 gfc_add_expr_to_block (&se->pre, tmp);
3173 /* Generate code for the ALLOCATED intrinsic.
3174 Generate inline code that directly check the address of the argument. */
3177 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3179 gfc_actual_arglist *arg1;
3184 gfc_init_se (&arg1se, NULL);
3185 arg1 = expr->value.function.actual;
3186 ss1 = gfc_walk_expr (arg1->expr);
3187 arg1se.descriptor_only = 1;
3188 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3190 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3191 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
3192 fold_convert (TREE_TYPE (tmp), null_pointer_node));
3193 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3197 /* Generate code for the ASSOCIATED intrinsic.
3198 If both POINTER and TARGET are arrays, generate a call to library function
3199 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3200 In other cases, generate inline code that directly compare the address of
3201 POINTER with the address of TARGET. */
3204 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3206 gfc_actual_arglist *arg1;
3207 gfc_actual_arglist *arg2;
3213 tree nonzero_charlen;
3214 tree nonzero_arraylen;
3217 gfc_init_se (&arg1se, NULL);
3218 gfc_init_se (&arg2se, NULL);
3219 arg1 = expr->value.function.actual;
3221 ss1 = gfc_walk_expr (arg1->expr);
3225 /* No optional target. */
3226 if (ss1 == gfc_ss_terminator)
3228 /* A pointer to a scalar. */
3229 arg1se.want_pointer = 1;
3230 gfc_conv_expr (&arg1se, arg1->expr);
3235 /* A pointer to an array. */
3236 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3237 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3239 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3240 gfc_add_block_to_block (&se->post, &arg1se.post);
3241 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
3242 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3247 /* An optional target. */
3248 ss2 = gfc_walk_expr (arg2->expr);
3250 nonzero_charlen = NULL_TREE;
3251 if (arg1->expr->ts.type == BT_CHARACTER)
3252 nonzero_charlen = build2 (NE_EXPR, boolean_type_node,
3253 arg1->expr->ts.cl->backend_decl,
3256 if (ss1 == gfc_ss_terminator)
3258 /* A pointer to a scalar. */
3259 gcc_assert (ss2 == gfc_ss_terminator);
3260 arg1se.want_pointer = 1;
3261 gfc_conv_expr (&arg1se, arg1->expr);
3262 arg2se.want_pointer = 1;
3263 gfc_conv_expr (&arg2se, arg2->expr);
3264 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3265 gfc_add_block_to_block (&se->post, &arg1se.post);
3266 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
3267 tmp2 = build2 (NE_EXPR, boolean_type_node, arg1se.expr,
3269 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node, tmp, tmp2);
3274 /* An array pointer of zero length is not associated if target is
3276 arg1se.descriptor_only = 1;
3277 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3278 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3279 gfc_rank_cst[arg1->expr->rank - 1]);
3280 nonzero_arraylen = build2 (NE_EXPR, boolean_type_node,
3281 tmp, build_int_cst (TREE_TYPE (tmp), 0));
3283 /* A pointer to an array, call library function _gfor_associated. */
3284 gcc_assert (ss2 != gfc_ss_terminator);
3285 arg1se.want_pointer = 1;
3286 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3288 arg2se.want_pointer = 1;
3289 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3290 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3291 gfc_add_block_to_block (&se->post, &arg2se.post);
3292 fndecl = gfor_fndecl_associated;
3293 se->expr = build_call_expr (fndecl, 2, arg1se.expr, arg2se.expr);
3294 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3295 se->expr, nonzero_arraylen);
3299 /* If target is present zero character length pointers cannot
3301 if (nonzero_charlen != NULL_TREE)
3302 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3303 se->expr, nonzero_charlen);
3306 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3310 /* Scan a string for any one of the characters in a set of characters. */
3313 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
3315 tree logical4_type_node = gfc_get_logical_type (4);
3319 unsigned int num_args;
3321 num_args = gfc_intrinsic_argument_list_length (expr);
3322 args = alloca (sizeof (tree) * 5);
3324 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3325 type = gfc_typenode_for_spec (&expr->ts);
3328 args[4] = build_int_cst (logical4_type_node, 0);
3331 gcc_assert (num_args == 5);
3332 args[4] = convert (logical4_type_node, args[4]);
3335 fndecl = build_addr (gfor_fndecl_string_scan, current_function_decl);
3336 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_scan)),
3338 se->expr = convert (type, se->expr);
3342 /* Verify that a set of characters contains all the characters in a string
3343 by identifying the position of the first character in a string of
3344 characters that does not appear in a given set of characters. */
3347 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
3349 tree logical4_type_node = gfc_get_logical_type (4);
3353 unsigned int num_args;
3355 num_args = gfc_intrinsic_argument_list_length (expr);
3356 args = alloca (sizeof (tree) * 5);
3358 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3359 type = gfc_typenode_for_spec (&expr->ts);
3362 args[4] = build_int_cst (logical4_type_node, 0);
3365 gcc_assert (num_args == 5);
3366 args[4] = convert (logical4_type_node, args[4]);
3369 fndecl = build_addr (gfor_fndecl_string_verify, current_function_decl);
3370 se->expr = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_verify)),
3373 se->expr = convert (type, se->expr);
3377 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3380 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
3384 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3385 arg = build_fold_addr_expr (arg);
3386 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, arg);
3389 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3392 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
3394 gfc_actual_arglist *actual;
3399 for (actual = expr->value.function.actual; actual; actual = actual->next)
3401 gfc_init_se (&argse, se);
3403 /* Pass a NULL pointer for an absent arg. */
3404 if (actual->expr == NULL)
3405 argse.expr = null_pointer_node;
3407 gfc_conv_expr_reference (&argse, actual->expr);
3409 gfc_add_block_to_block (&se->pre, &argse.pre);
3410 gfc_add_block_to_block (&se->post, &argse.post);
3411 args = gfc_chainon_list (args, argse.expr);
3413 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3417 /* Generate code for TRIM (A) intrinsic function. */
3420 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3422 tree gfc_int4_type_node = gfc_get_int_type (4);
3431 unsigned int num_args;
3433 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
3434 args = alloca (sizeof (tree) * num_args);
3436 type = build_pointer_type (gfc_character1_type_node);
3437 var = gfc_create_var (type, "pstr");
3438 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3439 len = gfc_create_var (gfc_int4_type_node, "len");
3441 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
3442 args[0] = build_fold_addr_expr (len);
3445 fndecl = build_addr (gfor_fndecl_string_trim, current_function_decl);
3446 tmp = build_call_array (TREE_TYPE (TREE_TYPE (gfor_fndecl_string_trim)),
3447 fndecl, num_args, args);
3448 gfc_add_expr_to_block (&se->pre, tmp);
3450 /* Free the temporary afterwards, if necessary. */
3451 cond = build2 (GT_EXPR, boolean_type_node, len,
3452 build_int_cst (TREE_TYPE (len), 0));
3453 tmp = gfc_call_free (var);
3454 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3455 gfc_add_expr_to_block (&se->post, tmp);
3458 se->string_length = len;
3462 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3465 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3467 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
3468 tree type, cond, tmp, count, exit_label, n, max, largest;
3469 stmtblock_t block, body;
3472 /* Get the arguments. */
3473 gfc_conv_intrinsic_function_args (se, expr, args, 3);
3474 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
3476 ncopies = gfc_evaluate_now (args[2], &se->pre);
3477 ncopies_type = TREE_TYPE (ncopies);
3479 /* Check that NCOPIES is not negative. */
3480 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3481 build_int_cst (ncopies_type, 0));
3482 gfc_trans_runtime_check (cond,
3483 "Argument NCOPIES of REPEAT intrinsic is negative",
3484 &se->pre, &expr->where);
3486 /* If the source length is zero, any non negative value of NCOPIES
3487 is valid, and nothing happens. */
3488 n = gfc_create_var (ncopies_type, "ncopies");
3489 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3490 build_int_cst (size_type_node, 0));
3491 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
3492 build_int_cst (ncopies_type, 0), ncopies);
3493 gfc_add_modify_expr (&se->pre, n, tmp);
3496 /* Check that ncopies is not too large: ncopies should be less than
3497 (or equal to) MAX / slen, where MAX is the maximal integer of
3498 the gfc_charlen_type_node type. If slen == 0, we need a special
3499 case to avoid the division by zero. */
3500 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
3501 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
3502 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
3503 fold_convert (size_type_node, max), slen);
3504 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
3505 ? size_type_node : ncopies_type;
3506 cond = fold_build2 (GT_EXPR, boolean_type_node,
3507 fold_convert (largest, ncopies),
3508 fold_convert (largest, max));
3509 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
3510 build_int_cst (size_type_node, 0));
3511 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
3513 gfc_trans_runtime_check (cond,
3514 "Argument NCOPIES of REPEAT intrinsic is too large",
3515 &se->pre, &expr->where);
3517 /* Compute the destination length. */
3518 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node, slen, ncopies);
3519 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3520 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
3522 /* Generate the code to do the repeat operation:
3523 for (i = 0; i < ncopies; i++)
3524 memmove (dest + (i * slen), src, slen); */
3525 gfc_start_block (&block);
3526 count = gfc_create_var (ncopies_type, "count");
3527 gfc_add_modify_expr (&block, count, build_int_cst (ncopies_type, 0));
3528 exit_label = gfc_build_label_decl (NULL_TREE);
3530 /* Start the loop body. */
3531 gfc_start_block (&body);
3533 /* Exit the loop if count >= ncopies. */
3534 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
3535 tmp = build1_v (GOTO_EXPR, exit_label);
3536 TREE_USED (exit_label) = 1;
3537 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
3538 build_empty_stmt ());
3539 gfc_add_expr_to_block (&body, tmp);
3541 /* Call memmove (dest + (i*slen), src, slen). */
3542 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node, slen,
3543 fold_convert (gfc_charlen_type_node, count));
3544 tmp = fold_build2 (PLUS_EXPR, pchar_type_node, dest,
3545 fold_convert (pchar_type_node, tmp));
3546 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMMOVE], 3,
3548 gfc_add_expr_to_block (&body, tmp);
3550 /* Increment count. */
3551 tmp = build2 (PLUS_EXPR, ncopies_type, count,
3552 build_int_cst (TREE_TYPE (count), 1));
3553 gfc_add_modify_expr (&body, count, tmp);
3555 /* Build the loop. */
3556 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
3557 gfc_add_expr_to_block (&block, tmp);
3559 /* Add the exit label. */
3560 tmp = build1_v (LABEL_EXPR, exit_label);
3561 gfc_add_expr_to_block (&block, tmp);
3563 /* Finish the block. */
3564 tmp = gfc_finish_block (&block);
3565 gfc_add_expr_to_block (&se->pre, tmp);
3567 /* Set the result value. */
3569 se->string_length = dlen;
3573 /* Generate code for the IARGC intrinsic. */
3576 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3582 /* Call the library function. This always returns an INTEGER(4). */
3583 fndecl = gfor_fndecl_iargc;
3584 tmp = build_call_expr (fndecl, 0);
3586 /* Convert it to the required type. */
3587 type = gfc_typenode_for_spec (&expr->ts);
3588 tmp = fold_convert (type, tmp);
3594 /* The loc intrinsic returns the address of its argument as
3595 gfc_index_integer_kind integer. */
3598 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3604 gcc_assert (!se->ss);
3606 arg_expr = expr->value.function.actual->expr;
3607 ss = gfc_walk_expr (arg_expr);
3608 if (ss == gfc_ss_terminator)
3609 gfc_conv_expr_reference (se, arg_expr);
3611 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3612 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
3614 /* Create a temporary variable for loc return value. Without this,
3615 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3616 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
3617 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3618 se->expr = temp_var;
3621 /* Generate code for an intrinsic function. Some map directly to library
3622 calls, others get special handling. In some cases the name of the function
3623 used depends on the type specifiers. */
3626 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
3628 gfc_intrinsic_sym *isym;
3632 isym = expr->value.function.isym;
3634 name = &expr->value.function.name[2];
3636 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
3638 lib = gfc_is_intrinsic_libcall (expr);
3642 se->ignore_optional = 1;
3643 gfc_conv_intrinsic_funcall (se, expr);
3648 switch (expr->value.function.isym->id)
3653 case GFC_ISYM_REPEAT:
3654 gfc_conv_intrinsic_repeat (se, expr);
3658 gfc_conv_intrinsic_trim (se, expr);
3661 case GFC_ISYM_SI_KIND:
3662 gfc_conv_intrinsic_si_kind (se, expr);
3665 case GFC_ISYM_SR_KIND:
3666 gfc_conv_intrinsic_sr_kind (se, expr);
3669 case GFC_ISYM_EXPONENT:
3670 gfc_conv_intrinsic_exponent (se, expr);
3674 gfc_conv_intrinsic_scan (se, expr);
3677 case GFC_ISYM_VERIFY:
3678 gfc_conv_intrinsic_verify (se, expr);
3681 case GFC_ISYM_ALLOCATED:
3682 gfc_conv_allocated (se, expr);
3685 case GFC_ISYM_ASSOCIATED:
3686 gfc_conv_associated(se, expr);
3690 gfc_conv_intrinsic_abs (se, expr);
3693 case GFC_ISYM_ADJUSTL:
3694 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
3697 case GFC_ISYM_ADJUSTR:
3698 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
3701 case GFC_ISYM_AIMAG:
3702 gfc_conv_intrinsic_imagpart (se, expr);
3706 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
3710 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
3713 case GFC_ISYM_ANINT:
3714 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
3718 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3722 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
3725 case GFC_ISYM_BTEST:
3726 gfc_conv_intrinsic_btest (se, expr);
3729 case GFC_ISYM_ACHAR:
3731 gfc_conv_intrinsic_char (se, expr);
3734 case GFC_ISYM_CONVERSION:
3736 case GFC_ISYM_LOGICAL:
3738 gfc_conv_intrinsic_conversion (se, expr);
3741 /* Integer conversions are handled separately to make sure we get the
3742 correct rounding mode. */
3747 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
3751 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
3754 case GFC_ISYM_CEILING:
3755 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
3758 case GFC_ISYM_FLOOR:
3759 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
3763 gfc_conv_intrinsic_mod (se, expr, 0);
3766 case GFC_ISYM_MODULO:
3767 gfc_conv_intrinsic_mod (se, expr, 1);
3770 case GFC_ISYM_CMPLX:
3771 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3774 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3775 gfc_conv_intrinsic_iargc (se, expr);
3778 case GFC_ISYM_COMPLEX:
3779 gfc_conv_intrinsic_cmplx (se, expr, 1);
3782 case GFC_ISYM_CONJG:
3783 gfc_conv_intrinsic_conjg (se, expr);
3786 case GFC_ISYM_COUNT:
3787 gfc_conv_intrinsic_count (se, expr);
3790 case GFC_ISYM_CTIME:
3791 gfc_conv_intrinsic_ctime (se, expr);
3795 gfc_conv_intrinsic_dim (se, expr);
3798 case GFC_ISYM_DOT_PRODUCT:
3799 gfc_conv_intrinsic_dot_product (se, expr);
3802 case GFC_ISYM_DPROD:
3803 gfc_conv_intrinsic_dprod (se, expr);
3806 case GFC_ISYM_FDATE:
3807 gfc_conv_intrinsic_fdate (se, expr);
3811 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3814 case GFC_ISYM_IBCLR:
3815 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3818 case GFC_ISYM_IBITS:
3819 gfc_conv_intrinsic_ibits (se, expr);
3822 case GFC_ISYM_IBSET:
3823 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3826 case GFC_ISYM_IACHAR:
3827 case GFC_ISYM_ICHAR:
3828 /* We assume ASCII character sequence. */
3829 gfc_conv_intrinsic_ichar (se, expr);
3832 case GFC_ISYM_IARGC:
3833 gfc_conv_intrinsic_iargc (se, expr);
3837 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3840 case GFC_ISYM_INDEX:
3841 gfc_conv_intrinsic_index (se, expr);
3845 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3848 case GFC_ISYM_LSHIFT:
3849 gfc_conv_intrinsic_rlshift (se, expr, 0);
3852 case GFC_ISYM_RSHIFT:
3853 gfc_conv_intrinsic_rlshift (se, expr, 1);
3856 case GFC_ISYM_ISHFT:
3857 gfc_conv_intrinsic_ishft (se, expr);
3860 case GFC_ISYM_ISHFTC:
3861 gfc_conv_intrinsic_ishftc (se, expr);
3864 case GFC_ISYM_LBOUND:
3865 gfc_conv_intrinsic_bound (se, expr, 0);
3868 case GFC_ISYM_TRANSPOSE:
3869 if (se->ss && se->ss->useflags)
3871 gfc_conv_tmp_array_ref (se);
3872 gfc_advance_se_ss_chain (se);
3875 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3879 gfc_conv_intrinsic_len (se, expr);
3882 case GFC_ISYM_LEN_TRIM:
3883 gfc_conv_intrinsic_len_trim (se, expr);
3887 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3891 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3895 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3899 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3903 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3906 case GFC_ISYM_MAXLOC:
3907 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3910 case GFC_ISYM_MAXVAL:
3911 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3914 case GFC_ISYM_MERGE:
3915 gfc_conv_intrinsic_merge (se, expr);
3919 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3922 case GFC_ISYM_MINLOC:
3923 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3926 case GFC_ISYM_MINVAL:
3927 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3931 gfc_conv_intrinsic_not (se, expr);
3935 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3938 case GFC_ISYM_PRESENT:
3939 gfc_conv_intrinsic_present (se, expr);
3942 case GFC_ISYM_PRODUCT:
3943 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3947 gfc_conv_intrinsic_sign (se, expr);
3951 gfc_conv_intrinsic_size (se, expr);
3954 case GFC_ISYM_SIZEOF:
3955 gfc_conv_intrinsic_sizeof (se, expr);
3959 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3962 case GFC_ISYM_TRANSFER:
3965 if (se->ss->useflags)
3967 /* Access the previously obtained result. */
3968 gfc_conv_tmp_array_ref (se);
3969 gfc_advance_se_ss_chain (se);
3973 gfc_conv_intrinsic_array_transfer (se, expr);
3976 gfc_conv_intrinsic_transfer (se, expr);
3979 case GFC_ISYM_TTYNAM:
3980 gfc_conv_intrinsic_ttynam (se, expr);
3983 case GFC_ISYM_UBOUND:
3984 gfc_conv_intrinsic_bound (se, expr, 1);
3988 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3992 gfc_conv_intrinsic_loc (se, expr);
3995 case GFC_ISYM_ACCESS:
3996 case GFC_ISYM_CHDIR:
3997 case GFC_ISYM_CHMOD:
3998 case GFC_ISYM_ETIME:
4000 case GFC_ISYM_FGETC:
4003 case GFC_ISYM_FPUTC:
4004 case GFC_ISYM_FSTAT:
4005 case GFC_ISYM_FTELL:
4006 case GFC_ISYM_GETCWD:
4007 case GFC_ISYM_GETGID:
4008 case GFC_ISYM_GETPID:
4009 case GFC_ISYM_GETUID:
4010 case GFC_ISYM_HOSTNM:
4012 case GFC_ISYM_IERRNO:
4013 case GFC_ISYM_IRAND:
4014 case GFC_ISYM_ISATTY:
4016 case GFC_ISYM_LSTAT:
4017 case GFC_ISYM_MALLOC:
4018 case GFC_ISYM_MATMUL:
4019 case GFC_ISYM_MCLOCK:
4020 case GFC_ISYM_MCLOCK8:
4022 case GFC_ISYM_RENAME:
4023 case GFC_ISYM_SECOND:
4024 case GFC_ISYM_SECNDS:
4025 case GFC_ISYM_SIGNAL:
4027 case GFC_ISYM_SYMLNK:
4028 case GFC_ISYM_SYSTEM:
4030 case GFC_ISYM_TIME8:
4031 case GFC_ISYM_UMASK:
4032 case GFC_ISYM_UNLINK:
4033 gfc_conv_intrinsic_funcall (se, expr);
4037 gfc_conv_intrinsic_lib_function (se, expr);
4043 /* This generates code to execute before entering the scalarization loop.
4044 Currently does nothing. */
4047 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
4049 switch (ss->expr->value.function.isym->id)
4051 case GFC_ISYM_UBOUND:
4052 case GFC_ISYM_LBOUND:
4061 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
4062 inside the scalarization loop. */
4065 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
4069 /* The two argument version returns a scalar. */
4070 if (expr->value.function.actual->next->expr)
4073 newss = gfc_get_ss ();
4074 newss->type = GFC_SS_INTRINSIC;
4077 newss->data.info.dimen = 1;
4083 /* Walk an intrinsic array libcall. */
4086 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
4090 gcc_assert (expr->rank > 0);
4092 newss = gfc_get_ss ();
4093 newss->type = GFC_SS_FUNCTION;
4096 newss->data.info.dimen = expr->rank;
4102 /* Returns nonzero if the specified intrinsic function call maps directly to a
4103 an external library call. Should only be used for functions that return
4107 gfc_is_intrinsic_libcall (gfc_expr * expr)
4109 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
4110 gcc_assert (expr->rank > 0);
4112 switch (expr->value.function.isym->id)
4116 case GFC_ISYM_COUNT:
4117 case GFC_ISYM_MATMUL:
4118 case GFC_ISYM_MAXLOC:
4119 case GFC_ISYM_MAXVAL:
4120 case GFC_ISYM_MINLOC:
4121 case GFC_ISYM_MINVAL:
4122 case GFC_ISYM_PRODUCT:
4124 case GFC_ISYM_SHAPE:
4125 case GFC_ISYM_SPREAD:
4126 case GFC_ISYM_TRANSPOSE:
4127 /* Ignore absent optional parameters. */
4130 case GFC_ISYM_RESHAPE:
4131 case GFC_ISYM_CSHIFT:
4132 case GFC_ISYM_EOSHIFT:
4134 case GFC_ISYM_UNPACK:
4135 /* Pass absent optional parameters. */
4143 /* Walk an intrinsic function. */
4145 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
4146 gfc_intrinsic_sym * isym)
4150 if (isym->elemental)
4151 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
4153 if (expr->rank == 0)
4156 if (gfc_is_intrinsic_libcall (expr))
4157 return gfc_walk_intrinsic_libfunc (ss, expr);
4159 /* Special cases. */
4162 case GFC_ISYM_LBOUND:
4163 case GFC_ISYM_UBOUND:
4164 return gfc_walk_intrinsic_bound (ss, expr);
4166 case GFC_ISYM_TRANSFER:
4167 return gfc_walk_intrinsic_libfunc (ss, expr);
4170 /* This probably meant someone forgot to add an intrinsic to the above
4171 list(s) when they implemented it, or something's gone horribly wrong.
4173 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
4174 expr->value.function.name);
4178 #include "gt-fortran-trans-intrinsic.h"