Merge from mainline
[official-gcc.git] / gcc / fortran / trans-intrinsic.c
blob5b241a6a0fd71a413024098d6f6f5b84b09c5a0e
1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Paul Brook <paul@nowt.org>
4 and Steven Bosscher <s.bosscher@student.tudelft.nl>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA. */
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "ggc.h"
30 #include "toplev.h"
31 #include "real.h"
32 #include "tree-gimple.h"
33 #include "flags.h"
34 #include "gfortran.h"
35 #include "arith.h"
36 #include "intrinsic.h"
37 #include "trans.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
41 #include "defaults.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43 #include "trans-stmt.h"
45 /* This maps fortran intrinsic math functions to external library or GCC
46 builtin functions. */
47 typedef struct gfc_intrinsic_map_t GTY(())
49 /* The explicit enum is required to work around inadequacies in the
50 garbage collection/gengtype parsing mechanism. */
51 enum gfc_generic_isym_id id;
53 /* Enum value from the "language-independent", aka C-centric, part
54 of gcc, or END_BUILTINS of no such value set. */
55 enum built_in_function code_r4;
56 enum built_in_function code_r8;
57 enum built_in_function code_r10;
58 enum built_in_function code_r16;
59 enum built_in_function code_c4;
60 enum built_in_function code_c8;
61 enum built_in_function code_c10;
62 enum built_in_function code_c16;
64 /* True if the naming pattern is to prepend "c" for complex and
65 append "f" for kind=4. False if the naming pattern is to
66 prepend "_gfortran_" and append "[rc](4|8|10|16)". */
67 bool libm_name;
69 /* True if a complex version of the function exists. */
70 bool complex_available;
72 /* True if the function should be marked const. */
73 bool is_constant;
75 /* The base library name of this function. */
76 const char *name;
78 /* Cache decls created for the various operand types. */
79 tree real4_decl;
80 tree real8_decl;
81 tree real10_decl;
82 tree real16_decl;
83 tree complex4_decl;
84 tree complex8_decl;
85 tree complex10_decl;
86 tree complex16_decl;
88 gfc_intrinsic_map_t;
90 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
91 defines complex variants of all of the entries in mathbuiltins.def
92 except for atan2. */
93 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
94 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
95 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, 0, 0, 0, 0, true, \
96 false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
97 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
99 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
100 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
101 BUILT_IN_ ## ID ## L, BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, \
102 BUILT_IN_C ## ID, BUILT_IN_C ## ID ## L, BUILT_IN_C ## ID ## L, true, \
103 true, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
104 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
106 #define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
107 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
108 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
109 true, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
110 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
112 #define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
113 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
114 END_BUILTINS, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
115 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
116 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
118 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
120 /* Functions built into gcc itself. */
121 #include "mathbuiltins.def"
123 /* Functions in libm. */
124 /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
125 pattern for other mathbuiltins.def entries. At present we have no
126 optimizations for this in the common sources. */
127 LIBM_FUNCTION (SCALE, "scalbn", false),
129 /* Functions in libgfortran. */
130 LIBF_FUNCTION (FRACTION, "fraction", false),
131 LIBF_FUNCTION (NEAREST, "nearest", false),
132 LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
134 /* End the list. */
135 LIBF_FUNCTION (NONE, NULL, false)
137 #undef DEFINE_MATH_BUILTIN
138 #undef DEFINE_MATH_BUILTIN_C
139 #undef LIBM_FUNCTION
140 #undef LIBF_FUNCTION
142 /* Structure for storing components of a floating number to be used by
143 elemental functions to manipulate reals. */
144 typedef struct
146 tree arg; /* Variable tree to view convert to integer. */
147 tree expn; /* Variable tree to save exponent. */
148 tree frac; /* Variable tree to save fraction. */
149 tree smask; /* Constant tree of sign's mask. */
150 tree emask; /* Constant tree of exponent's mask. */
151 tree fmask; /* Constant tree of fraction's mask. */
152 tree edigits; /* Constant tree of the number of exponent bits. */
153 tree fdigits; /* Constant tree of the number of fraction bits. */
154 tree f1; /* Constant tree of the f1 defined in the real model. */
155 tree bias; /* Constant tree of the bias of exponent in the memory. */
156 tree type; /* Type tree of arg1. */
157 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
159 real_compnt_info;
162 /* Evaluate the arguments to an intrinsic function. */
164 static tree
165 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
167 gfc_actual_arglist *actual;
168 tree args;
169 gfc_se argse;
171 args = NULL_TREE;
172 for (actual = expr->value.function.actual; actual; actual = actual->next)
174 /* Skip omitted optional arguments. */
175 if (!actual->expr)
176 continue;
178 /* Evaluate the parameter. This will substitute scalarized
179 references automatically. */
180 gfc_init_se (&argse, se);
182 if (actual->expr->ts.type == BT_CHARACTER)
184 gfc_conv_expr (&argse, actual->expr);
185 gfc_conv_string_parameter (&argse);
186 args = gfc_chainon_list (args, argse.string_length);
188 else
189 gfc_conv_expr_val (&argse, actual->expr);
191 gfc_add_block_to_block (&se->pre, &argse.pre);
192 gfc_add_block_to_block (&se->post, &argse.post);
193 args = gfc_chainon_list (args, argse.expr);
195 return args;
199 /* Conversions between different types are output by the frontend as
200 intrinsic functions. We implement these directly with inline code. */
202 static void
203 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
205 tree type;
206 tree arg;
208 /* Evaluate the argument. */
209 type = gfc_typenode_for_spec (&expr->ts);
210 gcc_assert (expr->value.function.actual->expr);
211 arg = gfc_conv_intrinsic_function_args (se, expr);
212 arg = TREE_VALUE (arg);
214 /* Conversion from complex to non-complex involves taking the real
215 component of the value. */
216 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
217 && expr->ts.type != BT_COMPLEX)
219 tree artype;
221 artype = TREE_TYPE (TREE_TYPE (arg));
222 arg = build1 (REALPART_EXPR, artype, arg);
225 se->expr = convert (type, arg);
228 /* This is needed because the gcc backend only implements
229 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
230 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
231 Similarly for CEILING. */
233 static tree
234 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
236 tree tmp;
237 tree cond;
238 tree argtype;
239 tree intval;
241 argtype = TREE_TYPE (arg);
242 arg = gfc_evaluate_now (arg, pblock);
244 intval = convert (type, arg);
245 intval = gfc_evaluate_now (intval, pblock);
247 tmp = convert (argtype, intval);
248 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
250 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
251 build_int_cst (type, 1));
252 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
253 return tmp;
257 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
258 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
260 static tree
261 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
263 tree tmp;
264 tree cond;
265 tree neg;
266 tree pos;
267 tree argtype;
268 REAL_VALUE_TYPE r;
270 argtype = TREE_TYPE (arg);
271 arg = gfc_evaluate_now (arg, pblock);
273 real_from_string (&r, "0.5");
274 pos = build_real (argtype, r);
276 real_from_string (&r, "-0.5");
277 neg = build_real (argtype, r);
279 tmp = gfc_build_const (argtype, integer_zero_node);
280 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
282 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
283 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
284 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
288 /* Convert a real to an integer using a specific rounding mode.
289 Ideally we would just build the corresponding GENERIC node,
290 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
292 static tree
293 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
294 enum tree_code op)
296 switch (op)
298 case FIX_FLOOR_EXPR:
299 return build_fixbound_expr (pblock, arg, type, 0);
300 break;
302 case FIX_CEIL_EXPR:
303 return build_fixbound_expr (pblock, arg, type, 1);
304 break;
306 case FIX_ROUND_EXPR:
307 return build_round_expr (pblock, arg, type);
309 default:
310 return build1 (op, type, arg);
315 /* Round a real value using the specified rounding mode.
316 We use a temporary integer of that same kind size as the result.
317 Values larger than those that can be represented by this kind are
318 unchanged, as thay will not be accurate enough to represent the
319 rounding.
320 huge = HUGE (KIND (a))
321 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
324 static void
325 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum tree_code op)
327 tree type;
328 tree itype;
329 tree arg;
330 tree tmp;
331 tree cond;
332 mpfr_t huge;
333 int n;
334 int kind;
336 kind = expr->ts.kind;
338 n = END_BUILTINS;
339 /* We have builtin functions for some cases. */
340 switch (op)
342 case FIX_ROUND_EXPR:
343 switch (kind)
345 case 4:
346 n = BUILT_IN_ROUNDF;
347 break;
349 case 8:
350 n = BUILT_IN_ROUND;
351 break;
353 case 10:
354 case 16:
355 n = BUILT_IN_ROUNDL;
356 break;
358 break;
360 case FIX_TRUNC_EXPR:
361 switch (kind)
363 case 4:
364 n = BUILT_IN_TRUNCF;
365 break;
367 case 8:
368 n = BUILT_IN_TRUNC;
369 break;
371 case 10:
372 case 16:
373 n = BUILT_IN_TRUNCL;
374 break;
376 break;
378 default:
379 gcc_unreachable ();
382 /* Evaluate the argument. */
383 gcc_assert (expr->value.function.actual->expr);
384 arg = gfc_conv_intrinsic_function_args (se, expr);
386 /* Use a builtin function if one exists. */
387 if (n != END_BUILTINS)
389 tmp = built_in_decls[n];
390 se->expr = build_function_call_expr (tmp, arg);
391 return;
394 /* This code is probably redundant, but we'll keep it lying around just
395 in case. */
396 type = gfc_typenode_for_spec (&expr->ts);
397 arg = TREE_VALUE (arg);
398 arg = gfc_evaluate_now (arg, &se->pre);
400 /* Test if the value is too large to handle sensibly. */
401 gfc_set_model_kind (kind);
402 mpfr_init (huge);
403 n = gfc_validate_kind (BT_INTEGER, kind, false);
404 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
405 tmp = gfc_conv_mpfr_to_tree (huge, kind);
406 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
408 mpfr_neg (huge, huge, GFC_RND_MODE);
409 tmp = gfc_conv_mpfr_to_tree (huge, kind);
410 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
411 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
412 itype = gfc_get_int_type (kind);
414 tmp = build_fix_expr (&se->pre, arg, itype, op);
415 tmp = convert (type, tmp);
416 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
417 mpfr_clear (huge);
421 /* Convert to an integer using the specified rounding mode. */
423 static void
424 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
426 tree type;
427 tree arg;
429 /* Evaluate the argument. */
430 type = gfc_typenode_for_spec (&expr->ts);
431 gcc_assert (expr->value.function.actual->expr);
432 arg = gfc_conv_intrinsic_function_args (se, expr);
433 arg = TREE_VALUE (arg);
435 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
437 /* Conversion to a different integer kind. */
438 se->expr = convert (type, arg);
440 else
442 /* Conversion from complex to non-complex involves taking the real
443 component of the value. */
444 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
445 && expr->ts.type != BT_COMPLEX)
447 tree artype;
449 artype = TREE_TYPE (TREE_TYPE (arg));
450 arg = build1 (REALPART_EXPR, artype, arg);
453 se->expr = build_fix_expr (&se->pre, arg, type, op);
458 /* Get the imaginary component of a value. */
460 static void
461 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
463 tree arg;
465 arg = gfc_conv_intrinsic_function_args (se, expr);
466 arg = TREE_VALUE (arg);
467 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
471 /* Get the complex conjugate of a value. */
473 static void
474 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
476 tree arg;
478 arg = gfc_conv_intrinsic_function_args (se, expr);
479 arg = TREE_VALUE (arg);
480 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
484 /* Initialize function decls for library functions. The external functions
485 are created as required. Builtin functions are added here. */
487 void
488 gfc_build_intrinsic_lib_fndecls (void)
490 gfc_intrinsic_map_t *m;
492 /* Add GCC builtin functions. */
493 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
495 if (m->code_r4 != END_BUILTINS)
496 m->real4_decl = built_in_decls[m->code_r4];
497 if (m->code_r8 != END_BUILTINS)
498 m->real8_decl = built_in_decls[m->code_r8];
499 if (m->code_r10 != END_BUILTINS)
500 m->real10_decl = built_in_decls[m->code_r10];
501 if (m->code_r16 != END_BUILTINS)
502 m->real16_decl = built_in_decls[m->code_r16];
503 if (m->code_c4 != END_BUILTINS)
504 m->complex4_decl = built_in_decls[m->code_c4];
505 if (m->code_c8 != END_BUILTINS)
506 m->complex8_decl = built_in_decls[m->code_c8];
507 if (m->code_c10 != END_BUILTINS)
508 m->complex10_decl = built_in_decls[m->code_c10];
509 if (m->code_c16 != END_BUILTINS)
510 m->complex16_decl = built_in_decls[m->code_c16];
515 /* Create a fndecl for a simple intrinsic library function. */
517 static tree
518 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
520 tree type;
521 tree argtypes;
522 tree fndecl;
523 gfc_actual_arglist *actual;
524 tree *pdecl;
525 gfc_typespec *ts;
526 char name[GFC_MAX_SYMBOL_LEN + 3];
528 ts = &expr->ts;
529 if (ts->type == BT_REAL)
531 switch (ts->kind)
533 case 4:
534 pdecl = &m->real4_decl;
535 break;
536 case 8:
537 pdecl = &m->real8_decl;
538 break;
539 case 10:
540 pdecl = &m->real10_decl;
541 break;
542 case 16:
543 pdecl = &m->real16_decl;
544 break;
545 default:
546 gcc_unreachable ();
549 else if (ts->type == BT_COMPLEX)
551 gcc_assert (m->complex_available);
553 switch (ts->kind)
555 case 4:
556 pdecl = &m->complex4_decl;
557 break;
558 case 8:
559 pdecl = &m->complex8_decl;
560 break;
561 case 10:
562 pdecl = &m->complex10_decl;
563 break;
564 case 16:
565 pdecl = &m->complex16_decl;
566 break;
567 default:
568 gcc_unreachable ();
571 else
572 gcc_unreachable ();
574 if (*pdecl)
575 return *pdecl;
577 if (m->libm_name)
579 gcc_assert (ts->kind == 4 || ts->kind == 8 || ts->kind == 10
580 || ts->kind == 16);
581 snprintf (name, sizeof (name), "%s%s%s",
582 ts->type == BT_COMPLEX ? "c" : "",
583 m->name,
584 ts->kind == 4 ? "f" : "");
586 else
588 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
589 ts->type == BT_COMPLEX ? 'c' : 'r',
590 ts->kind);
593 argtypes = NULL_TREE;
594 for (actual = expr->value.function.actual; actual; actual = actual->next)
596 type = gfc_typenode_for_spec (&actual->expr->ts);
597 argtypes = gfc_chainon_list (argtypes, type);
599 argtypes = gfc_chainon_list (argtypes, void_type_node);
600 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
601 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
603 /* Mark the decl as external. */
604 DECL_EXTERNAL (fndecl) = 1;
605 TREE_PUBLIC (fndecl) = 1;
607 /* Mark it __attribute__((const)), if possible. */
608 TREE_READONLY (fndecl) = m->is_constant;
610 rest_of_decl_compilation (fndecl, 1, 0);
612 (*pdecl) = fndecl;
613 return fndecl;
617 /* Convert an intrinsic function into an external or builtin call. */
619 static void
620 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
622 gfc_intrinsic_map_t *m;
623 tree args;
624 tree fndecl;
625 gfc_generic_isym_id id;
627 id = expr->value.function.isym->generic_id;
628 /* Find the entry for this function. */
629 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
631 if (id == m->id)
632 break;
635 if (m->id == GFC_ISYM_NONE)
637 internal_error ("Intrinsic function %s(%d) not recognized",
638 expr->value.function.name, id);
641 /* Get the decl and generate the call. */
642 args = gfc_conv_intrinsic_function_args (se, expr);
643 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
644 se->expr = build_function_call_expr (fndecl, args);
647 /* Generate code for EXPONENT(X) intrinsic function. */
649 static void
650 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
652 tree args, fndecl;
653 gfc_expr *a1;
655 args = gfc_conv_intrinsic_function_args (se, expr);
657 a1 = expr->value.function.actual->expr;
658 switch (a1->ts.kind)
660 case 4:
661 fndecl = gfor_fndecl_math_exponent4;
662 break;
663 case 8:
664 fndecl = gfor_fndecl_math_exponent8;
665 break;
666 case 10:
667 fndecl = gfor_fndecl_math_exponent10;
668 break;
669 case 16:
670 fndecl = gfor_fndecl_math_exponent16;
671 break;
672 default:
673 gcc_unreachable ();
676 se->expr = build_function_call_expr (fndecl, args);
679 /* Evaluate a single upper or lower bound. */
680 /* TODO: bound intrinsic generates way too much unnecessary code. */
682 static void
683 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
685 gfc_actual_arglist *arg;
686 gfc_actual_arglist *arg2;
687 tree desc;
688 tree type;
689 tree bound;
690 tree tmp;
691 tree cond;
692 gfc_se argse;
693 gfc_ss *ss;
694 int i;
696 arg = expr->value.function.actual;
697 arg2 = arg->next;
699 if (se->ss)
701 /* Create an implicit second parameter from the loop variable. */
702 gcc_assert (!arg2->expr);
703 gcc_assert (se->loop->dimen == 1);
704 gcc_assert (se->ss->expr == expr);
705 gfc_advance_se_ss_chain (se);
706 bound = se->loop->loopvar[0];
707 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
708 se->loop->from[0]);
710 else
712 /* use the passed argument. */
713 gcc_assert (arg->next->expr);
714 gfc_init_se (&argse, NULL);
715 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
716 gfc_add_block_to_block (&se->pre, &argse.pre);
717 bound = argse.expr;
718 /* Convert from one based to zero based. */
719 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
720 gfc_index_one_node);
723 /* TODO: don't re-evaluate the descriptor on each iteration. */
724 /* Get a descriptor for the first parameter. */
725 ss = gfc_walk_expr (arg->expr);
726 gcc_assert (ss != gfc_ss_terminator);
727 gfc_init_se (&argse, NULL);
728 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
729 gfc_add_block_to_block (&se->pre, &argse.pre);
730 gfc_add_block_to_block (&se->post, &argse.post);
732 desc = argse.expr;
734 if (INTEGER_CST_P (bound))
736 gcc_assert (TREE_INT_CST_HIGH (bound) == 0);
737 i = TREE_INT_CST_LOW (bound);
738 gcc_assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
740 else
742 if (flag_bounds_check)
744 bound = gfc_evaluate_now (bound, &se->pre);
745 cond = fold_build2 (LT_EXPR, boolean_type_node,
746 bound, build_int_cst (TREE_TYPE (bound), 0));
747 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
748 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
749 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
750 gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
754 if (upper)
755 se->expr = gfc_conv_descriptor_ubound(desc, bound);
756 else
757 se->expr = gfc_conv_descriptor_lbound(desc, bound);
759 type = gfc_typenode_for_spec (&expr->ts);
760 se->expr = convert (type, se->expr);
764 static void
765 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
767 tree args;
768 tree val;
769 int n;
771 args = gfc_conv_intrinsic_function_args (se, expr);
772 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
773 val = TREE_VALUE (args);
775 switch (expr->value.function.actual->expr->ts.type)
777 case BT_INTEGER:
778 case BT_REAL:
779 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
780 break;
782 case BT_COMPLEX:
783 switch (expr->ts.kind)
785 case 4:
786 n = BUILT_IN_CABSF;
787 break;
788 case 8:
789 n = BUILT_IN_CABS;
790 break;
791 case 10:
792 case 16:
793 n = BUILT_IN_CABSL;
794 break;
795 default:
796 gcc_unreachable ();
798 se->expr = build_function_call_expr (built_in_decls[n], args);
799 break;
801 default:
802 gcc_unreachable ();
807 /* Create a complex value from one or two real components. */
809 static void
810 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
812 tree arg;
813 tree real;
814 tree imag;
815 tree type;
817 type = gfc_typenode_for_spec (&expr->ts);
818 arg = gfc_conv_intrinsic_function_args (se, expr);
819 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
820 if (both)
821 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
822 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
824 arg = TREE_VALUE (arg);
825 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
826 imag = convert (TREE_TYPE (type), imag);
828 else
829 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
831 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
834 /* Remainder function MOD(A, P) = A - INT(A / P) * P
835 MODULO(A, P) = A - FLOOR (A / P) * P */
836 /* TODO: MOD(x, 0) */
838 static void
839 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
841 tree arg;
842 tree arg2;
843 tree type;
844 tree itype;
845 tree tmp;
846 tree test;
847 tree test2;
848 mpfr_t huge;
849 int n;
851 arg = gfc_conv_intrinsic_function_args (se, expr);
852 arg2 = TREE_VALUE (TREE_CHAIN (arg));
853 arg = TREE_VALUE (arg);
854 type = TREE_TYPE (arg);
856 switch (expr->ts.type)
858 case BT_INTEGER:
859 /* Integer case is easy, we've got a builtin op. */
860 if (modulo)
861 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
862 else
863 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
864 break;
866 case BT_REAL:
867 /* Real values we have to do the hard way. */
868 arg = gfc_evaluate_now (arg, &se->pre);
869 arg2 = gfc_evaluate_now (arg2, &se->pre);
871 tmp = build2 (RDIV_EXPR, type, arg, arg2);
872 /* Test if the value is too large to handle sensibly. */
873 gfc_set_model_kind (expr->ts.kind);
874 mpfr_init (huge);
875 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, false);
876 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
877 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
878 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
880 mpfr_neg (huge, huge, GFC_RND_MODE);
881 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
882 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
883 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
885 itype = gfc_get_int_type (expr->ts.kind);
886 if (modulo)
887 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_FLOOR_EXPR);
888 else
889 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
890 tmp = convert (type, tmp);
891 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
892 tmp = build2 (MULT_EXPR, type, tmp, arg2);
893 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
894 mpfr_clear (huge);
895 break;
897 default:
898 gcc_unreachable ();
902 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
904 static void
905 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
907 tree arg;
908 tree arg2;
909 tree val;
910 tree tmp;
911 tree type;
912 tree zero;
914 arg = gfc_conv_intrinsic_function_args (se, expr);
915 arg2 = TREE_VALUE (TREE_CHAIN (arg));
916 arg = TREE_VALUE (arg);
917 type = TREE_TYPE (arg);
919 val = build2 (MINUS_EXPR, type, arg, arg2);
920 val = gfc_evaluate_now (val, &se->pre);
922 zero = gfc_build_const (type, integer_zero_node);
923 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
924 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
928 /* SIGN(A, B) is absolute value of A times sign of B.
929 The real value versions use library functions to ensure the correct
930 handling of negative zero. Integer case implemented as:
931 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
934 static void
935 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
937 tree tmp;
938 tree arg;
939 tree arg2;
940 tree type;
941 tree zero;
942 tree testa;
943 tree testb;
946 arg = gfc_conv_intrinsic_function_args (se, expr);
947 if (expr->ts.type == BT_REAL)
949 switch (expr->ts.kind)
951 case 4:
952 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
953 break;
954 case 8:
955 tmp = built_in_decls[BUILT_IN_COPYSIGN];
956 break;
957 case 10:
958 case 16:
959 tmp = built_in_decls[BUILT_IN_COPYSIGNL];
960 break;
961 default:
962 gcc_unreachable ();
964 se->expr = build_function_call_expr (tmp, arg);
965 return;
968 arg2 = TREE_VALUE (TREE_CHAIN (arg));
969 arg = TREE_VALUE (arg);
970 type = TREE_TYPE (arg);
971 zero = gfc_build_const (type, integer_zero_node);
973 testa = fold_build2 (GE_EXPR, boolean_type_node, arg, zero);
974 testb = fold_build2 (GE_EXPR, boolean_type_node, arg2, zero);
975 tmp = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, testa, testb);
976 se->expr = fold_build3 (COND_EXPR, type, tmp,
977 build1 (NEGATE_EXPR, type, arg), arg);
981 /* Test for the presence of an optional argument. */
983 static void
984 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
986 gfc_expr *arg;
988 arg = expr->value.function.actual->expr;
989 gcc_assert (arg->expr_type == EXPR_VARIABLE);
990 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
991 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
995 /* Calculate the double precision product of two single precision values. */
997 static void
998 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1000 tree arg;
1001 tree arg2;
1002 tree type;
1004 arg = gfc_conv_intrinsic_function_args (se, expr);
1005 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1006 arg = TREE_VALUE (arg);
1008 /* Convert the args to double precision before multiplying. */
1009 type = gfc_typenode_for_spec (&expr->ts);
1010 arg = convert (type, arg);
1011 arg2 = convert (type, arg2);
1012 se->expr = build2 (MULT_EXPR, type, arg, arg2);
1016 /* Return a length one character string containing an ascii character. */
1018 static void
1019 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1021 tree arg;
1022 tree var;
1023 tree type;
1025 arg = gfc_conv_intrinsic_function_args (se, expr);
1026 arg = TREE_VALUE (arg);
1028 /* We currently don't support character types != 1. */
1029 gcc_assert (expr->ts.kind == 1);
1030 type = gfc_character1_type_node;
1031 var = gfc_create_var (type, "char");
1033 arg = convert (type, arg);
1034 gfc_add_modify_expr (&se->pre, var, arg);
1035 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1036 se->string_length = integer_one_node;
1040 static void
1041 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1043 tree var;
1044 tree len;
1045 tree tmp;
1046 tree arglist;
1047 tree type;
1048 tree cond;
1049 tree gfc_int8_type_node = gfc_get_int_type (8);
1051 type = build_pointer_type (gfc_character1_type_node);
1052 var = gfc_create_var (type, "pstr");
1053 len = gfc_create_var (gfc_int8_type_node, "len");
1055 tmp = gfc_conv_intrinsic_function_args (se, expr);
1056 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1057 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1058 arglist = chainon (arglist, tmp);
1060 tmp = build_function_call_expr (gfor_fndecl_ctime, arglist);
1061 gfc_add_expr_to_block (&se->pre, tmp);
1063 /* Free the temporary afterwards, if necessary. */
1064 cond = build2 (GT_EXPR, boolean_type_node, len,
1065 build_int_cst (TREE_TYPE (len), 0));
1066 arglist = gfc_chainon_list (NULL_TREE, var);
1067 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1068 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1069 gfc_add_expr_to_block (&se->post, tmp);
1071 se->expr = var;
1072 se->string_length = len;
1076 static void
1077 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1079 tree var;
1080 tree len;
1081 tree tmp;
1082 tree arglist;
1083 tree type;
1084 tree cond;
1085 tree gfc_int4_type_node = gfc_get_int_type (4);
1087 type = build_pointer_type (gfc_character1_type_node);
1088 var = gfc_create_var (type, "pstr");
1089 len = gfc_create_var (gfc_int4_type_node, "len");
1091 tmp = gfc_conv_intrinsic_function_args (se, expr);
1092 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1093 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1094 arglist = chainon (arglist, tmp);
1096 tmp = build_function_call_expr (gfor_fndecl_fdate, arglist);
1097 gfc_add_expr_to_block (&se->pre, tmp);
1099 /* Free the temporary afterwards, if necessary. */
1100 cond = build2 (GT_EXPR, boolean_type_node, len,
1101 build_int_cst (TREE_TYPE (len), 0));
1102 arglist = gfc_chainon_list (NULL_TREE, var);
1103 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1104 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1105 gfc_add_expr_to_block (&se->post, tmp);
1107 se->expr = var;
1108 se->string_length = len;
1112 /* Return a character string containing the tty name. */
1114 static void
1115 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1117 tree var;
1118 tree len;
1119 tree tmp;
1120 tree arglist;
1121 tree type;
1122 tree cond;
1123 tree gfc_int4_type_node = gfc_get_int_type (4);
1125 type = build_pointer_type (gfc_character1_type_node);
1126 var = gfc_create_var (type, "pstr");
1127 len = gfc_create_var (gfc_int4_type_node, "len");
1129 tmp = gfc_conv_intrinsic_function_args (se, expr);
1130 arglist = gfc_chainon_list (NULL_TREE, build_fold_addr_expr (var));
1131 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
1132 arglist = chainon (arglist, tmp);
1134 tmp = build_function_call_expr (gfor_fndecl_ttynam, arglist);
1135 gfc_add_expr_to_block (&se->pre, tmp);
1137 /* Free the temporary afterwards, if necessary. */
1138 cond = build2 (GT_EXPR, boolean_type_node, len,
1139 build_int_cst (TREE_TYPE (len), 0));
1140 arglist = gfc_chainon_list (NULL_TREE, var);
1141 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
1142 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
1143 gfc_add_expr_to_block (&se->post, tmp);
1145 se->expr = var;
1146 se->string_length = len;
1150 /* Get the minimum/maximum value of all the parameters.
1151 minmax (a1, a2, a3, ...)
1153 if (a2 .op. a1)
1154 mvar = a2;
1155 else
1156 mvar = a1;
1157 if (a3 .op. mvar)
1158 mvar = a3;
1160 return mvar
1164 /* TODO: Mismatching types can occur when specific names are used.
1165 These should be handled during resolution. */
1166 static void
1167 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1169 tree limit;
1170 tree tmp;
1171 tree mvar;
1172 tree val;
1173 tree thencase;
1174 tree elsecase;
1175 tree arg;
1176 tree type;
1178 arg = gfc_conv_intrinsic_function_args (se, expr);
1179 type = gfc_typenode_for_spec (&expr->ts);
1181 limit = TREE_VALUE (arg);
1182 if (TREE_TYPE (limit) != type)
1183 limit = convert (type, limit);
1184 /* Only evaluate the argument once. */
1185 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1186 limit = gfc_evaluate_now(limit, &se->pre);
1188 mvar = gfc_create_var (type, "M");
1189 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1190 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1192 val = TREE_VALUE (arg);
1193 if (TREE_TYPE (val) != type)
1194 val = convert (type, val);
1196 /* Only evaluate the argument once. */
1197 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1198 val = gfc_evaluate_now(val, &se->pre);
1200 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1202 tmp = build2 (op, boolean_type_node, val, limit);
1203 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1204 gfc_add_expr_to_block (&se->pre, tmp);
1205 elsecase = build_empty_stmt ();
1206 limit = mvar;
1208 se->expr = mvar;
1212 /* Create a symbol node for this intrinsic. The symbol from the frontend
1213 has the generic name. */
1215 static gfc_symbol *
1216 gfc_get_symbol_for_expr (gfc_expr * expr)
1218 gfc_symbol *sym;
1220 /* TODO: Add symbols for intrinsic function to the global namespace. */
1221 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1222 sym = gfc_new_symbol (expr->value.function.name, NULL);
1224 sym->ts = expr->ts;
1225 sym->attr.external = 1;
1226 sym->attr.function = 1;
1227 sym->attr.always_explicit = 1;
1228 sym->attr.proc = PROC_INTRINSIC;
1229 sym->attr.flavor = FL_PROCEDURE;
1230 sym->result = sym;
1231 if (expr->rank > 0)
1233 sym->attr.dimension = 1;
1234 sym->as = gfc_get_array_spec ();
1235 sym->as->type = AS_ASSUMED_SHAPE;
1236 sym->as->rank = expr->rank;
1239 /* TODO: proper argument lists for external intrinsics. */
1240 return sym;
1243 /* Generate a call to an external intrinsic function. */
1244 static void
1245 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1247 gfc_symbol *sym;
1249 gcc_assert (!se->ss || se->ss->expr == expr);
1251 if (se->ss)
1252 gcc_assert (expr->rank > 0);
1253 else
1254 gcc_assert (expr->rank == 0);
1256 sym = gfc_get_symbol_for_expr (expr);
1257 gfc_conv_function_call (se, sym, expr->value.function.actual);
1258 gfc_free (sym);
1261 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1262 Implemented as
1263 any(a)
1265 forall (i=...)
1266 if (a[i] != 0)
1267 return 1
1268 end forall
1269 return 0
1271 all(a)
1273 forall (i=...)
1274 if (a[i] == 0)
1275 return 0
1276 end forall
1277 return 1
1280 static void
1281 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1283 tree resvar;
1284 stmtblock_t block;
1285 stmtblock_t body;
1286 tree type;
1287 tree tmp;
1288 tree found;
1289 gfc_loopinfo loop;
1290 gfc_actual_arglist *actual;
1291 gfc_ss *arrayss;
1292 gfc_se arrayse;
1293 tree exit_label;
1295 if (se->ss)
1297 gfc_conv_intrinsic_funcall (se, expr);
1298 return;
1301 actual = expr->value.function.actual;
1302 type = gfc_typenode_for_spec (&expr->ts);
1303 /* Initialize the result. */
1304 resvar = gfc_create_var (type, "test");
1305 if (op == EQ_EXPR)
1306 tmp = convert (type, boolean_true_node);
1307 else
1308 tmp = convert (type, boolean_false_node);
1309 gfc_add_modify_expr (&se->pre, resvar, tmp);
1311 /* Walk the arguments. */
1312 arrayss = gfc_walk_expr (actual->expr);
1313 gcc_assert (arrayss != gfc_ss_terminator);
1315 /* Initialize the scalarizer. */
1316 gfc_init_loopinfo (&loop);
1317 exit_label = gfc_build_label_decl (NULL_TREE);
1318 TREE_USED (exit_label) = 1;
1319 gfc_add_ss_to_loop (&loop, arrayss);
1321 /* Initialize the loop. */
1322 gfc_conv_ss_startstride (&loop);
1323 gfc_conv_loop_setup (&loop);
1325 gfc_mark_ss_chain_used (arrayss, 1);
1326 /* Generate the loop body. */
1327 gfc_start_scalarized_body (&loop, &body);
1329 /* If the condition matches then set the return value. */
1330 gfc_start_block (&block);
1331 if (op == EQ_EXPR)
1332 tmp = convert (type, boolean_false_node);
1333 else
1334 tmp = convert (type, boolean_true_node);
1335 gfc_add_modify_expr (&block, resvar, tmp);
1337 /* And break out of the loop. */
1338 tmp = build1_v (GOTO_EXPR, exit_label);
1339 gfc_add_expr_to_block (&block, tmp);
1341 found = gfc_finish_block (&block);
1343 /* Check this element. */
1344 gfc_init_se (&arrayse, NULL);
1345 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1346 arrayse.ss = arrayss;
1347 gfc_conv_expr_val (&arrayse, actual->expr);
1349 gfc_add_block_to_block (&body, &arrayse.pre);
1350 tmp = build2 (op, boolean_type_node, arrayse.expr,
1351 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1352 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1353 gfc_add_expr_to_block (&body, tmp);
1354 gfc_add_block_to_block (&body, &arrayse.post);
1356 gfc_trans_scalarizing_loops (&loop, &body);
1358 /* Add the exit label. */
1359 tmp = build1_v (LABEL_EXPR, exit_label);
1360 gfc_add_expr_to_block (&loop.pre, tmp);
1362 gfc_add_block_to_block (&se->pre, &loop.pre);
1363 gfc_add_block_to_block (&se->pre, &loop.post);
1364 gfc_cleanup_loop (&loop);
1366 se->expr = resvar;
1369 /* COUNT(A) = Number of true elements in A. */
1370 static void
1371 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1373 tree resvar;
1374 tree type;
1375 stmtblock_t body;
1376 tree tmp;
1377 gfc_loopinfo loop;
1378 gfc_actual_arglist *actual;
1379 gfc_ss *arrayss;
1380 gfc_se arrayse;
1382 if (se->ss)
1384 gfc_conv_intrinsic_funcall (se, expr);
1385 return;
1388 actual = expr->value.function.actual;
1390 type = gfc_typenode_for_spec (&expr->ts);
1391 /* Initialize the result. */
1392 resvar = gfc_create_var (type, "count");
1393 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1395 /* Walk the arguments. */
1396 arrayss = gfc_walk_expr (actual->expr);
1397 gcc_assert (arrayss != gfc_ss_terminator);
1399 /* Initialize the scalarizer. */
1400 gfc_init_loopinfo (&loop);
1401 gfc_add_ss_to_loop (&loop, arrayss);
1403 /* Initialize the loop. */
1404 gfc_conv_ss_startstride (&loop);
1405 gfc_conv_loop_setup (&loop);
1407 gfc_mark_ss_chain_used (arrayss, 1);
1408 /* Generate the loop body. */
1409 gfc_start_scalarized_body (&loop, &body);
1411 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1412 build_int_cst (TREE_TYPE (resvar), 1));
1413 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1415 gfc_init_se (&arrayse, NULL);
1416 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1417 arrayse.ss = arrayss;
1418 gfc_conv_expr_val (&arrayse, actual->expr);
1419 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1421 gfc_add_block_to_block (&body, &arrayse.pre);
1422 gfc_add_expr_to_block (&body, tmp);
1423 gfc_add_block_to_block (&body, &arrayse.post);
1425 gfc_trans_scalarizing_loops (&loop, &body);
1427 gfc_add_block_to_block (&se->pre, &loop.pre);
1428 gfc_add_block_to_block (&se->pre, &loop.post);
1429 gfc_cleanup_loop (&loop);
1431 se->expr = resvar;
1434 /* Inline implementation of the sum and product intrinsics. */
1435 static void
1436 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1438 tree resvar;
1439 tree type;
1440 stmtblock_t body;
1441 stmtblock_t block;
1442 tree tmp;
1443 gfc_loopinfo loop;
1444 gfc_actual_arglist *actual;
1445 gfc_ss *arrayss;
1446 gfc_ss *maskss;
1447 gfc_se arrayse;
1448 gfc_se maskse;
1449 gfc_expr *arrayexpr;
1450 gfc_expr *maskexpr;
1452 if (se->ss)
1454 gfc_conv_intrinsic_funcall (se, expr);
1455 return;
1458 type = gfc_typenode_for_spec (&expr->ts);
1459 /* Initialize the result. */
1460 resvar = gfc_create_var (type, "val");
1461 if (op == PLUS_EXPR)
1462 tmp = gfc_build_const (type, integer_zero_node);
1463 else
1464 tmp = gfc_build_const (type, integer_one_node);
1466 gfc_add_modify_expr (&se->pre, resvar, tmp);
1468 /* Walk the arguments. */
1469 actual = expr->value.function.actual;
1470 arrayexpr = actual->expr;
1471 arrayss = gfc_walk_expr (arrayexpr);
1472 gcc_assert (arrayss != gfc_ss_terminator);
1474 actual = actual->next->next;
1475 gcc_assert (actual);
1476 maskexpr = actual->expr;
1477 if (maskexpr)
1479 maskss = gfc_walk_expr (maskexpr);
1480 gcc_assert (maskss != gfc_ss_terminator);
1482 else
1483 maskss = NULL;
1485 /* Initialize the scalarizer. */
1486 gfc_init_loopinfo (&loop);
1487 gfc_add_ss_to_loop (&loop, arrayss);
1488 if (maskss)
1489 gfc_add_ss_to_loop (&loop, maskss);
1491 /* Initialize the loop. */
1492 gfc_conv_ss_startstride (&loop);
1493 gfc_conv_loop_setup (&loop);
1495 gfc_mark_ss_chain_used (arrayss, 1);
1496 if (maskss)
1497 gfc_mark_ss_chain_used (maskss, 1);
1498 /* Generate the loop body. */
1499 gfc_start_scalarized_body (&loop, &body);
1501 /* If we have a mask, only add this element if the mask is set. */
1502 if (maskss)
1504 gfc_init_se (&maskse, NULL);
1505 gfc_copy_loopinfo_to_se (&maskse, &loop);
1506 maskse.ss = maskss;
1507 gfc_conv_expr_val (&maskse, maskexpr);
1508 gfc_add_block_to_block (&body, &maskse.pre);
1510 gfc_start_block (&block);
1512 else
1513 gfc_init_block (&block);
1515 /* Do the actual summation/product. */
1516 gfc_init_se (&arrayse, NULL);
1517 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1518 arrayse.ss = arrayss;
1519 gfc_conv_expr_val (&arrayse, arrayexpr);
1520 gfc_add_block_to_block (&block, &arrayse.pre);
1522 tmp = build2 (op, type, resvar, arrayse.expr);
1523 gfc_add_modify_expr (&block, resvar, tmp);
1524 gfc_add_block_to_block (&block, &arrayse.post);
1526 if (maskss)
1528 /* We enclose the above in if (mask) {...} . */
1529 tmp = gfc_finish_block (&block);
1531 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1533 else
1534 tmp = gfc_finish_block (&block);
1535 gfc_add_expr_to_block (&body, tmp);
1537 gfc_trans_scalarizing_loops (&loop, &body);
1538 gfc_add_block_to_block (&se->pre, &loop.pre);
1539 gfc_add_block_to_block (&se->pre, &loop.post);
1540 gfc_cleanup_loop (&loop);
1542 se->expr = resvar;
1545 static void
1546 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1548 stmtblock_t body;
1549 stmtblock_t block;
1550 stmtblock_t ifblock;
1551 tree limit;
1552 tree type;
1553 tree tmp;
1554 tree ifbody;
1555 tree cond;
1556 gfc_loopinfo loop;
1557 gfc_actual_arglist *actual;
1558 gfc_ss *arrayss;
1559 gfc_ss *maskss;
1560 gfc_se arrayse;
1561 gfc_se maskse;
1562 gfc_expr *arrayexpr;
1563 gfc_expr *maskexpr;
1564 tree pos;
1565 int n;
1567 if (se->ss)
1569 gfc_conv_intrinsic_funcall (se, expr);
1570 return;
1573 /* Initialize the result. */
1574 pos = gfc_create_var (gfc_array_index_type, "pos");
1575 type = gfc_typenode_for_spec (&expr->ts);
1577 /* Walk the arguments. */
1578 actual = expr->value.function.actual;
1579 arrayexpr = actual->expr;
1580 arrayss = gfc_walk_expr (arrayexpr);
1581 gcc_assert (arrayss != gfc_ss_terminator);
1583 actual = actual->next->next;
1584 gcc_assert (actual);
1585 maskexpr = actual->expr;
1586 if (maskexpr)
1588 maskss = gfc_walk_expr (maskexpr);
1589 gcc_assert (maskss != gfc_ss_terminator);
1591 else
1592 maskss = NULL;
1594 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1595 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1596 switch (arrayexpr->ts.type)
1598 case BT_REAL:
1599 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1600 break;
1602 case BT_INTEGER:
1603 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1604 arrayexpr->ts.kind);
1605 break;
1607 default:
1608 gcc_unreachable ();
1611 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1612 if (op == GT_EXPR)
1613 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1614 gfc_add_modify_expr (&se->pre, limit, tmp);
1616 /* Initialize the scalarizer. */
1617 gfc_init_loopinfo (&loop);
1618 gfc_add_ss_to_loop (&loop, arrayss);
1619 if (maskss)
1620 gfc_add_ss_to_loop (&loop, maskss);
1622 /* Initialize the loop. */
1623 gfc_conv_ss_startstride (&loop);
1624 gfc_conv_loop_setup (&loop);
1626 gcc_assert (loop.dimen == 1);
1628 /* Initialize the position to the first element. If the array has zero
1629 size we need to return zero. Otherwise use the first element of the
1630 array, in case all elements are equal to the limit.
1631 i.e. pos = (ubound >= lbound) ? lbound, lbound - 1; */
1632 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1633 loop.from[0], gfc_index_one_node);
1634 cond = fold_build2 (GE_EXPR, boolean_type_node,
1635 loop.to[0], loop.from[0]);
1636 tmp = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
1637 loop.from[0], tmp);
1638 gfc_add_modify_expr (&loop.pre, pos, tmp);
1640 gfc_mark_ss_chain_used (arrayss, 1);
1641 if (maskss)
1642 gfc_mark_ss_chain_used (maskss, 1);
1643 /* Generate the loop body. */
1644 gfc_start_scalarized_body (&loop, &body);
1646 /* If we have a mask, only check this element if the mask is set. */
1647 if (maskss)
1649 gfc_init_se (&maskse, NULL);
1650 gfc_copy_loopinfo_to_se (&maskse, &loop);
1651 maskse.ss = maskss;
1652 gfc_conv_expr_val (&maskse, maskexpr);
1653 gfc_add_block_to_block (&body, &maskse.pre);
1655 gfc_start_block (&block);
1657 else
1658 gfc_init_block (&block);
1660 /* Compare with the current limit. */
1661 gfc_init_se (&arrayse, NULL);
1662 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1663 arrayse.ss = arrayss;
1664 gfc_conv_expr_val (&arrayse, arrayexpr);
1665 gfc_add_block_to_block (&block, &arrayse.pre);
1667 /* We do the following if this is a more extreme value. */
1668 gfc_start_block (&ifblock);
1670 /* Assign the value to the limit... */
1671 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1673 /* Remember where we are. */
1674 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1676 ifbody = gfc_finish_block (&ifblock);
1678 /* If it is a more extreme value. */
1679 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
1680 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1681 gfc_add_expr_to_block (&block, tmp);
1683 if (maskss)
1685 /* We enclose the above in if (mask) {...}. */
1686 tmp = gfc_finish_block (&block);
1688 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1690 else
1691 tmp = gfc_finish_block (&block);
1692 gfc_add_expr_to_block (&body, tmp);
1694 gfc_trans_scalarizing_loops (&loop, &body);
1696 gfc_add_block_to_block (&se->pre, &loop.pre);
1697 gfc_add_block_to_block (&se->pre, &loop.post);
1698 gfc_cleanup_loop (&loop);
1700 /* Return a value in the range 1..SIZE(array). */
1701 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1702 gfc_index_one_node);
1703 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
1704 /* And convert to the required type. */
1705 se->expr = convert (type, tmp);
1708 static void
1709 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1711 tree limit;
1712 tree type;
1713 tree tmp;
1714 tree ifbody;
1715 stmtblock_t body;
1716 stmtblock_t block;
1717 gfc_loopinfo loop;
1718 gfc_actual_arglist *actual;
1719 gfc_ss *arrayss;
1720 gfc_ss *maskss;
1721 gfc_se arrayse;
1722 gfc_se maskse;
1723 gfc_expr *arrayexpr;
1724 gfc_expr *maskexpr;
1725 int n;
1727 if (se->ss)
1729 gfc_conv_intrinsic_funcall (se, expr);
1730 return;
1733 type = gfc_typenode_for_spec (&expr->ts);
1734 /* Initialize the result. */
1735 limit = gfc_create_var (type, "limit");
1736 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
1737 switch (expr->ts.type)
1739 case BT_REAL:
1740 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1741 break;
1743 case BT_INTEGER:
1744 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1745 break;
1747 default:
1748 gcc_unreachable ();
1751 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1752 if (op == GT_EXPR)
1753 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1754 gfc_add_modify_expr (&se->pre, limit, tmp);
1756 /* Walk the arguments. */
1757 actual = expr->value.function.actual;
1758 arrayexpr = actual->expr;
1759 arrayss = gfc_walk_expr (arrayexpr);
1760 gcc_assert (arrayss != gfc_ss_terminator);
1762 actual = actual->next->next;
1763 gcc_assert (actual);
1764 maskexpr = actual->expr;
1765 if (maskexpr)
1767 maskss = gfc_walk_expr (maskexpr);
1768 gcc_assert (maskss != gfc_ss_terminator);
1770 else
1771 maskss = NULL;
1773 /* Initialize the scalarizer. */
1774 gfc_init_loopinfo (&loop);
1775 gfc_add_ss_to_loop (&loop, arrayss);
1776 if (maskss)
1777 gfc_add_ss_to_loop (&loop, maskss);
1779 /* Initialize the loop. */
1780 gfc_conv_ss_startstride (&loop);
1781 gfc_conv_loop_setup (&loop);
1783 gfc_mark_ss_chain_used (arrayss, 1);
1784 if (maskss)
1785 gfc_mark_ss_chain_used (maskss, 1);
1786 /* Generate the loop body. */
1787 gfc_start_scalarized_body (&loop, &body);
1789 /* If we have a mask, only add this element if the mask is set. */
1790 if (maskss)
1792 gfc_init_se (&maskse, NULL);
1793 gfc_copy_loopinfo_to_se (&maskse, &loop);
1794 maskse.ss = maskss;
1795 gfc_conv_expr_val (&maskse, maskexpr);
1796 gfc_add_block_to_block (&body, &maskse.pre);
1798 gfc_start_block (&block);
1800 else
1801 gfc_init_block (&block);
1803 /* Compare with the current limit. */
1804 gfc_init_se (&arrayse, NULL);
1805 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1806 arrayse.ss = arrayss;
1807 gfc_conv_expr_val (&arrayse, arrayexpr);
1808 gfc_add_block_to_block (&block, &arrayse.pre);
1810 /* Assign the value to the limit... */
1811 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
1813 /* If it is a more extreme value. */
1814 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
1815 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1816 gfc_add_expr_to_block (&block, tmp);
1817 gfc_add_block_to_block (&block, &arrayse.post);
1819 tmp = gfc_finish_block (&block);
1820 if (maskss)
1821 /* We enclose the above in if (mask) {...}. */
1822 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1823 gfc_add_expr_to_block (&body, tmp);
1825 gfc_trans_scalarizing_loops (&loop, &body);
1827 gfc_add_block_to_block (&se->pre, &loop.pre);
1828 gfc_add_block_to_block (&se->pre, &loop.post);
1829 gfc_cleanup_loop (&loop);
1831 se->expr = limit;
1834 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
1835 static void
1836 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
1838 tree arg;
1839 tree arg2;
1840 tree type;
1841 tree tmp;
1843 arg = gfc_conv_intrinsic_function_args (se, expr);
1844 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1845 arg = TREE_VALUE (arg);
1846 type = TREE_TYPE (arg);
1848 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
1849 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
1850 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
1851 build_int_cst (type, 0));
1852 type = gfc_typenode_for_spec (&expr->ts);
1853 se->expr = convert (type, tmp);
1856 /* Generate code to perform the specified operation. */
1857 static void
1858 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
1860 tree arg;
1861 tree arg2;
1862 tree type;
1864 arg = gfc_conv_intrinsic_function_args (se, expr);
1865 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1866 arg = TREE_VALUE (arg);
1867 type = TREE_TYPE (arg);
1869 se->expr = fold_build2 (op, type, arg, arg2);
1872 /* Bitwise not. */
1873 static void
1874 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
1876 tree arg;
1878 arg = gfc_conv_intrinsic_function_args (se, expr);
1879 arg = TREE_VALUE (arg);
1881 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
1884 /* Set or clear a single bit. */
1885 static void
1886 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
1888 tree arg;
1889 tree arg2;
1890 tree type;
1891 tree tmp;
1892 int op;
1894 arg = gfc_conv_intrinsic_function_args (se, expr);
1895 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1896 arg = TREE_VALUE (arg);
1897 type = TREE_TYPE (arg);
1899 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
1900 if (set)
1901 op = BIT_IOR_EXPR;
1902 else
1904 op = BIT_AND_EXPR;
1905 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
1907 se->expr = fold_build2 (op, type, arg, tmp);
1910 /* Extract a sequence of bits.
1911 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
1912 static void
1913 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
1915 tree arg;
1916 tree arg2;
1917 tree arg3;
1918 tree type;
1919 tree tmp;
1920 tree mask;
1922 arg = gfc_conv_intrinsic_function_args (se, expr);
1923 arg2 = TREE_CHAIN (arg);
1924 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
1925 arg = TREE_VALUE (arg);
1926 arg2 = TREE_VALUE (arg2);
1927 type = TREE_TYPE (arg);
1929 mask = build_int_cst (NULL_TREE, -1);
1930 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
1931 mask = build1 (BIT_NOT_EXPR, type, mask);
1933 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
1935 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
1938 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
1940 : ((shift >= 0) ? i << shift : i >> -shift)
1941 where all shifts are logical shifts. */
1942 static void
1943 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
1945 tree arg;
1946 tree arg2;
1947 tree type;
1948 tree utype;
1949 tree tmp;
1950 tree width;
1951 tree num_bits;
1952 tree cond;
1953 tree lshift;
1954 tree rshift;
1956 arg = gfc_conv_intrinsic_function_args (se, expr);
1957 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1958 arg = TREE_VALUE (arg);
1959 type = TREE_TYPE (arg);
1960 utype = gfc_unsigned_type (type);
1962 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
1964 /* Left shift if positive. */
1965 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
1967 /* Right shift if negative.
1968 We convert to an unsigned type because we want a logical shift.
1969 The standard doesn't define the case of shifting negative
1970 numbers, and we try to be compatible with other compilers, most
1971 notably g77, here. */
1972 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
1973 convert (utype, arg), width));
1975 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
1976 build_int_cst (TREE_TYPE (arg2), 0));
1977 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
1979 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
1980 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
1981 special case. */
1982 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
1983 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
1985 se->expr = fold_build3 (COND_EXPR, type, cond,
1986 build_int_cst (type, 0), tmp);
1989 /* Circular shift. AKA rotate or barrel shift. */
1990 static void
1991 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
1993 tree arg;
1994 tree arg2;
1995 tree arg3;
1996 tree type;
1997 tree tmp;
1998 tree lrot;
1999 tree rrot;
2000 tree zero;
2002 arg = gfc_conv_intrinsic_function_args (se, expr);
2003 arg2 = TREE_CHAIN (arg);
2004 arg3 = TREE_CHAIN (arg2);
2005 if (arg3)
2007 /* Use a library function for the 3 parameter version. */
2008 tree int4type = gfc_get_int_type (4);
2010 type = TREE_TYPE (TREE_VALUE (arg));
2011 /* We convert the first argument to at least 4 bytes, and
2012 convert back afterwards. This removes the need for library
2013 functions for all argument sizes, and function will be
2014 aligned to at least 32 bits, so there's no loss. */
2015 if (expr->ts.kind < 4)
2017 tmp = convert (int4type, TREE_VALUE (arg));
2018 TREE_VALUE (arg) = tmp;
2020 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
2021 need loads of library functions. They cannot have values >
2022 BIT_SIZE (I) so the conversion is safe. */
2023 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
2024 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
2026 switch (expr->ts.kind)
2028 case 1:
2029 case 2:
2030 case 4:
2031 tmp = gfor_fndecl_math_ishftc4;
2032 break;
2033 case 8:
2034 tmp = gfor_fndecl_math_ishftc8;
2035 break;
2036 case 16:
2037 tmp = gfor_fndecl_math_ishftc16;
2038 break;
2039 default:
2040 gcc_unreachable ();
2042 se->expr = build_function_call_expr (tmp, arg);
2043 /* Convert the result back to the original type, if we extended
2044 the first argument's width above. */
2045 if (expr->ts.kind < 4)
2046 se->expr = convert (type, se->expr);
2048 return;
2050 arg = TREE_VALUE (arg);
2051 arg2 = TREE_VALUE (arg2);
2052 type = TREE_TYPE (arg);
2054 /* Rotate left if positive. */
2055 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
2057 /* Rotate right if negative. */
2058 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
2059 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
2061 zero = build_int_cst (TREE_TYPE (arg2), 0);
2062 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
2063 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
2065 /* Do nothing if shift == 0. */
2066 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
2067 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
2070 /* The length of a character string. */
2071 static void
2072 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
2074 tree len;
2075 tree type;
2076 tree decl;
2077 gfc_symbol *sym;
2078 gfc_se argse;
2079 gfc_expr *arg;
2081 gcc_assert (!se->ss);
2083 arg = expr->value.function.actual->expr;
2085 type = gfc_typenode_for_spec (&expr->ts);
2086 switch (arg->expr_type)
2088 case EXPR_CONSTANT:
2089 len = build_int_cst (NULL_TREE, arg->value.character.length);
2090 break;
2092 default:
2093 if (arg->expr_type == EXPR_VARIABLE
2094 && (arg->ref == NULL || (arg->ref->next == NULL
2095 && arg->ref->type == REF_ARRAY)))
2097 /* This doesn't catch all cases.
2098 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
2099 and the surrounding thread. */
2100 sym = arg->symtree->n.sym;
2101 decl = gfc_get_symbol_decl (sym);
2102 if (decl == current_function_decl && sym->attr.function
2103 && (sym->result == sym))
2104 decl = gfc_get_fake_result_decl (sym);
2106 len = sym->ts.cl->backend_decl;
2107 gcc_assert (len);
2109 else
2111 /* Anybody stupid enough to do this deserves inefficient code. */
2112 gfc_init_se (&argse, se);
2113 gfc_conv_expr (&argse, arg);
2114 gfc_add_block_to_block (&se->pre, &argse.pre);
2115 gfc_add_block_to_block (&se->post, &argse.post);
2116 len = argse.string_length;
2118 break;
2120 se->expr = convert (type, len);
2123 /* The length of a character string not including trailing blanks. */
2124 static void
2125 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
2127 tree args;
2128 tree type;
2130 args = gfc_conv_intrinsic_function_args (se, expr);
2131 type = gfc_typenode_for_spec (&expr->ts);
2132 se->expr = build_function_call_expr (gfor_fndecl_string_len_trim, args);
2133 se->expr = convert (type, se->expr);
2137 /* Returns the starting position of a substring within a string. */
2139 static void
2140 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
2142 tree logical4_type_node = gfc_get_logical_type (4);
2143 tree args;
2144 tree back;
2145 tree type;
2146 tree tmp;
2148 args = gfc_conv_intrinsic_function_args (se, expr);
2149 type = gfc_typenode_for_spec (&expr->ts);
2150 tmp = gfc_advance_chain (args, 3);
2151 if (TREE_CHAIN (tmp) == NULL_TREE)
2153 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2154 NULL_TREE);
2155 TREE_CHAIN (tmp) = back;
2157 else
2159 back = TREE_CHAIN (tmp);
2160 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2163 se->expr = build_function_call_expr (gfor_fndecl_string_index, args);
2164 se->expr = convert (type, se->expr);
2167 /* The ascii value for a single character. */
2168 static void
2169 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
2171 tree arg;
2172 tree type;
2174 arg = gfc_conv_intrinsic_function_args (se, expr);
2175 arg = TREE_VALUE (TREE_CHAIN (arg));
2176 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2177 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2178 type = gfc_typenode_for_spec (&expr->ts);
2180 se->expr = build_fold_indirect_ref (arg);
2181 se->expr = convert (type, se->expr);
2185 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2187 static void
2188 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2190 tree arg;
2191 tree tsource;
2192 tree fsource;
2193 tree mask;
2194 tree type;
2195 tree len;
2197 arg = gfc_conv_intrinsic_function_args (se, expr);
2198 if (expr->ts.type != BT_CHARACTER)
2200 tsource = TREE_VALUE (arg);
2201 arg = TREE_CHAIN (arg);
2202 fsource = TREE_VALUE (arg);
2203 mask = TREE_VALUE (TREE_CHAIN (arg));
2205 else
2207 /* We do the same as in the non-character case, but the argument
2208 list is different because of the string length arguments. We
2209 also have to set the string length for the result. */
2210 len = TREE_VALUE (arg);
2211 arg = TREE_CHAIN (arg);
2212 tsource = TREE_VALUE (arg);
2213 arg = TREE_CHAIN (TREE_CHAIN (arg));
2214 fsource = TREE_VALUE (arg);
2215 mask = TREE_VALUE (TREE_CHAIN (arg));
2217 se->string_length = len;
2219 type = TREE_TYPE (tsource);
2220 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2224 static void
2225 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2227 gfc_actual_arglist *actual;
2228 tree args;
2229 tree type;
2230 tree fndecl;
2231 gfc_se argse;
2232 gfc_ss *ss;
2234 gfc_init_se (&argse, NULL);
2235 actual = expr->value.function.actual;
2237 ss = gfc_walk_expr (actual->expr);
2238 gcc_assert (ss != gfc_ss_terminator);
2239 argse.want_pointer = 1;
2240 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2241 gfc_add_block_to_block (&se->pre, &argse.pre);
2242 gfc_add_block_to_block (&se->post, &argse.post);
2243 args = gfc_chainon_list (NULL_TREE, argse.expr);
2245 actual = actual->next;
2246 if (actual->expr)
2248 gfc_init_se (&argse, NULL);
2249 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2250 gfc_add_block_to_block (&se->pre, &argse.pre);
2251 args = gfc_chainon_list (args, argse.expr);
2252 fndecl = gfor_fndecl_size1;
2254 else
2255 fndecl = gfor_fndecl_size0;
2257 se->expr = build_function_call_expr (fndecl, args);
2258 type = gfc_typenode_for_spec (&expr->ts);
2259 se->expr = convert (type, se->expr);
2263 /* Intrinsic string comparison functions. */
2265 static void
2266 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2268 tree type;
2269 tree args;
2270 tree arg2;
2272 args = gfc_conv_intrinsic_function_args (se, expr);
2273 arg2 = TREE_CHAIN (TREE_CHAIN (args));
2275 se->expr = gfc_build_compare_string (TREE_VALUE (args),
2276 TREE_VALUE (TREE_CHAIN (args)), TREE_VALUE (arg2),
2277 TREE_VALUE (TREE_CHAIN (arg2)));
2279 type = gfc_typenode_for_spec (&expr->ts);
2280 se->expr = fold_build2 (op, type, se->expr,
2281 build_int_cst (TREE_TYPE (se->expr), 0));
2284 /* Generate a call to the adjustl/adjustr library function. */
2285 static void
2286 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2288 tree args;
2289 tree len;
2290 tree type;
2291 tree var;
2292 tree tmp;
2294 args = gfc_conv_intrinsic_function_args (se, expr);
2295 len = TREE_VALUE (args);
2297 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2298 var = gfc_conv_string_tmp (se, type, len);
2299 args = tree_cons (NULL_TREE, var, args);
2301 tmp = build_function_call_expr (fndecl, args);
2302 gfc_add_expr_to_block (&se->pre, tmp);
2303 se->expr = var;
2304 se->string_length = len;
2308 /* Scalar transfer statement.
2309 TRANSFER (source, mold) = *(typeof<mold> *)&source. */
2311 static void
2312 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2314 gfc_actual_arglist *arg;
2315 gfc_se argse;
2316 tree type;
2317 tree ptr;
2318 gfc_ss *ss;
2320 gcc_assert (!se->ss);
2322 /* Get a pointer to the source. */
2323 arg = expr->value.function.actual;
2324 ss = gfc_walk_expr (arg->expr);
2325 gfc_init_se (&argse, NULL);
2326 if (ss == gfc_ss_terminator)
2327 gfc_conv_expr_reference (&argse, arg->expr);
2328 else
2329 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2330 gfc_add_block_to_block (&se->pre, &argse.pre);
2331 gfc_add_block_to_block (&se->post, &argse.post);
2332 ptr = argse.expr;
2334 arg = arg->next;
2335 type = gfc_typenode_for_spec (&expr->ts);
2336 ptr = convert (build_pointer_type (type), ptr);
2337 if (expr->ts.type == BT_CHARACTER)
2339 gfc_init_se (&argse, NULL);
2340 gfc_conv_expr (&argse, arg->expr);
2341 gfc_add_block_to_block (&se->pre, &argse.pre);
2342 gfc_add_block_to_block (&se->post, &argse.post);
2343 se->expr = ptr;
2344 se->string_length = argse.string_length;
2346 else
2348 se->expr = build_fold_indirect_ref (ptr);
2353 /* Generate code for the ALLOCATED intrinsic.
2354 Generate inline code that directly check the address of the argument. */
2356 static void
2357 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2359 gfc_actual_arglist *arg1;
2360 gfc_se arg1se;
2361 gfc_ss *ss1;
2362 tree tmp;
2364 gfc_init_se (&arg1se, NULL);
2365 arg1 = expr->value.function.actual;
2366 ss1 = gfc_walk_expr (arg1->expr);
2367 arg1se.descriptor_only = 1;
2368 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2370 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
2371 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
2372 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2373 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2377 /* Generate code for the ASSOCIATED intrinsic.
2378 If both POINTER and TARGET are arrays, generate a call to library function
2379 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2380 In other cases, generate inline code that directly compare the address of
2381 POINTER with the address of TARGET. */
2383 static void
2384 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2386 gfc_actual_arglist *arg1;
2387 gfc_actual_arglist *arg2;
2388 gfc_se arg1se;
2389 gfc_se arg2se;
2390 tree tmp2;
2391 tree tmp;
2392 tree args, fndecl;
2393 gfc_ss *ss1, *ss2;
2395 gfc_init_se (&arg1se, NULL);
2396 gfc_init_se (&arg2se, NULL);
2397 arg1 = expr->value.function.actual;
2398 arg2 = arg1->next;
2399 ss1 = gfc_walk_expr (arg1->expr);
2401 if (!arg2->expr)
2403 /* No optional target. */
2404 if (ss1 == gfc_ss_terminator)
2406 /* A pointer to a scalar. */
2407 arg1se.want_pointer = 1;
2408 gfc_conv_expr (&arg1se, arg1->expr);
2409 tmp2 = arg1se.expr;
2411 else
2413 /* A pointer to an array. */
2414 arg1se.descriptor_only = 1;
2415 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2416 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
2418 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
2419 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
2420 se->expr = tmp;
2422 else
2424 /* An optional target. */
2425 ss2 = gfc_walk_expr (arg2->expr);
2426 if (ss1 == gfc_ss_terminator)
2428 /* A pointer to a scalar. */
2429 gcc_assert (ss2 == gfc_ss_terminator);
2430 arg1se.want_pointer = 1;
2431 gfc_conv_expr (&arg1se, arg1->expr);
2432 arg2se.want_pointer = 1;
2433 gfc_conv_expr (&arg2se, arg2->expr);
2434 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2435 se->expr = tmp;
2437 else
2439 /* A pointer to an array, call library function _gfor_associated. */
2440 gcc_assert (ss2 != gfc_ss_terminator);
2441 args = NULL_TREE;
2442 arg1se.want_pointer = 1;
2443 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2444 args = gfc_chainon_list (args, arg1se.expr);
2445 arg2se.want_pointer = 1;
2446 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2447 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2448 gfc_add_block_to_block (&se->post, &arg2se.post);
2449 args = gfc_chainon_list (args, arg2se.expr);
2450 fndecl = gfor_fndecl_associated;
2451 se->expr = build_function_call_expr (fndecl, args);
2454 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2458 /* Scan a string for any one of the characters in a set of characters. */
2460 static void
2461 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2463 tree logical4_type_node = gfc_get_logical_type (4);
2464 tree args;
2465 tree back;
2466 tree type;
2467 tree tmp;
2469 args = gfc_conv_intrinsic_function_args (se, expr);
2470 type = gfc_typenode_for_spec (&expr->ts);
2471 tmp = gfc_advance_chain (args, 3);
2472 if (TREE_CHAIN (tmp) == NULL_TREE)
2474 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2475 NULL_TREE);
2476 TREE_CHAIN (tmp) = back;
2478 else
2480 back = TREE_CHAIN (tmp);
2481 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2484 se->expr = build_function_call_expr (gfor_fndecl_string_scan, args);
2485 se->expr = convert (type, se->expr);
2489 /* Verify that a set of characters contains all the characters in a string
2490 by identifying the position of the first character in a string of
2491 characters that does not appear in a given set of characters. */
2493 static void
2494 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2496 tree logical4_type_node = gfc_get_logical_type (4);
2497 tree args;
2498 tree back;
2499 tree type;
2500 tree tmp;
2502 args = gfc_conv_intrinsic_function_args (se, expr);
2503 type = gfc_typenode_for_spec (&expr->ts);
2504 tmp = gfc_advance_chain (args, 3);
2505 if (TREE_CHAIN (tmp) == NULL_TREE)
2507 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2508 NULL_TREE);
2509 TREE_CHAIN (tmp) = back;
2511 else
2513 back = TREE_CHAIN (tmp);
2514 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2517 se->expr = build_function_call_expr (gfor_fndecl_string_verify, args);
2518 se->expr = convert (type, se->expr);
2521 /* Prepare components and related information of a real number which is
2522 the first argument of a elemental functions to manipulate reals. */
2524 static void
2525 prepare_arg_info (gfc_se * se, gfc_expr * expr,
2526 real_compnt_info * rcs, int all)
2528 tree arg;
2529 tree masktype;
2530 tree tmp;
2531 tree wbits;
2532 tree one;
2533 tree exponent, fraction;
2534 int n;
2535 gfc_expr *a1;
2537 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
2538 gfc_todo_error ("Non-IEEE floating format");
2540 gcc_assert (expr->expr_type == EXPR_FUNCTION);
2542 arg = gfc_conv_intrinsic_function_args (se, expr);
2543 arg = TREE_VALUE (arg);
2544 rcs->type = TREE_TYPE (arg);
2546 /* Force arg'type to integer by unaffected convert */
2547 a1 = expr->value.function.actual->expr;
2548 masktype = gfc_get_int_type (a1->ts.kind);
2549 rcs->mtype = masktype;
2550 tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
2551 arg = gfc_create_var (masktype, "arg");
2552 gfc_add_modify_expr(&se->pre, arg, tmp);
2553 rcs->arg = arg;
2555 /* Calculate the numbers of bits of exponent, fraction and word */
2556 n = gfc_validate_kind (a1->ts.type, a1->ts.kind, false);
2557 tmp = build_int_cst (NULL_TREE, gfc_real_kinds[n].digits - 1);
2558 rcs->fdigits = convert (masktype, tmp);
2559 wbits = build_int_cst (NULL_TREE, TYPE_PRECISION (rcs->type) - 1);
2560 wbits = convert (masktype, wbits);
2561 rcs->edigits = fold_build2 (MINUS_EXPR, masktype, wbits, tmp);
2563 /* Form masks for exponent/fraction/sign */
2564 one = gfc_build_const (masktype, integer_one_node);
2565 rcs->smask = fold_build2 (LSHIFT_EXPR, masktype, one, wbits);
2566 rcs->f1 = fold_build2 (LSHIFT_EXPR, masktype, one, rcs->fdigits);
2567 rcs->emask = fold_build2 (MINUS_EXPR, masktype, rcs->smask, rcs->f1);
2568 rcs->fmask = fold_build2 (MINUS_EXPR, masktype, rcs->f1, one);
2569 /* Form bias. */
2570 tmp = fold_build2 (MINUS_EXPR, masktype, rcs->edigits, one);
2571 tmp = fold_build2 (LSHIFT_EXPR, masktype, one, tmp);
2572 rcs->bias = fold_build2 (MINUS_EXPR, masktype, tmp ,one);
2574 if (all)
2576 /* exponent, and fraction */
2577 tmp = build2 (BIT_AND_EXPR, masktype, arg, rcs->emask);
2578 tmp = build2 (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
2579 exponent = gfc_create_var (masktype, "exponent");
2580 gfc_add_modify_expr(&se->pre, exponent, tmp);
2581 rcs->expn = exponent;
2583 tmp = build2 (BIT_AND_EXPR, masktype, arg, rcs->fmask);
2584 fraction = gfc_create_var (masktype, "fraction");
2585 gfc_add_modify_expr(&se->pre, fraction, tmp);
2586 rcs->frac = fraction;
2590 /* Build a call to __builtin_clz. */
2592 static tree
2593 call_builtin_clz (tree result_type, tree op0)
2595 tree fn, parms, call;
2596 enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
2598 if (op0_mode == TYPE_MODE (integer_type_node))
2599 fn = built_in_decls[BUILT_IN_CLZ];
2600 else if (op0_mode == TYPE_MODE (long_integer_type_node))
2601 fn = built_in_decls[BUILT_IN_CLZL];
2602 else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
2603 fn = built_in_decls[BUILT_IN_CLZLL];
2604 else
2605 gcc_unreachable ();
2607 parms = tree_cons (NULL, op0, NULL);
2608 call = build_function_call_expr (fn, parms);
2610 return convert (result_type, call);
2614 /* Generate code for SPACING (X) intrinsic function.
2615 SPACING (X) = POW (2, e-p)
2617 We generate:
2619 t = expn - fdigits // e - p.
2620 res = t << fdigits // Form the exponent. Fraction is zero.
2621 if (t < 0) // The result is out of range. Denormalized case.
2622 res = tiny(X)
2625 static void
2626 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2628 tree arg;
2629 tree masktype;
2630 tree tmp, t1, cond;
2631 tree tiny, zero;
2632 tree fdigits;
2633 real_compnt_info rcs;
2635 prepare_arg_info (se, expr, &rcs, 0);
2636 arg = rcs.arg;
2637 masktype = rcs.mtype;
2638 fdigits = rcs.fdigits;
2639 tiny = rcs.f1;
2640 zero = gfc_build_const (masktype, integer_zero_node);
2641 tmp = build2 (BIT_AND_EXPR, masktype, rcs.emask, arg);
2642 tmp = build2 (RSHIFT_EXPR, masktype, tmp, fdigits);
2643 tmp = build2 (MINUS_EXPR, masktype, tmp, fdigits);
2644 cond = build2 (LE_EXPR, boolean_type_node, tmp, zero);
2645 t1 = build2 (LSHIFT_EXPR, masktype, tmp, fdigits);
2646 tmp = build3 (COND_EXPR, masktype, cond, tiny, t1);
2647 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2649 se->expr = tmp;
2652 /* Generate code for RRSPACING (X) intrinsic function.
2653 RRSPACING (X) = |X * POW (2, -e)| * POW (2, p) = |FRACTION (X)| * POW (2, p)
2655 So the result's exponent is p. And if X is normalized, X's fraction part
2656 is the result's fraction. If X is denormalized, to get the X's fraction we
2657 shift X's fraction part to left until the first '1' is removed.
2659 We generate:
2661 if (expn == 0 && frac == 0)
2662 res = 0;
2663 else
2665 // edigits is the number of exponent bits. Add the sign bit.
2666 sedigits = edigits + 1;
2668 if (expn == 0) // Denormalized case.
2670 t1 = leadzero (frac);
2671 frac = frac << (t1 + 1); //Remove the first '1'.
2672 frac = frac >> (sedigits); //Form the fraction.
2675 //fdigits is the number of fraction bits. Form the exponent.
2676 t = bias + fdigits;
2678 res = (t << fdigits) | frac;
2682 static void
2683 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2685 tree masktype;
2686 tree tmp, t1, t2, cond, cond2;
2687 tree one, zero;
2688 tree fdigits, fraction;
2689 real_compnt_info rcs;
2691 prepare_arg_info (se, expr, &rcs, 1);
2692 masktype = rcs.mtype;
2693 fdigits = rcs.fdigits;
2694 fraction = rcs.frac;
2695 one = gfc_build_const (masktype, integer_one_node);
2696 zero = gfc_build_const (masktype, integer_zero_node);
2697 t2 = fold_build2 (PLUS_EXPR, masktype, rcs.edigits, one);
2699 t1 = call_builtin_clz (masktype, fraction);
2700 tmp = build2 (PLUS_EXPR, masktype, t1, one);
2701 tmp = build2 (LSHIFT_EXPR, masktype, fraction, tmp);
2702 tmp = build2 (RSHIFT_EXPR, masktype, tmp, t2);
2703 cond = build2 (EQ_EXPR, boolean_type_node, rcs.expn, zero);
2704 fraction = build3 (COND_EXPR, masktype, cond, tmp, fraction);
2706 tmp = fold_build2 (PLUS_EXPR, masktype, rcs.bias, fdigits);
2707 tmp = fold_build2 (LSHIFT_EXPR, masktype, tmp, fdigits);
2708 tmp = build2 (BIT_IOR_EXPR, masktype, tmp, fraction);
2710 cond2 = build2 (EQ_EXPR, boolean_type_node, rcs.frac, zero);
2711 cond = build2 (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
2712 tmp = build3 (COND_EXPR, masktype, cond,
2713 build_int_cst (masktype, 0), tmp);
2715 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2716 se->expr = tmp;
2719 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
2721 static void
2722 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
2724 tree args;
2726 args = gfc_conv_intrinsic_function_args (se, expr);
2727 args = TREE_VALUE (args);
2728 args = build_fold_addr_expr (args);
2729 args = tree_cons (NULL_TREE, args, NULL_TREE);
2730 se->expr = build_function_call_expr (gfor_fndecl_si_kind, args);
2733 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
2735 static void
2736 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
2738 gfc_actual_arglist *actual;
2739 tree args;
2740 gfc_se argse;
2742 args = NULL_TREE;
2743 for (actual = expr->value.function.actual; actual; actual = actual->next)
2745 gfc_init_se (&argse, se);
2747 /* Pass a NULL pointer for an absent arg. */
2748 if (actual->expr == NULL)
2749 argse.expr = null_pointer_node;
2750 else
2751 gfc_conv_expr_reference (&argse, actual->expr);
2753 gfc_add_block_to_block (&se->pre, &argse.pre);
2754 gfc_add_block_to_block (&se->post, &argse.post);
2755 args = gfc_chainon_list (args, argse.expr);
2757 se->expr = build_function_call_expr (gfor_fndecl_sr_kind, args);
2761 /* Generate code for TRIM (A) intrinsic function. */
2763 static void
2764 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
2766 tree gfc_int4_type_node = gfc_get_int_type (4);
2767 tree var;
2768 tree len;
2769 tree addr;
2770 tree tmp;
2771 tree arglist;
2772 tree type;
2773 tree cond;
2775 arglist = NULL_TREE;
2777 type = build_pointer_type (gfc_character1_type_node);
2778 var = gfc_create_var (type, "pstr");
2779 addr = gfc_build_addr_expr (ppvoid_type_node, var);
2780 len = gfc_create_var (gfc_int4_type_node, "len");
2782 tmp = gfc_conv_intrinsic_function_args (se, expr);
2783 arglist = gfc_chainon_list (arglist, build_fold_addr_expr (len));
2784 arglist = gfc_chainon_list (arglist, addr);
2785 arglist = chainon (arglist, tmp);
2787 tmp = build_function_call_expr (gfor_fndecl_string_trim, arglist);
2788 gfc_add_expr_to_block (&se->pre, tmp);
2790 /* Free the temporary afterwards, if necessary. */
2791 cond = build2 (GT_EXPR, boolean_type_node, len,
2792 build_int_cst (TREE_TYPE (len), 0));
2793 arglist = gfc_chainon_list (NULL_TREE, var);
2794 tmp = build_function_call_expr (gfor_fndecl_internal_free, arglist);
2795 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2796 gfc_add_expr_to_block (&se->post, tmp);
2798 se->expr = var;
2799 se->string_length = len;
2803 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
2805 static void
2806 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
2808 tree gfc_int4_type_node = gfc_get_int_type (4);
2809 tree tmp;
2810 tree len;
2811 tree args;
2812 tree arglist;
2813 tree ncopies;
2814 tree var;
2815 tree type;
2817 args = gfc_conv_intrinsic_function_args (se, expr);
2818 len = TREE_VALUE (args);
2819 tmp = gfc_advance_chain (args, 2);
2820 ncopies = TREE_VALUE (tmp);
2821 len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
2822 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
2823 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
2825 arglist = NULL_TREE;
2826 arglist = gfc_chainon_list (arglist, var);
2827 arglist = chainon (arglist, args);
2828 tmp = build_function_call_expr (gfor_fndecl_string_repeat, arglist);
2829 gfc_add_expr_to_block (&se->pre, tmp);
2831 se->expr = var;
2832 se->string_length = len;
2836 /* Generate code for the IARGC intrinsic. */
2838 static void
2839 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
2841 tree tmp;
2842 tree fndecl;
2843 tree type;
2845 /* Call the library function. This always returns an INTEGER(4). */
2846 fndecl = gfor_fndecl_iargc;
2847 tmp = build_function_call_expr (fndecl, NULL_TREE);
2849 /* Convert it to the required type. */
2850 type = gfc_typenode_for_spec (&expr->ts);
2851 tmp = fold_convert (type, tmp);
2853 se->expr = tmp;
2857 /* The loc intrinsic returns the address of its argument as
2858 gfc_index_integer_kind integer. */
2860 static void
2861 gfc_conv_intrinsic_loc(gfc_se * se, gfc_expr * expr)
2863 tree temp_var;
2864 gfc_expr *arg_expr;
2865 gfc_ss *ss;
2867 gcc_assert (!se->ss);
2869 arg_expr = expr->value.function.actual->expr;
2870 ss = gfc_walk_expr (arg_expr);
2871 if (ss == gfc_ss_terminator)
2872 gfc_conv_expr_reference (se, arg_expr);
2873 else
2874 gfc_conv_array_parameter (se, arg_expr, ss, 1);
2875 se->expr= convert (gfc_unsigned_type (long_integer_type_node),
2876 se->expr);
2878 /* Create a temporary variable for loc return value. Without this,
2879 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
2880 temp_var = gfc_create_var (gfc_unsigned_type (long_integer_type_node),
2881 NULL);
2882 gfc_add_modify_expr (&se->pre, temp_var, se->expr);
2883 se->expr = temp_var;
2886 /* Generate code for an intrinsic function. Some map directly to library
2887 calls, others get special handling. In some cases the name of the function
2888 used depends on the type specifiers. */
2890 void
2891 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
2893 gfc_intrinsic_sym *isym;
2894 const char *name;
2895 int lib;
2897 isym = expr->value.function.isym;
2899 name = &expr->value.function.name[2];
2901 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
2903 lib = gfc_is_intrinsic_libcall (expr);
2904 if (lib != 0)
2906 if (lib == 1)
2907 se->ignore_optional = 1;
2908 gfc_conv_intrinsic_funcall (se, expr);
2909 return;
2913 switch (expr->value.function.isym->generic_id)
2915 case GFC_ISYM_NONE:
2916 gcc_unreachable ();
2918 case GFC_ISYM_REPEAT:
2919 gfc_conv_intrinsic_repeat (se, expr);
2920 break;
2922 case GFC_ISYM_TRIM:
2923 gfc_conv_intrinsic_trim (se, expr);
2924 break;
2926 case GFC_ISYM_SI_KIND:
2927 gfc_conv_intrinsic_si_kind (se, expr);
2928 break;
2930 case GFC_ISYM_SR_KIND:
2931 gfc_conv_intrinsic_sr_kind (se, expr);
2932 break;
2934 case GFC_ISYM_EXPONENT:
2935 gfc_conv_intrinsic_exponent (se, expr);
2936 break;
2938 case GFC_ISYM_SPACING:
2939 gfc_conv_intrinsic_spacing (se, expr);
2940 break;
2942 case GFC_ISYM_RRSPACING:
2943 gfc_conv_intrinsic_rrspacing (se, expr);
2944 break;
2946 case GFC_ISYM_SCAN:
2947 gfc_conv_intrinsic_scan (se, expr);
2948 break;
2950 case GFC_ISYM_VERIFY:
2951 gfc_conv_intrinsic_verify (se, expr);
2952 break;
2954 case GFC_ISYM_ALLOCATED:
2955 gfc_conv_allocated (se, expr);
2956 break;
2958 case GFC_ISYM_ASSOCIATED:
2959 gfc_conv_associated(se, expr);
2960 break;
2962 case GFC_ISYM_ABS:
2963 gfc_conv_intrinsic_abs (se, expr);
2964 break;
2966 case GFC_ISYM_ADJUSTL:
2967 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
2968 break;
2970 case GFC_ISYM_ADJUSTR:
2971 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
2972 break;
2974 case GFC_ISYM_AIMAG:
2975 gfc_conv_intrinsic_imagpart (se, expr);
2976 break;
2978 case GFC_ISYM_AINT:
2979 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
2980 break;
2982 case GFC_ISYM_ALL:
2983 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
2984 break;
2986 case GFC_ISYM_ANINT:
2987 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
2988 break;
2990 case GFC_ISYM_AND:
2991 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
2992 break;
2994 case GFC_ISYM_ANY:
2995 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
2996 break;
2998 case GFC_ISYM_BTEST:
2999 gfc_conv_intrinsic_btest (se, expr);
3000 break;
3002 case GFC_ISYM_ACHAR:
3003 case GFC_ISYM_CHAR:
3004 gfc_conv_intrinsic_char (se, expr);
3005 break;
3007 case GFC_ISYM_CONVERSION:
3008 case GFC_ISYM_REAL:
3009 case GFC_ISYM_LOGICAL:
3010 case GFC_ISYM_DBLE:
3011 gfc_conv_intrinsic_conversion (se, expr);
3012 break;
3014 /* Integer conversions are handled separately to make sure we get the
3015 correct rounding mode. */
3016 case GFC_ISYM_INT:
3017 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
3018 break;
3020 case GFC_ISYM_NINT:
3021 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
3022 break;
3024 case GFC_ISYM_CEILING:
3025 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
3026 break;
3028 case GFC_ISYM_FLOOR:
3029 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
3030 break;
3032 case GFC_ISYM_MOD:
3033 gfc_conv_intrinsic_mod (se, expr, 0);
3034 break;
3036 case GFC_ISYM_MODULO:
3037 gfc_conv_intrinsic_mod (se, expr, 1);
3038 break;
3040 case GFC_ISYM_CMPLX:
3041 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
3042 break;
3044 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
3045 gfc_conv_intrinsic_iargc (se, expr);
3046 break;
3048 case GFC_ISYM_COMPLEX:
3049 gfc_conv_intrinsic_cmplx (se, expr, 1);
3050 break;
3052 case GFC_ISYM_CONJG:
3053 gfc_conv_intrinsic_conjg (se, expr);
3054 break;
3056 case GFC_ISYM_COUNT:
3057 gfc_conv_intrinsic_count (se, expr);
3058 break;
3060 case GFC_ISYM_CTIME:
3061 gfc_conv_intrinsic_ctime (se, expr);
3062 break;
3064 case GFC_ISYM_DIM:
3065 gfc_conv_intrinsic_dim (se, expr);
3066 break;
3068 case GFC_ISYM_DPROD:
3069 gfc_conv_intrinsic_dprod (se, expr);
3070 break;
3072 case GFC_ISYM_FDATE:
3073 gfc_conv_intrinsic_fdate (se, expr);
3074 break;
3076 case GFC_ISYM_IAND:
3077 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
3078 break;
3080 case GFC_ISYM_IBCLR:
3081 gfc_conv_intrinsic_singlebitop (se, expr, 0);
3082 break;
3084 case GFC_ISYM_IBITS:
3085 gfc_conv_intrinsic_ibits (se, expr);
3086 break;
3088 case GFC_ISYM_IBSET:
3089 gfc_conv_intrinsic_singlebitop (se, expr, 1);
3090 break;
3092 case GFC_ISYM_IACHAR:
3093 case GFC_ISYM_ICHAR:
3094 /* We assume ASCII character sequence. */
3095 gfc_conv_intrinsic_ichar (se, expr);
3096 break;
3098 case GFC_ISYM_IARGC:
3099 gfc_conv_intrinsic_iargc (se, expr);
3100 break;
3102 case GFC_ISYM_IEOR:
3103 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3104 break;
3106 case GFC_ISYM_INDEX:
3107 gfc_conv_intrinsic_index (se, expr);
3108 break;
3110 case GFC_ISYM_IOR:
3111 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3112 break;
3114 case GFC_ISYM_ISHFT:
3115 gfc_conv_intrinsic_ishft (se, expr);
3116 break;
3118 case GFC_ISYM_ISHFTC:
3119 gfc_conv_intrinsic_ishftc (se, expr);
3120 break;
3122 case GFC_ISYM_LBOUND:
3123 gfc_conv_intrinsic_bound (se, expr, 0);
3124 break;
3126 case GFC_ISYM_TRANSPOSE:
3127 if (se->ss && se->ss->useflags)
3129 gfc_conv_tmp_array_ref (se);
3130 gfc_advance_se_ss_chain (se);
3132 else
3133 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
3134 break;
3136 case GFC_ISYM_LEN:
3137 gfc_conv_intrinsic_len (se, expr);
3138 break;
3140 case GFC_ISYM_LEN_TRIM:
3141 gfc_conv_intrinsic_len_trim (se, expr);
3142 break;
3144 case GFC_ISYM_LGE:
3145 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
3146 break;
3148 case GFC_ISYM_LGT:
3149 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
3150 break;
3152 case GFC_ISYM_LLE:
3153 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
3154 break;
3156 case GFC_ISYM_LLT:
3157 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
3158 break;
3160 case GFC_ISYM_MAX:
3161 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
3162 break;
3164 case GFC_ISYM_MAXLOC:
3165 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
3166 break;
3168 case GFC_ISYM_MAXVAL:
3169 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
3170 break;
3172 case GFC_ISYM_MERGE:
3173 gfc_conv_intrinsic_merge (se, expr);
3174 break;
3176 case GFC_ISYM_MIN:
3177 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
3178 break;
3180 case GFC_ISYM_MINLOC:
3181 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
3182 break;
3184 case GFC_ISYM_MINVAL:
3185 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
3186 break;
3188 case GFC_ISYM_NOT:
3189 gfc_conv_intrinsic_not (se, expr);
3190 break;
3192 case GFC_ISYM_OR:
3193 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
3194 break;
3196 case GFC_ISYM_PRESENT:
3197 gfc_conv_intrinsic_present (se, expr);
3198 break;
3200 case GFC_ISYM_PRODUCT:
3201 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
3202 break;
3204 case GFC_ISYM_SIGN:
3205 gfc_conv_intrinsic_sign (se, expr);
3206 break;
3208 case GFC_ISYM_SIZE:
3209 gfc_conv_intrinsic_size (se, expr);
3210 break;
3212 case GFC_ISYM_SUM:
3213 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
3214 break;
3216 case GFC_ISYM_TRANSFER:
3217 gfc_conv_intrinsic_transfer (se, expr);
3218 break;
3220 case GFC_ISYM_TTYNAM:
3221 gfc_conv_intrinsic_ttynam (se, expr);
3222 break;
3224 case GFC_ISYM_UBOUND:
3225 gfc_conv_intrinsic_bound (se, expr, 1);
3226 break;
3228 case GFC_ISYM_XOR:
3229 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
3230 break;
3232 case GFC_ISYM_LOC:
3233 gfc_conv_intrinsic_loc (se, expr);
3234 break;
3236 case GFC_ISYM_CHDIR:
3237 case GFC_ISYM_DOT_PRODUCT:
3238 case GFC_ISYM_ETIME:
3239 case GFC_ISYM_FGET:
3240 case GFC_ISYM_FGETC:
3241 case GFC_ISYM_FNUM:
3242 case GFC_ISYM_FPUT:
3243 case GFC_ISYM_FPUTC:
3244 case GFC_ISYM_FSTAT:
3245 case GFC_ISYM_FTELL:
3246 case GFC_ISYM_GETCWD:
3247 case GFC_ISYM_GETGID:
3248 case GFC_ISYM_GETPID:
3249 case GFC_ISYM_GETUID:
3250 case GFC_ISYM_HOSTNM:
3251 case GFC_ISYM_KILL:
3252 case GFC_ISYM_IERRNO:
3253 case GFC_ISYM_IRAND:
3254 case GFC_ISYM_ISATTY:
3255 case GFC_ISYM_LINK:
3256 case GFC_ISYM_MALLOC:
3257 case GFC_ISYM_MATMUL:
3258 case GFC_ISYM_RAND:
3259 case GFC_ISYM_RENAME:
3260 case GFC_ISYM_SECOND:
3261 case GFC_ISYM_SECNDS:
3262 case GFC_ISYM_SIGNAL:
3263 case GFC_ISYM_STAT:
3264 case GFC_ISYM_SYMLNK:
3265 case GFC_ISYM_SYSTEM:
3266 case GFC_ISYM_TIME:
3267 case GFC_ISYM_TIME8:
3268 case GFC_ISYM_UMASK:
3269 case GFC_ISYM_UNLINK:
3270 gfc_conv_intrinsic_funcall (se, expr);
3271 break;
3273 default:
3274 gfc_conv_intrinsic_lib_function (se, expr);
3275 break;
3280 /* This generates code to execute before entering the scalarization loop.
3281 Currently does nothing. */
3283 void
3284 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
3286 switch (ss->expr->value.function.isym->generic_id)
3288 case GFC_ISYM_UBOUND:
3289 case GFC_ISYM_LBOUND:
3290 break;
3292 default:
3293 gcc_unreachable ();
3298 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
3299 inside the scalarization loop. */
3301 static gfc_ss *
3302 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
3304 gfc_ss *newss;
3306 /* The two argument version returns a scalar. */
3307 if (expr->value.function.actual->next->expr)
3308 return ss;
3310 newss = gfc_get_ss ();
3311 newss->type = GFC_SS_INTRINSIC;
3312 newss->expr = expr;
3313 newss->next = ss;
3315 return newss;
3319 /* Walk an intrinsic array libcall. */
3321 static gfc_ss *
3322 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
3324 gfc_ss *newss;
3326 gcc_assert (expr->rank > 0);
3328 newss = gfc_get_ss ();
3329 newss->type = GFC_SS_FUNCTION;
3330 newss->expr = expr;
3331 newss->next = ss;
3332 newss->data.info.dimen = expr->rank;
3334 return newss;
3338 /* Returns nonzero if the specified intrinsic function call maps directly to a
3339 an external library call. Should only be used for functions that return
3340 arrays. */
3343 gfc_is_intrinsic_libcall (gfc_expr * expr)
3345 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3346 gcc_assert (expr->rank > 0);
3348 switch (expr->value.function.isym->generic_id)
3350 case GFC_ISYM_ALL:
3351 case GFC_ISYM_ANY:
3352 case GFC_ISYM_COUNT:
3353 case GFC_ISYM_MATMUL:
3354 case GFC_ISYM_MAXLOC:
3355 case GFC_ISYM_MAXVAL:
3356 case GFC_ISYM_MINLOC:
3357 case GFC_ISYM_MINVAL:
3358 case GFC_ISYM_PRODUCT:
3359 case GFC_ISYM_SUM:
3360 case GFC_ISYM_SHAPE:
3361 case GFC_ISYM_SPREAD:
3362 case GFC_ISYM_TRANSPOSE:
3363 /* Ignore absent optional parameters. */
3364 return 1;
3366 case GFC_ISYM_RESHAPE:
3367 case GFC_ISYM_CSHIFT:
3368 case GFC_ISYM_EOSHIFT:
3369 case GFC_ISYM_PACK:
3370 case GFC_ISYM_UNPACK:
3371 /* Pass absent optional parameters. */
3372 return 2;
3374 default:
3375 return 0;
3379 /* Walk an intrinsic function. */
3380 gfc_ss *
3381 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3382 gfc_intrinsic_sym * isym)
3384 gcc_assert (isym);
3386 if (isym->elemental)
3387 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
3389 if (expr->rank == 0)
3390 return ss;
3392 if (gfc_is_intrinsic_libcall (expr))
3393 return gfc_walk_intrinsic_libfunc (ss, expr);
3395 /* Special cases. */
3396 switch (isym->generic_id)
3398 case GFC_ISYM_LBOUND:
3399 case GFC_ISYM_UBOUND:
3400 return gfc_walk_intrinsic_bound (ss, expr);
3402 default:
3403 /* This probably meant someone forgot to add an intrinsic to the above
3404 list(s) when they implemented it, or something's gone horribly wrong.
3406 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3407 expr->value.function.name);
3411 #include "gt-fortran-trans-intrinsic.h"