tree.h (enum tree_code_class): Add tcc_vl_exp.
[official-gcc.git] / gcc / fortran / trans-intrinsic.c
blobe6bc46f228d10aee5a65c5268821efd03851b549
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
12 version.
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
17 for more details.
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
22 02110-1301, USA. */
24 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tree.h"
30 #include "ggc.h"
31 #include "toplev.h"
32 #include "real.h"
33 #include "tree-gimple.h"
34 #include "flags.h"
35 #include "gfortran.h"
36 #include "arith.h"
37 #include "intrinsic.h"
38 #include "trans.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
42 #include "defaults.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
47 builtin functions. */
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. */
52 enum gfc_generic_isym_id id;
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)". */
68 bool libm_name;
70 /* True if a complex version of the function exists. */
71 bool complex_available;
73 /* True if the function should be marked const. */
74 bool is_constant;
76 /* The base library name of this function. */
77 const char *name;
79 /* Cache decls created for the various operand types. */
80 tree real4_decl;
81 tree real8_decl;
82 tree real10_decl;
83 tree real16_decl;
84 tree complex4_decl;
85 tree complex8_decl;
86 tree complex10_decl;
87 tree complex16_decl;
89 gfc_intrinsic_map_t;
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
93 except for atan2. */
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),
137 /* End the list. */
138 LIBF_FUNCTION (NONE, NULL, false)
140 #undef DEFINE_MATH_BUILTIN
141 #undef DEFINE_MATH_BUILTIN_C
142 #undef LIBM_FUNCTION
143 #undef LIBF_FUNCTION
145 /* Structure for storing components of a floating number to be used by
146 elemental functions to manipulate reals. */
147 typedef struct
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. */
162 real_compnt_info;
164 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
166 /* Evaluate the arguments to an intrinsic function. */
167 /* FIXME: This function and its callers should be rewritten so that it's
168 not necessary to cons up a list to hold the arguments. */
170 static tree
171 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
173 gfc_actual_arglist *actual;
174 gfc_expr *e;
175 gfc_intrinsic_arg *formal;
176 gfc_se argse;
177 tree args;
179 args = NULL_TREE;
180 formal = expr->value.function.isym->formal;
182 for (actual = expr->value.function.actual; actual; actual = actual->next,
183 formal = formal ? formal->next : NULL)
185 e = actual->expr;
186 /* Skip omitted optional arguments. */
187 if (!e)
188 continue;
190 /* Evaluate the parameter. This will substitute scalarized
191 references automatically. */
192 gfc_init_se (&argse, se);
194 if (e->ts.type == BT_CHARACTER)
196 gfc_conv_expr (&argse, e);
197 gfc_conv_string_parameter (&argse);
198 args = gfc_chainon_list (args, argse.string_length);
200 else
201 gfc_conv_expr_val (&argse, e);
203 /* If an optional argument is itself an optional dummy argument,
204 check its presence and substitute a null if absent. */
205 if (e->expr_type ==EXPR_VARIABLE
206 && e->symtree->n.sym->attr.optional
207 && formal
208 && formal->optional)
209 gfc_conv_missing_dummy (&argse, e, formal->ts);
211 gfc_add_block_to_block (&se->pre, &argse.pre);
212 gfc_add_block_to_block (&se->post, &argse.post);
213 args = gfc_chainon_list (args, argse.expr);
215 return args;
219 /* Conversions between different types are output by the frontend as
220 intrinsic functions. We implement these directly with inline code. */
222 static void
223 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
225 tree type;
226 tree arg;
228 /* Evaluate the argument. */
229 type = gfc_typenode_for_spec (&expr->ts);
230 gcc_assert (expr->value.function.actual->expr);
231 arg = gfc_conv_intrinsic_function_args (se, expr);
232 arg = TREE_VALUE (arg);
234 /* Conversion from complex to non-complex involves taking the real
235 component of the value. */
236 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
237 && expr->ts.type != BT_COMPLEX)
239 tree artype;
241 artype = TREE_TYPE (TREE_TYPE (arg));
242 arg = build1 (REALPART_EXPR, artype, arg);
245 se->expr = convert (type, arg);
248 /* This is needed because the gcc backend only implements
249 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
250 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
251 Similarly for CEILING. */
253 static tree
254 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
256 tree tmp;
257 tree cond;
258 tree argtype;
259 tree intval;
261 argtype = TREE_TYPE (arg);
262 arg = gfc_evaluate_now (arg, pblock);
264 intval = convert (type, arg);
265 intval = gfc_evaluate_now (intval, pblock);
267 tmp = convert (argtype, intval);
268 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
270 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
271 build_int_cst (type, 1));
272 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
273 return tmp;
277 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
278 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
280 static tree
281 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
283 tree tmp;
284 tree cond;
285 tree neg;
286 tree pos;
287 tree argtype;
288 REAL_VALUE_TYPE r;
290 argtype = TREE_TYPE (arg);
291 arg = gfc_evaluate_now (arg, pblock);
293 real_from_string (&r, "0.5");
294 pos = build_real (argtype, r);
296 real_from_string (&r, "-0.5");
297 neg = build_real (argtype, r);
299 tmp = gfc_build_const (argtype, integer_zero_node);
300 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
302 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
303 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
304 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
308 /* Convert a real to an integer using a specific rounding mode.
309 Ideally we would just build the corresponding GENERIC node,
310 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
312 static tree
313 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
314 enum rounding_mode op)
316 switch (op)
318 case RND_FLOOR:
319 return build_fixbound_expr (pblock, arg, type, 0);
320 break;
322 case RND_CEIL:
323 return build_fixbound_expr (pblock, arg, type, 1);
324 break;
326 case RND_ROUND:
327 return build_round_expr (pblock, arg, type);
329 default:
330 gcc_assert (op == RND_TRUNC);
331 return build1 (FIX_TRUNC_EXPR, type, arg);
336 /* Round a real value using the specified rounding mode.
337 We use a temporary integer of that same kind size as the result.
338 Values larger than those that can be represented by this kind are
339 unchanged, as they will not be accurate enough to represent the
340 rounding.
341 huge = HUGE (KIND (a))
342 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
345 static void
346 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
348 tree type;
349 tree itype;
350 tree arg;
351 tree tmp;
352 tree cond;
353 mpfr_t huge;
354 int n;
355 int kind;
357 kind = expr->ts.kind;
359 n = END_BUILTINS;
360 /* We have builtin functions for some cases. */
361 switch (op)
363 case RND_ROUND:
364 switch (kind)
366 case 4:
367 n = BUILT_IN_ROUNDF;
368 break;
370 case 8:
371 n = BUILT_IN_ROUND;
372 break;
374 case 10:
375 case 16:
376 n = BUILT_IN_ROUNDL;
377 break;
379 break;
381 case RND_TRUNC:
382 switch (kind)
384 case 4:
385 n = BUILT_IN_TRUNCF;
386 break;
388 case 8:
389 n = BUILT_IN_TRUNC;
390 break;
392 case 10:
393 case 16:
394 n = BUILT_IN_TRUNCL;
395 break;
397 break;
399 default:
400 gcc_unreachable ();
403 /* Evaluate the argument. */
404 gcc_assert (expr->value.function.actual->expr);
405 arg = gfc_conv_intrinsic_function_args (se, expr);
407 /* Use a builtin function if one exists. */
408 if (n != END_BUILTINS)
410 tmp = built_in_decls[n];
411 se->expr = build_function_call_expr (tmp, arg);
412 return;
415 /* This code is probably redundant, but we'll keep it lying around just
416 in case. */
417 type = gfc_typenode_for_spec (&expr->ts);
418 arg = TREE_VALUE (arg);
419 arg = gfc_evaluate_now (arg, &se->pre);
421 /* Test if the value is too large to handle sensibly. */
422 gfc_set_model_kind (kind);
423 mpfr_init (huge);
424 n = gfc_validate_kind (BT_INTEGER, kind, false);
425 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
426 tmp = gfc_conv_mpfr_to_tree (huge, kind);
427 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
429 mpfr_neg (huge, huge, GFC_RND_MODE);
430 tmp = gfc_conv_mpfr_to_tree (huge, kind);
431 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
432 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
433 itype = gfc_get_int_type (kind);
435 tmp = build_fix_expr (&se->pre, arg, itype, op);
436 tmp = convert (type, tmp);
437 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
438 mpfr_clear (huge);
442 /* Convert to an integer using the specified rounding mode. */
444 static void
445 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
447 tree type;
448 tree arg;
450 /* Evaluate the argument. */
451 type = gfc_typenode_for_spec (&expr->ts);
452 gcc_assert (expr->value.function.actual->expr);
453 arg = gfc_conv_intrinsic_function_args (se, expr);
454 arg = TREE_VALUE (arg);
456 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
458 /* Conversion to a different integer kind. */
459 se->expr = convert (type, arg);
461 else
463 /* Conversion from complex to non-complex involves taking the real
464 component of the value. */
465 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
466 && expr->ts.type != BT_COMPLEX)
468 tree artype;
470 artype = TREE_TYPE (TREE_TYPE (arg));
471 arg = build1 (REALPART_EXPR, artype, arg);
474 se->expr = build_fix_expr (&se->pre, arg, type, op);
479 /* Get the imaginary component of a value. */
481 static void
482 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
484 tree arg;
486 arg = gfc_conv_intrinsic_function_args (se, expr);
487 arg = TREE_VALUE (arg);
488 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
492 /* Get the complex conjugate of a value. */
494 static void
495 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
497 tree arg;
499 arg = gfc_conv_intrinsic_function_args (se, expr);
500 arg = TREE_VALUE (arg);
501 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
505 /* Initialize function decls for library functions. The external functions
506 are created as required. Builtin functions are added here. */
508 void
509 gfc_build_intrinsic_lib_fndecls (void)
511 gfc_intrinsic_map_t *m;
513 /* Add GCC builtin functions. */
514 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
516 if (m->code_r4 != END_BUILTINS)
517 m->real4_decl = built_in_decls[m->code_r4];
518 if (m->code_r8 != END_BUILTINS)
519 m->real8_decl = built_in_decls[m->code_r8];
520 if (m->code_r10 != END_BUILTINS)
521 m->real10_decl = built_in_decls[m->code_r10];
522 if (m->code_r16 != END_BUILTINS)
523 m->real16_decl = built_in_decls[m->code_r16];
524 if (m->code_c4 != END_BUILTINS)
525 m->complex4_decl = built_in_decls[m->code_c4];
526 if (m->code_c8 != END_BUILTINS)
527 m->complex8_decl = built_in_decls[m->code_c8];
528 if (m->code_c10 != END_BUILTINS)
529 m->complex10_decl = built_in_decls[m->code_c10];
530 if (m->code_c16 != END_BUILTINS)
531 m->complex16_decl = built_in_decls[m->code_c16];
536 /* Create a fndecl for a simple intrinsic library function. */
538 static tree
539 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
541 tree type;
542 tree argtypes;
543 tree fndecl;
544 gfc_actual_arglist *actual;
545 tree *pdecl;
546 gfc_typespec *ts;
547 char name[GFC_MAX_SYMBOL_LEN + 3];
549 ts = &expr->ts;
550 if (ts->type == BT_REAL)
552 switch (ts->kind)
554 case 4:
555 pdecl = &m->real4_decl;
556 break;
557 case 8:
558 pdecl = &m->real8_decl;
559 break;
560 case 10:
561 pdecl = &m->real10_decl;
562 break;
563 case 16:
564 pdecl = &m->real16_decl;
565 break;
566 default:
567 gcc_unreachable ();
570 else if (ts->type == BT_COMPLEX)
572 gcc_assert (m->complex_available);
574 switch (ts->kind)
576 case 4:
577 pdecl = &m->complex4_decl;
578 break;
579 case 8:
580 pdecl = &m->complex8_decl;
581 break;
582 case 10:
583 pdecl = &m->complex10_decl;
584 break;
585 case 16:
586 pdecl = &m->complex16_decl;
587 break;
588 default:
589 gcc_unreachable ();
592 else
593 gcc_unreachable ();
595 if (*pdecl)
596 return *pdecl;
598 if (m->libm_name)
600 if (ts->kind == 4)
601 snprintf (name, sizeof (name), "%s%s%s",
602 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
603 else if (ts->kind == 8)
604 snprintf (name, sizeof (name), "%s%s",
605 ts->type == BT_COMPLEX ? "c" : "", m->name);
606 else
608 gcc_assert (ts->kind == 10 || ts->kind == 16);
609 snprintf (name, sizeof (name), "%s%s%s",
610 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
613 else
615 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
616 ts->type == BT_COMPLEX ? 'c' : 'r',
617 ts->kind);
620 argtypes = NULL_TREE;
621 for (actual = expr->value.function.actual; actual; actual = actual->next)
623 type = gfc_typenode_for_spec (&actual->expr->ts);
624 argtypes = gfc_chainon_list (argtypes, type);
626 argtypes = gfc_chainon_list (argtypes, void_type_node);
627 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
628 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
630 /* Mark the decl as external. */
631 DECL_EXTERNAL (fndecl) = 1;
632 TREE_PUBLIC (fndecl) = 1;
634 /* Mark it __attribute__((const)), if possible. */
635 TREE_READONLY (fndecl) = m->is_constant;
637 rest_of_decl_compilation (fndecl, 1, 0);
639 (*pdecl) = fndecl;
640 return fndecl;
644 /* Convert an intrinsic function into an external or builtin call. */
646 static void
647 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
649 gfc_intrinsic_map_t *m;
650 tree args;
651 tree fndecl;
652 gfc_generic_isym_id id;
654 id = expr->value.function.isym->generic_id;
655 /* Find the entry for this function. */
656 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
658 if (id == m->id)
659 break;
662 if (m->id == GFC_ISYM_NONE)
664 internal_error ("Intrinsic function %s(%d) not recognized",
665 expr->value.function.name, id);
668 /* Get the decl and generate the call. */
669 args = gfc_conv_intrinsic_function_args (se, expr);
670 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
671 se->expr = build_function_call_expr (fndecl, args);
674 /* Generate code for EXPONENT(X) intrinsic function. */
676 static void
677 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
679 tree args, fndecl;
680 gfc_expr *a1;
682 args = gfc_conv_intrinsic_function_args (se, expr);
684 a1 = expr->value.function.actual->expr;
685 switch (a1->ts.kind)
687 case 4:
688 fndecl = gfor_fndecl_math_exponent4;
689 break;
690 case 8:
691 fndecl = gfor_fndecl_math_exponent8;
692 break;
693 case 10:
694 fndecl = gfor_fndecl_math_exponent10;
695 break;
696 case 16:
697 fndecl = gfor_fndecl_math_exponent16;
698 break;
699 default:
700 gcc_unreachable ();
703 se->expr = build_function_call_expr (fndecl, args);
706 /* Evaluate a single upper or lower bound. */
707 /* TODO: bound intrinsic generates way too much unnecessary code. */
709 static void
710 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
712 gfc_actual_arglist *arg;
713 gfc_actual_arglist *arg2;
714 tree desc;
715 tree type;
716 tree bound;
717 tree tmp;
718 tree cond, cond1, cond2, cond3, cond4, size;
719 tree ubound;
720 tree lbound;
721 gfc_se argse;
722 gfc_ss *ss;
723 gfc_array_spec * as;
724 gfc_ref *ref;
726 arg = expr->value.function.actual;
727 arg2 = arg->next;
729 if (se->ss)
731 /* Create an implicit second parameter from the loop variable. */
732 gcc_assert (!arg2->expr);
733 gcc_assert (se->loop->dimen == 1);
734 gcc_assert (se->ss->expr == expr);
735 gfc_advance_se_ss_chain (se);
736 bound = se->loop->loopvar[0];
737 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
738 se->loop->from[0]);
740 else
742 /* use the passed argument. */
743 gcc_assert (arg->next->expr);
744 gfc_init_se (&argse, NULL);
745 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
746 gfc_add_block_to_block (&se->pre, &argse.pre);
747 bound = argse.expr;
748 /* Convert from one based to zero based. */
749 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
750 gfc_index_one_node);
753 /* TODO: don't re-evaluate the descriptor on each iteration. */
754 /* Get a descriptor for the first parameter. */
755 ss = gfc_walk_expr (arg->expr);
756 gcc_assert (ss != gfc_ss_terminator);
757 gfc_init_se (&argse, NULL);
758 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
759 gfc_add_block_to_block (&se->pre, &argse.pre);
760 gfc_add_block_to_block (&se->post, &argse.post);
762 desc = argse.expr;
764 if (INTEGER_CST_P (bound))
766 int hi, low;
768 hi = TREE_INT_CST_HIGH (bound);
769 low = TREE_INT_CST_LOW (bound);
770 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
771 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
772 "dimension index", upper ? "UBOUND" : "LBOUND",
773 &expr->where);
775 else
777 if (flag_bounds_check)
779 bound = gfc_evaluate_now (bound, &se->pre);
780 cond = fold_build2 (LT_EXPR, boolean_type_node,
781 bound, build_int_cst (TREE_TYPE (bound), 0));
782 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
783 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
784 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
785 gfc_trans_runtime_check (cond, gfc_msg_fault, &se->pre, &expr->where);
789 ubound = gfc_conv_descriptor_ubound (desc, bound);
790 lbound = gfc_conv_descriptor_lbound (desc, bound);
792 /* Follow any component references. */
793 if (arg->expr->expr_type == EXPR_VARIABLE
794 || arg->expr->expr_type == EXPR_CONSTANT)
796 as = arg->expr->symtree->n.sym->as;
797 for (ref = arg->expr->ref; ref; ref = ref->next)
799 switch (ref->type)
801 case REF_COMPONENT:
802 as = ref->u.c.component->as;
803 continue;
805 case REF_SUBSTRING:
806 continue;
808 case REF_ARRAY:
810 switch (ref->u.ar.type)
812 case AR_ELEMENT:
813 case AR_SECTION:
814 case AR_UNKNOWN:
815 as = NULL;
816 continue;
818 case AR_FULL:
819 break;
825 else
826 as = NULL;
828 /* 13.14.53: Result value for LBOUND
830 Case (i): For an array section or for an array expression other than a
831 whole array or array structure component, LBOUND(ARRAY, DIM)
832 has the value 1. For a whole array or array structure
833 component, LBOUND(ARRAY, DIM) has the value:
834 (a) equal to the lower bound for subscript DIM of ARRAY if
835 dimension DIM of ARRAY does not have extent zero
836 or if ARRAY is an assumed-size array of rank DIM,
837 or (b) 1 otherwise.
839 13.14.113: Result value for UBOUND
841 Case (i): For an array section or for an array expression other than a
842 whole array or array structure component, UBOUND(ARRAY, DIM)
843 has the value equal to the number of elements in the given
844 dimension; otherwise, it has a value equal to the upper bound
845 for subscript DIM of ARRAY if dimension DIM of ARRAY does
846 not have size zero and has value zero if dimension DIM has
847 size zero. */
849 if (as)
851 tree stride = gfc_conv_descriptor_stride (desc, bound);
853 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
854 cond2 = fold_build2 (LE_EXPR, boolean_type_node, ubound, lbound);
856 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
857 gfc_index_zero_node);
858 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
860 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
861 gfc_index_zero_node);
862 cond4 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond2);
864 if (upper)
866 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
868 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
869 ubound, gfc_index_zero_node);
871 else
873 if (as->type == AS_ASSUMED_SIZE)
874 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
875 build_int_cst (TREE_TYPE (bound),
876 arg->expr->rank - 1));
877 else
878 cond = boolean_false_node;
880 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
881 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
883 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
884 lbound, gfc_index_one_node);
887 else
889 if (upper)
891 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
892 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
893 gfc_index_one_node);
895 else
896 se->expr = gfc_index_one_node;
899 type = gfc_typenode_for_spec (&expr->ts);
900 se->expr = convert (type, se->expr);
904 static void
905 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
907 tree args;
908 tree val;
909 int n;
911 args = gfc_conv_intrinsic_function_args (se, expr);
912 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
913 val = TREE_VALUE (args);
915 switch (expr->value.function.actual->expr->ts.type)
917 case BT_INTEGER:
918 case BT_REAL:
919 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
920 break;
922 case BT_COMPLEX:
923 switch (expr->ts.kind)
925 case 4:
926 n = BUILT_IN_CABSF;
927 break;
928 case 8:
929 n = BUILT_IN_CABS;
930 break;
931 case 10:
932 case 16:
933 n = BUILT_IN_CABSL;
934 break;
935 default:
936 gcc_unreachable ();
938 se->expr = build_function_call_expr (built_in_decls[n], args);
939 break;
941 default:
942 gcc_unreachable ();
947 /* Create a complex value from one or two real components. */
949 static void
950 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
952 tree arg;
953 tree real;
954 tree imag;
955 tree type;
957 type = gfc_typenode_for_spec (&expr->ts);
958 arg = gfc_conv_intrinsic_function_args (se, expr);
959 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
960 if (both)
961 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
962 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
964 arg = TREE_VALUE (arg);
965 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
966 imag = convert (TREE_TYPE (type), imag);
968 else
969 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
971 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
974 /* Remainder function MOD(A, P) = A - INT(A / P) * P
975 MODULO(A, P) = A - FLOOR (A / P) * P */
976 /* TODO: MOD(x, 0) */
978 static void
979 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
981 tree arg;
982 tree arg2;
983 tree type;
984 tree itype;
985 tree tmp;
986 tree test;
987 tree test2;
988 mpfr_t huge;
989 int n, ikind;
991 arg = gfc_conv_intrinsic_function_args (se, expr);
993 switch (expr->ts.type)
995 case BT_INTEGER:
996 /* Integer case is easy, we've got a builtin op. */
997 arg2 = TREE_VALUE (TREE_CHAIN (arg));
998 arg = TREE_VALUE (arg);
999 type = TREE_TYPE (arg);
1001 if (modulo)
1002 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
1003 else
1004 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
1005 break;
1007 case BT_REAL:
1008 n = END_BUILTINS;
1009 /* Check if we have a builtin fmod. */
1010 switch (expr->ts.kind)
1012 case 4:
1013 n = BUILT_IN_FMODF;
1014 break;
1016 case 8:
1017 n = BUILT_IN_FMOD;
1018 break;
1020 case 10:
1021 case 16:
1022 n = BUILT_IN_FMODL;
1023 break;
1025 default:
1026 break;
1029 /* Use it if it exists. */
1030 if (n != END_BUILTINS)
1032 tmp = built_in_decls[n];
1033 se->expr = build_function_call_expr (tmp, arg);
1034 if (modulo == 0)
1035 return;
1038 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1039 arg = TREE_VALUE (arg);
1040 type = TREE_TYPE (arg);
1042 arg = gfc_evaluate_now (arg, &se->pre);
1043 arg2 = gfc_evaluate_now (arg2, &se->pre);
1045 /* Definition:
1046 modulo = arg - floor (arg/arg2) * arg2, so
1047 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1048 where
1049 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1050 thereby avoiding another division and retaining the accuracy
1051 of the builtin function. */
1052 if (n != END_BUILTINS && modulo)
1054 tree zero = gfc_build_const (type, integer_zero_node);
1055 tmp = gfc_evaluate_now (se->expr, &se->pre);
1056 test = build2 (LT_EXPR, boolean_type_node, arg, zero);
1057 test2 = build2 (LT_EXPR, boolean_type_node, arg2, zero);
1058 test2 = build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1059 test = build2 (NE_EXPR, boolean_type_node, tmp, zero);
1060 test = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1061 test = gfc_evaluate_now (test, &se->pre);
1062 se->expr = build3 (COND_EXPR, type, test,
1063 build2 (PLUS_EXPR, type, tmp, arg2), tmp);
1064 return;
1067 /* If we do not have a built_in fmod, the calculation is going to
1068 have to be done longhand. */
1069 tmp = build2 (RDIV_EXPR, type, arg, arg2);
1071 /* Test if the value is too large to handle sensibly. */
1072 gfc_set_model_kind (expr->ts.kind);
1073 mpfr_init (huge);
1074 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1075 ikind = expr->ts.kind;
1076 if (n < 0)
1078 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1079 ikind = gfc_max_integer_kind;
1081 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1082 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1083 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
1085 mpfr_neg (huge, huge, GFC_RND_MODE);
1086 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
1087 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
1088 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1090 itype = gfc_get_int_type (ikind);
1091 if (modulo)
1092 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1093 else
1094 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1095 tmp = convert (type, tmp);
1096 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
1097 tmp = build2 (MULT_EXPR, type, tmp, arg2);
1098 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
1099 mpfr_clear (huge);
1100 break;
1102 default:
1103 gcc_unreachable ();
1107 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1109 static void
1110 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1112 tree arg;
1113 tree arg2;
1114 tree val;
1115 tree tmp;
1116 tree type;
1117 tree zero;
1119 arg = gfc_conv_intrinsic_function_args (se, expr);
1120 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1121 arg = TREE_VALUE (arg);
1122 type = TREE_TYPE (arg);
1124 val = build2 (MINUS_EXPR, type, arg, arg2);
1125 val = gfc_evaluate_now (val, &se->pre);
1127 zero = gfc_build_const (type, integer_zero_node);
1128 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
1129 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
1133 /* SIGN(A, B) is absolute value of A times sign of B.
1134 The real value versions use library functions to ensure the correct
1135 handling of negative zero. Integer case implemented as:
1136 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1139 static void
1140 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1142 tree tmp;
1143 tree arg;
1144 tree arg2;
1145 tree type;
1147 arg = gfc_conv_intrinsic_function_args (se, expr);
1148 if (expr->ts.type == BT_REAL)
1150 switch (expr->ts.kind)
1152 case 4:
1153 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
1154 break;
1155 case 8:
1156 tmp = built_in_decls[BUILT_IN_COPYSIGN];
1157 break;
1158 case 10:
1159 case 16:
1160 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
1161 break;
1162 default:
1163 gcc_unreachable ();
1165 se->expr = build_function_call_expr (tmp, arg);
1166 return;
1169 /* Having excluded floating point types, we know we are now dealing
1170 with signed integer types. */
1171 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1172 arg = TREE_VALUE (arg);
1173 type = TREE_TYPE (arg);
1175 /* Arg is used multiple times below. */
1176 arg = gfc_evaluate_now (arg, &se->pre);
1178 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1179 the signs of A and B are the same, and of all ones if they differ. */
1180 tmp = fold_build2 (BIT_XOR_EXPR, type, arg, arg2);
1181 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1182 build_int_cst (type, TYPE_PRECISION (type) - 1));
1183 tmp = gfc_evaluate_now (tmp, &se->pre);
1185 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1186 is all ones (i.e. -1). */
1187 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1188 fold_build2 (PLUS_EXPR, type, arg, tmp),
1189 tmp);
1193 /* Test for the presence of an optional argument. */
1195 static void
1196 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1198 gfc_expr *arg;
1200 arg = expr->value.function.actual->expr;
1201 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1202 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1203 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1207 /* Calculate the double precision product of two single precision values. */
1209 static void
1210 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1212 tree arg;
1213 tree arg2;
1214 tree type;
1216 arg = gfc_conv_intrinsic_function_args (se, expr);
1217 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1218 arg = TREE_VALUE (arg);
1220 /* Convert the args to double precision before multiplying. */
1221 type = gfc_typenode_for_spec (&expr->ts);
1222 arg = convert (type, arg);
1223 arg2 = convert (type, arg2);
1224 se->expr = build2 (MULT_EXPR, type, arg, arg2);
1228 /* Return a length one character string containing an ascii character. */
1230 static void
1231 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1233 tree arg;
1234 tree var;
1235 tree type;
1237 arg = gfc_conv_intrinsic_function_args (se, expr);
1238 arg = TREE_VALUE (arg);
1240 /* We currently don't support character types != 1. */
1241 gcc_assert (expr->ts.kind == 1);
1242 type = gfc_character1_type_node;
1243 var = gfc_create_var (type, "char");
1245 arg = convert (type, arg);
1246 gfc_add_modify_expr (&se->pre, var, arg);
1247 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1248 se->string_length = integer_one_node;
1252 static void
1253 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1255 tree var;
1256 tree len;
1257 tree tmp;
1258 tree arglist;
1259 tree type;
1260 tree cond;
1261 tree gfc_int8_type_node = gfc_get_int_type (8);
1263 type = build_pointer_type (gfc_character1_type_node);
1264 var = gfc_create_var (type, "pstr");
1265 len = gfc_create_var (gfc_int8_type_node, "len");
1267 tmp = gfc_conv_intrinsic_function_args (se, expr);
1268 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1269 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1270 arglist = chainon (arglist, tmp);
1272 tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
1273 gfc_add_expr_to_block (&se->pre, tmp);
1275 /* Free the temporary afterwards, if necessary. */
1276 cond = build2 (GT_EXPR, boolean_type_node, len,
1277 build_int_cst (TREE_TYPE (len), 0));
1278 tmp = build_call_expr (gfor_fndecl_internal_free, 1, var);
1279 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1280 gfc_add_expr_to_block (&se->post, tmp);
1282 se->expr = var;
1283 se->string_length = len;
1287 static void
1288 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1290 tree var;
1291 tree len;
1292 tree tmp;
1293 tree arglist;
1294 tree type;
1295 tree cond;
1296 tree gfc_int4_type_node = gfc_get_int_type (4);
1298 type = build_pointer_type (gfc_character1_type_node);
1299 var = gfc_create_var (type, "pstr");
1300 len = gfc_create_var (gfc_int4_type_node, "len");
1302 tmp = gfc_conv_intrinsic_function_args (se, expr);
1303 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1304 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1305 arglist = chainon (arglist, tmp);
1307 tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
1308 gfc_add_expr_to_block (&se->pre, tmp);
1310 /* Free the temporary afterwards, if necessary. */
1311 cond = build2 (GT_EXPR, boolean_type_node, len,
1312 build_int_cst (TREE_TYPE (len), 0));
1313 tmp = build_call_expr (gfor_fndecl_internal_free, 1, var);
1314 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1315 gfc_add_expr_to_block (&se->post, tmp);
1317 se->expr = var;
1318 se->string_length = len;
1322 /* Return a character string containing the tty name. */
1324 static void
1325 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1327 tree var;
1328 tree len;
1329 tree tmp;
1330 tree arglist;
1331 tree type;
1332 tree cond;
1333 tree gfc_int4_type_node = gfc_get_int_type (4);
1335 type = build_pointer_type (gfc_character1_type_node);
1336 var = gfc_create_var (type, "pstr");
1337 len = gfc_create_var (gfc_int4_type_node, "len");
1339 tmp = gfc_conv_intrinsic_function_args (se, expr);
1340 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1341 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1342 arglist = chainon (arglist, tmp);
1344 tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
1345 gfc_add_expr_to_block (&se->pre, tmp);
1347 /* Free the temporary afterwards, if necessary. */
1348 cond = build2 (GT_EXPR, boolean_type_node, len,
1349 build_int_cst (TREE_TYPE (len), 0));
1350 tmp = build_call_expr (gfor_fndecl_internal_free, 1, var);
1351 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1352 gfc_add_expr_to_block (&se->post, tmp);
1354 se->expr = var;
1355 se->string_length = len;
1359 /* Get the minimum/maximum value of all the parameters.
1360 minmax (a1, a2, a3, ...)
1362 if (a2 .op. a1)
1363 mvar = a2;
1364 else
1365 mvar = a1;
1366 if (a3 .op. mvar)
1367 mvar = a3;
1369 return mvar
1373 /* TODO: Mismatching types can occur when specific names are used.
1374 These should be handled during resolution. */
1375 static void
1376 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1378 tree limit;
1379 tree tmp;
1380 tree mvar;
1381 tree val;
1382 tree thencase;
1383 tree elsecase;
1384 tree arg;
1385 tree type;
1387 arg = gfc_conv_intrinsic_function_args (se, expr);
1388 type = gfc_typenode_for_spec (&expr->ts);
1390 limit = TREE_VALUE (arg);
1391 if (TREE_TYPE (limit) != type)
1392 limit = convert (type, limit);
1393 /* Only evaluate the argument once. */
1394 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1395 limit = gfc_evaluate_now (limit, &se->pre);
1397 mvar = gfc_create_var (type, "M");
1398 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1399 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1401 val = TREE_VALUE (arg);
1402 if (TREE_TYPE (val) != type)
1403 val = convert (type, val);
1405 /* Only evaluate the argument once. */
1406 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1407 val = gfc_evaluate_now (val, &se->pre);
1409 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1411 tmp = build2 (op, boolean_type_node, val, limit);
1412 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1413 gfc_add_expr_to_block (&se->pre, tmp);
1414 elsecase = build_empty_stmt ();
1415 limit = mvar;
1417 se->expr = mvar;
1421 /* Create a symbol node for this intrinsic. The symbol from the frontend
1422 has the generic name. */
1424 static gfc_symbol *
1425 gfc_get_symbol_for_expr (gfc_expr * expr)
1427 gfc_symbol *sym;
1429 /* TODO: Add symbols for intrinsic function to the global namespace. */
1430 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1431 sym = gfc_new_symbol (expr->value.function.name, NULL);
1433 sym->ts = expr->ts;
1434 sym->attr.external = 1;
1435 sym->attr.function = 1;
1436 sym->attr.always_explicit = 1;
1437 sym->attr.proc = PROC_INTRINSIC;
1438 sym->attr.flavor = FL_PROCEDURE;
1439 sym->result = sym;
1440 if (expr->rank > 0)
1442 sym->attr.dimension = 1;
1443 sym->as = gfc_get_array_spec ();
1444 sym->as->type = AS_ASSUMED_SHAPE;
1445 sym->as->rank = expr->rank;
1448 /* TODO: proper argument lists for external intrinsics. */
1449 return sym;
1452 /* Generate a call to an external intrinsic function. */
1453 static void
1454 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1456 gfc_symbol *sym;
1457 tree append_args;
1459 gcc_assert (!se->ss || se->ss->expr == expr);
1461 if (se->ss)
1462 gcc_assert (expr->rank > 0);
1463 else
1464 gcc_assert (expr->rank == 0);
1466 sym = gfc_get_symbol_for_expr (expr);
1468 /* Calls to libgfortran_matmul need to be appended special arguments,
1469 to be able to call the BLAS ?gemm functions if required and possible. */
1470 append_args = NULL_TREE;
1471 if (expr->value.function.isym->generic_id == GFC_ISYM_MATMUL
1472 && sym->ts.type != BT_LOGICAL)
1474 tree cint = gfc_get_int_type (gfc_c_int_kind);
1476 if (gfc_option.flag_external_blas
1477 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1478 && (sym->ts.kind == gfc_default_real_kind
1479 || sym->ts.kind == gfc_default_double_kind))
1481 tree gemm_fndecl;
1483 if (sym->ts.type == BT_REAL)
1485 if (sym->ts.kind == gfc_default_real_kind)
1486 gemm_fndecl = gfor_fndecl_sgemm;
1487 else
1488 gemm_fndecl = gfor_fndecl_dgemm;
1490 else
1492 if (sym->ts.kind == gfc_default_real_kind)
1493 gemm_fndecl = gfor_fndecl_cgemm;
1494 else
1495 gemm_fndecl = gfor_fndecl_zgemm;
1498 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1499 append_args = gfc_chainon_list
1500 (append_args, build_int_cst
1501 (cint, gfc_option.blas_matmul_limit));
1502 append_args = gfc_chainon_list (append_args,
1503 gfc_build_addr_expr (NULL_TREE,
1504 gemm_fndecl));
1506 else
1508 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1509 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1510 append_args = gfc_chainon_list (append_args, null_pointer_node);
1514 gfc_conv_function_call (se, sym, expr->value.function.actual, append_args);
1515 gfc_free (sym);
1518 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1519 Implemented as
1520 any(a)
1522 forall (i=...)
1523 if (a[i] != 0)
1524 return 1
1525 end forall
1526 return 0
1528 all(a)
1530 forall (i=...)
1531 if (a[i] == 0)
1532 return 0
1533 end forall
1534 return 1
1537 static void
1538 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1540 tree resvar;
1541 stmtblock_t block;
1542 stmtblock_t body;
1543 tree type;
1544 tree tmp;
1545 tree found;
1546 gfc_loopinfo loop;
1547 gfc_actual_arglist *actual;
1548 gfc_ss *arrayss;
1549 gfc_se arrayse;
1550 tree exit_label;
1552 if (se->ss)
1554 gfc_conv_intrinsic_funcall (se, expr);
1555 return;
1558 actual = expr->value.function.actual;
1559 type = gfc_typenode_for_spec (&expr->ts);
1560 /* Initialize the result. */
1561 resvar = gfc_create_var (type, "test");
1562 if (op == EQ_EXPR)
1563 tmp = convert (type, boolean_true_node);
1564 else
1565 tmp = convert (type, boolean_false_node);
1566 gfc_add_modify_expr (&se->pre, resvar, tmp);
1568 /* Walk the arguments. */
1569 arrayss = gfc_walk_expr (actual->expr);
1570 gcc_assert (arrayss != gfc_ss_terminator);
1572 /* Initialize the scalarizer. */
1573 gfc_init_loopinfo (&loop);
1574 exit_label = gfc_build_label_decl (NULL_TREE);
1575 TREE_USED (exit_label) = 1;
1576 gfc_add_ss_to_loop (&loop, arrayss);
1578 /* Initialize the loop. */
1579 gfc_conv_ss_startstride (&loop);
1580 gfc_conv_loop_setup (&loop);
1582 gfc_mark_ss_chain_used (arrayss, 1);
1583 /* Generate the loop body. */
1584 gfc_start_scalarized_body (&loop, &body);
1586 /* If the condition matches then set the return value. */
1587 gfc_start_block (&block);
1588 if (op == EQ_EXPR)
1589 tmp = convert (type, boolean_false_node);
1590 else
1591 tmp = convert (type, boolean_true_node);
1592 gfc_add_modify_expr (&block, resvar, tmp);
1594 /* And break out of the loop. */
1595 tmp = build1_v (GOTO_EXPR, exit_label);
1596 gfc_add_expr_to_block (&block, tmp);
1598 found = gfc_finish_block (&block);
1600 /* Check this element. */
1601 gfc_init_se (&arrayse, NULL);
1602 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1603 arrayse.ss = arrayss;
1604 gfc_conv_expr_val (&arrayse, actual->expr);
1606 gfc_add_block_to_block (&body, &arrayse.pre);
1607 tmp = build2 (op, boolean_type_node, arrayse.expr,
1608 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1609 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1610 gfc_add_expr_to_block (&body, tmp);
1611 gfc_add_block_to_block (&body, &arrayse.post);
1613 gfc_trans_scalarizing_loops (&loop, &body);
1615 /* Add the exit label. */
1616 tmp = build1_v (LABEL_EXPR, exit_label);
1617 gfc_add_expr_to_block (&loop.pre, tmp);
1619 gfc_add_block_to_block (&se->pre, &loop.pre);
1620 gfc_add_block_to_block (&se->pre, &loop.post);
1621 gfc_cleanup_loop (&loop);
1623 se->expr = resvar;
1626 /* COUNT(A) = Number of true elements in A. */
1627 static void
1628 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1630 tree resvar;
1631 tree type;
1632 stmtblock_t body;
1633 tree tmp;
1634 gfc_loopinfo loop;
1635 gfc_actual_arglist *actual;
1636 gfc_ss *arrayss;
1637 gfc_se arrayse;
1639 if (se->ss)
1641 gfc_conv_intrinsic_funcall (se, expr);
1642 return;
1645 actual = expr->value.function.actual;
1647 type = gfc_typenode_for_spec (&expr->ts);
1648 /* Initialize the result. */
1649 resvar = gfc_create_var (type, "count");
1650 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1652 /* Walk the arguments. */
1653 arrayss = gfc_walk_expr (actual->expr);
1654 gcc_assert (arrayss != gfc_ss_terminator);
1656 /* Initialize the scalarizer. */
1657 gfc_init_loopinfo (&loop);
1658 gfc_add_ss_to_loop (&loop, arrayss);
1660 /* Initialize the loop. */
1661 gfc_conv_ss_startstride (&loop);
1662 gfc_conv_loop_setup (&loop);
1664 gfc_mark_ss_chain_used (arrayss, 1);
1665 /* Generate the loop body. */
1666 gfc_start_scalarized_body (&loop, &body);
1668 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1669 build_int_cst (TREE_TYPE (resvar), 1));
1670 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1672 gfc_init_se (&arrayse, NULL);
1673 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1674 arrayse.ss = arrayss;
1675 gfc_conv_expr_val (&arrayse, actual->expr);
1676 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1678 gfc_add_block_to_block (&body, &arrayse.pre);
1679 gfc_add_expr_to_block (&body, tmp);
1680 gfc_add_block_to_block (&body, &arrayse.post);
1682 gfc_trans_scalarizing_loops (&loop, &body);
1684 gfc_add_block_to_block (&se->pre, &loop.pre);
1685 gfc_add_block_to_block (&se->pre, &loop.post);
1686 gfc_cleanup_loop (&loop);
1688 se->expr = resvar;
1691 /* Inline implementation of the sum and product intrinsics. */
1692 static void
1693 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1695 tree resvar;
1696 tree type;
1697 stmtblock_t body;
1698 stmtblock_t block;
1699 tree tmp;
1700 gfc_loopinfo loop;
1701 gfc_actual_arglist *actual;
1702 gfc_ss *arrayss;
1703 gfc_ss *maskss;
1704 gfc_se arrayse;
1705 gfc_se maskse;
1706 gfc_expr *arrayexpr;
1707 gfc_expr *maskexpr;
1709 if (se->ss)
1711 gfc_conv_intrinsic_funcall (se, expr);
1712 return;
1715 type = gfc_typenode_for_spec (&expr->ts);
1716 /* Initialize the result. */
1717 resvar = gfc_create_var (type, "val");
1718 if (op == PLUS_EXPR)
1719 tmp = gfc_build_const (type, integer_zero_node);
1720 else
1721 tmp = gfc_build_const (type, integer_one_node);
1723 gfc_add_modify_expr (&se->pre, resvar, tmp);
1725 /* Walk the arguments. */
1726 actual = expr->value.function.actual;
1727 arrayexpr = actual->expr;
1728 arrayss = gfc_walk_expr (arrayexpr);
1729 gcc_assert (arrayss != gfc_ss_terminator);
1731 actual = actual->next->next;
1732 gcc_assert (actual);
1733 maskexpr = actual->expr;
1734 if (maskexpr && maskexpr->rank != 0)
1736 maskss = gfc_walk_expr (maskexpr);
1737 gcc_assert (maskss != gfc_ss_terminator);
1739 else
1740 maskss = NULL;
1742 /* Initialize the scalarizer. */
1743 gfc_init_loopinfo (&loop);
1744 gfc_add_ss_to_loop (&loop, arrayss);
1745 if (maskss)
1746 gfc_add_ss_to_loop (&loop, maskss);
1748 /* Initialize the loop. */
1749 gfc_conv_ss_startstride (&loop);
1750 gfc_conv_loop_setup (&loop);
1752 gfc_mark_ss_chain_used (arrayss, 1);
1753 if (maskss)
1754 gfc_mark_ss_chain_used (maskss, 1);
1755 /* Generate the loop body. */
1756 gfc_start_scalarized_body (&loop, &body);
1758 /* If we have a mask, only add this element if the mask is set. */
1759 if (maskss)
1761 gfc_init_se (&maskse, NULL);
1762 gfc_copy_loopinfo_to_se (&maskse, &loop);
1763 maskse.ss = maskss;
1764 gfc_conv_expr_val (&maskse, maskexpr);
1765 gfc_add_block_to_block (&body, &maskse.pre);
1767 gfc_start_block (&block);
1769 else
1770 gfc_init_block (&block);
1772 /* Do the actual summation/product. */
1773 gfc_init_se (&arrayse, NULL);
1774 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1775 arrayse.ss = arrayss;
1776 gfc_conv_expr_val (&arrayse, arrayexpr);
1777 gfc_add_block_to_block (&block, &arrayse.pre);
1779 tmp = build2 (op, type, resvar, arrayse.expr);
1780 gfc_add_modify_expr (&block, resvar, tmp);
1781 gfc_add_block_to_block (&block, &arrayse.post);
1783 if (maskss)
1785 /* We enclose the above in if (mask) {...} . */
1786 tmp = gfc_finish_block (&block);
1788 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1790 else
1791 tmp = gfc_finish_block (&block);
1792 gfc_add_expr_to_block (&body, tmp);
1794 gfc_trans_scalarizing_loops (&loop, &body);
1796 /* For a scalar mask, enclose the loop in an if statement. */
1797 if (maskexpr && maskss == NULL)
1799 gfc_init_se (&maskse, NULL);
1800 gfc_conv_expr_val (&maskse, maskexpr);
1801 gfc_init_block (&block);
1802 gfc_add_block_to_block (&block, &loop.pre);
1803 gfc_add_block_to_block (&block, &loop.post);
1804 tmp = gfc_finish_block (&block);
1806 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1807 gfc_add_expr_to_block (&block, tmp);
1808 gfc_add_block_to_block (&se->pre, &block);
1810 else
1812 gfc_add_block_to_block (&se->pre, &loop.pre);
1813 gfc_add_block_to_block (&se->pre, &loop.post);
1816 gfc_cleanup_loop (&loop);
1818 se->expr = resvar;
1822 /* Inline implementation of the dot_product intrinsic. This function
1823 is based on gfc_conv_intrinsic_arith (the previous function). */
1824 static void
1825 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1827 tree resvar;
1828 tree type;
1829 stmtblock_t body;
1830 stmtblock_t block;
1831 tree tmp;
1832 gfc_loopinfo loop;
1833 gfc_actual_arglist *actual;
1834 gfc_ss *arrayss1, *arrayss2;
1835 gfc_se arrayse1, arrayse2;
1836 gfc_expr *arrayexpr1, *arrayexpr2;
1838 type = gfc_typenode_for_spec (&expr->ts);
1840 /* Initialize the result. */
1841 resvar = gfc_create_var (type, "val");
1842 if (expr->ts.type == BT_LOGICAL)
1843 tmp = convert (type, integer_zero_node);
1844 else
1845 tmp = gfc_build_const (type, integer_zero_node);
1847 gfc_add_modify_expr (&se->pre, resvar, tmp);
1849 /* Walk argument #1. */
1850 actual = expr->value.function.actual;
1851 arrayexpr1 = actual->expr;
1852 arrayss1 = gfc_walk_expr (arrayexpr1);
1853 gcc_assert (arrayss1 != gfc_ss_terminator);
1855 /* Walk argument #2. */
1856 actual = actual->next;
1857 arrayexpr2 = actual->expr;
1858 arrayss2 = gfc_walk_expr (arrayexpr2);
1859 gcc_assert (arrayss2 != gfc_ss_terminator);
1861 /* Initialize the scalarizer. */
1862 gfc_init_loopinfo (&loop);
1863 gfc_add_ss_to_loop (&loop, arrayss1);
1864 gfc_add_ss_to_loop (&loop, arrayss2);
1866 /* Initialize the loop. */
1867 gfc_conv_ss_startstride (&loop);
1868 gfc_conv_loop_setup (&loop);
1870 gfc_mark_ss_chain_used (arrayss1, 1);
1871 gfc_mark_ss_chain_used (arrayss2, 1);
1873 /* Generate the loop body. */
1874 gfc_start_scalarized_body (&loop, &body);
1875 gfc_init_block (&block);
1877 /* Make the tree expression for [conjg(]array1[)]. */
1878 gfc_init_se (&arrayse1, NULL);
1879 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
1880 arrayse1.ss = arrayss1;
1881 gfc_conv_expr_val (&arrayse1, arrayexpr1);
1882 if (expr->ts.type == BT_COMPLEX)
1883 arrayse1.expr = build1 (CONJ_EXPR, type, arrayse1.expr);
1884 gfc_add_block_to_block (&block, &arrayse1.pre);
1886 /* Make the tree expression for array2. */
1887 gfc_init_se (&arrayse2, NULL);
1888 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
1889 arrayse2.ss = arrayss2;
1890 gfc_conv_expr_val (&arrayse2, arrayexpr2);
1891 gfc_add_block_to_block (&block, &arrayse2.pre);
1893 /* Do the actual product and sum. */
1894 if (expr->ts.type == BT_LOGICAL)
1896 tmp = build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
1897 tmp = build2 (TRUTH_OR_EXPR, type, resvar, tmp);
1899 else
1901 tmp = build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
1902 tmp = build2 (PLUS_EXPR, type, resvar, tmp);
1904 gfc_add_modify_expr (&block, resvar, tmp);
1906 /* Finish up the loop block and the loop. */
1907 tmp = gfc_finish_block (&block);
1908 gfc_add_expr_to_block (&body, tmp);
1910 gfc_trans_scalarizing_loops (&loop, &body);
1911 gfc_add_block_to_block (&se->pre, &loop.pre);
1912 gfc_add_block_to_block (&se->pre, &loop.post);
1913 gfc_cleanup_loop (&loop);
1915 se->expr = resvar;
1919 static void
1920 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1922 stmtblock_t body;
1923 stmtblock_t block;
1924 stmtblock_t ifblock;
1925 stmtblock_t elseblock;
1926 tree limit;
1927 tree type;
1928 tree tmp;
1929 tree elsetmp;
1930 tree ifbody;
1931 gfc_loopinfo loop;
1932 gfc_actual_arglist *actual;
1933 gfc_ss *arrayss;
1934 gfc_ss *maskss;
1935 gfc_se arrayse;
1936 gfc_se maskse;
1937 gfc_expr *arrayexpr;
1938 gfc_expr *maskexpr;
1939 tree pos;
1940 int n;
1942 if (se->ss)
1944 gfc_conv_intrinsic_funcall (se, expr);
1945 return;
1948 /* Initialize the result. */
1949 pos = gfc_create_var (gfc_array_index_type, "pos");
1950 type = gfc_typenode_for_spec (&expr->ts);
1952 /* Walk the arguments. */
1953 actual = expr->value.function.actual;
1954 arrayexpr = actual->expr;
1955 arrayss = gfc_walk_expr (arrayexpr);
1956 gcc_assert (arrayss != gfc_ss_terminator);
1958 actual = actual->next->next;
1959 gcc_assert (actual);
1960 maskexpr = actual->expr;
1961 if (maskexpr && maskexpr->rank != 0)
1963 maskss = gfc_walk_expr (maskexpr);
1964 gcc_assert (maskss != gfc_ss_terminator);
1966 else
1967 maskss = NULL;
1969 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1970 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1971 switch (arrayexpr->ts.type)
1973 case BT_REAL:
1974 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1975 break;
1977 case BT_INTEGER:
1978 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1979 arrayexpr->ts.kind);
1980 break;
1982 default:
1983 gcc_unreachable ();
1986 /* We start with the most negative possible value for MAXLOC, and the most
1987 positive possible value for MINLOC. The most negative possible value is
1988 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
1989 possible value is HUGE in both cases. */
1990 if (op == GT_EXPR)
1991 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1992 gfc_add_modify_expr (&se->pre, limit, tmp);
1994 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
1995 tmp = build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
1996 build_int_cst (type, 1));
1998 /* Initialize the scalarizer. */
1999 gfc_init_loopinfo (&loop);
2000 gfc_add_ss_to_loop (&loop, arrayss);
2001 if (maskss)
2002 gfc_add_ss_to_loop (&loop, maskss);
2004 /* Initialize the loop. */
2005 gfc_conv_ss_startstride (&loop);
2006 gfc_conv_loop_setup (&loop);
2008 gcc_assert (loop.dimen == 1);
2010 /* Initialize the position to zero, following Fortran 2003. We are free
2011 to do this because Fortran 95 allows the result of an entirely false
2012 mask to be processor dependent. */
2013 gfc_add_modify_expr (&loop.pre, pos, gfc_index_zero_node);
2015 gfc_mark_ss_chain_used (arrayss, 1);
2016 if (maskss)
2017 gfc_mark_ss_chain_used (maskss, 1);
2018 /* Generate the loop body. */
2019 gfc_start_scalarized_body (&loop, &body);
2021 /* If we have a mask, only check this element if the mask is set. */
2022 if (maskss)
2024 gfc_init_se (&maskse, NULL);
2025 gfc_copy_loopinfo_to_se (&maskse, &loop);
2026 maskse.ss = maskss;
2027 gfc_conv_expr_val (&maskse, maskexpr);
2028 gfc_add_block_to_block (&body, &maskse.pre);
2030 gfc_start_block (&block);
2032 else
2033 gfc_init_block (&block);
2035 /* Compare with the current limit. */
2036 gfc_init_se (&arrayse, NULL);
2037 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2038 arrayse.ss = arrayss;
2039 gfc_conv_expr_val (&arrayse, arrayexpr);
2040 gfc_add_block_to_block (&block, &arrayse.pre);
2042 /* We do the following if this is a more extreme value. */
2043 gfc_start_block (&ifblock);
2045 /* Assign the value to the limit... */
2046 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
2048 /* Remember where we are. */
2049 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
2051 ifbody = gfc_finish_block (&ifblock);
2053 /* If it is a more extreme value or pos is still zero. */
2054 tmp = build2 (TRUTH_OR_EXPR, boolean_type_node,
2055 build2 (op, boolean_type_node, arrayse.expr, limit),
2056 build2 (EQ_EXPR, boolean_type_node, pos, gfc_index_zero_node));
2057 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2058 gfc_add_expr_to_block (&block, tmp);
2060 if (maskss)
2062 /* We enclose the above in if (mask) {...}. */
2063 tmp = gfc_finish_block (&block);
2065 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2067 else
2068 tmp = gfc_finish_block (&block);
2069 gfc_add_expr_to_block (&body, tmp);
2071 gfc_trans_scalarizing_loops (&loop, &body);
2073 /* For a scalar mask, enclose the loop in an if statement. */
2074 if (maskexpr && maskss == NULL)
2076 gfc_init_se (&maskse, NULL);
2077 gfc_conv_expr_val (&maskse, maskexpr);
2078 gfc_init_block (&block);
2079 gfc_add_block_to_block (&block, &loop.pre);
2080 gfc_add_block_to_block (&block, &loop.post);
2081 tmp = gfc_finish_block (&block);
2083 /* For the else part of the scalar mask, just initialize
2084 the pos variable the same way as above. */
2086 gfc_init_block (&elseblock);
2087 gfc_add_modify_expr (&elseblock, pos, gfc_index_zero_node);
2088 elsetmp = gfc_finish_block (&elseblock);
2090 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2091 gfc_add_expr_to_block (&block, tmp);
2092 gfc_add_block_to_block (&se->pre, &block);
2094 else
2096 gfc_add_block_to_block (&se->pre, &loop.pre);
2097 gfc_add_block_to_block (&se->pre, &loop.post);
2099 gfc_cleanup_loop (&loop);
2101 /* Return a value in the range 1..SIZE(array). */
2102 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
2103 gfc_index_one_node);
2104 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
2105 /* And convert to the required type. */
2106 se->expr = convert (type, tmp);
2109 static void
2110 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
2112 tree limit;
2113 tree type;
2114 tree tmp;
2115 tree ifbody;
2116 stmtblock_t body;
2117 stmtblock_t block;
2118 gfc_loopinfo loop;
2119 gfc_actual_arglist *actual;
2120 gfc_ss *arrayss;
2121 gfc_ss *maskss;
2122 gfc_se arrayse;
2123 gfc_se maskse;
2124 gfc_expr *arrayexpr;
2125 gfc_expr *maskexpr;
2126 int n;
2128 if (se->ss)
2130 gfc_conv_intrinsic_funcall (se, expr);
2131 return;
2134 type = gfc_typenode_for_spec (&expr->ts);
2135 /* Initialize the result. */
2136 limit = gfc_create_var (type, "limit");
2137 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2138 switch (expr->ts.type)
2140 case BT_REAL:
2141 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
2142 break;
2144 case BT_INTEGER:
2145 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2146 break;
2148 default:
2149 gcc_unreachable ();
2152 /* We start with the most negative possible value for MAXVAL, and the most
2153 positive possible value for MINVAL. The most negative possible value is
2154 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2155 possible value is HUGE in both cases. */
2156 if (op == GT_EXPR)
2157 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2159 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2160 tmp = build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2161 build_int_cst (type, 1));
2163 gfc_add_modify_expr (&se->pre, limit, tmp);
2165 /* Walk the arguments. */
2166 actual = expr->value.function.actual;
2167 arrayexpr = actual->expr;
2168 arrayss = gfc_walk_expr (arrayexpr);
2169 gcc_assert (arrayss != gfc_ss_terminator);
2171 actual = actual->next->next;
2172 gcc_assert (actual);
2173 maskexpr = actual->expr;
2174 if (maskexpr && maskexpr->rank != 0)
2176 maskss = gfc_walk_expr (maskexpr);
2177 gcc_assert (maskss != gfc_ss_terminator);
2179 else
2180 maskss = NULL;
2182 /* Initialize the scalarizer. */
2183 gfc_init_loopinfo (&loop);
2184 gfc_add_ss_to_loop (&loop, arrayss);
2185 if (maskss)
2186 gfc_add_ss_to_loop (&loop, maskss);
2188 /* Initialize the loop. */
2189 gfc_conv_ss_startstride (&loop);
2190 gfc_conv_loop_setup (&loop);
2192 gfc_mark_ss_chain_used (arrayss, 1);
2193 if (maskss)
2194 gfc_mark_ss_chain_used (maskss, 1);
2195 /* Generate the loop body. */
2196 gfc_start_scalarized_body (&loop, &body);
2198 /* If we have a mask, only add this element if the mask is set. */
2199 if (maskss)
2201 gfc_init_se (&maskse, NULL);
2202 gfc_copy_loopinfo_to_se (&maskse, &loop);
2203 maskse.ss = maskss;
2204 gfc_conv_expr_val (&maskse, maskexpr);
2205 gfc_add_block_to_block (&body, &maskse.pre);
2207 gfc_start_block (&block);
2209 else
2210 gfc_init_block (&block);
2212 /* Compare with the current limit. */
2213 gfc_init_se (&arrayse, NULL);
2214 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2215 arrayse.ss = arrayss;
2216 gfc_conv_expr_val (&arrayse, arrayexpr);
2217 gfc_add_block_to_block (&block, &arrayse.pre);
2219 /* Assign the value to the limit... */
2220 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2222 /* If it is a more extreme value. */
2223 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
2224 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
2225 gfc_add_expr_to_block (&block, tmp);
2226 gfc_add_block_to_block (&block, &arrayse.post);
2228 tmp = gfc_finish_block (&block);
2229 if (maskss)
2230 /* We enclose the above in if (mask) {...}. */
2231 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2232 gfc_add_expr_to_block (&body, tmp);
2234 gfc_trans_scalarizing_loops (&loop, &body);
2236 /* For a scalar mask, enclose the loop in an if statement. */
2237 if (maskexpr && maskss == NULL)
2239 gfc_init_se (&maskse, NULL);
2240 gfc_conv_expr_val (&maskse, maskexpr);
2241 gfc_init_block (&block);
2242 gfc_add_block_to_block (&block, &loop.pre);
2243 gfc_add_block_to_block (&block, &loop.post);
2244 tmp = gfc_finish_block (&block);
2246 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
2247 gfc_add_expr_to_block (&block, tmp);
2248 gfc_add_block_to_block (&se->pre, &block);
2250 else
2252 gfc_add_block_to_block (&se->pre, &loop.pre);
2253 gfc_add_block_to_block (&se->pre, &loop.post);
2256 gfc_cleanup_loop (&loop);
2258 se->expr = limit;
2261 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2262 static void
2263 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2265 tree arg;
2266 tree arg2;
2267 tree type;
2268 tree tmp;
2270 arg = gfc_conv_intrinsic_function_args (se, expr);
2271 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2272 arg = TREE_VALUE (arg);
2273 type = TREE_TYPE (arg);
2275 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2276 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
2277 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2278 build_int_cst (type, 0));
2279 type = gfc_typenode_for_spec (&expr->ts);
2280 se->expr = convert (type, tmp);
2283 /* Generate code to perform the specified operation. */
2284 static void
2285 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
2287 tree arg;
2288 tree arg2;
2289 tree type;
2291 arg = gfc_conv_intrinsic_function_args (se, expr);
2292 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2293 arg = TREE_VALUE (arg);
2294 type = TREE_TYPE (arg);
2296 se->expr = fold_build2 (op, type, arg, arg2);
2299 /* Bitwise not. */
2300 static void
2301 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2303 tree arg;
2305 arg = gfc_conv_intrinsic_function_args (se, expr);
2306 arg = TREE_VALUE (arg);
2308 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2311 /* Set or clear a single bit. */
2312 static void
2313 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2315 tree arg;
2316 tree arg2;
2317 tree type;
2318 tree tmp;
2319 int op;
2321 arg = gfc_conv_intrinsic_function_args (se, expr);
2322 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2323 arg = TREE_VALUE (arg);
2324 type = TREE_TYPE (arg);
2326 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
2327 if (set)
2328 op = BIT_IOR_EXPR;
2329 else
2331 op = BIT_AND_EXPR;
2332 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2334 se->expr = fold_build2 (op, type, arg, tmp);
2337 /* Extract a sequence of bits.
2338 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2339 static void
2340 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2342 tree arg;
2343 tree arg2;
2344 tree arg3;
2345 tree type;
2346 tree tmp;
2347 tree mask;
2349 arg = gfc_conv_intrinsic_function_args (se, expr);
2350 arg2 = TREE_CHAIN (arg);
2351 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
2352 arg = TREE_VALUE (arg);
2353 arg2 = TREE_VALUE (arg2);
2354 type = TREE_TYPE (arg);
2356 mask = build_int_cst (type, -1);
2357 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
2358 mask = build1 (BIT_NOT_EXPR, type, mask);
2360 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
2362 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2365 /* RSHIFT (I, SHIFT) = I >> SHIFT
2366 LSHIFT (I, SHIFT) = I << SHIFT */
2367 static void
2368 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
2370 tree arg;
2371 tree arg2;
2373 arg = gfc_conv_intrinsic_function_args (se, expr);
2374 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2375 arg = TREE_VALUE (arg);
2377 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
2378 TREE_TYPE (arg), arg, arg2);
2381 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
2383 : ((shift >= 0) ? i << shift : i >> -shift)
2384 where all shifts are logical shifts. */
2385 static void
2386 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
2388 tree arg;
2389 tree arg2;
2390 tree type;
2391 tree utype;
2392 tree tmp;
2393 tree width;
2394 tree num_bits;
2395 tree cond;
2396 tree lshift;
2397 tree rshift;
2399 arg = gfc_conv_intrinsic_function_args (se, expr);
2400 arg2 = TREE_VALUE (TREE_CHAIN (arg));
2401 arg = TREE_VALUE (arg);
2402 type = TREE_TYPE (arg);
2403 utype = gfc_unsigned_type (type);
2405 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
2407 /* Left shift if positive. */
2408 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
2410 /* Right shift if negative.
2411 We convert to an unsigned type because we want a logical shift.
2412 The standard doesn't define the case of shifting negative
2413 numbers, and we try to be compatible with other compilers, most
2414 notably g77, here. */
2415 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
2416 convert (utype, arg), width));
2418 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
2419 build_int_cst (TREE_TYPE (arg2), 0));
2420 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
2422 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
2423 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
2424 special case. */
2425 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
2426 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
2428 se->expr = fold_build3 (COND_EXPR, type, cond,
2429 build_int_cst (type, 0), tmp);
2432 /* Circular shift. AKA rotate or barrel shift. */
2433 static void
2434 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
2436 tree arg;
2437 tree arg2;
2438 tree arg3;
2439 tree type;
2440 tree tmp;
2441 tree lrot;
2442 tree rrot;
2443 tree zero;
2445 arg = gfc_conv_intrinsic_function_args (se, expr);
2446 arg2 = TREE_CHAIN (arg);
2447 arg3 = TREE_CHAIN (arg2);
2448 if (arg3)
2450 /* Use a library function for the 3 parameter version. */
2451 tree int4type = gfc_get_int_type (4);
2453 type = TREE_TYPE (TREE_VALUE (arg));
2454 /* We convert the first argument to at least 4 bytes, and
2455 convert back afterwards. This removes the need for library
2456 functions for all argument sizes, and function will be
2457 aligned to at least 32 bits, so there's no loss. */
2458 if (expr->ts.kind < 4)
2460 tmp = convert (int4type, TREE_VALUE (arg));
2461 TREE_VALUE (arg) = tmp;
2463 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2464 need loads of library functions. They cannot have values >
2465 BIT_SIZE (I) so the conversion is safe. */
2466 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
2467 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
2469 switch (expr->ts.kind)
2471 case 1:
2472 case 2:
2473 case 4:
2474 tmp = gfor_fndecl_math_ishftc4;
2475 break;
2476 case 8:
2477 tmp = gfor_fndecl_math_ishftc8;
2478 break;
2479 case 16:
2480 tmp = gfor_fndecl_math_ishftc16;
2481 break;
2482 default:
2483 gcc_unreachable ();
2485 se->expr = build_function_call_expr (tmp, arg);
2486 /* Convert the result back to the original type, if we extended
2487 the first argument's width above. */
2488 if (expr->ts.kind < 4)
2489 se->expr = convert (type, se->expr);
2491 return;
2493 arg = TREE_VALUE (arg);
2494 arg2 = TREE_VALUE (arg2);
2495 type = TREE_TYPE (arg);
2497 /* Rotate left if positive. */
2498 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
2500 /* Rotate right if negative. */
2501 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
2502 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
2504 zero = build_int_cst (TREE_TYPE (arg2), 0);
2505 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
2506 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2508 /* Do nothing if shift == 0. */
2509 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
2510 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
2513 /* The length of a character string. */
2514 static void
2515 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2517 tree len;
2518 tree type;
2519 tree decl;
2520 gfc_symbol *sym;
2521 gfc_se argse;
2522 gfc_expr *arg;
2523 gfc_ss *ss;
2525 gcc_assert (!se->ss);
2527 arg = expr->value.function.actual->expr;
2529 type = gfc_typenode_for_spec (&expr->ts);
2530 switch (arg->expr_type)
2532 case EXPR_CONSTANT:
2533 len = build_int_cst (NULL_TREE, arg->value.character.length);
2534 break;
2536 case EXPR_ARRAY:
2537 /* Obtain the string length from the function used by
2538 trans-array.c(gfc_trans_array_constructor). */
2539 len = NULL_TREE;
2540 get_array_ctor_strlen (arg->value.constructor, &len);
2541 break;
2543 case EXPR_VARIABLE:
2544 if (arg->ref == NULL
2545 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
2547 /* This doesn't catch all cases.
2548 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2549 and the surrounding thread. */
2550 sym = arg->symtree->n.sym;
2551 decl = gfc_get_symbol_decl (sym);
2552 if (decl == current_function_decl && sym->attr.function
2553 && (sym->result == sym))
2554 decl = gfc_get_fake_result_decl (sym, 0);
2556 len = sym->ts.cl->backend_decl;
2557 gcc_assert (len);
2558 break;
2561 /* Otherwise fall through. */
2563 default:
2564 /* Anybody stupid enough to do this deserves inefficient code. */
2565 ss = gfc_walk_expr (arg);
2566 gfc_init_se (&argse, se);
2567 if (ss == gfc_ss_terminator)
2568 gfc_conv_expr (&argse, arg);
2569 else
2570 gfc_conv_expr_descriptor (&argse, arg, ss);
2571 gfc_add_block_to_block (&se->pre, &argse.pre);
2572 gfc_add_block_to_block (&se->post, &argse.post);
2573 len = argse.string_length;
2574 break;
2576 se->expr = convert (type, len);
2579 /* The length of a character string not including trailing blanks. */
2580 static void
2581 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2583 tree args;
2584 tree type;
2586 args = gfc_conv_intrinsic_function_args (se, expr);
2587 type = gfc_typenode_for_spec (&expr->ts);
2588 se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
2589 se->expr = convert (type, se->expr);
2593 /* Returns the starting position of a substring within a string. */
2595 static void
2596 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2598 tree logical4_type_node = gfc_get_logical_type (4);
2599 tree args;
2600 tree back;
2601 tree type;
2602 tree tmp;
2604 args = gfc_conv_intrinsic_function_args (se, expr);
2605 type = gfc_typenode_for_spec (&expr->ts);
2606 tmp = gfc_advance_chain (args, 3);
2607 if (TREE_CHAIN (tmp) == NULL_TREE)
2609 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2610 NULL_TREE);
2611 TREE_CHAIN (tmp) = back;
2613 else
2615 back = TREE_CHAIN (tmp);
2616 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2619 se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
2620 se->expr = convert (type, se->expr);
2623 /* The ascii value for a single character. */
2624 static void
2625 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2627 tree arg;
2628 tree type;
2630 arg = gfc_conv_intrinsic_function_args (se, expr);
2631 arg = TREE_VALUE (TREE_CHAIN (arg));
2632 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2633 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2634 type = gfc_typenode_for_spec (&expr->ts);
2636 se->expr = build_fold_indirect_ref (arg);
2637 se->expr = convert (type, se->expr);
2641 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2643 static void
2644 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2646 tree arg;
2647 tree tsource;
2648 tree fsource;
2649 tree mask;
2650 tree type;
2651 tree len;
2653 arg = gfc_conv_intrinsic_function_args (se, expr);
2654 if (expr->ts.type != BT_CHARACTER)
2656 tsource = TREE_VALUE (arg);
2657 arg = TREE_CHAIN (arg);
2658 fsource = TREE_VALUE (arg);
2659 mask = TREE_VALUE (TREE_CHAIN (arg));
2661 else
2663 /* We do the same as in the non-character case, but the argument
2664 list is different because of the string length arguments. We
2665 also have to set the string length for the result. */
2666 len = TREE_VALUE (arg);
2667 arg = TREE_CHAIN (arg);
2668 tsource = TREE_VALUE (arg);
2669 arg = TREE_CHAIN (TREE_CHAIN (arg));
2670 fsource = TREE_VALUE (arg);
2671 mask = TREE_VALUE (TREE_CHAIN (arg));
2673 se->string_length = len;
2675 type = TREE_TYPE (tsource);
2676 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2680 static void
2681 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2683 gfc_actual_arglist *actual;
2684 tree args;
2685 tree type;
2686 tree fndecl;
2687 gfc_se argse;
2688 gfc_ss *ss;
2690 gfc_init_se (&argse, NULL);
2691 actual = expr->value.function.actual;
2693 ss = gfc_walk_expr (actual->expr);
2694 gcc_assert (ss != gfc_ss_terminator);
2695 argse.want_pointer = 1;
2696 argse.data_not_needed = 1;
2697 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2698 gfc_add_block_to_block (&se->pre, &argse.pre);
2699 gfc_add_block_to_block (&se->post, &argse.post);
2700 args = gfc_chainon_list (NULL_TREE, argse.expr);
2702 actual = actual->next;
2703 if (actual->expr)
2705 gfc_init_se (&argse, NULL);
2706 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2707 gfc_add_block_to_block (&se->pre, &argse.pre);
2708 args = gfc_chainon_list (args, argse.expr);
2709 fndecl = gfor_fndecl_size1;
2711 else
2712 fndecl = gfor_fndecl_size0;
2714 se->expr = build_function_call_expr (fndecl, args);
2715 type = gfc_typenode_for_spec (&expr->ts);
2716 se->expr = convert (type, se->expr);
2720 /* Intrinsic string comparison functions. */
2722 static void
2723 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2725 tree type;
2726 tree args;
2727 tree arg2;
2729 args = gfc_conv_intrinsic_function_args (se, expr);
2730 arg2 = TREE_CHAIN (TREE_CHAIN (args));
2732 se->expr = gfc_build_compare_string (TREE_VALUE (args),
2733 TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
2734 TREE_VALUE (TREE_CHAIN (arg2)));
2736 type = gfc_typenode_for_spec (&expr->ts);
2737 se->expr = fold_build2 (op, type, se->expr,
2738 build_int_cst (TREE_TYPE (se->expr), 0));
2741 /* Generate a call to the adjustl/adjustr library function. */
2742 static void
2743 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2745 tree args;
2746 tree len;
2747 tree type;
2748 tree var;
2749 tree tmp;
2751 args = gfc_conv_intrinsic_function_args (se, expr);
2752 len = TREE_VALUE (args);
2754 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2755 var = gfc_conv_string_tmp (se, type, len);
2756 args = tree_cons (NULL_TREE, var, args);
2758 tmp = build_function_call_expr (fndecl, args);
2759 gfc_add_expr_to_block (&se->pre, tmp);
2760 se->expr = var;
2761 se->string_length = len;
2765 /* A helper function for gfc_conv_intrinsic_array_transfer to compute
2766 the size of tree expressions in bytes. */
2767 static tree
2768 gfc_size_in_bytes (gfc_se *se, gfc_expr *e)
2770 tree tmp;
2772 if (e->ts.type == BT_CHARACTER)
2773 tmp = se->string_length;
2774 else
2776 if (e->rank)
2778 tmp = gfc_get_element_type (TREE_TYPE (se->expr));
2779 tmp = size_in_bytes (tmp);
2781 else
2782 tmp = size_in_bytes (TREE_TYPE (TREE_TYPE (se->expr)));
2785 return fold_convert (gfc_array_index_type, tmp);
2789 /* Array transfer statement.
2790 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
2791 where:
2792 typeof<DEST> = typeof<MOLD>
2793 and:
2794 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
2795 sizeof (DEST(0) * SIZE). */
2797 static void
2798 gfc_conv_intrinsic_array_transfer (gfc_se * se, gfc_expr * expr)
2800 tree tmp;
2801 tree extent;
2802 tree source;
2803 tree source_bytes;
2804 tree dest_word_len;
2805 tree size_words;
2806 tree size_bytes;
2807 tree upper;
2808 tree lower;
2809 tree stride;
2810 tree stmt;
2811 gfc_actual_arglist *arg;
2812 gfc_se argse;
2813 gfc_ss *ss;
2814 gfc_ss_info *info;
2815 stmtblock_t block;
2816 int n;
2818 gcc_assert (se->loop);
2819 info = &se->ss->data.info;
2821 /* Convert SOURCE. The output from this stage is:-
2822 source_bytes = length of the source in bytes
2823 source = pointer to the source data. */
2824 arg = expr->value.function.actual;
2825 gfc_init_se (&argse, NULL);
2826 ss = gfc_walk_expr (arg->expr);
2828 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
2830 /* Obtain the pointer to source and the length of source in bytes. */
2831 if (ss == gfc_ss_terminator)
2833 gfc_conv_expr_reference (&argse, arg->expr);
2834 source = argse.expr;
2836 /* Obtain the source word length. */
2837 tmp = gfc_size_in_bytes (&argse, arg->expr);
2839 else
2841 gfc_init_se (&argse, NULL);
2842 argse.want_pointer = 0;
2843 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2844 source = gfc_conv_descriptor_data_get (argse.expr);
2846 /* Repack the source if not a full variable array. */
2847 if (!(arg->expr->expr_type == EXPR_VARIABLE
2848 && arg->expr->ref->u.ar.type == AR_FULL))
2850 tmp = build_fold_addr_expr (argse.expr);
2851 source = build_call_expr (gfor_fndecl_in_pack, 1, tmp);
2852 source = gfc_evaluate_now (source, &argse.pre);
2854 /* Free the temporary. */
2855 gfc_start_block (&block);
2856 tmp = convert (pvoid_type_node, source);
2857 tmp = build_call_expr (gfor_fndecl_internal_free, 1, tmp);
2858 gfc_add_expr_to_block (&block, tmp);
2859 stmt = gfc_finish_block (&block);
2861 /* Clean up if it was repacked. */
2862 gfc_init_block (&block);
2863 tmp = gfc_conv_array_data (argse.expr);
2864 tmp = build2 (NE_EXPR, boolean_type_node, source, tmp);
2865 tmp = build3_v (COND_EXPR, tmp, stmt, build_empty_stmt ());
2866 gfc_add_expr_to_block (&block, tmp);
2867 gfc_add_block_to_block (&block, &se->post);
2868 gfc_init_block (&se->post);
2869 gfc_add_block_to_block (&se->post, &block);
2872 /* Obtain the source word length. */
2873 tmp = gfc_size_in_bytes (&argse, arg->expr);
2875 /* Obtain the size of the array in bytes. */
2876 extent = gfc_create_var (gfc_array_index_type, NULL);
2877 for (n = 0; n < arg->expr->rank; n++)
2879 tree idx;
2880 idx = gfc_rank_cst[n];
2881 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2882 stride = gfc_conv_descriptor_stride (argse.expr, idx);
2883 lower = gfc_conv_descriptor_lbound (argse.expr, idx);
2884 upper = gfc_conv_descriptor_ubound (argse.expr, idx);
2885 tmp = build2 (MINUS_EXPR, gfc_array_index_type,
2886 upper, lower);
2887 gfc_add_modify_expr (&argse.pre, extent, tmp);
2888 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2889 extent, gfc_index_one_node);
2890 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2891 tmp, source_bytes);
2895 gfc_add_modify_expr (&argse.pre, source_bytes, tmp);
2896 gfc_add_block_to_block (&se->pre, &argse.pre);
2897 gfc_add_block_to_block (&se->post, &argse.post);
2899 /* Now convert MOLD. The sole output is:
2900 dest_word_len = destination word length in bytes. */
2901 arg = arg->next;
2903 gfc_init_se (&argse, NULL);
2904 ss = gfc_walk_expr (arg->expr);
2906 if (ss == gfc_ss_terminator)
2908 gfc_conv_expr_reference (&argse, arg->expr);
2910 /* Obtain the source word length. */
2911 tmp = gfc_size_in_bytes (&argse, arg->expr);
2913 else
2915 gfc_init_se (&argse, NULL);
2916 argse.want_pointer = 0;
2917 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
2919 /* Obtain the source word length. */
2920 tmp = gfc_size_in_bytes (&argse, arg->expr);
2923 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
2924 gfc_add_modify_expr (&se->pre, dest_word_len, tmp);
2926 /* Finally convert SIZE, if it is present. */
2927 arg = arg->next;
2928 size_words = gfc_create_var (gfc_array_index_type, NULL);
2930 if (arg->expr)
2932 gfc_init_se (&argse, NULL);
2933 gfc_conv_expr_reference (&argse, arg->expr);
2934 tmp = convert (gfc_array_index_type,
2935 build_fold_indirect_ref (argse.expr));
2936 gfc_add_block_to_block (&se->pre, &argse.pre);
2937 gfc_add_block_to_block (&se->post, &argse.post);
2939 else
2940 tmp = NULL_TREE;
2942 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
2943 if (tmp != NULL_TREE)
2945 tmp = build2 (MULT_EXPR, gfc_array_index_type,
2946 tmp, dest_word_len);
2947 tmp = build2 (MIN_EXPR, gfc_array_index_type, tmp, source_bytes);
2949 else
2950 tmp = source_bytes;
2952 gfc_add_modify_expr (&se->pre, size_bytes, tmp);
2953 gfc_add_modify_expr (&se->pre, size_words,
2954 build2 (CEIL_DIV_EXPR, gfc_array_index_type,
2955 size_bytes, dest_word_len));
2957 /* Evaluate the bounds of the result. If the loop range exists, we have
2958 to check if it is too large. If so, we modify loop->to be consistent
2959 with min(size, size(source)). Otherwise, size is made consistent with
2960 the loop range, so that the right number of bytes is transferred.*/
2961 n = se->loop->order[0];
2962 if (se->loop->to[n] != NULL_TREE)
2964 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2965 se->loop->to[n], se->loop->from[n]);
2966 tmp = build2 (PLUS_EXPR, gfc_array_index_type,
2967 tmp, gfc_index_one_node);
2968 tmp = build2 (MIN_EXPR, gfc_array_index_type,
2969 tmp, size_words);
2970 gfc_add_modify_expr (&se->pre, size_words, tmp);
2971 gfc_add_modify_expr (&se->pre, size_bytes,
2972 build2 (MULT_EXPR, gfc_array_index_type,
2973 size_words, dest_word_len));
2974 upper = build2 (PLUS_EXPR, gfc_array_index_type,
2975 size_words, se->loop->from[n]);
2976 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2977 upper, gfc_index_one_node);
2979 else
2981 upper = build2 (MINUS_EXPR, gfc_array_index_type,
2982 size_words, gfc_index_one_node);
2983 se->loop->from[n] = gfc_index_zero_node;
2986 se->loop->to[n] = upper;
2988 /* Build a destination descriptor, using the pointer, source, as the
2989 data field. This is already allocated so set callee_alloc.
2990 FIXME callee_alloc is not set! */
2992 tmp = gfc_typenode_for_spec (&expr->ts);
2993 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
2994 info, tmp, false, true, false);
2996 /* Use memcpy to do the transfer. */
2997 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY],
2999 gfc_conv_descriptor_data_get (info->descriptor),
3000 fold_convert (pvoid_type_node, source),
3001 size_bytes);
3002 gfc_add_expr_to_block (&se->pre, tmp);
3004 se->expr = info->descriptor;
3005 if (expr->ts.type == BT_CHARACTER)
3006 se->string_length = dest_word_len;
3010 /* Scalar transfer statement.
3011 TRANSFER (source, mold) = memcpy(&tmpdecl, &source, size), tmpdecl. */
3013 static void
3014 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3016 gfc_actual_arglist *arg;
3017 gfc_se argse;
3018 tree type;
3019 tree ptr;
3020 gfc_ss *ss;
3021 tree tmpdecl, tmp;
3023 /* Get a pointer to the source. */
3024 arg = expr->value.function.actual;
3025 ss = gfc_walk_expr (arg->expr);
3026 gfc_init_se (&argse, NULL);
3027 if (ss == gfc_ss_terminator)
3028 gfc_conv_expr_reference (&argse, arg->expr);
3029 else
3030 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
3031 gfc_add_block_to_block (&se->pre, &argse.pre);
3032 gfc_add_block_to_block (&se->post, &argse.post);
3033 ptr = argse.expr;
3035 arg = arg->next;
3036 type = gfc_typenode_for_spec (&expr->ts);
3038 if (expr->ts.type == BT_CHARACTER)
3040 ptr = convert (build_pointer_type (type), ptr);
3041 gfc_init_se (&argse, NULL);
3042 gfc_conv_expr (&argse, arg->expr);
3043 gfc_add_block_to_block (&se->pre, &argse.pre);
3044 gfc_add_block_to_block (&se->post, &argse.post);
3045 se->expr = ptr;
3046 se->string_length = argse.string_length;
3048 else
3050 tree moldsize;
3051 tmpdecl = gfc_create_var (type, "transfer");
3052 moldsize = size_in_bytes (type);
3054 /* Use memcpy to do the transfer. */
3055 tmp = build1 (ADDR_EXPR, build_pointer_type (type), tmpdecl);
3056 tmp = build_call_expr (built_in_decls[BUILT_IN_MEMCPY], 3,
3057 fold_convert (pvoid_type_node, tmp),
3058 fold_convert (pvoid_type_node, ptr),
3059 moldsize);
3060 gfc_add_expr_to_block (&se->pre, tmp);
3062 se->expr = tmpdecl;
3067 /* Generate code for the ALLOCATED intrinsic.
3068 Generate inline code that directly check the address of the argument. */
3070 static void
3071 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
3073 gfc_actual_arglist *arg1;
3074 gfc_se arg1se;
3075 gfc_ss *ss1;
3076 tree tmp;
3078 gfc_init_se (&arg1se, NULL);
3079 arg1 = expr->value.function.actual;
3080 ss1 = gfc_walk_expr (arg1->expr);
3081 arg1se.descriptor_only = 1;
3082 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3084 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
3085 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
3086 fold_convert (TREE_TYPE (tmp), null_pointer_node));
3087 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
3091 /* Generate code for the ASSOCIATED intrinsic.
3092 If both POINTER and TARGET are arrays, generate a call to library function
3093 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
3094 In other cases, generate inline code that directly compare the address of
3095 POINTER with the address of TARGET. */
3097 static void
3098 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
3100 gfc_actual_arglist *arg1;
3101 gfc_actual_arglist *arg2;
3102 gfc_se arg1se;
3103 gfc_se arg2se;
3104 tree tmp2;
3105 tree tmp;
3106 tree fndecl;
3107 tree nonzero_charlen;
3108 tree nonzero_arraylen;
3109 gfc_ss *ss1, *ss2;
3111 gfc_init_se (&arg1se, NULL);
3112 gfc_init_se (&arg2se, NULL);
3113 arg1 = expr->value.function.actual;
3114 arg2 = arg1->next;
3115 ss1 = gfc_walk_expr (arg1->expr);
3117 if (!arg2->expr)
3119 /* No optional target. */
3120 if (ss1 == gfc_ss_terminator)
3122 /* A pointer to a scalar. */
3123 arg1se.want_pointer = 1;
3124 gfc_conv_expr (&arg1se, arg1->expr);
3125 tmp2 = arg1se.expr;
3127 else
3129 /* A pointer to an array. */
3130 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3131 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
3133 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3134 gfc_add_block_to_block (&se->post, &arg1se.post);
3135 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
3136 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
3137 se->expr = tmp;
3139 else
3141 /* An optional target. */
3142 ss2 = gfc_walk_expr (arg2->expr);
3144 nonzero_charlen = NULL_TREE;
3145 if (arg1->expr->ts.type == BT_CHARACTER)
3146 nonzero_charlen = build2 (NE_EXPR, boolean_type_node,
3147 arg1->expr->ts.cl->backend_decl,
3148 integer_zero_node);
3150 if (ss1 == gfc_ss_terminator)
3152 /* A pointer to a scalar. */
3153 gcc_assert (ss2 == gfc_ss_terminator);
3154 arg1se.want_pointer = 1;
3155 gfc_conv_expr (&arg1se, arg1->expr);
3156 arg2se.want_pointer = 1;
3157 gfc_conv_expr (&arg2se, arg2->expr);
3158 gfc_add_block_to_block (&se->pre, &arg1se.pre);
3159 gfc_add_block_to_block (&se->post, &arg1se.post);
3160 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
3161 tmp2 = build2 (NE_EXPR, boolean_type_node, arg1se.expr,
3162 null_pointer_node);
3163 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node, tmp, tmp2);
3165 else
3168 /* An array pointer of zero length is not associated if target is
3169 present. */
3170 arg1se.descriptor_only = 1;
3171 gfc_conv_expr_lhs (&arg1se, arg1->expr);
3172 tmp = gfc_conv_descriptor_stride (arg1se.expr,
3173 gfc_rank_cst[arg1->expr->rank - 1]);
3174 nonzero_arraylen = build2 (NE_EXPR, boolean_type_node,
3175 tmp, integer_zero_node);
3177 /* A pointer to an array, call library function _gfor_associated. */
3178 gcc_assert (ss2 != gfc_ss_terminator);
3179 arg1se.want_pointer = 1;
3180 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
3182 arg2se.want_pointer = 1;
3183 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
3184 gfc_add_block_to_block (&se->pre, &arg2se.pre);
3185 gfc_add_block_to_block (&se->post, &arg2se.post);
3186 fndecl = gfor_fndecl_associated;
3187 se->expr = build_call_expr (fndecl, 2, arg1se.expr, arg2se.expr);
3188 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3189 se->expr, nonzero_arraylen);
3193 /* If target is present zero character length pointers cannot
3194 be associated. */
3195 if (nonzero_charlen != NULL_TREE)
3196 se->expr = build2 (TRUTH_AND_EXPR, boolean_type_node,
3197 se->expr, nonzero_charlen);
3200 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3204 /* Scan a string for any one of the characters in a set of characters. */
3206 static void
3207 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
3209 tree logical4_type_node = gfc_get_logical_type (4);
3210 tree args;
3211 tree back;
3212 tree type;
3213 tree tmp;
3215 args = gfc_conv_intrinsic_function_args (se, expr);
3216 type = gfc_typenode_for_spec (&expr->ts);
3217 tmp = gfc_advance_chain (args, 3);
3218 if (TREE_CHAIN (tmp) == NULL_TREE)
3220 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3221 NULL_TREE);
3222 TREE_CHAIN (tmp) = back;
3224 else
3226 back = TREE_CHAIN (tmp);
3227 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3230 se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
3231 se->expr = convert (type, se->expr);
3235 /* Verify that a set of characters contains all the characters in a string
3236 by identifying the position of the first character in a string of
3237 characters that does not appear in a given set of characters. */
3239 static void
3240 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
3242 tree logical4_type_node = gfc_get_logical_type (4);
3243 tree args;
3244 tree back;
3245 tree type;
3246 tree tmp;
3248 args = gfc_conv_intrinsic_function_args (se, expr);
3249 type = gfc_typenode_for_spec (&expr->ts);
3250 tmp = gfc_advance_chain (args, 3);
3251 if (TREE_CHAIN (tmp) == NULL_TREE)
3253 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
3254 NULL_TREE);
3255 TREE_CHAIN (tmp) = back;
3257 else
3259 back = TREE_CHAIN (tmp);
3260 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
3263 se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
3264 se->expr = convert (type, se->expr);
3268 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
3270 static void
3271 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
3273 tree args;
3275 args = gfc_conv_intrinsic_function_args (se, expr);
3276 args = TREE_VALUE (args);
3277 args = build_fold_addr_expr (args);
3278 se->expr = build_call_expr (gfor_fndecl_si_kind, 1, args);
3281 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
3283 static void
3284 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
3286 gfc_actual_arglist *actual;
3287 tree args;
3288 gfc_se argse;
3290 args = NULL_TREE;
3291 for (actual = expr->value.function.actual; actual; actual = actual->next)
3293 gfc_init_se (&argse, se);
3295 /* Pass a NULL pointer for an absent arg. */
3296 if (actual->expr == NULL)
3297 argse.expr = null_pointer_node;
3298 else
3299 gfc_conv_expr_reference (&argse, actual->expr);
3301 gfc_add_block_to_block (&se->pre, &argse.pre);
3302 gfc_add_block_to_block (&se->post, &argse.post);
3303 args = gfc_chainon_list (args, argse.expr);
3305 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
3309 /* Generate code for TRIM (A) intrinsic function. */
3311 static void
3312 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
3314 tree gfc_int4_type_node = gfc_get_int_type (4);
3315 tree var;
3316 tree len;
3317 tree addr;
3318 tree tmp;
3319 tree arglist;
3320 tree type;
3321 tree cond;
3323 arglist = NULL_TREE;
3325 type = build_pointer_type (gfc_character1_type_node);
3326 var = gfc_create_var (type, "pstr");
3327 addr = gfc_build_addr_expr (ppvoid_type_node, var);
3328 len = gfc_create_var (gfc_int4_type_node, "len");
3330 tmp = gfc_conv_intrinsic_function_args (se, expr);
3331 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
3332 arglist = gfc_chainon_list (arglist, addr);
3333 arglist = chainon (arglist, tmp);
3335 tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
3336 gfc_add_expr_to_block (&se->pre, tmp);
3338 /* Free the temporary afterwards, if necessary. */
3339 cond = build2 (GT_EXPR, boolean_type_node, len,
3340 build_int_cst (TREE_TYPE (len), 0));
3341 tmp = build_call_expr (gfor_fndecl_internal_free, 1, var);
3342 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
3343 gfc_add_expr_to_block (&se->post, tmp);
3345 se->expr = var;
3346 se->string_length = len;
3350 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
3352 static void
3353 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
3355 tree gfc_int4_type_node = gfc_get_int_type (4);
3356 tree tmp;
3357 tree len;
3358 tree args;
3359 tree ncopies;
3360 tree var;
3361 tree type;
3362 tree cond;
3364 args = gfc_conv_intrinsic_function_args (se, expr);
3365 len = TREE_VALUE (args);
3366 tmp = gfc_advance_chain (args, 2);
3367 ncopies = TREE_VALUE (tmp);
3369 /* Check that ncopies is not negative. */
3370 ncopies = gfc_evaluate_now (ncopies, &se->pre);
3371 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
3372 build_int_cst (TREE_TYPE (ncopies), 0));
3373 gfc_trans_runtime_check (cond,
3374 "Argument NCOPIES of REPEAT intrinsic is negative",
3375 &se->pre, &expr->where);
3377 /* Compute the destination length. */
3378 len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
3379 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
3380 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
3382 /* Create the argument list and generate the function call. */
3383 tmp = build_call_expr (gfor_fndecl_string_repeat, 4, var,
3384 TREE_VALUE (args),
3385 TREE_VALUE (TREE_CHAIN (args)), ncopies);
3386 gfc_add_expr_to_block (&se->pre, tmp);
3388 se->expr = var;
3389 se->string_length = len;
3393 /* Generate code for the IARGC intrinsic. */
3395 static void
3396 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
3398 tree tmp;
3399 tree fndecl;
3400 tree type;
3402 /* Call the library function. This always returns an INTEGER(4). */
3403 fndecl = gfor_fndecl_iargc;
3404 tmp = build_call_expr (fndecl, 0);
3406 /* Convert it to the required type. */
3407 type = gfc_typenode_for_spec (&expr->ts);
3408 tmp = fold_convert (type, tmp);
3410 se->expr = tmp;
3414 /* The loc intrinsic returns the address of its argument as
3415 gfc_index_integer_kind integer. */
3417 static void
3418 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
3420 tree temp_var;
3421 gfc_expr *arg_expr;
3422 gfc_ss *ss;
3424 gcc_assert (!se->ss);
3426 arg_expr = expr->value.function.actual->expr;
3427 ss = gfc_walk_expr (arg_expr);
3428 if (ss == gfc_ss_terminator)
3429 gfc_conv_expr_reference (se, arg_expr);
3430 else
3431 gfc_conv_array_parameter (se, arg_expr, ss, 1);
3432 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
3434 /* Create a temporary variable for loc return value. Without this,
3435 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
3436 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
3437 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
3438 se->expr = temp_var;
3441 /* Generate code for an intrinsic function. Some map directly to library
3442 calls, others get special handling. In some cases the name of the function
3443 used depends on the type specifiers. */
3445 void
3446 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
3448 gfc_intrinsic_sym *isym;
3449 const char *name;
3450 int lib;
3452 isym = expr->value.function.isym;
3454 name = &expr->value.function.name[2];
3456 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
3458 lib = gfc_is_intrinsic_libcall (expr);
3459 if (lib != 0)
3461 if (lib == 1)
3462 se->ignore_optional = 1;
3463 gfc_conv_intrinsic_funcall (se, expr);
3464 return;
3468 switch (expr->value.function.isym->generic_id)
3470 case GFC_ISYM_NONE:
3471 gcc_unreachable ();
3473 case GFC_ISYM_REPEAT:
3474 gfc_conv_intrinsic_repeat (se, expr);
3475 break;
3477 case GFC_ISYM_TRIM:
3478 gfc_conv_intrinsic_trim (se, expr);
3479 break;
3481 case GFC_ISYM_SI_KIND:
3482 gfc_conv_intrinsic_si_kind (se, expr);
3483 break;
3485 case GFC_ISYM_SR_KIND:
3486 gfc_conv_intrinsic_sr_kind (se, expr);
3487 break;
3489 case GFC_ISYM_EXPONENT:
3490 gfc_conv_intrinsic_exponent (se, expr);
3491 break;
3493 case GFC_ISYM_SCAN:
3494 gfc_conv_intrinsic_scan (se, expr);
3495 break;
3497 case GFC_ISYM_VERIFY:
3498 gfc_conv_intrinsic_verify (se, expr);
3499 break;
3501 case GFC_ISYM_ALLOCATED:
3502 gfc_conv_allocated (se, expr);
3503 break;
3505 case GFC_ISYM_ASSOCIATED:
3506 gfc_conv_associated(se, expr);
3507 break;
3509 case GFC_ISYM_ABS:
3510 gfc_conv_intrinsic_abs (se, expr);
3511 break;
3513 case GFC_ISYM_ADJUSTL:
3514 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
3515 break;
3517 case GFC_ISYM_ADJUSTR:
3518 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
3519 break;
3521 case GFC_ISYM_AIMAG:
3522 gfc_conv_intrinsic_imagpart (se, expr);
3523 break;
3525 case GFC_ISYM_AINT:
3526 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
3527 break;
3529 case GFC_ISYM_ALL:
3530 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
3531 break;
3533 case GFC_ISYM_ANINT:
3534 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
3535 break;
3537 case GFC_ISYM_AND:
3538 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3539 break;
3541 case GFC_ISYM_ANY:
3542 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
3543 break;
3545 case GFC_ISYM_BTEST:
3546 gfc_conv_intrinsic_btest (se, expr);
3547 break;
3549 case GFC_ISYM_ACHAR:
3550 case GFC_ISYM_CHAR:
3551 gfc_conv_intrinsic_char (se, expr);
3552 break;
3554 case GFC_ISYM_CONVERSION:
3555 case GFC_ISYM_REAL:
3556 case GFC_ISYM_LOGICAL:
3557 case GFC_ISYM_DBLE:
3558 gfc_conv_intrinsic_conversion (se, expr);
3559 break;
3561 /* Integer conversions are handled separately to make sure we get the
3562 correct rounding mode. */
3563 case GFC_ISYM_INT:
3564 case GFC_ISYM_INT2:
3565 case GFC_ISYM_INT8:
3566 case GFC_ISYM_LONG:
3567 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
3568 break;
3570 case GFC_ISYM_NINT:
3571 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
3572 break;
3574 case GFC_ISYM_CEILING:
3575 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
3576 break;
3578 case GFC_ISYM_FLOOR:
3579 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
3580 break;
3582 case GFC_ISYM_MOD:
3583 gfc_conv_intrinsic_mod (se, expr, 0);
3584 break;
3586 case GFC_ISYM_MODULO:
3587 gfc_conv_intrinsic_mod (se, expr, 1);
3588 break;
3590 case GFC_ISYM_CMPLX:
3591 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3592 break;
3594 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3595 gfc_conv_intrinsic_iargc (se, expr);
3596 break;
3598 case GFC_ISYM_COMPLEX:
3599 gfc_conv_intrinsic_cmplx (se, expr, 1);
3600 break;
3602 case GFC_ISYM_CONJG:
3603 gfc_conv_intrinsic_conjg (se, expr);
3604 break;
3606 case GFC_ISYM_COUNT:
3607 gfc_conv_intrinsic_count (se, expr);
3608 break;
3610 case GFC_ISYM_CTIME:
3611 gfc_conv_intrinsic_ctime (se, expr);
3612 break;
3614 case GFC_ISYM_DIM:
3615 gfc_conv_intrinsic_dim (se, expr);
3616 break;
3618 case GFC_ISYM_DOT_PRODUCT:
3619 gfc_conv_intrinsic_dot_product (se, expr);
3620 break;
3622 case GFC_ISYM_DPROD:
3623 gfc_conv_intrinsic_dprod (se, expr);
3624 break;
3626 case GFC_ISYM_FDATE:
3627 gfc_conv_intrinsic_fdate (se, expr);
3628 break;
3630 case GFC_ISYM_IAND:
3631 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3632 break;
3634 case GFC_ISYM_IBCLR:
3635 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3636 break;
3638 case GFC_ISYM_IBITS:
3639 gfc_conv_intrinsic_ibits (se, expr);
3640 break;
3642 case GFC_ISYM_IBSET:
3643 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3644 break;
3646 case GFC_ISYM_IACHAR:
3647 case GFC_ISYM_ICHAR:
3648 /* We assume ASCII character sequence. */
3649 gfc_conv_intrinsic_ichar (se, expr);
3650 break;
3652 case GFC_ISYM_IARGC:
3653 gfc_conv_intrinsic_iargc (se, expr);
3654 break;
3656 case GFC_ISYM_IEOR:
3657 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3658 break;
3660 case GFC_ISYM_INDEX:
3661 gfc_conv_intrinsic_index (se, expr);
3662 break;
3664 case GFC_ISYM_IOR:
3665 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3666 break;
3668 case GFC_ISYM_LSHIFT:
3669 gfc_conv_intrinsic_rlshift (se, expr, 0);
3670 break;
3672 case GFC_ISYM_RSHIFT:
3673 gfc_conv_intrinsic_rlshift (se, expr, 1);
3674 break;
3676 case GFC_ISYM_ISHFT:
3677 gfc_conv_intrinsic_ishft (se, expr);
3678 break;
3680 case GFC_ISYM_ISHFTC:
3681 gfc_conv_intrinsic_ishftc (se, expr);
3682 break;
3684 case GFC_ISYM_LBOUND:
3685 gfc_conv_intrinsic_bound (se, expr, 0);
3686 break;
3688 case GFC_ISYM_TRANSPOSE:
3689 if (se->ss && se->ss->useflags)
3691 gfc_conv_tmp_array_ref (se);
3692 gfc_advance_se_ss_chain (se);
3694 else
3695 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3696 break;
3698 case GFC_ISYM_LEN:
3699 gfc_conv_intrinsic_len (se, expr);
3700 break;
3702 case GFC_ISYM_LEN_TRIM:
3703 gfc_conv_intrinsic_len_trim (se, expr);
3704 break;
3706 case GFC_ISYM_LGE:
3707 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3708 break;
3710 case GFC_ISYM_LGT:
3711 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3712 break;
3714 case GFC_ISYM_LLE:
3715 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3716 break;
3718 case GFC_ISYM_LLT:
3719 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3720 break;
3722 case GFC_ISYM_MAX:
3723 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3724 break;
3726 case GFC_ISYM_MAXLOC:
3727 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3728 break;
3730 case GFC_ISYM_MAXVAL:
3731 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3732 break;
3734 case GFC_ISYM_MERGE:
3735 gfc_conv_intrinsic_merge (se, expr);
3736 break;
3738 case GFC_ISYM_MIN:
3739 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3740 break;
3742 case GFC_ISYM_MINLOC:
3743 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3744 break;
3746 case GFC_ISYM_MINVAL:
3747 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3748 break;
3750 case GFC_ISYM_NOT:
3751 gfc_conv_intrinsic_not (se, expr);
3752 break;
3754 case GFC_ISYM_OR:
3755 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3756 break;
3758 case GFC_ISYM_PRESENT:
3759 gfc_conv_intrinsic_present (se, expr);
3760 break;
3762 case GFC_ISYM_PRODUCT:
3763 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3764 break;
3766 case GFC_ISYM_SIGN:
3767 gfc_conv_intrinsic_sign (se, expr);
3768 break;
3770 case GFC_ISYM_SIZE:
3771 gfc_conv_intrinsic_size (se, expr);
3772 break;
3774 case GFC_ISYM_SUM:
3775 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3776 break;
3778 case GFC_ISYM_TRANSFER:
3779 if (se->ss)
3781 if (se->ss->useflags)
3783 /* Access the previously obtained result. */
3784 gfc_conv_tmp_array_ref (se);
3785 gfc_advance_se_ss_chain (se);
3786 break;
3788 else
3789 gfc_conv_intrinsic_array_transfer (se, expr);
3791 else
3792 gfc_conv_intrinsic_transfer (se, expr);
3793 break;
3795 case GFC_ISYM_TTYNAM:
3796 gfc_conv_intrinsic_ttynam (se, expr);
3797 break;
3799 case GFC_ISYM_UBOUND:
3800 gfc_conv_intrinsic_bound (se, expr, 1);
3801 break;
3803 case GFC_ISYM_XOR:
3804 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3805 break;
3807 case GFC_ISYM_LOC:
3808 gfc_conv_intrinsic_loc (se, expr);
3809 break;
3811 case GFC_ISYM_ACCESS:
3812 case GFC_ISYM_CHDIR:
3813 case GFC_ISYM_CHMOD:
3814 case GFC_ISYM_ETIME:
3815 case GFC_ISYM_FGET:
3816 case GFC_ISYM_FGETC:
3817 case GFC_ISYM_FNUM:
3818 case GFC_ISYM_FPUT:
3819 case GFC_ISYM_FPUTC:
3820 case GFC_ISYM_FSTAT:
3821 case GFC_ISYM_FTELL:
3822 case GFC_ISYM_GETCWD:
3823 case GFC_ISYM_GETGID:
3824 case GFC_ISYM_GETPID:
3825 case GFC_ISYM_GETUID:
3826 case GFC_ISYM_HOSTNM:
3827 case GFC_ISYM_KILL:
3828 case GFC_ISYM_IERRNO:
3829 case GFC_ISYM_IRAND:
3830 case GFC_ISYM_ISATTY:
3831 case GFC_ISYM_LINK:
3832 case GFC_ISYM_LSTAT:
3833 case GFC_ISYM_MALLOC:
3834 case GFC_ISYM_MATMUL:
3835 case GFC_ISYM_MCLOCK:
3836 case GFC_ISYM_MCLOCK8:
3837 case GFC_ISYM_RAND:
3838 case GFC_ISYM_RENAME:
3839 case GFC_ISYM_SECOND:
3840 case GFC_ISYM_SECNDS:
3841 case GFC_ISYM_SIGNAL:
3842 case GFC_ISYM_STAT:
3843 case GFC_ISYM_SYMLNK:
3844 case GFC_ISYM_SYSTEM:
3845 case GFC_ISYM_TIME:
3846 case GFC_ISYM_TIME8:
3847 case GFC_ISYM_UMASK:
3848 case GFC_ISYM_UNLINK:
3849 gfc_conv_intrinsic_funcall (se, expr);
3850 break;
3852 default:
3853 gfc_conv_intrinsic_lib_function (se, expr);
3854 break;
3859 /* This generates code to execute before entering the scalarization loop.
3860 Currently does nothing. */
3862 void
3863 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
3865 switch (ss->expr->value.function.isym->generic_id)
3867 case GFC_ISYM_UBOUND:
3868 case GFC_ISYM_LBOUND:
3869 break;
3871 default:
3872 gcc_unreachable ();
3877 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
3878 inside the scalarization loop. */
3880 static gfc_ss *
3881 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
3883 gfc_ss *newss;
3885 /* The two argument version returns a scalar. */
3886 if (expr->value.function.actual->next->expr)
3887 return ss;
3889 newss = gfc_get_ss ();
3890 newss->type = GFC_SS_INTRINSIC;
3891 newss->expr = expr;
3892 newss->next = ss;
3893 newss->data.info.dimen = 1;
3895 return newss;
3899 /* Walk an intrinsic array libcall. */
3901 static gfc_ss *
3902 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
3904 gfc_ss *newss;
3906 gcc_assert (expr->rank > 0);
3908 newss = gfc_get_ss ();
3909 newss->type = GFC_SS_FUNCTION;
3910 newss->expr = expr;
3911 newss->next = ss;
3912 newss->data.info.dimen = expr->rank;
3914 return newss;
3918 /* Returns nonzero if the specified intrinsic function call maps directly to a
3919 an external library call. Should only be used for functions that return
3920 arrays. */
3923 gfc_is_intrinsic_libcall (gfc_expr * expr)
3925 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3926 gcc_assert (expr->rank > 0);
3928 switch (expr->value.function.isym->generic_id)
3930 case GFC_ISYM_ALL:
3931 case GFC_ISYM_ANY:
3932 case GFC_ISYM_COUNT:
3933 case GFC_ISYM_MATMUL:
3934 case GFC_ISYM_MAXLOC:
3935 case GFC_ISYM_MAXVAL:
3936 case GFC_ISYM_MINLOC:
3937 case GFC_ISYM_MINVAL:
3938 case GFC_ISYM_PRODUCT:
3939 case GFC_ISYM_SUM:
3940 case GFC_ISYM_SHAPE:
3941 case GFC_ISYM_SPREAD:
3942 case GFC_ISYM_TRANSPOSE:
3943 /* Ignore absent optional parameters. */
3944 return 1;
3946 case GFC_ISYM_RESHAPE:
3947 case GFC_ISYM_CSHIFT:
3948 case GFC_ISYM_EOSHIFT:
3949 case GFC_ISYM_PACK:
3950 case GFC_ISYM_UNPACK:
3951 /* Pass absent optional parameters. */
3952 return 2;
3954 default:
3955 return 0;
3959 /* Walk an intrinsic function. */
3960 gfc_ss *
3961 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3962 gfc_intrinsic_sym * isym)
3964 gcc_assert (isym);
3966 if (isym->elemental)
3967 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
3969 if (expr->rank == 0)
3970 return ss;
3972 if (gfc_is_intrinsic_libcall (expr))
3973 return gfc_walk_intrinsic_libfunc (ss, expr);
3975 /* Special cases. */
3976 switch (isym->generic_id)
3978 case GFC_ISYM_LBOUND:
3979 case GFC_ISYM_UBOUND:
3980 return gfc_walk_intrinsic_bound (ss, expr);
3982 case GFC_ISYM_TRANSFER:
3983 return gfc_walk_intrinsic_libfunc (ss, expr);
3985 default:
3986 /* This probably meant someone forgot to add an intrinsic to the above
3987 list(s) when they implemented it, or something's gone horribly wrong.
3989 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3990 expr->value.function.name);
3994 #include "gt-fortran-trans-intrinsic.h"