2004-08-23 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / fortran / trans-intrinsic.c
blob1a8a8b6f70b1e566d5d554c871f57df9a1aadd88
1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004 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, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, 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 <stdio.h>
30 #include <string.h>
31 #include "ggc.h"
32 #include "toplev.h"
33 #include "real.h"
34 #include "tree-gimple.h"
35 #include "flags.h"
36 #include <assert.h>
37 #include "gfortran.h"
38 #include "arith.h"
39 #include "intrinsic.h"
40 #include "trans.h"
41 #include "trans-const.h"
42 #include "trans-types.h"
43 #include "trans-array.h"
44 #include "defaults.h"
45 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
46 #include "trans-stmt.h"
48 /* This maps fortran intrinsic math functions to external library or GCC
49 builtin functions. */
50 typedef struct gfc_intrinsic_map_t GTY(())
52 /* The explicit enum is required to work around inadequacies in the
53 garbage collection/gengtype parsing mechanism. */
54 enum gfc_generic_isym_id id;
56 /* Enum value from the "language-independent", aka C-centric, part
57 of gcc, or END_BUILTINS of no such value set. */
58 /* ??? There are now complex variants in builtins.def, though we
59 don't currently do anything with them. */
60 enum built_in_function code4;
61 enum built_in_function code8;
63 /* True if the naming pattern is to prepend "c" for complex and
64 append "f" for kind=4. False if the naming pattern is to
65 prepend "_gfortran_" and append "[rc][48]". */
66 bool libm_name;
68 /* True if a complex version of the function exists. */
69 bool complex_available;
71 /* True if the function should be marked const. */
72 bool is_constant;
74 /* The base library name of this function. */
75 const char *name;
77 /* Cache decls created for the various operand types. */
78 tree real4_decl;
79 tree real8_decl;
80 tree complex4_decl;
81 tree complex8_decl;
83 gfc_intrinsic_map_t;
85 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
86 defines complex variants of all of the entries in mathbuiltins.def
87 except for atan2. */
88 #define DEFINE_MATH_BUILTIN(ID, NAME, NARGS) \
89 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, true, \
90 NARGS == 1, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
92 #define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
93 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, true, HAVE_COMPLEX, true, \
94 NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
96 #define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
97 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, false, HAVE_COMPLEX, true, \
98 NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
100 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
102 /* Functions built into gcc itself. */
103 #include "mathbuiltins.def"
105 /* Functions in libm. */
106 /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
107 pattern for other mathbuiltins.def entries. At present we have no
108 optimizations for this in the common sources. */
109 LIBM_FUNCTION (SCALE, "scalbn", false),
111 /* Functions in libgfortran. */
112 LIBF_FUNCTION (FRACTION, "fraction", false),
113 LIBF_FUNCTION (NEAREST, "nearest", false),
114 LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
116 /* End the list. */
117 LIBF_FUNCTION (NONE, NULL, false)
119 #undef DEFINE_MATH_BUILTIN
120 #undef LIBM_FUNCTION
121 #undef LIBF_FUNCTION
123 /* Structure for storing components of a floating number to be used by
124 elemental functions to manipulate reals. */
125 typedef struct
127 tree arg; /* Variable tree to view convert to integer. */
128 tree expn; /* Variable tree to save exponent. */
129 tree frac; /* Variable tree to save fraction. */
130 tree smask; /* Constant tree of sign's mask. */
131 tree emask; /* Constant tree of exponent's mask. */
132 tree fmask; /* Constant tree of fraction's mask. */
133 tree edigits; /* Constant tree of bit numbers of exponent. */
134 tree fdigits; /* Constant tree of bit numbers of fraction. */
135 tree f1; /* Constant tree of the f1 defined in the real model. */
136 tree bias; /* Constant tree of the bias of exponent in the memory. */
137 tree type; /* Type tree of arg1. */
138 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
140 real_compnt_info;
143 /* Evaluate the arguments to an intrinsic function. */
145 static tree
146 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
148 gfc_actual_arglist *actual;
149 tree args;
150 gfc_se argse;
152 args = NULL_TREE;
153 for (actual = expr->value.function.actual; actual; actual = actual->next)
155 /* Skip ommitted optional arguments. */
156 if (!actual->expr)
157 continue;
159 /* Evaluate the parameter. This will substitute scalarized
160 references automatically. */
161 gfc_init_se (&argse, se);
163 if (actual->expr->ts.type == BT_CHARACTER)
165 gfc_conv_expr (&argse, actual->expr);
166 gfc_conv_string_parameter (&argse);
167 args = gfc_chainon_list (args, argse.string_length);
169 else
170 gfc_conv_expr_val (&argse, actual->expr);
172 gfc_add_block_to_block (&se->pre, &argse.pre);
173 gfc_add_block_to_block (&se->post, &argse.post);
174 args = gfc_chainon_list (args, argse.expr);
176 return args;
180 /* Conversions between different types are output by the frontend as
181 intrinsic functions. We implement these directly with inline code. */
183 static void
184 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
186 tree type;
187 tree arg;
189 /* Evaluate the argument. */
190 type = gfc_typenode_for_spec (&expr->ts);
191 assert (expr->value.function.actual->expr);
192 arg = gfc_conv_intrinsic_function_args (se, expr);
193 arg = TREE_VALUE (arg);
195 /* Conversion from complex to non-complex involves taking the real
196 component of the value. */
197 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
198 && expr->ts.type != BT_COMPLEX)
200 tree artype;
202 artype = TREE_TYPE (TREE_TYPE (arg));
203 arg = build1 (REALPART_EXPR, artype, arg);
206 se->expr = convert (type, arg);
210 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
211 TRUNC(x) = INT(x) <= x ? INT(x) : INT(x) - 1
212 Similarly for CEILING. */
214 static tree
215 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
217 tree tmp;
218 tree cond;
219 tree argtype;
220 tree intval;
222 argtype = TREE_TYPE (arg);
223 arg = gfc_evaluate_now (arg, pblock);
225 intval = convert (type, arg);
226 intval = gfc_evaluate_now (intval, pblock);
228 tmp = convert (argtype, intval);
229 cond = build (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
231 tmp = build (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
232 convert (type, integer_one_node));
233 tmp = build (COND_EXPR, type, cond, intval, tmp);
234 return tmp;
238 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
239 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
241 static tree
242 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
244 tree tmp;
245 tree cond;
246 tree neg;
247 tree pos;
248 tree argtype;
249 REAL_VALUE_TYPE r;
251 argtype = TREE_TYPE (arg);
252 arg = gfc_evaluate_now (arg, pblock);
254 real_from_string (&r, "0.5");
255 pos = build_real (argtype, r);
257 real_from_string (&r, "-0.5");
258 neg = build_real (argtype, r);
260 tmp = gfc_build_const (argtype, integer_zero_node);
261 cond = fold (build (GT_EXPR, boolean_type_node, arg, tmp));
263 tmp = fold (build (COND_EXPR, argtype, cond, pos, neg));
264 tmp = fold (build (PLUS_EXPR, argtype, arg, tmp));
265 return fold (build1 (FIX_TRUNC_EXPR, type, tmp));
269 /* Convert a real to an integer using a specific rounding mode.
270 Ideally we would just build the corresponding GENERIC node,
271 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
273 static tree
274 build_fix_expr (stmtblock_t * pblock, tree arg, tree type, int op)
276 switch (op)
278 case FIX_FLOOR_EXPR:
279 return build_fixbound_expr (pblock, arg, type, 0);
280 break;
282 case FIX_CEIL_EXPR:
283 return build_fixbound_expr (pblock, arg, type, 1);
284 break;
286 case FIX_ROUND_EXPR:
287 return build_round_expr (pblock, arg, type);
289 default:
290 return build1 (op, type, arg);
295 /* Round a real value using the specified rounding mode.
296 We use a temporary integer of that same kind size as the result.
297 Values larger than can be represented by this kind are unchanged, as
298 will not be accurate enough to represent the rounding.
299 huge = HUGE (KIND (a))
300 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
303 static void
304 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, int op)
306 tree type;
307 tree itype;
308 tree arg;
309 tree tmp;
310 tree cond;
311 mpfr_t huge;
312 int n;
313 int kind;
315 kind = expr->ts.kind;
317 n = END_BUILTINS;
318 /* We have builtin functions for some cases. */
319 switch (op)
321 case FIX_ROUND_EXPR:
322 switch (kind)
324 case 4:
325 n = BUILT_IN_ROUNDF;
326 break;
328 case 8:
329 n = BUILT_IN_ROUND;
330 break;
332 break;
334 case FIX_FLOOR_EXPR:
335 switch (kind)
337 case 4:
338 n = BUILT_IN_FLOORF;
339 break;
341 case 8:
342 n = BUILT_IN_FLOOR;
343 break;
347 /* Evaluate the argument. */
348 assert (expr->value.function.actual->expr);
349 arg = gfc_conv_intrinsic_function_args (se, expr);
351 /* Use a builtin function if one exists. */
352 if (n != END_BUILTINS)
354 tmp = built_in_decls[n];
355 se->expr = gfc_build_function_call (tmp, arg);
356 return;
359 /* This code is probably redundant, but we'll keep it lying around just
360 in case. */
361 type = gfc_typenode_for_spec (&expr->ts);
362 arg = TREE_VALUE (arg);
363 arg = gfc_evaluate_now (arg, &se->pre);
365 /* Test if the value is too large to handle sensibly. */
366 gfc_set_model_kind (kind);
367 mpfr_init (huge);
368 n = gfc_validate_kind (BT_INTEGER, kind);
369 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
370 tmp = gfc_conv_mpfr_to_tree (huge, kind);
371 cond = build (LT_EXPR, boolean_type_node, arg, tmp);
373 mpfr_neg (huge, huge, GFC_RND_MODE);
374 tmp = gfc_conv_mpfr_to_tree (huge, kind);
375 tmp = build (GT_EXPR, boolean_type_node, arg, tmp);
376 cond = build (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
377 itype = gfc_get_int_type (kind);
379 tmp = build_fix_expr (&se->pre, arg, itype, op);
380 tmp = convert (type, tmp);
381 se->expr = build (COND_EXPR, type, cond, tmp, arg);
382 mpfr_clear (huge);
386 /* Convert to an integer using the specified rounding mode. */
388 static void
389 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
391 tree type;
392 tree arg;
394 /* Evaluate the argument. */
395 type = gfc_typenode_for_spec (&expr->ts);
396 assert (expr->value.function.actual->expr);
397 arg = gfc_conv_intrinsic_function_args (se, expr);
398 arg = TREE_VALUE (arg);
400 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
402 /* Conversion to a different integer kind. */
403 se->expr = convert (type, arg);
405 else
407 /* Conversion from complex to non-complex involves taking the real
408 component of the value. */
409 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
410 && expr->ts.type != BT_COMPLEX)
412 tree artype;
414 artype = TREE_TYPE (TREE_TYPE (arg));
415 arg = build1 (REALPART_EXPR, artype, arg);
418 se->expr = build_fix_expr (&se->pre, arg, type, op);
423 /* Get the imaginary component of a value. */
425 static void
426 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
428 tree arg;
430 arg = gfc_conv_intrinsic_function_args (se, expr);
431 arg = TREE_VALUE (arg);
432 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
436 /* Get the complex conjugate of a value. */
438 static void
439 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
441 tree arg;
443 arg = gfc_conv_intrinsic_function_args (se, expr);
444 arg = TREE_VALUE (arg);
445 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
449 /* Initialize function decls for library functions. The external functions
450 are created as required. Builtin functions are added here. */
452 void
453 gfc_build_intrinsic_lib_fndecls (void)
455 gfc_intrinsic_map_t *m;
457 /* Add GCC builtin functions. */
458 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
460 if (m->code4 != END_BUILTINS)
461 m->real4_decl = built_in_decls[m->code4];
462 if (m->code8 != END_BUILTINS)
463 m->real8_decl = built_in_decls[m->code8];
468 /* Create a fndecl for a simple intrinsic library function. */
470 static tree
471 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
473 tree type;
474 tree argtypes;
475 tree fndecl;
476 gfc_actual_arglist *actual;
477 tree *pdecl;
478 gfc_typespec *ts;
479 char name[GFC_MAX_SYMBOL_LEN + 3];
481 ts = &expr->ts;
482 if (ts->type == BT_REAL)
484 switch (ts->kind)
486 case 4:
487 pdecl = &m->real4_decl;
488 break;
489 case 8:
490 pdecl = &m->real8_decl;
491 break;
492 default:
493 abort ();
496 else if (ts->type == BT_COMPLEX)
498 if (!m->complex_available)
499 abort ();
501 switch (ts->kind)
503 case 4:
504 pdecl = &m->complex4_decl;
505 break;
506 case 8:
507 pdecl = &m->complex8_decl;
508 break;
509 default:
510 abort ();
513 else
514 abort ();
516 if (*pdecl)
517 return *pdecl;
519 if (m->libm_name)
521 if (ts->kind != 4 && ts->kind != 8)
522 abort ();
523 snprintf (name, sizeof (name), "%s%s%s",
524 ts->type == BT_COMPLEX ? "c" : "",
525 m->name,
526 ts->kind == 4 ? "f" : "");
528 else
530 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
531 ts->type == BT_COMPLEX ? 'c' : 'r',
532 ts->kind);
535 argtypes = NULL_TREE;
536 for (actual = expr->value.function.actual; actual; actual = actual->next)
538 type = gfc_typenode_for_spec (&actual->expr->ts);
539 argtypes = gfc_chainon_list (argtypes, type);
541 argtypes = gfc_chainon_list (argtypes, void_type_node);
542 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
543 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
545 /* Mark the decl as external. */
546 DECL_EXTERNAL (fndecl) = 1;
547 TREE_PUBLIC (fndecl) = 1;
549 /* Mark it __attribute__((const)), if possible. */
550 TREE_READONLY (fndecl) = m->is_constant;
552 rest_of_decl_compilation (fndecl, 1, 0);
554 (*pdecl) = fndecl;
555 return fndecl;
559 /* Convert an intrinsic function into an external or builtin call. */
561 static void
562 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
564 gfc_intrinsic_map_t *m;
565 tree args;
566 tree fndecl;
567 gfc_generic_isym_id id;
569 id = expr->value.function.isym->generic_id;
570 /* Find the entry for this function. */
571 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
573 if (id == m->id)
574 break;
577 if (m->id == GFC_ISYM_NONE)
579 internal_error ("Intrinsic function %s(%d) not recognized",
580 expr->value.function.name, id);
583 /* Get the decl and generate the call. */
584 args = gfc_conv_intrinsic_function_args (se, expr);
585 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
586 se->expr = gfc_build_function_call (fndecl, args);
589 /* Generate code for EXPONENT(X) intrinsic function. */
591 static void
592 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
594 tree args, fndecl;
595 gfc_expr *a1;
597 args = gfc_conv_intrinsic_function_args (se, expr);
599 a1 = expr->value.function.actual->expr;
600 switch (a1->ts.kind)
602 case 4:
603 fndecl = gfor_fndecl_math_exponent4;
604 break;
605 case 8:
606 fndecl = gfor_fndecl_math_exponent8;
607 break;
608 default:
609 abort ();
612 se->expr = gfc_build_function_call (fndecl, args);
615 /* Evaluate a single upper or lower bound. */
616 /* TODO: bound intrinsic generates way too much unneccessary code. */
618 static void
619 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
621 gfc_actual_arglist *arg;
622 gfc_actual_arglist *arg2;
623 tree desc;
624 tree type;
625 tree bound;
626 tree tmp;
627 tree cond;
628 gfc_se argse;
629 gfc_ss *ss;
630 int i;
632 gfc_init_se (&argse, NULL);
633 arg = expr->value.function.actual;
634 arg2 = arg->next;
636 if (se->ss)
638 /* Create an implicit second parameter from the loop variable. */
639 assert (!arg2->expr);
640 assert (se->loop->dimen == 1);
641 assert (se->ss->expr == expr);
642 gfc_advance_se_ss_chain (se);
643 bound = se->loop->loopvar[0];
644 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
645 se->loop->from[0]));
647 else
649 /* use the passed argument. */
650 assert (arg->next->expr);
651 gfc_init_se (&argse, NULL);
652 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
653 gfc_add_block_to_block (&se->pre, &argse.pre);
654 bound = argse.expr;
655 /* Convert from one based to zero based. */
656 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
657 gfc_index_one_node));
660 /* TODO: don't re-evaluate the descriptor on each iteration. */
661 /* Get a descriptor for the first parameter. */
662 ss = gfc_walk_expr (arg->expr);
663 assert (ss != gfc_ss_terminator);
664 argse.want_pointer = 0;
665 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
666 gfc_add_block_to_block (&se->pre, &argse.pre);
667 gfc_add_block_to_block (&se->post, &argse.post);
669 desc = argse.expr;
671 if (INTEGER_CST_P (bound))
673 assert (TREE_INT_CST_HIGH (bound) == 0);
674 i = TREE_INT_CST_LOW (bound);
675 assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
677 else
679 if (flag_bounds_check)
681 bound = gfc_evaluate_now (bound, &se->pre);
682 cond = fold (build (LT_EXPR, boolean_type_node, bound,
683 convert (TREE_TYPE (bound), integer_zero_node)));
684 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
685 tmp = fold (build (GE_EXPR, boolean_type_node, bound, tmp));
686 cond = fold(build (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp));
687 gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
691 if (upper)
692 se->expr = gfc_conv_descriptor_ubound(desc, bound);
693 else
694 se->expr = gfc_conv_descriptor_lbound(desc, bound);
696 type = gfc_typenode_for_spec (&expr->ts);
697 se->expr = convert (type, se->expr);
701 static void
702 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
704 tree args;
705 tree val;
706 int n;
708 args = gfc_conv_intrinsic_function_args (se, expr);
709 assert (args && TREE_CHAIN (args) == NULL_TREE);
710 val = TREE_VALUE (args);
712 switch (expr->value.function.actual->expr->ts.type)
714 case BT_INTEGER:
715 case BT_REAL:
716 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
717 break;
719 case BT_COMPLEX:
720 switch (expr->ts.kind)
722 case 4:
723 n = BUILT_IN_CABSF;
724 break;
725 case 8:
726 n = BUILT_IN_CABS;
727 break;
728 default:
729 abort ();
731 se->expr = fold (gfc_build_function_call (built_in_decls[n], args));
732 break;
734 default:
735 abort ();
740 /* Create a complex value from one or two real components. */
742 static void
743 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
745 tree arg;
746 tree real;
747 tree imag;
748 tree type;
750 type = gfc_typenode_for_spec (&expr->ts);
751 arg = gfc_conv_intrinsic_function_args (se, expr);
752 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
753 if (both)
754 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
755 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
757 arg = TREE_VALUE (arg);
758 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
759 imag = convert (TREE_TYPE (type), imag);
761 else
762 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
764 se->expr = fold (build (COMPLEX_EXPR, type, real, imag));
767 /* Remainder function MOD(A, P) = A - INT(A / P) * P.
768 MODULO(A, P) = (A==0 .or. !(A>0 .xor. P>0))? MOD(A,P):MOD(A,P)+P. */
769 /* TODO: MOD(x, 0) */
771 static void
772 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
774 tree arg;
775 tree arg2;
776 tree type;
777 tree itype;
778 tree tmp;
779 tree zero;
780 tree test;
781 tree test2;
782 mpfr_t huge;
783 int n;
785 arg = gfc_conv_intrinsic_function_args (se, expr);
786 arg2 = TREE_VALUE (TREE_CHAIN (arg));
787 arg = TREE_VALUE (arg);
788 type = TREE_TYPE (arg);
790 switch (expr->ts.type)
792 case BT_INTEGER:
793 /* Integer case is easy, we've got a builtin op. */
794 se->expr = build (TRUNC_MOD_EXPR, type, arg, arg2);
795 break;
797 case BT_REAL:
798 /* Real values we have to do the hard way. */
799 arg = gfc_evaluate_now (arg, &se->pre);
800 arg2 = gfc_evaluate_now (arg2, &se->pre);
802 tmp = build (RDIV_EXPR, type, arg, arg2);
803 /* Test if the value is too large to handle sensibly. */
804 gfc_set_model_kind (expr->ts.kind);
805 mpfr_init (huge);
806 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind);
807 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
808 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
809 test2 = build (LT_EXPR, boolean_type_node, tmp, test);
811 mpfr_neg (huge, huge, GFC_RND_MODE);
812 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
813 test = build (GT_EXPR, boolean_type_node, tmp, test);
814 test2 = build (TRUTH_AND_EXPR, boolean_type_node, test, test2);
816 itype = gfc_get_int_type (expr->ts.kind);
817 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
818 tmp = convert (type, tmp);
819 tmp = build (COND_EXPR, type, test2, tmp, arg);
820 tmp = build (MULT_EXPR, type, tmp, arg2);
821 se->expr = build (MINUS_EXPR, type, arg, tmp);
822 mpfr_clear (huge);
823 break;
825 default:
826 abort ();
829 if (modulo)
831 zero = gfc_build_const (type, integer_zero_node);
832 /* Build !(A > 0 .xor. P > 0). */
833 test = build (GT_EXPR, boolean_type_node, arg, zero);
834 test2 = build (GT_EXPR, boolean_type_node, arg2, zero);
835 test = build (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
836 test = build1 (TRUTH_NOT_EXPR, boolean_type_node, test);
837 /* Build (A == 0) .or. !(A > 0 .xor. P > 0). */
838 test2 = build (EQ_EXPR, boolean_type_node, arg, zero);
839 test = build (TRUTH_OR_EXPR, boolean_type_node, test, test2);
841 se->expr = build (COND_EXPR, type, test, se->expr,
842 build (PLUS_EXPR, type, se->expr, arg2));
846 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
848 static void
849 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
851 tree arg;
852 tree arg2;
853 tree val;
854 tree tmp;
855 tree type;
856 tree zero;
858 arg = gfc_conv_intrinsic_function_args (se, expr);
859 arg2 = TREE_VALUE (TREE_CHAIN (arg));
860 arg = TREE_VALUE (arg);
861 type = TREE_TYPE (arg);
863 val = build (MINUS_EXPR, type, arg, arg2);
864 val = gfc_evaluate_now (val, &se->pre);
866 zero = gfc_build_const (type, integer_zero_node);
867 tmp = build (LE_EXPR, boolean_type_node, val, zero);
868 se->expr = build (COND_EXPR, type, tmp, zero, val);
872 /* SIGN(A, B) is absolute value of A times sign of B.
873 The real value versions use library functions to ensure the correct
874 handling of negative zero. Integer case implemented as:
875 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
878 static void
879 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
881 tree tmp;
882 tree arg;
883 tree arg2;
884 tree type;
885 tree zero;
886 tree testa;
887 tree testb;
890 arg = gfc_conv_intrinsic_function_args (se, expr);
891 if (expr->ts.type == BT_REAL)
893 switch (expr->ts.kind)
895 case 4:
896 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
897 break;
898 case 8:
899 tmp = built_in_decls[BUILT_IN_COPYSIGN];
900 break;
901 default:
902 abort ();
904 se->expr = fold (gfc_build_function_call (tmp, arg));
905 return;
908 arg2 = TREE_VALUE (TREE_CHAIN (arg));
909 arg = TREE_VALUE (arg);
910 type = TREE_TYPE (arg);
911 zero = gfc_build_const (type, integer_zero_node);
913 testa = fold (build (GE_EXPR, boolean_type_node, arg, zero));
914 testb = fold (build (GE_EXPR, boolean_type_node, arg2, zero));
915 tmp = fold (build (TRUTH_XOR_EXPR, boolean_type_node, testa, testb));
916 se->expr = fold (build (COND_EXPR, type, tmp,
917 build1 (NEGATE_EXPR, type, arg), arg));
921 /* Test for the presence of an optional argument. */
923 static void
924 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
926 gfc_expr *arg;
928 arg = expr->value.function.actual->expr;
929 assert (arg->expr_type == EXPR_VARIABLE);
930 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
931 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
935 /* Calculate the double precision product of two single precision values. */
937 static void
938 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
940 tree arg;
941 tree arg2;
942 tree type;
944 arg = gfc_conv_intrinsic_function_args (se, expr);
945 arg2 = TREE_VALUE (TREE_CHAIN (arg));
946 arg = TREE_VALUE (arg);
948 /* Convert the args to double precision before multiplying. */
949 type = gfc_typenode_for_spec (&expr->ts);
950 arg = convert (type, arg);
951 arg2 = convert (type, arg2);
952 se->expr = build (MULT_EXPR, type, arg, arg2);
956 /* Return a length one character string containing an ascii character. */
958 static void
959 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
961 tree arg;
962 tree var;
963 tree type;
965 arg = gfc_conv_intrinsic_function_args (se, expr);
966 arg = TREE_VALUE (arg);
968 /* We currently don't support character types != 1. */
969 assert (expr->ts.kind == 1);
970 type = gfc_character1_type_node;
971 var = gfc_create_var (type, "char");
973 arg = convert (type, arg);
974 gfc_add_modify_expr (&se->pre, var, arg);
975 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
976 se->string_length = integer_one_node;
980 /* Get the minimum/maximum value of all the parameters.
981 minmax (a1, a2, a3, ...)
983 if (a2 .op. a1)
984 mvar = a2;
985 else
986 mvar = a1;
987 if (a3 .op. mvar)
988 mvar = a3;
990 return mvar
994 /* TODO: Mismatching types can occur when specific names are used.
995 These should be handled during resolution. */
996 static void
997 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
999 tree limit;
1000 tree tmp;
1001 tree mvar;
1002 tree val;
1003 tree thencase;
1004 tree elsecase;
1005 tree arg;
1006 tree type;
1008 arg = gfc_conv_intrinsic_function_args (se, expr);
1009 type = gfc_typenode_for_spec (&expr->ts);
1011 limit = TREE_VALUE (arg);
1012 if (TREE_TYPE (limit) != type)
1013 limit = convert (type, limit);
1014 /* Only evaluate the argument once. */
1015 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1016 limit = gfc_evaluate_now(limit, &se->pre);
1018 mvar = gfc_create_var (type, "M");
1019 elsecase = build_v (MODIFY_EXPR, mvar, limit);
1020 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1022 val = TREE_VALUE (arg);
1023 if (TREE_TYPE (val) != type)
1024 val = convert (type, val);
1026 /* Only evaluate the argument once. */
1027 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1028 val = gfc_evaluate_now(val, &se->pre);
1030 thencase = build_v (MODIFY_EXPR, mvar, convert (type, val));
1032 tmp = build (op, boolean_type_node, val, limit);
1033 tmp = build_v (COND_EXPR, tmp, thencase, elsecase);
1034 gfc_add_expr_to_block (&se->pre, tmp);
1035 elsecase = build_empty_stmt ();
1036 limit = mvar;
1038 se->expr = mvar;
1042 /* Create a symbol node for this intrinsic. The symbol form the frontend
1043 is for the generic name. */
1045 static gfc_symbol *
1046 gfc_get_symbol_for_expr (gfc_expr * expr)
1048 gfc_symbol *sym;
1050 /* TODO: Add symbols for intrinsic function to the global namespace. */
1051 assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1052 sym = gfc_new_symbol (expr->value.function.name, NULL);
1054 sym->ts = expr->ts;
1055 sym->attr.external = 1;
1056 sym->attr.function = 1;
1057 sym->attr.always_explicit = 1;
1058 sym->attr.proc = PROC_INTRINSIC;
1059 sym->attr.flavor = FL_PROCEDURE;
1060 sym->result = sym;
1061 if (expr->rank > 0)
1063 sym->attr.dimension = 1;
1064 sym->as = gfc_get_array_spec ();
1065 sym->as->type = AS_ASSUMED_SHAPE;
1066 sym->as->rank = expr->rank;
1069 /* TODO: proper argument lists for external intrinsics. */
1070 return sym;
1073 /* Generate a call to an external intrinsic function. */
1074 static void
1075 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1077 gfc_symbol *sym;
1079 assert (!se->ss || se->ss->expr == expr);
1081 if (se->ss)
1082 assert (expr->rank > 0);
1083 else
1084 assert (expr->rank == 0);
1086 sym = gfc_get_symbol_for_expr (expr);
1087 gfc_conv_function_call (se, sym, expr->value.function.actual);
1088 gfc_free (sym);
1091 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1092 Implemented as
1093 any(a)
1095 forall (i=...)
1096 if (a[i] != 0)
1097 return 1
1098 end forall
1099 return 0
1101 all(a)
1103 forall (i=...)
1104 if (a[i] == 0)
1105 return 0
1106 end forall
1107 return 1
1110 static void
1111 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1113 tree resvar;
1114 stmtblock_t block;
1115 stmtblock_t body;
1116 tree type;
1117 tree tmp;
1118 tree found;
1119 gfc_loopinfo loop;
1120 gfc_actual_arglist *actual;
1121 gfc_ss *arrayss;
1122 gfc_se arrayse;
1123 tree exit_label;
1125 if (se->ss)
1127 gfc_conv_intrinsic_funcall (se, expr);
1128 return;
1131 actual = expr->value.function.actual;
1132 type = gfc_typenode_for_spec (&expr->ts);
1133 /* Initialize the result. */
1134 resvar = gfc_create_var (type, "test");
1135 if (op == EQ_EXPR)
1136 tmp = convert (type, boolean_true_node);
1137 else
1138 tmp = convert (type, boolean_false_node);
1139 gfc_add_modify_expr (&se->pre, resvar, tmp);
1141 /* Walk the arguments. */
1142 arrayss = gfc_walk_expr (actual->expr);
1143 assert (arrayss != gfc_ss_terminator);
1145 /* Initialize the scalarizer. */
1146 gfc_init_loopinfo (&loop);
1147 exit_label = gfc_build_label_decl (NULL_TREE);
1148 TREE_USED (exit_label) = 1;
1149 gfc_add_ss_to_loop (&loop, arrayss);
1151 /* Initialize the loop. */
1152 gfc_conv_ss_startstride (&loop);
1153 gfc_conv_loop_setup (&loop);
1155 gfc_mark_ss_chain_used (arrayss, 1);
1156 /* Generate the loop body. */
1157 gfc_start_scalarized_body (&loop, &body);
1159 /* If the condition matches then set the return value. */
1160 gfc_start_block (&block);
1161 if (op == EQ_EXPR)
1162 tmp = convert (type, boolean_false_node);
1163 else
1164 tmp = convert (type, boolean_true_node);
1165 gfc_add_modify_expr (&block, resvar, tmp);
1167 /* And break out of the loop. */
1168 tmp = build1_v (GOTO_EXPR, exit_label);
1169 gfc_add_expr_to_block (&block, tmp);
1171 found = gfc_finish_block (&block);
1173 /* Check this element. */
1174 gfc_init_se (&arrayse, NULL);
1175 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1176 arrayse.ss = arrayss;
1177 gfc_conv_expr_val (&arrayse, actual->expr);
1179 gfc_add_block_to_block (&body, &arrayse.pre);
1180 tmp = build (op, boolean_type_node, arrayse.expr,
1181 fold_convert (TREE_TYPE (arrayse.expr),
1182 integer_zero_node));
1183 tmp = build_v (COND_EXPR, tmp, found, build_empty_stmt ());
1184 gfc_add_expr_to_block (&body, tmp);
1185 gfc_add_block_to_block (&body, &arrayse.post);
1187 gfc_trans_scalarizing_loops (&loop, &body);
1189 /* Add the exit label. */
1190 tmp = build1_v (LABEL_EXPR, exit_label);
1191 gfc_add_expr_to_block (&loop.pre, tmp);
1193 gfc_add_block_to_block (&se->pre, &loop.pre);
1194 gfc_add_block_to_block (&se->pre, &loop.post);
1195 gfc_cleanup_loop (&loop);
1197 se->expr = resvar;
1200 /* COUNT(A) = Number of true elements in A. */
1201 static void
1202 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1204 tree resvar;
1205 tree type;
1206 stmtblock_t body;
1207 tree tmp;
1208 gfc_loopinfo loop;
1209 gfc_actual_arglist *actual;
1210 gfc_ss *arrayss;
1211 gfc_se arrayse;
1213 if (se->ss)
1215 gfc_conv_intrinsic_funcall (se, expr);
1216 return;
1219 actual = expr->value.function.actual;
1221 type = gfc_typenode_for_spec (&expr->ts);
1222 /* Initialize the result. */
1223 resvar = gfc_create_var (type, "count");
1224 gfc_add_modify_expr (&se->pre, resvar, convert (type, integer_zero_node));
1226 /* Walk the arguments. */
1227 arrayss = gfc_walk_expr (actual->expr);
1228 assert (arrayss != gfc_ss_terminator);
1230 /* Initialize the scalarizer. */
1231 gfc_init_loopinfo (&loop);
1232 gfc_add_ss_to_loop (&loop, arrayss);
1234 /* Initialize the loop. */
1235 gfc_conv_ss_startstride (&loop);
1236 gfc_conv_loop_setup (&loop);
1238 gfc_mark_ss_chain_used (arrayss, 1);
1239 /* Generate the loop body. */
1240 gfc_start_scalarized_body (&loop, &body);
1242 tmp = build (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1243 convert (TREE_TYPE (resvar), integer_one_node));
1244 tmp = build_v (MODIFY_EXPR, resvar, tmp);
1246 gfc_init_se (&arrayse, NULL);
1247 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1248 arrayse.ss = arrayss;
1249 gfc_conv_expr_val (&arrayse, actual->expr);
1250 tmp = build_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1252 gfc_add_block_to_block (&body, &arrayse.pre);
1253 gfc_add_expr_to_block (&body, tmp);
1254 gfc_add_block_to_block (&body, &arrayse.post);
1256 gfc_trans_scalarizing_loops (&loop, &body);
1258 gfc_add_block_to_block (&se->pre, &loop.pre);
1259 gfc_add_block_to_block (&se->pre, &loop.post);
1260 gfc_cleanup_loop (&loop);
1262 se->expr = resvar;
1265 /* Inline implementation of the sum and product intrinsics. */
1266 static void
1267 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1269 tree resvar;
1270 tree type;
1271 stmtblock_t body;
1272 stmtblock_t block;
1273 tree tmp;
1274 gfc_loopinfo loop;
1275 gfc_actual_arglist *actual;
1276 gfc_ss *arrayss;
1277 gfc_ss *maskss;
1278 gfc_se arrayse;
1279 gfc_se maskse;
1280 gfc_expr *arrayexpr;
1281 gfc_expr *maskexpr;
1283 if (se->ss)
1285 gfc_conv_intrinsic_funcall (se, expr);
1286 return;
1289 type = gfc_typenode_for_spec (&expr->ts);
1290 /* Initialize the result. */
1291 resvar = gfc_create_var (type, "val");
1292 if (op == PLUS_EXPR)
1293 tmp = gfc_build_const (type, integer_zero_node);
1294 else
1295 tmp = gfc_build_const (type, integer_one_node);
1297 gfc_add_modify_expr (&se->pre, resvar, tmp);
1299 /* Walk the arguments. */
1300 actual = expr->value.function.actual;
1301 arrayexpr = actual->expr;
1302 arrayss = gfc_walk_expr (arrayexpr);
1303 assert (arrayss != gfc_ss_terminator);
1305 actual = actual->next->next;
1306 assert (actual);
1307 maskexpr = actual->expr;
1308 if (maskexpr)
1310 maskss = gfc_walk_expr (maskexpr);
1311 assert (maskss != gfc_ss_terminator);
1313 else
1314 maskss = NULL;
1316 /* Initialize the scalarizer. */
1317 gfc_init_loopinfo (&loop);
1318 gfc_add_ss_to_loop (&loop, arrayss);
1319 if (maskss)
1320 gfc_add_ss_to_loop (&loop, maskss);
1322 /* Initialize the loop. */
1323 gfc_conv_ss_startstride (&loop);
1324 gfc_conv_loop_setup (&loop);
1326 gfc_mark_ss_chain_used (arrayss, 1);
1327 if (maskss)
1328 gfc_mark_ss_chain_used (maskss, 1);
1329 /* Generate the loop body. */
1330 gfc_start_scalarized_body (&loop, &body);
1332 /* If we have a mask, only add this element if the mask is set. */
1333 if (maskss)
1335 gfc_init_se (&maskse, NULL);
1336 gfc_copy_loopinfo_to_se (&maskse, &loop);
1337 maskse.ss = maskss;
1338 gfc_conv_expr_val (&maskse, maskexpr);
1339 gfc_add_block_to_block (&body, &maskse.pre);
1341 gfc_start_block (&block);
1343 else
1344 gfc_init_block (&block);
1346 /* Do the actual summation/product. */
1347 gfc_init_se (&arrayse, NULL);
1348 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1349 arrayse.ss = arrayss;
1350 gfc_conv_expr_val (&arrayse, arrayexpr);
1351 gfc_add_block_to_block (&block, &arrayse.pre);
1353 tmp = build (op, type, resvar, arrayse.expr);
1354 gfc_add_modify_expr (&block, resvar, tmp);
1355 gfc_add_block_to_block (&block, &arrayse.post);
1357 if (maskss)
1359 /* We enclose the above in if (mask) {...} . */
1360 tmp = gfc_finish_block (&block);
1362 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1364 else
1365 tmp = gfc_finish_block (&block);
1366 gfc_add_expr_to_block (&body, tmp);
1368 gfc_trans_scalarizing_loops (&loop, &body);
1369 gfc_add_block_to_block (&se->pre, &loop.pre);
1370 gfc_add_block_to_block (&se->pre, &loop.post);
1371 gfc_cleanup_loop (&loop);
1373 se->expr = resvar;
1376 static void
1377 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1379 stmtblock_t body;
1380 stmtblock_t block;
1381 stmtblock_t ifblock;
1382 tree limit;
1383 tree type;
1384 tree tmp;
1385 tree ifbody;
1386 tree cond;
1387 gfc_loopinfo loop;
1388 gfc_actual_arglist *actual;
1389 gfc_ss *arrayss;
1390 gfc_ss *maskss;
1391 gfc_se arrayse;
1392 gfc_se maskse;
1393 gfc_expr *arrayexpr;
1394 gfc_expr *maskexpr;
1395 tree pos;
1396 int n;
1398 if (se->ss)
1400 gfc_conv_intrinsic_funcall (se, expr);
1401 return;
1404 /* Initialize the result. */
1405 pos = gfc_create_var (gfc_array_index_type, "pos");
1406 type = gfc_typenode_for_spec (&expr->ts);
1408 /* Walk the arguments. */
1409 actual = expr->value.function.actual;
1410 arrayexpr = actual->expr;
1411 arrayss = gfc_walk_expr (arrayexpr);
1412 assert (arrayss != gfc_ss_terminator);
1414 actual = actual->next->next;
1415 assert (actual);
1416 maskexpr = actual->expr;
1417 if (maskexpr)
1419 maskss = gfc_walk_expr (maskexpr);
1420 assert (maskss != gfc_ss_terminator);
1422 else
1423 maskss = NULL;
1425 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1426 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind);
1427 switch (arrayexpr->ts.type)
1429 case BT_REAL:
1430 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1431 break;
1433 case BT_INTEGER:
1434 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1435 arrayexpr->ts.kind);
1436 break;
1438 default:
1439 abort ();
1442 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1443 if (op == GT_EXPR)
1444 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1445 gfc_add_modify_expr (&se->pre, limit, tmp);
1447 /* Initialize the scalarizer. */
1448 gfc_init_loopinfo (&loop);
1449 gfc_add_ss_to_loop (&loop, arrayss);
1450 if (maskss)
1451 gfc_add_ss_to_loop (&loop, maskss);
1453 /* Initialize the loop. */
1454 gfc_conv_ss_startstride (&loop);
1455 gfc_conv_loop_setup (&loop);
1457 assert (loop.dimen == 1);
1459 /* Initialize the position to the first element. If the array has zero
1460 size we need to return zero. Otherwise use the first element of the
1461 array, in case all elements are equal to the limit.
1462 ie. pos = (ubound >= lbound) ? lbound, lbound - 1; */
1463 tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
1464 loop.from[0], gfc_index_one_node));
1465 cond = fold (build (GE_EXPR, boolean_type_node,
1466 loop.to[0], loop.from[0]));
1467 tmp = fold (build (COND_EXPR, gfc_array_index_type, cond,
1468 loop.from[0], tmp));
1469 gfc_add_modify_expr (&loop.pre, pos, tmp);
1471 gfc_mark_ss_chain_used (arrayss, 1);
1472 if (maskss)
1473 gfc_mark_ss_chain_used (maskss, 1);
1474 /* Generate the loop body. */
1475 gfc_start_scalarized_body (&loop, &body);
1477 /* If we have a mask, only check this element if the mask is set. */
1478 if (maskss)
1480 gfc_init_se (&maskse, NULL);
1481 gfc_copy_loopinfo_to_se (&maskse, &loop);
1482 maskse.ss = maskss;
1483 gfc_conv_expr_val (&maskse, maskexpr);
1484 gfc_add_block_to_block (&body, &maskse.pre);
1486 gfc_start_block (&block);
1488 else
1489 gfc_init_block (&block);
1491 /* Compare with the current limit. */
1492 gfc_init_se (&arrayse, NULL);
1493 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1494 arrayse.ss = arrayss;
1495 gfc_conv_expr_val (&arrayse, arrayexpr);
1496 gfc_add_block_to_block (&block, &arrayse.pre);
1498 /* We do the following if this is a more extreme value. */
1499 gfc_start_block (&ifblock);
1501 /* Assign the value to the limit... */
1502 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1504 /* Remember where we are. */
1505 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1507 ifbody = gfc_finish_block (&ifblock);
1509 /* If it is a more extreme value. */
1510 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1511 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1512 gfc_add_expr_to_block (&block, tmp);
1514 if (maskss)
1516 /* We enclose the above in if (mask) {...}. */
1517 tmp = gfc_finish_block (&block);
1519 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1521 else
1522 tmp = gfc_finish_block (&block);
1523 gfc_add_expr_to_block (&body, tmp);
1525 gfc_trans_scalarizing_loops (&loop, &body);
1527 gfc_add_block_to_block (&se->pre, &loop.pre);
1528 gfc_add_block_to_block (&se->pre, &loop.post);
1529 gfc_cleanup_loop (&loop);
1531 /* Return a value in the range 1..SIZE(array). */
1532 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1533 gfc_index_one_node));
1534 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, pos, tmp));
1535 /* And convert to the required type. */
1536 se->expr = convert (type, tmp);
1539 static void
1540 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1542 tree limit;
1543 tree type;
1544 tree tmp;
1545 tree ifbody;
1546 stmtblock_t body;
1547 stmtblock_t block;
1548 gfc_loopinfo loop;
1549 gfc_actual_arglist *actual;
1550 gfc_ss *arrayss;
1551 gfc_ss *maskss;
1552 gfc_se arrayse;
1553 gfc_se maskse;
1554 gfc_expr *arrayexpr;
1555 gfc_expr *maskexpr;
1556 int n;
1558 if (se->ss)
1560 gfc_conv_intrinsic_funcall (se, expr);
1561 return;
1564 type = gfc_typenode_for_spec (&expr->ts);
1565 /* Initialize the result. */
1566 limit = gfc_create_var (type, "limit");
1567 n = gfc_validate_kind (expr->ts.type, expr->ts.kind);
1568 switch (expr->ts.type)
1570 case BT_REAL:
1571 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1572 break;
1574 case BT_INTEGER:
1575 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1576 break;
1578 default:
1579 abort ();
1582 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1583 if (op == GT_EXPR)
1584 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1585 gfc_add_modify_expr (&se->pre, limit, tmp);
1587 /* Walk the arguments. */
1588 actual = expr->value.function.actual;
1589 arrayexpr = actual->expr;
1590 arrayss = gfc_walk_expr (arrayexpr);
1591 assert (arrayss != gfc_ss_terminator);
1593 actual = actual->next->next;
1594 assert (actual);
1595 maskexpr = actual->expr;
1596 if (maskexpr)
1598 maskss = gfc_walk_expr (maskexpr);
1599 assert (maskss != gfc_ss_terminator);
1601 else
1602 maskss = NULL;
1604 /* Initialize the scalarizer. */
1605 gfc_init_loopinfo (&loop);
1606 gfc_add_ss_to_loop (&loop, arrayss);
1607 if (maskss)
1608 gfc_add_ss_to_loop (&loop, maskss);
1610 /* Initialize the loop. */
1611 gfc_conv_ss_startstride (&loop);
1612 gfc_conv_loop_setup (&loop);
1614 gfc_mark_ss_chain_used (arrayss, 1);
1615 if (maskss)
1616 gfc_mark_ss_chain_used (maskss, 1);
1617 /* Generate the loop body. */
1618 gfc_start_scalarized_body (&loop, &body);
1620 /* If we have a mask, only add this element if the mask is set. */
1621 if (maskss)
1623 gfc_init_se (&maskse, NULL);
1624 gfc_copy_loopinfo_to_se (&maskse, &loop);
1625 maskse.ss = maskss;
1626 gfc_conv_expr_val (&maskse, maskexpr);
1627 gfc_add_block_to_block (&body, &maskse.pre);
1629 gfc_start_block (&block);
1631 else
1632 gfc_init_block (&block);
1634 /* Compare with the current limit. */
1635 gfc_init_se (&arrayse, NULL);
1636 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1637 arrayse.ss = arrayss;
1638 gfc_conv_expr_val (&arrayse, arrayexpr);
1639 gfc_add_block_to_block (&block, &arrayse.pre);
1641 /* Assign the value to the limit... */
1642 ifbody = build_v (MODIFY_EXPR, limit, arrayse.expr);
1644 /* If it is a more extreme value. */
1645 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1646 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1647 gfc_add_expr_to_block (&block, tmp);
1648 gfc_add_block_to_block (&block, &arrayse.post);
1650 tmp = gfc_finish_block (&block);
1651 if (maskss)
1653 /* We enclose the above in if (mask) {...}. */
1654 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1656 gfc_add_expr_to_block (&body, tmp);
1658 gfc_trans_scalarizing_loops (&loop, &body);
1660 gfc_add_block_to_block (&se->pre, &loop.pre);
1661 gfc_add_block_to_block (&se->pre, &loop.post);
1662 gfc_cleanup_loop (&loop);
1664 se->expr = limit;
1667 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
1668 static void
1669 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
1671 tree arg;
1672 tree arg2;
1673 tree type;
1674 tree tmp;
1676 arg = gfc_conv_intrinsic_function_args (se, expr);
1677 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1678 arg = TREE_VALUE (arg);
1679 type = TREE_TYPE (arg);
1681 tmp = build (LSHIFT_EXPR, type, convert (type, integer_one_node), arg2);
1682 tmp = build (BIT_AND_EXPR, type, arg, tmp);
1683 tmp = fold (build (NE_EXPR, boolean_type_node, tmp,
1684 convert (type, integer_zero_node)));
1685 type = gfc_typenode_for_spec (&expr->ts);
1686 se->expr = convert (type, tmp);
1689 /* Generate code to perform the specified operation. */
1690 static void
1691 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
1693 tree arg;
1694 tree arg2;
1695 tree type;
1697 arg = gfc_conv_intrinsic_function_args (se, expr);
1698 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1699 arg = TREE_VALUE (arg);
1700 type = TREE_TYPE (arg);
1702 se->expr = fold (build (op, type, arg, arg2));
1705 /* Bitwise not. */
1706 static void
1707 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
1709 tree arg;
1711 arg = gfc_conv_intrinsic_function_args (se, expr);
1712 arg = TREE_VALUE (arg);
1714 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
1717 /* Set or clear a single bit. */
1718 static void
1719 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
1721 tree arg;
1722 tree arg2;
1723 tree type;
1724 tree tmp;
1725 int op;
1727 arg = gfc_conv_intrinsic_function_args (se, expr);
1728 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1729 arg = TREE_VALUE (arg);
1730 type = TREE_TYPE (arg);
1732 tmp = fold (build (LSHIFT_EXPR, type,
1733 convert (type, integer_one_node), arg2));
1734 if (set)
1735 op = BIT_IOR_EXPR;
1736 else
1738 op = BIT_AND_EXPR;
1739 tmp = fold (build1 (BIT_NOT_EXPR, type, tmp));
1741 se->expr = fold (build (op, type, arg, tmp));
1744 /* Extract a sequence of bits.
1745 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
1746 static void
1747 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
1749 tree arg;
1750 tree arg2;
1751 tree arg3;
1752 tree type;
1753 tree tmp;
1754 tree mask;
1756 arg = gfc_conv_intrinsic_function_args (se, expr);
1757 arg2 = TREE_CHAIN (arg);
1758 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
1759 arg = TREE_VALUE (arg);
1760 arg2 = TREE_VALUE (arg2);
1761 type = TREE_TYPE (arg);
1763 mask = build_int_cst (NULL_TREE, -1, ~(unsigned HOST_WIDE_INT) 0);
1764 mask = build (LSHIFT_EXPR, type, mask, arg3);
1765 mask = build1 (BIT_NOT_EXPR, type, mask);
1767 tmp = build (RSHIFT_EXPR, type, arg, arg2);
1769 se->expr = fold (build (BIT_AND_EXPR, type, tmp, mask));
1772 /* ISHFT (I, SHIFT) = (shift >= 0) ? i << shift : i >> -shift. */
1773 static void
1774 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
1776 tree arg;
1777 tree arg2;
1778 tree type;
1779 tree tmp;
1780 tree lshift;
1781 tree rshift;
1783 arg = gfc_conv_intrinsic_function_args (se, expr);
1784 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1785 arg = TREE_VALUE (arg);
1786 type = TREE_TYPE (arg);
1788 /* Left shift if positive. */
1789 lshift = build (LSHIFT_EXPR, type, arg, arg2);
1791 /* Right shift if negative. This will perform an arithmetic shift as
1792 we are dealing with signed integers. Section 13.5.7 allows this. */
1793 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1794 rshift = build (RSHIFT_EXPR, type, arg, tmp);
1796 tmp = build (GT_EXPR, boolean_type_node, arg2,
1797 convert (TREE_TYPE (arg2), integer_zero_node));
1798 rshift = build (COND_EXPR, type, tmp, lshift, rshift);
1800 /* Do nothing if shift == 0. */
1801 tmp = build (EQ_EXPR, boolean_type_node, arg2,
1802 convert (TREE_TYPE (arg2), integer_zero_node));
1803 se->expr = build (COND_EXPR, type, tmp, arg, rshift);
1806 /* Circular shift. AKA rotate or barrel shift. */
1807 static void
1808 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
1810 tree arg;
1811 tree arg2;
1812 tree arg3;
1813 tree type;
1814 tree tmp;
1815 tree lrot;
1816 tree rrot;
1818 arg = gfc_conv_intrinsic_function_args (se, expr);
1819 arg2 = TREE_CHAIN (arg);
1820 arg3 = TREE_CHAIN (arg2);
1821 if (arg3)
1823 /* Use a library function for the 3 parameter version. */
1824 type = TREE_TYPE (TREE_VALUE (arg));
1825 /* Convert all args to the same type otherwise we need loads of library
1826 functions. SIZE and SHIFT cannot have values > BIT_SIZE (I) so the
1827 conversion is safe. */
1828 tmp = convert (type, TREE_VALUE (arg2));
1829 TREE_VALUE (arg2) = tmp;
1830 tmp = convert (type, TREE_VALUE (arg3));
1831 TREE_VALUE (arg3) = tmp;
1833 switch (expr->ts.kind)
1835 case 4:
1836 tmp = gfor_fndecl_math_ishftc4;
1837 break;
1838 case 8:
1839 tmp = gfor_fndecl_math_ishftc8;
1840 break;
1841 default:
1842 abort ();
1844 se->expr = gfc_build_function_call (tmp, arg);
1845 return;
1847 arg = TREE_VALUE (arg);
1848 arg2 = TREE_VALUE (arg2);
1849 type = TREE_TYPE (arg);
1851 /* Rotate left if positive. */
1852 lrot = build (LROTATE_EXPR, type, arg, arg2);
1854 /* Rotate right if negative. */
1855 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1856 rrot = build (RROTATE_EXPR, type, arg, tmp);
1858 tmp = build (GT_EXPR, boolean_type_node, arg2,
1859 convert (TREE_TYPE (arg2), integer_zero_node));
1860 rrot = build (COND_EXPR, type, tmp, lrot, rrot);
1862 /* Do nothing if shift == 0. */
1863 tmp = build (EQ_EXPR, boolean_type_node, arg2,
1864 convert (TREE_TYPE (arg2), integer_zero_node));
1865 se->expr = build (COND_EXPR, type, tmp, arg, rrot);
1868 /* The length of a character string. */
1869 static void
1870 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
1872 tree len;
1873 tree type;
1874 tree decl;
1875 gfc_symbol *sym;
1876 gfc_se argse;
1877 gfc_expr *arg;
1879 assert (!se->ss);
1881 arg = expr->value.function.actual->expr;
1883 type = gfc_typenode_for_spec (&expr->ts);
1884 switch (arg->expr_type)
1886 case EXPR_CONSTANT:
1887 len = build_int_cst (NULL_TREE, arg->value.character.length, 0);
1888 break;
1890 default:
1891 if (arg->expr_type == EXPR_VARIABLE
1892 && (arg->ref == NULL || (arg->ref->next == NULL
1893 && arg->ref->type == REF_ARRAY)))
1895 /* This doesn't catch all cases.
1896 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
1897 and the surrounding thread. */
1898 sym = arg->symtree->n.sym;
1899 decl = gfc_get_symbol_decl (sym);
1900 if (decl == current_function_decl && sym->attr.function
1901 && (sym->result == sym))
1902 decl = gfc_get_fake_result_decl (sym);
1904 len = sym->ts.cl->backend_decl;
1905 assert (len);
1907 else
1909 /* Anybody stupid enough to do this deserves inefficient code. */
1910 gfc_init_se (&argse, se);
1911 gfc_conv_expr (&argse, arg);
1912 gfc_add_block_to_block (&se->pre, &argse.pre);
1913 gfc_add_block_to_block (&se->post, &argse.post);
1914 len = argse.string_length;
1916 break;
1918 se->expr = convert (type, len);
1921 /* The length of a character string not including trailing blanks. */
1922 static void
1923 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
1925 tree args;
1926 tree type;
1928 args = gfc_conv_intrinsic_function_args (se, expr);
1929 type = gfc_typenode_for_spec (&expr->ts);
1930 se->expr = gfc_build_function_call (gfor_fndecl_string_len_trim, args);
1931 se->expr = convert (type, se->expr);
1935 /* Returns the starting position of a substring within a string. */
1937 static void
1938 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
1940 tree args;
1941 tree back;
1942 tree type;
1943 tree tmp;
1945 args = gfc_conv_intrinsic_function_args (se, expr);
1946 type = gfc_typenode_for_spec (&expr->ts);
1947 tmp = gfc_advance_chain (args, 3);
1948 if (TREE_CHAIN (tmp) == NULL_TREE)
1950 back = convert (gfc_logical4_type_node, integer_one_node);
1951 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
1952 TREE_CHAIN (tmp) = back;
1954 else
1956 back = TREE_CHAIN (tmp);
1957 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
1960 se->expr = gfc_build_function_call (gfor_fndecl_string_index, args);
1961 se->expr = convert (type, se->expr);
1964 /* The ascii value for a single character. */
1965 static void
1966 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
1968 tree arg;
1969 tree type;
1971 arg = gfc_conv_intrinsic_function_args (se, expr);
1972 arg = TREE_VALUE (TREE_CHAIN (arg));
1973 assert (POINTER_TYPE_P (TREE_TYPE (arg)));
1974 arg = build1 (NOP_EXPR, pchar_type_node, arg);
1975 type = gfc_typenode_for_spec (&expr->ts);
1977 se->expr = gfc_build_indirect_ref (arg);
1978 se->expr = convert (type, se->expr);
1982 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
1984 static void
1985 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
1987 tree arg;
1988 tree tsource;
1989 tree fsource;
1990 tree mask;
1991 tree type;
1993 arg = gfc_conv_intrinsic_function_args (se, expr);
1994 tsource = TREE_VALUE (arg);
1995 arg = TREE_CHAIN (arg);
1996 fsource = TREE_VALUE (arg);
1997 arg = TREE_CHAIN (arg);
1998 mask = TREE_VALUE (arg);
2000 type = TREE_TYPE (tsource);
2001 se->expr = fold (build (COND_EXPR, type, mask, tsource, fsource));
2005 static void
2006 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2008 gfc_actual_arglist *actual;
2009 tree args;
2010 tree type;
2011 tree fndecl;
2012 gfc_se argse;
2013 gfc_ss *ss;
2015 gfc_init_se (&argse, NULL);
2016 actual = expr->value.function.actual;
2018 ss = gfc_walk_expr (actual->expr);
2019 assert (ss != gfc_ss_terminator);
2020 argse.want_pointer = 1;
2021 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2022 gfc_add_block_to_block (&se->pre, &argse.pre);
2023 gfc_add_block_to_block (&se->post, &argse.post);
2024 args = gfc_chainon_list (NULL_TREE, argse.expr);
2026 actual = actual->next;
2027 if (actual->expr)
2029 gfc_init_se (&argse, NULL);
2030 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2031 gfc_add_block_to_block (&se->pre, &argse.pre);
2032 args = gfc_chainon_list (args, argse.expr);
2033 fndecl = gfor_fndecl_size1;
2035 else
2036 fndecl = gfor_fndecl_size0;
2038 se->expr = gfc_build_function_call (fndecl, args);
2039 type = gfc_typenode_for_spec (&expr->ts);
2040 se->expr = convert (type, se->expr);
2044 /* Intrinsic string comparison functions. */
2046 static void
2047 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2049 tree type;
2050 tree args;
2052 args = gfc_conv_intrinsic_function_args (se, expr);
2053 /* Build a call for the comparison. */
2054 se->expr = gfc_build_function_call (gfor_fndecl_compare_string, args);
2056 type = gfc_typenode_for_spec (&expr->ts);
2057 se->expr = build (op, type, se->expr,
2058 convert (TREE_TYPE (se->expr), integer_zero_node));
2061 /* Generate a call to the adjustl/adjustr library function. */
2062 static void
2063 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2065 tree args;
2066 tree len;
2067 tree type;
2068 tree var;
2069 tree tmp;
2071 args = gfc_conv_intrinsic_function_args (se, expr);
2072 len = TREE_VALUE (args);
2074 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2075 var = gfc_conv_string_tmp (se, type, len);
2076 args = tree_cons (NULL_TREE, var, args);
2078 tmp = gfc_build_function_call (fndecl, args);
2079 gfc_add_expr_to_block (&se->pre, tmp);
2080 se->expr = var;
2081 se->string_length = len;
2085 /* Scalar transfer statement.
2086 TRANSFER (source, mold) = *(typeof<mould> *)&source */
2088 static void
2089 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2091 gfc_actual_arglist *arg;
2092 gfc_se argse;
2093 tree type;
2094 tree ptr;
2095 gfc_ss *ss;
2097 assert (!se->ss);
2099 /* Get a pointer to the source. */
2100 arg = expr->value.function.actual;
2101 ss = gfc_walk_expr (arg->expr);
2102 gfc_init_se (&argse, NULL);
2103 if (ss == gfc_ss_terminator)
2104 gfc_conv_expr_reference (&argse, arg->expr);
2105 else
2106 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2107 gfc_add_block_to_block (&se->pre, &argse.pre);
2108 gfc_add_block_to_block (&se->post, &argse.post);
2109 ptr = argse.expr;
2111 arg = arg->next;
2112 type = gfc_typenode_for_spec (&expr->ts);
2113 ptr = convert (build_pointer_type (type), ptr);
2114 if (expr->ts.type == BT_CHARACTER)
2116 gfc_init_se (&argse, NULL);
2117 gfc_conv_expr (&argse, arg->expr);
2118 gfc_add_block_to_block (&se->pre, &argse.pre);
2119 gfc_add_block_to_block (&se->post, &argse.post);
2120 se->expr = ptr;
2121 se->string_length = argse.string_length;
2123 else
2125 se->expr = gfc_build_indirect_ref (ptr);
2130 /* Generate code for the ALLOCATED intrinsic.
2131 Generate inline code that directly check the address of the argument. */
2133 static void
2134 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2136 gfc_actual_arglist *arg1;
2137 gfc_se arg1se;
2138 gfc_ss *ss1;
2139 tree tmp;
2141 gfc_init_se (&arg1se, NULL);
2142 arg1 = expr->value.function.actual;
2143 ss1 = gfc_walk_expr (arg1->expr);
2144 arg1se.descriptor_only = 1;
2145 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2147 tmp = gfc_conv_descriptor_data (arg1se.expr);
2148 tmp = build (NE_EXPR, boolean_type_node, tmp,
2149 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2150 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2154 /* Generate code for the ASSOCIATED intrinsic.
2155 If both POINTER and TARGET are arrays, generate a call to library function
2156 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2157 In other cases, generate inline code that directly compare the address of
2158 POINTER with the address of TARGET. */
2160 static void
2161 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2163 gfc_actual_arglist *arg1;
2164 gfc_actual_arglist *arg2;
2165 gfc_se arg1se;
2166 gfc_se arg2se;
2167 tree tmp2;
2168 tree tmp;
2169 tree args, fndecl;
2170 gfc_ss *ss1, *ss2;
2172 gfc_init_se (&arg1se, NULL);
2173 gfc_init_se (&arg2se, NULL);
2174 arg1 = expr->value.function.actual;
2175 arg2 = arg1->next;
2176 ss1 = gfc_walk_expr (arg1->expr);
2178 if (!arg2->expr)
2180 /* No optional target. */
2181 if (ss1 == gfc_ss_terminator)
2183 /* A pointer to a scalar. */
2184 arg1se.want_pointer = 1;
2185 gfc_conv_expr (&arg1se, arg1->expr);
2186 tmp2 = arg1se.expr;
2188 else
2190 /* A pointer to an array. */
2191 arg1se.descriptor_only = 1;
2192 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2193 tmp2 = gfc_conv_descriptor_data (arg1se.expr);
2195 tmp = build (NE_EXPR, boolean_type_node, tmp2,
2196 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
2197 se->expr = tmp;
2199 else
2201 /* An optional target. */
2202 ss2 = gfc_walk_expr (arg2->expr);
2203 if (ss1 == gfc_ss_terminator)
2205 /* A pointer to a scalar. */
2206 assert (ss2 == gfc_ss_terminator);
2207 arg1se.want_pointer = 1;
2208 gfc_conv_expr (&arg1se, arg1->expr);
2209 arg2se.want_pointer = 1;
2210 gfc_conv_expr (&arg2se, arg2->expr);
2211 tmp = build (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2212 se->expr = tmp;
2214 else
2216 /* A pointer to an array, call library function _gfor_associated. */
2217 assert (ss2 != gfc_ss_terminator);
2218 args = NULL_TREE;
2219 arg1se.want_pointer = 1;
2220 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2221 args = gfc_chainon_list (args, arg1se.expr);
2222 arg2se.want_pointer = 1;
2223 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2224 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2225 gfc_add_block_to_block (&se->post, &arg2se.post);
2226 args = gfc_chainon_list (args, arg2se.expr);
2227 fndecl = gfor_fndecl_associated;
2228 se->expr = gfc_build_function_call (fndecl, args);
2231 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2235 /* Scan a string for any one of the characters in a set of characters. */
2237 static void
2238 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2240 tree args;
2241 tree back;
2242 tree type;
2243 tree tmp;
2245 args = gfc_conv_intrinsic_function_args (se, expr);
2246 type = gfc_typenode_for_spec (&expr->ts);
2247 tmp = gfc_advance_chain (args, 3);
2248 if (TREE_CHAIN (tmp) == NULL_TREE)
2250 back = convert (gfc_logical4_type_node, integer_one_node);
2251 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2252 TREE_CHAIN (tmp) = back;
2254 else
2256 back = TREE_CHAIN (tmp);
2257 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2260 se->expr = gfc_build_function_call (gfor_fndecl_string_scan, args);
2261 se->expr = convert (type, se->expr);
2265 /* Verify that a set of characters contains all the characters in a string
2266 by indentifying the position of the first character in a string of
2267 characters that does not appear in a given set of characters. */
2269 static void
2270 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2272 tree args;
2273 tree back;
2274 tree type;
2275 tree tmp;
2277 args = gfc_conv_intrinsic_function_args (se, expr);
2278 type = gfc_typenode_for_spec (&expr->ts);
2279 tmp = gfc_advance_chain (args, 3);
2280 if (TREE_CHAIN (tmp) == NULL_TREE)
2282 back = convert (gfc_logical4_type_node, integer_one_node);
2283 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2284 TREE_CHAIN (tmp) = back;
2286 else
2288 back = TREE_CHAIN (tmp);
2289 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2292 se->expr = gfc_build_function_call (gfor_fndecl_string_verify, args);
2293 se->expr = convert (type, se->expr);
2296 /* Prepare components and related information of a real number which is
2297 the first argument of a elemental functions to manipulate reals. */
2299 static
2300 void prepare_arg_info (gfc_se * se, gfc_expr * expr,
2301 real_compnt_info * rcs, int all)
2303 tree arg;
2304 tree masktype;
2305 tree tmp;
2306 tree wbits;
2307 tree one;
2308 tree exponent, fraction;
2309 int n;
2310 gfc_expr *a1;
2312 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
2313 gfc_todo_error ("Non-IEEE floating format");
2315 assert (expr->expr_type == EXPR_FUNCTION);
2317 arg = gfc_conv_intrinsic_function_args (se, expr);
2318 arg = TREE_VALUE (arg);
2319 rcs->type = TREE_TYPE (arg);
2321 /* Force arg'type to integer by unaffected convert */
2322 a1 = expr->value.function.actual->expr;
2323 masktype = gfc_get_int_type (a1->ts.kind);
2324 rcs->mtype = masktype;
2325 tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
2326 arg = gfc_create_var (masktype, "arg");
2327 gfc_add_modify_expr(&se->pre, arg, tmp);
2328 rcs->arg = arg;
2330 /* Caculate the numbers of bits of exponent, fraction and word */
2331 n = gfc_validate_kind (a1->ts.type, a1->ts.kind);
2332 tmp = build_int_cst (NULL_TREE, gfc_real_kinds[n].digits - 1, 0);
2333 rcs->fdigits = convert (masktype, tmp);
2334 wbits = build_int_cst (NULL_TREE, TYPE_PRECISION (rcs->type) - 1, 0);
2335 wbits = convert (masktype, wbits);
2336 rcs->edigits = fold (build (MINUS_EXPR, masktype, wbits, tmp));
2338 /* Form masks for exponent/fraction/sign */
2339 one = gfc_build_const (masktype, integer_one_node);
2340 rcs->smask = fold (build (LSHIFT_EXPR, masktype, one, wbits));
2341 rcs->f1 = fold (build (LSHIFT_EXPR, masktype, one, rcs->fdigits));
2342 rcs->emask = fold (build (MINUS_EXPR, masktype, rcs->smask, rcs->f1));
2343 rcs->fmask = fold (build (MINUS_EXPR, masktype, rcs->f1, one));
2344 /* Form bias. */
2345 tmp = fold (build (MINUS_EXPR, masktype, rcs->edigits, one));
2346 tmp = fold (build (LSHIFT_EXPR, masktype, one, tmp));
2347 rcs->bias = fold (build (MINUS_EXPR, masktype, tmp ,one));
2349 if (all)
2351 /* exponent, and fraction */
2352 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->emask);
2353 tmp = build (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
2354 exponent = gfc_create_var (masktype, "exponent");
2355 gfc_add_modify_expr(&se->pre, exponent, tmp);
2356 rcs->expn = exponent;
2358 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->fmask);
2359 fraction = gfc_create_var (masktype, "fraction");
2360 gfc_add_modify_expr(&se->pre, fraction, tmp);
2361 rcs->frac = fraction;
2365 /* Build a call to __builtin_clz. */
2367 static tree
2368 call_builtin_clz (tree result_type, tree op0)
2370 tree fn, parms, call;
2371 enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
2373 if (op0_mode == TYPE_MODE (integer_type_node))
2374 fn = built_in_decls[BUILT_IN_CLZ];
2375 else if (op0_mode == TYPE_MODE (long_integer_type_node))
2376 fn = built_in_decls[BUILT_IN_CLZL];
2377 else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
2378 fn = built_in_decls[BUILT_IN_CLZLL];
2379 else
2380 abort ();
2382 parms = tree_cons (NULL, op0, NULL);
2383 call = gfc_build_function_call (fn, parms);
2385 return convert (result_type, call);
2388 /* Generate code for SPACING (X) intrinsic function. We generate:
2390 t = expn - (BITS_OF_FRACTION)
2391 res = t << (BITS_OF_FRACTION)
2392 if (t < 0)
2393 res = tiny(X)
2396 static void
2397 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2399 tree arg;
2400 tree masktype;
2401 tree tmp, t1, cond;
2402 tree tiny, zero;
2403 tree fdigits;
2404 real_compnt_info rcs;
2406 prepare_arg_info (se, expr, &rcs, 0);
2407 arg = rcs.arg;
2408 masktype = rcs.mtype;
2409 fdigits = rcs.fdigits;
2410 tiny = rcs.f1;
2411 zero = gfc_build_const (masktype, integer_zero_node);
2412 tmp = build (BIT_AND_EXPR, masktype, rcs.emask, arg);
2413 tmp = build (RSHIFT_EXPR, masktype, tmp, fdigits);
2414 tmp = build (MINUS_EXPR, masktype, tmp, fdigits);
2415 cond = build (LE_EXPR, boolean_type_node, tmp, zero);
2416 t1 = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2417 tmp = build (COND_EXPR, masktype, cond, tiny, t1);
2418 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2420 se->expr = tmp;
2423 /* Generate code for RRSPACING (X) intrinsic function. We generate:
2425 if (expn == 0 && frac == 0)
2426 res = 0;
2427 else
2429 sedigits = edigits + 1;
2430 if (expn == 0)
2432 t1 = leadzero (frac);
2433 frac = frac << (t1 + sedigits);
2434 frac = frac >> (sedigits);
2436 t = bias + BITS_OF_FRACTION_OF;
2437 res = (t << BITS_OF_FRACTION_OF) | frac;
2440 static void
2441 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2443 tree masktype;
2444 tree tmp, t1, t2, cond, cond2;
2445 tree one, zero;
2446 tree fdigits, fraction;
2447 real_compnt_info rcs;
2449 prepare_arg_info (se, expr, &rcs, 1);
2450 masktype = rcs.mtype;
2451 fdigits = rcs.fdigits;
2452 fraction = rcs.frac;
2453 one = gfc_build_const (masktype, integer_one_node);
2454 zero = gfc_build_const (masktype, integer_zero_node);
2455 t2 = build (PLUS_EXPR, masktype, rcs.edigits, one);
2457 t1 = call_builtin_clz (masktype, fraction);
2458 tmp = build (PLUS_EXPR, masktype, t1, one);
2459 tmp = build (LSHIFT_EXPR, masktype, fraction, tmp);
2460 tmp = build (RSHIFT_EXPR, masktype, tmp, t2);
2461 cond = build (EQ_EXPR, boolean_type_node, rcs.expn, zero);
2462 fraction = build (COND_EXPR, masktype, cond, tmp, fraction);
2464 tmp = build (PLUS_EXPR, masktype, rcs.bias, fdigits);
2465 tmp = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2466 tmp = build (BIT_IOR_EXPR, masktype, tmp, fraction);
2468 cond2 = build (EQ_EXPR, boolean_type_node, rcs.frac, zero);
2469 cond = build (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
2470 tmp = build (COND_EXPR, masktype, cond,
2471 convert (masktype, integer_zero_node), tmp);
2473 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2474 se->expr = tmp;
2477 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
2479 static void
2480 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
2482 tree args;
2484 args = gfc_conv_intrinsic_function_args (se, expr);
2485 args = TREE_VALUE (args);
2486 args = gfc_build_addr_expr (NULL, args);
2487 args = tree_cons (NULL_TREE, args, NULL_TREE);
2488 se->expr = gfc_build_function_call (gfor_fndecl_si_kind, args);
2491 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
2493 static void
2494 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
2496 gfc_actual_arglist *actual;
2497 tree args;
2498 gfc_se argse;
2500 args = NULL_TREE;
2501 for (actual = expr->value.function.actual; actual; actual = actual->next)
2503 gfc_init_se (&argse, se);
2505 /* Pass a NULL pointer for an absent arg. */
2506 if (actual->expr == NULL)
2507 argse.expr = null_pointer_node;
2508 else
2509 gfc_conv_expr_reference (&argse, actual->expr);
2511 gfc_add_block_to_block (&se->pre, &argse.pre);
2512 gfc_add_block_to_block (&se->post, &argse.post);
2513 args = gfc_chainon_list (args, argse.expr);
2515 se->expr = gfc_build_function_call (gfor_fndecl_sr_kind, args);
2519 /* Generate code for TRIM (A) intrinsic function. */
2521 static void
2522 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
2524 tree var;
2525 tree len;
2526 tree addr;
2527 tree tmp;
2528 tree arglist;
2529 tree type;
2530 tree cond;
2532 arglist = NULL_TREE;
2534 type = build_pointer_type (gfc_character1_type_node);
2535 var = gfc_create_var (type, "pstr");
2536 addr = gfc_build_addr_expr (ppvoid_type_node, var);
2537 len = gfc_create_var (gfc_int4_type_node, "len");
2539 tmp = gfc_conv_intrinsic_function_args (se, expr);
2540 arglist = gfc_chainon_list (arglist, gfc_build_addr_expr (NULL, len));
2541 arglist = gfc_chainon_list (arglist, addr);
2542 arglist = chainon (arglist, tmp);
2544 tmp = gfc_build_function_call (gfor_fndecl_string_trim, arglist);
2545 gfc_add_expr_to_block (&se->pre, tmp);
2547 /* Free the temporary afterwards, if necessary. */
2548 cond = build (GT_EXPR, boolean_type_node, len,
2549 convert (TREE_TYPE (len), integer_zero_node));
2550 arglist = gfc_chainon_list (NULL_TREE, var);
2551 tmp = gfc_build_function_call (gfor_fndecl_internal_free, arglist);
2552 tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2553 gfc_add_expr_to_block (&se->post, tmp);
2555 se->expr = var;
2556 se->string_length = len;
2560 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
2562 static void
2563 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
2565 tree tmp;
2566 tree len;
2567 tree args;
2568 tree arglist;
2569 tree ncopies;
2570 tree var;
2571 tree type;
2573 args = gfc_conv_intrinsic_function_args (se, expr);
2574 len = TREE_VALUE (args);
2575 tmp = gfc_advance_chain (args, 2);
2576 ncopies = TREE_VALUE (tmp);
2577 len = fold (build (MULT_EXPR, gfc_int4_type_node, len, ncopies));
2578 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
2579 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
2581 arglist = NULL_TREE;
2582 arglist = gfc_chainon_list (arglist, var);
2583 arglist = chainon (arglist, args);
2584 tmp = gfc_build_function_call (gfor_fndecl_string_repeat, arglist);
2585 gfc_add_expr_to_block (&se->pre, tmp);
2587 se->expr = var;
2588 se->string_length = len;
2592 /* Generate code for the IARGC intrinsic. If args_only is true this is
2593 actually the COMMAND_ARGUMENT_COUNT intrinsic, so return IARGC - 1. */
2595 static void
2596 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr, bool args_only)
2598 tree tmp;
2599 tree fndecl;
2600 tree type;
2602 /* Call the library function. This always returns an INTEGER(4). */
2603 fndecl = gfor_fndecl_iargc;
2604 tmp = gfc_build_function_call (fndecl, NULL_TREE);
2606 /* Convert it to the required type. */
2607 type = gfc_typenode_for_spec (&expr->ts);
2608 tmp = fold_convert (type, tmp);
2610 if (args_only)
2611 tmp = build (MINUS_EXPR, type, tmp, convert (type, integer_one_node));
2612 se->expr = tmp;
2615 /* Generate code for an intrinsic function. Some map directly to library
2616 calls, others get special handling. In some cases the name of the function
2617 used depends on the type specifiers. */
2619 void
2620 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
2622 gfc_intrinsic_sym *isym;
2623 char *name;
2624 int lib;
2626 isym = expr->value.function.isym;
2628 name = &expr->value.function.name[2];
2630 if (expr->rank > 0)
2632 lib = gfc_is_intrinsic_libcall (expr);
2633 if (lib != 0)
2635 if (lib == 1)
2636 se->ignore_optional = 1;
2637 gfc_conv_intrinsic_funcall (se, expr);
2638 return;
2642 switch (expr->value.function.isym->generic_id)
2644 case GFC_ISYM_NONE:
2645 abort ();
2647 case GFC_ISYM_REPEAT:
2648 gfc_conv_intrinsic_repeat (se, expr);
2649 break;
2651 case GFC_ISYM_TRIM:
2652 gfc_conv_intrinsic_trim (se, expr);
2653 break;
2655 case GFC_ISYM_SI_KIND:
2656 gfc_conv_intrinsic_si_kind (se, expr);
2657 break;
2659 case GFC_ISYM_SR_KIND:
2660 gfc_conv_intrinsic_sr_kind (se, expr);
2661 break;
2663 case GFC_ISYM_EXPONENT:
2664 gfc_conv_intrinsic_exponent (se, expr);
2665 break;
2667 case GFC_ISYM_SPACING:
2668 gfc_conv_intrinsic_spacing (se, expr);
2669 break;
2671 case GFC_ISYM_RRSPACING:
2672 gfc_conv_intrinsic_rrspacing (se, expr);
2673 break;
2675 case GFC_ISYM_SCAN:
2676 gfc_conv_intrinsic_scan (se, expr);
2677 break;
2679 case GFC_ISYM_VERIFY:
2680 gfc_conv_intrinsic_verify (se, expr);
2681 break;
2683 case GFC_ISYM_ALLOCATED:
2684 gfc_conv_allocated (se, expr);
2685 break;
2687 case GFC_ISYM_ASSOCIATED:
2688 gfc_conv_associated(se, expr);
2689 break;
2691 case GFC_ISYM_ABS:
2692 gfc_conv_intrinsic_abs (se, expr);
2693 break;
2695 case GFC_ISYM_ADJUSTL:
2696 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
2697 break;
2699 case GFC_ISYM_ADJUSTR:
2700 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
2701 break;
2703 case GFC_ISYM_AIMAG:
2704 gfc_conv_intrinsic_imagpart (se, expr);
2705 break;
2707 case GFC_ISYM_AINT:
2708 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
2709 break;
2711 case GFC_ISYM_ALL:
2712 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
2713 break;
2715 case GFC_ISYM_ANINT:
2716 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
2717 break;
2719 case GFC_ISYM_ANY:
2720 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
2721 break;
2723 case GFC_ISYM_BTEST:
2724 gfc_conv_intrinsic_btest (se, expr);
2725 break;
2727 case GFC_ISYM_ACHAR:
2728 case GFC_ISYM_CHAR:
2729 gfc_conv_intrinsic_char (se, expr);
2730 break;
2732 case GFC_ISYM_CONVERSION:
2733 case GFC_ISYM_REAL:
2734 case GFC_ISYM_LOGICAL:
2735 case GFC_ISYM_DBLE:
2736 gfc_conv_intrinsic_conversion (se, expr);
2737 break;
2739 /* Integer conversions are handled seperately to make sure we get the
2740 correct rounding mode. */
2741 case GFC_ISYM_INT:
2742 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
2743 break;
2745 case GFC_ISYM_NINT:
2746 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
2747 break;
2749 case GFC_ISYM_CEILING:
2750 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
2751 break;
2753 case GFC_ISYM_FLOOR:
2754 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
2755 break;
2757 case GFC_ISYM_MOD:
2758 gfc_conv_intrinsic_mod (se, expr, 0);
2759 break;
2761 case GFC_ISYM_MODULO:
2762 gfc_conv_intrinsic_mod (se, expr, 1);
2763 break;
2765 case GFC_ISYM_CMPLX:
2766 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
2767 break;
2769 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
2770 gfc_conv_intrinsic_iargc (se, expr, TRUE);
2771 break;
2773 case GFC_ISYM_CONJG:
2774 gfc_conv_intrinsic_conjg (se, expr);
2775 break;
2777 case GFC_ISYM_COUNT:
2778 gfc_conv_intrinsic_count (se, expr);
2779 break;
2781 case GFC_ISYM_DIM:
2782 gfc_conv_intrinsic_dim (se, expr);
2783 break;
2785 case GFC_ISYM_DPROD:
2786 gfc_conv_intrinsic_dprod (se, expr);
2787 break;
2789 case GFC_ISYM_IAND:
2790 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
2791 break;
2793 case GFC_ISYM_IBCLR:
2794 gfc_conv_intrinsic_singlebitop (se, expr, 0);
2795 break;
2797 case GFC_ISYM_IBITS:
2798 gfc_conv_intrinsic_ibits (se, expr);
2799 break;
2801 case GFC_ISYM_IBSET:
2802 gfc_conv_intrinsic_singlebitop (se, expr, 1);
2803 break;
2805 case GFC_ISYM_IACHAR:
2806 case GFC_ISYM_ICHAR:
2807 /* We assume ASCII character sequence. */
2808 gfc_conv_intrinsic_ichar (se, expr);
2809 break;
2811 case GFC_ISYM_IARGC:
2812 gfc_conv_intrinsic_iargc (se, expr, FALSE);
2813 break;
2815 case GFC_ISYM_IEOR:
2816 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
2817 break;
2819 case GFC_ISYM_INDEX:
2820 gfc_conv_intrinsic_index (se, expr);
2821 break;
2823 case GFC_ISYM_IOR:
2824 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
2825 break;
2827 case GFC_ISYM_ISHFT:
2828 gfc_conv_intrinsic_ishft (se, expr);
2829 break;
2831 case GFC_ISYM_ISHFTC:
2832 gfc_conv_intrinsic_ishftc (se, expr);
2833 break;
2835 case GFC_ISYM_LBOUND:
2836 gfc_conv_intrinsic_bound (se, expr, 0);
2837 break;
2839 case GFC_ISYM_LEN:
2840 gfc_conv_intrinsic_len (se, expr);
2841 break;
2843 case GFC_ISYM_LEN_TRIM:
2844 gfc_conv_intrinsic_len_trim (se, expr);
2845 break;
2847 case GFC_ISYM_LGE:
2848 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
2849 break;
2851 case GFC_ISYM_LGT:
2852 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
2853 break;
2855 case GFC_ISYM_LLE:
2856 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
2857 break;
2859 case GFC_ISYM_LLT:
2860 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
2861 break;
2863 case GFC_ISYM_MAX:
2864 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
2865 break;
2867 case GFC_ISYM_MAXLOC:
2868 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
2869 break;
2871 case GFC_ISYM_MAXVAL:
2872 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
2873 break;
2875 case GFC_ISYM_MERGE:
2876 gfc_conv_intrinsic_merge (se, expr);
2877 break;
2879 case GFC_ISYM_MIN:
2880 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
2881 break;
2883 case GFC_ISYM_MINLOC:
2884 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
2885 break;
2887 case GFC_ISYM_MINVAL:
2888 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
2889 break;
2891 case GFC_ISYM_NOT:
2892 gfc_conv_intrinsic_not (se, expr);
2893 break;
2895 case GFC_ISYM_PRESENT:
2896 gfc_conv_intrinsic_present (se, expr);
2897 break;
2899 case GFC_ISYM_PRODUCT:
2900 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
2901 break;
2903 case GFC_ISYM_SIGN:
2904 gfc_conv_intrinsic_sign (se, expr);
2905 break;
2907 case GFC_ISYM_SIZE:
2908 gfc_conv_intrinsic_size (se, expr);
2909 break;
2911 case GFC_ISYM_SUM:
2912 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
2913 break;
2915 case GFC_ISYM_TRANSFER:
2916 gfc_conv_intrinsic_transfer (se, expr);
2917 break;
2919 case GFC_ISYM_UBOUND:
2920 gfc_conv_intrinsic_bound (se, expr, 1);
2921 break;
2923 case GFC_ISYM_DOT_PRODUCT:
2924 case GFC_ISYM_MATMUL:
2925 case GFC_ISYM_IRAND:
2926 case GFC_ISYM_RAND:
2927 case GFC_ISYM_ETIME:
2928 case GFC_ISYM_SECOND:
2929 gfc_conv_intrinsic_funcall (se, expr);
2930 break;
2932 default:
2933 gfc_conv_intrinsic_lib_function (se, expr);
2934 break;
2939 /* This generates code to execute before entering the scalarization loop.
2940 Currently does nothing. */
2942 void
2943 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
2945 switch (ss->expr->value.function.isym->generic_id)
2947 case GFC_ISYM_UBOUND:
2948 case GFC_ISYM_LBOUND:
2949 break;
2951 default:
2952 abort ();
2953 break;
2958 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
2959 inside the scalarization loop. */
2961 static gfc_ss *
2962 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
2964 gfc_ss *newss;
2966 /* The two argument version returns a scalar. */
2967 if (expr->value.function.actual->next->expr)
2968 return ss;
2970 newss = gfc_get_ss ();
2971 newss->type = GFC_SS_INTRINSIC;
2972 newss->expr = expr;
2973 newss->next = ss;
2975 return newss;
2979 /* Walk an intrinsic array libcall. */
2981 static gfc_ss *
2982 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
2984 gfc_ss *newss;
2986 assert (expr->rank > 0);
2988 newss = gfc_get_ss ();
2989 newss->type = GFC_SS_FUNCTION;
2990 newss->expr = expr;
2991 newss->next = ss;
2992 newss->data.info.dimen = expr->rank;
2994 return newss;
2998 /* Returns nonzero if the specified intrinsic function call maps directly to a
2999 an external library call. Should only be used for functions that return
3000 arrays. */
3003 gfc_is_intrinsic_libcall (gfc_expr * expr)
3005 assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3006 assert (expr->rank > 0);
3008 switch (expr->value.function.isym->generic_id)
3010 case GFC_ISYM_ALL:
3011 case GFC_ISYM_ANY:
3012 case GFC_ISYM_COUNT:
3013 case GFC_ISYM_MATMUL:
3014 case GFC_ISYM_MAXLOC:
3015 case GFC_ISYM_MAXVAL:
3016 case GFC_ISYM_MINLOC:
3017 case GFC_ISYM_MINVAL:
3018 case GFC_ISYM_PRODUCT:
3019 case GFC_ISYM_SUM:
3020 case GFC_ISYM_SHAPE:
3021 case GFC_ISYM_SPREAD:
3022 case GFC_ISYM_TRANSPOSE:
3023 /* Ignore absent optional parameters. */
3024 return 1;
3026 case GFC_ISYM_RESHAPE:
3027 case GFC_ISYM_CSHIFT:
3028 case GFC_ISYM_EOSHIFT:
3029 case GFC_ISYM_PACK:
3030 case GFC_ISYM_UNPACK:
3031 /* Pass absent optional parameters. */
3032 return 2;
3034 default:
3035 return 0;
3039 /* Walk an intrinsic function. */
3040 gfc_ss *
3041 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3042 gfc_intrinsic_sym * isym)
3044 assert (isym);
3046 if (isym->elemental)
3047 return gfc_walk_elemental_function_args (ss, expr, GFC_SS_SCALAR);
3049 if (expr->rank == 0)
3050 return ss;
3052 if (gfc_is_intrinsic_libcall (expr))
3053 return gfc_walk_intrinsic_libfunc (ss, expr);
3055 /* Special cases. */
3056 switch (isym->generic_id)
3058 case GFC_ISYM_LBOUND:
3059 case GFC_ISYM_UBOUND:
3060 return gfc_walk_intrinsic_bound (ss, expr);
3062 default:
3063 /* This probably meant someone forgot to add an intrinsic to the above
3064 list(s) when they implemented it, or something's gone horribly wrong.
3066 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3067 expr->value.function.name);
3071 #include "gt-fortran-trans-intrinsic.h"