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
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
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
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
34 #include "tree-gimple.h"
39 #include "intrinsic.h"
41 #include "trans-const.h"
42 #include "trans-types.h"
43 #include "trans-array.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
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]". */
68 /* True if a complex version of the function exists. */
69 bool complex_available;
71 /* True if the function should be marked const. */
74 /* The base library name of this function. */
77 /* Cache decls created for the various operand types. */
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
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),
117 LIBF_FUNCTION (NONE, NULL, false)
119 #undef DEFINE_MATH_BUILTIN
123 /* Structure for storing components of a floating number to be used by
124 elemental functions to manipulate reals. */
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. */
143 /* Evaluate the arguments to an intrinsic function. */
146 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
148 gfc_actual_arglist *actual;
153 for (actual = expr->value.function.actual; actual; actual = actual->next)
155 /* Skip ommitted optional arguments. */
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);
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);
180 /* Conversions between different types are output by the frontend as
181 intrinsic functions. We implement these directly with inline code. */
184 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
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)
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. */
215 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
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);
238 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
239 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
242 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
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. */
274 build_fix_expr (stmtblock_t * pblock, tree arg, tree type, int op)
279 return build_fixbound_expr (pblock, arg, type, 0);
283 return build_fixbound_expr (pblock, arg, type, 1);
287 return build_round_expr (pblock, arg, type);
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
304 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, int op)
315 kind = expr->ts.kind;
318 /* We have builtin functions for some cases. */
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);
359 /* This code is probably redundant, but we'll keep it lying around just
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. */
367 n = gfc_validate_kind (BT_INTEGER, kind);
368 mpf_set_z (huge, gfc_integer_kinds[n].huge);
369 tmp = gfc_conv_mpf_to_tree (huge, kind);
370 cond = build (LT_EXPR, boolean_type_node, arg, tmp);
372 mpf_neg (huge, huge);
373 tmp = gfc_conv_mpf_to_tree (huge, kind);
374 tmp = build (GT_EXPR, boolean_type_node, arg, tmp);
375 cond = build (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
376 itype = gfc_get_int_type (kind);
378 tmp = build_fix_expr (&se->pre, arg, itype, op);
379 tmp = convert (type, tmp);
380 se->expr = build (COND_EXPR, type, cond, tmp, arg);
384 /* Convert to an integer using the specified rounding mode. */
387 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
392 /* Evaluate the argument. */
393 type = gfc_typenode_for_spec (&expr->ts);
394 assert (expr->value.function.actual->expr);
395 arg = gfc_conv_intrinsic_function_args (se, expr);
396 arg = TREE_VALUE (arg);
398 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
400 /* Conversion to a different integer kind. */
401 se->expr = convert (type, arg);
405 /* Conversion from complex to non-complex involves taking the real
406 component of the value. */
407 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
408 && expr->ts.type != BT_COMPLEX)
412 artype = TREE_TYPE (TREE_TYPE (arg));
413 arg = build1 (REALPART_EXPR, artype, arg);
416 se->expr = build_fix_expr (&se->pre, arg, type, op);
421 /* Get the imaginary component of a value. */
424 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
428 arg = gfc_conv_intrinsic_function_args (se, expr);
429 arg = TREE_VALUE (arg);
430 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
434 /* Get the complex conjugate of a value. */
437 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
441 arg = gfc_conv_intrinsic_function_args (se, expr);
442 arg = TREE_VALUE (arg);
443 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
447 /* Initialize function decls for library functions. The external functions
448 are created as required. Builtin functions are added here. */
451 gfc_build_intrinsic_lib_fndecls (void)
453 gfc_intrinsic_map_t *m;
455 /* Add GCC builtin functions. */
456 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
458 if (m->code4 != END_BUILTINS)
459 m->real4_decl = built_in_decls[m->code4];
460 if (m->code8 != END_BUILTINS)
461 m->real8_decl = built_in_decls[m->code8];
466 /* Create a fndecl for a simple intrinsic library function. */
469 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
474 gfc_actual_arglist *actual;
477 char name[GFC_MAX_SYMBOL_LEN + 3];
480 if (ts->type == BT_REAL)
485 pdecl = &m->real4_decl;
488 pdecl = &m->real8_decl;
494 else if (ts->type == BT_COMPLEX)
496 if (!m->complex_available)
502 pdecl = &m->complex4_decl;
505 pdecl = &m->complex8_decl;
519 if (ts->kind != 4 && ts->kind != 8)
521 snprintf (name, sizeof (name), "%s%s%s",
522 ts->type == BT_COMPLEX ? "c" : "",
524 ts->kind == 4 ? "f" : "");
528 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
529 ts->type == BT_COMPLEX ? 'c' : 'r',
533 argtypes = NULL_TREE;
534 for (actual = expr->value.function.actual; actual; actual = actual->next)
536 type = gfc_typenode_for_spec (&actual->expr->ts);
537 argtypes = gfc_chainon_list (argtypes, type);
539 argtypes = gfc_chainon_list (argtypes, void_type_node);
540 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
541 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
543 /* Mark the decl as external. */
544 DECL_EXTERNAL (fndecl) = 1;
545 TREE_PUBLIC (fndecl) = 1;
547 /* Mark it __attribute__((const)), if possible. */
548 TREE_READONLY (fndecl) = m->is_constant;
550 rest_of_decl_compilation (fndecl, NULL, 1, 0);
557 /* Convert an intrinsic function into an external or builtin call. */
560 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
562 gfc_intrinsic_map_t *m;
565 gfc_generic_isym_id id;
567 id = expr->value.function.isym->generic_id;
568 /* Find the entry for this function. */
569 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
575 if (m->id == GFC_ISYM_NONE)
577 internal_error ("Intrinsic function %s(%d) not recognized",
578 expr->value.function.name, id);
581 /* Get the decl and generate the call. */
582 args = gfc_conv_intrinsic_function_args (se, expr);
583 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
584 se->expr = gfc_build_function_call (fndecl, args);
587 /* Generate code for EXPONENT(X) intrinsic function. */
590 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
595 args = gfc_conv_intrinsic_function_args (se, expr);
597 a1 = expr->value.function.actual->expr;
601 fndecl = gfor_fndecl_math_exponent4;
604 fndecl = gfor_fndecl_math_exponent8;
610 se->expr = gfc_build_function_call (fndecl, args);
613 /* Evaluate a single upper or lower bound. */
614 /* TODO: bound intrinsic generates way too much unneccessary code. */
617 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
619 gfc_actual_arglist *arg;
620 gfc_actual_arglist *arg2;
630 gfc_init_se (&argse, NULL);
631 arg = expr->value.function.actual;
636 /* Create an implicit second parameter from the loop variable. */
637 assert (!arg2->expr);
638 assert (se->loop->dimen == 1);
639 assert (se->ss->expr == expr);
640 gfc_advance_se_ss_chain (se);
641 bound = se->loop->loopvar[0];
642 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
647 /* use the passed argument. */
648 assert (arg->next->expr);
649 gfc_init_se (&argse, NULL);
650 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
651 gfc_add_block_to_block (&se->pre, &argse.pre);
653 /* Convert from one based to zero based. */
654 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
655 gfc_index_one_node));
658 /* TODO: don't re-evaluate the descriptor on each iteration. */
659 /* Get a descriptor for the first parameter. */
660 ss = gfc_walk_expr (arg->expr);
661 assert (ss != gfc_ss_terminator);
662 argse.want_pointer = 0;
663 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
664 gfc_add_block_to_block (&se->pre, &argse.pre);
665 gfc_add_block_to_block (&se->post, &argse.post);
669 if (INTEGER_CST_P (bound))
671 assert (TREE_INT_CST_HIGH (bound) == 0);
672 i = TREE_INT_CST_LOW (bound);
673 assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
677 if (flag_bounds_check)
679 bound = gfc_evaluate_now (bound, &se->pre);
680 cond = fold (build (LT_EXPR, boolean_type_node, bound,
681 convert (TREE_TYPE (bound), integer_zero_node)));
682 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
683 tmp = fold (build (GE_EXPR, boolean_type_node, bound, tmp));
684 cond = fold(build (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp));
685 gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
690 se->expr = gfc_conv_descriptor_ubound(desc, bound);
692 se->expr = gfc_conv_descriptor_lbound(desc, bound);
694 type = gfc_typenode_for_spec (&expr->ts);
695 se->expr = convert (type, se->expr);
700 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
706 args = gfc_conv_intrinsic_function_args (se, expr);
707 assert (args && TREE_CHAIN (args) == NULL_TREE);
708 val = TREE_VALUE (args);
710 switch (expr->value.function.actual->expr->ts.type)
714 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
718 switch (expr->ts.kind)
721 fndecl = gfor_fndecl_math_cabsf;
724 fndecl = gfor_fndecl_math_cabs;
729 se->expr = gfc_build_function_call (fndecl, args);
738 /* Create a complex value from one or two real components. */
741 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
748 type = gfc_typenode_for_spec (&expr->ts);
749 arg = gfc_conv_intrinsic_function_args (se, expr);
750 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
752 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
753 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
755 arg = TREE_VALUE (arg);
756 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
757 imag = convert (TREE_TYPE (type), imag);
760 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
762 se->expr = fold (build (COMPLEX_EXPR, type, real, imag));
765 /* Remainder function MOD(A, P) = A - INT(A / P) * P.
766 MODULO(A, P) = (A==0 .or. !(A>0 .xor. P>0))? MOD(A,P):MOD(A,P)+P. */
767 /* TODO: MOD(x, 0) */
770 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
783 arg = gfc_conv_intrinsic_function_args (se, expr);
784 arg2 = TREE_VALUE (TREE_CHAIN (arg));
785 arg = TREE_VALUE (arg);
786 type = TREE_TYPE (arg);
788 switch (expr->ts.type)
791 /* Integer case is easy, we've got a builtin op. */
792 se->expr = build (TRUNC_MOD_EXPR, type, arg, arg2);
796 /* Real values we have to do the hard way. */
797 arg = gfc_evaluate_now (arg, &se->pre);
798 arg2 = gfc_evaluate_now (arg2, &se->pre);
800 tmp = build (RDIV_EXPR, type, arg, arg2);
801 /* Test if the value is too large to handle sensibly. */
803 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind);
804 mpf_set_z (huge, gfc_integer_kinds[n].huge);
805 test = gfc_conv_mpf_to_tree (huge, expr->ts.kind);
806 test2 = build (LT_EXPR, boolean_type_node, tmp, test);
808 mpf_neg (huge, huge);
809 test = gfc_conv_mpf_to_tree (huge, expr->ts.kind);
810 test = build (GT_EXPR, boolean_type_node, tmp, test);
811 test2 = build (TRUTH_AND_EXPR, boolean_type_node, test, test2);
813 itype = gfc_get_int_type (expr->ts.kind);
814 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
815 tmp = convert (type, tmp);
816 tmp = build (COND_EXPR, type, test2, tmp, arg);
817 tmp = build (MULT_EXPR, type, tmp, arg2);
818 se->expr = build (MINUS_EXPR, type, arg, tmp);
827 zero = gfc_build_const (type, integer_zero_node);
828 /* Build !(A > 0 .xor. P > 0). */
829 test = build (GT_EXPR, boolean_type_node, arg, zero);
830 test2 = build (GT_EXPR, boolean_type_node, arg2, zero);
831 test = build (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
832 test = build1 (TRUTH_NOT_EXPR, boolean_type_node, test);
833 /* Build (A == 0) .or. !(A > 0 .xor. P > 0). */
834 test2 = build (EQ_EXPR, boolean_type_node, arg, zero);
835 test = build (TRUTH_OR_EXPR, boolean_type_node, test, test2);
837 se->expr = build (COND_EXPR, type, test, se->expr,
838 build (PLUS_EXPR, type, se->expr, arg2));
842 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
845 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
854 arg = gfc_conv_intrinsic_function_args (se, expr);
855 arg2 = TREE_VALUE (TREE_CHAIN (arg));
856 arg = TREE_VALUE (arg);
857 type = TREE_TYPE (arg);
859 val = build (MINUS_EXPR, type, arg, arg2);
860 val = gfc_evaluate_now (val, &se->pre);
862 zero = gfc_build_const (type, integer_zero_node);
863 tmp = build (LE_EXPR, boolean_type_node, val, zero);
864 se->expr = build (COND_EXPR, type, tmp, zero, val);
868 /* SIGN(A, B) is absolute value of A times sign of B.
869 The real value versions use library functions to ensure the correct
870 handling of negative zero. Integer case implemented as:
871 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
875 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
886 arg = gfc_conv_intrinsic_function_args (se, expr);
887 if (expr->ts.type == BT_REAL)
889 switch (expr->ts.kind)
892 tmp = gfor_fndecl_math_sign4;
895 tmp = gfor_fndecl_math_sign8;
900 se->expr = gfc_build_function_call (tmp, arg);
904 arg2 = TREE_VALUE (TREE_CHAIN (arg));
905 arg = TREE_VALUE (arg);
906 type = TREE_TYPE (arg);
907 zero = gfc_build_const (type, integer_zero_node);
909 testa = fold (build (GE_EXPR, boolean_type_node, arg, zero));
910 testb = fold (build (GE_EXPR, boolean_type_node, arg2, zero));
911 tmp = fold (build (TRUTH_XOR_EXPR, boolean_type_node, testa, testb));
912 se->expr = fold (build (COND_EXPR, type, tmp,
913 build1 (NEGATE_EXPR, type, arg), arg));
917 /* Test for the presence of an optional argument. */
920 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
924 arg = expr->value.function.actual->expr;
925 assert (arg->expr_type == EXPR_VARIABLE);
926 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
927 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
931 /* Calculate the double precision product of two single precision values. */
934 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
940 arg = gfc_conv_intrinsic_function_args (se, expr);
941 arg2 = TREE_VALUE (TREE_CHAIN (arg));
942 arg = TREE_VALUE (arg);
944 /* Convert the args to double precision before multiplying. */
945 type = gfc_typenode_for_spec (&expr->ts);
946 arg = convert (type, arg);
947 arg2 = convert (type, arg2);
948 se->expr = build (MULT_EXPR, type, arg, arg2);
952 /* Return a length one character string containing an ascii character. */
955 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
961 arg = gfc_conv_intrinsic_function_args (se, expr);
962 arg = TREE_VALUE (arg);
964 /* We currently don't support character types != 1. */
965 assert (expr->ts.kind == 1);
966 type = gfc_character1_type_node;
967 var = gfc_create_var (type, "char");
969 arg = convert (type, arg);
970 gfc_add_modify_expr (&se->pre, var, arg);
971 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
972 se->string_length = integer_one_node;
976 /* Get the minimum/maximum value of all the parameters.
977 minmax (a1, a2, a3, ...)
990 /* TODO: Mismatching types can occur when specific names are used.
991 These should be handled during resolution. */
993 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1004 arg = gfc_conv_intrinsic_function_args (se, expr);
1005 type = gfc_typenode_for_spec (&expr->ts);
1007 limit = TREE_VALUE (arg);
1008 if (TREE_TYPE (limit) != type)
1009 limit = convert (type, limit);
1010 /* Only evaluate the argument once. */
1011 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1012 limit = gfc_evaluate_now(limit, &se->pre);
1014 mvar = gfc_create_var (type, "M");
1015 elsecase = build_v (MODIFY_EXPR, mvar, limit);
1016 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1018 val = TREE_VALUE (arg);
1019 if (TREE_TYPE (val) != type)
1020 val = convert (type, val);
1022 /* Only evaluate the argument once. */
1023 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1024 val = gfc_evaluate_now(val, &se->pre);
1026 thencase = build_v (MODIFY_EXPR, mvar, convert (type, val));
1028 tmp = build (op, boolean_type_node, val, limit);
1029 tmp = build_v (COND_EXPR, tmp, thencase, elsecase);
1030 gfc_add_expr_to_block (&se->pre, tmp);
1031 elsecase = build_empty_stmt ();
1038 /* Create a symbol node for this intrinsic. The symbol form the frontend
1039 is for the generic name. */
1042 gfc_get_symbol_for_expr (gfc_expr * expr)
1046 /* TODO: Add symbols for intrinsic function to the global namespace. */
1047 assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1048 sym = gfc_new_symbol (expr->value.function.name, NULL);
1051 sym->attr.external = 1;
1052 sym->attr.function = 1;
1053 sym->attr.always_explicit = 1;
1054 sym->attr.proc = PROC_INTRINSIC;
1055 sym->attr.flavor = FL_PROCEDURE;
1059 sym->attr.dimension = 1;
1060 sym->as = gfc_get_array_spec ();
1061 sym->as->type = AS_ASSUMED_SHAPE;
1062 sym->as->rank = expr->rank;
1065 /* TODO: proper argument lists for external intrinsics. */
1069 /* Generate a call to an external intrinsic function. */
1071 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1075 assert (!se->ss || se->ss->expr == expr);
1078 assert (expr->rank > 0);
1080 assert (expr->rank == 0);
1082 sym = gfc_get_symbol_for_expr (expr);
1083 gfc_conv_function_call (se, sym, expr->value.function.actual);
1087 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1107 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1116 gfc_actual_arglist *actual;
1123 gfc_conv_intrinsic_funcall (se, expr);
1127 actual = expr->value.function.actual;
1128 type = gfc_typenode_for_spec (&expr->ts);
1129 /* Initialize the result. */
1130 resvar = gfc_create_var (type, "test");
1132 tmp = convert (type, boolean_true_node);
1134 tmp = convert (type, boolean_false_node);
1135 gfc_add_modify_expr (&se->pre, resvar, tmp);
1137 /* Walk the arguments. */
1138 arrayss = gfc_walk_expr (actual->expr);
1139 assert (arrayss != gfc_ss_terminator);
1141 /* Initialize the scalarizer. */
1142 gfc_init_loopinfo (&loop);
1143 exit_label = gfc_build_label_decl (NULL_TREE);
1144 TREE_USED (exit_label) = 1;
1145 gfc_add_ss_to_loop (&loop, arrayss);
1147 /* Initialize the loop. */
1148 gfc_conv_ss_startstride (&loop);
1149 gfc_conv_loop_setup (&loop);
1151 gfc_mark_ss_chain_used (arrayss, 1);
1152 /* Generate the loop body. */
1153 gfc_start_scalarized_body (&loop, &body);
1155 /* If the condition matches then set the return value. */
1156 gfc_start_block (&block);
1158 tmp = convert (type, boolean_false_node);
1160 tmp = convert (type, boolean_true_node);
1161 gfc_add_modify_expr (&block, resvar, tmp);
1163 /* And break out of the loop. */
1164 tmp = build1_v (GOTO_EXPR, exit_label);
1165 gfc_add_expr_to_block (&block, tmp);
1167 found = gfc_finish_block (&block);
1169 /* Check this element. */
1170 gfc_init_se (&arrayse, NULL);
1171 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1172 arrayse.ss = arrayss;
1173 gfc_conv_expr_val (&arrayse, actual->expr);
1175 gfc_add_block_to_block (&body, &arrayse.pre);
1176 tmp = build (op, boolean_type_node, arrayse.expr,
1177 fold_convert (TREE_TYPE (arrayse.expr),
1178 integer_zero_node));
1179 tmp = build_v (COND_EXPR, tmp, found, build_empty_stmt ());
1180 gfc_add_expr_to_block (&body, tmp);
1181 gfc_add_block_to_block (&body, &arrayse.post);
1183 gfc_trans_scalarizing_loops (&loop, &body);
1185 /* Add the exit label. */
1186 tmp = build1_v (LABEL_EXPR, exit_label);
1187 gfc_add_expr_to_block (&loop.pre, tmp);
1189 gfc_add_block_to_block (&se->pre, &loop.pre);
1190 gfc_add_block_to_block (&se->pre, &loop.post);
1191 gfc_cleanup_loop (&loop);
1196 /* COUNT(A) = Number of true elements in A. */
1198 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1205 gfc_actual_arglist *actual;
1211 gfc_conv_intrinsic_funcall (se, expr);
1215 actual = expr->value.function.actual;
1217 type = gfc_typenode_for_spec (&expr->ts);
1218 /* Initialize the result. */
1219 resvar = gfc_create_var (type, "count");
1220 gfc_add_modify_expr (&se->pre, resvar, convert (type, integer_zero_node));
1222 /* Walk the arguments. */
1223 arrayss = gfc_walk_expr (actual->expr);
1224 assert (arrayss != gfc_ss_terminator);
1226 /* Initialize the scalarizer. */
1227 gfc_init_loopinfo (&loop);
1228 gfc_add_ss_to_loop (&loop, arrayss);
1230 /* Initialize the loop. */
1231 gfc_conv_ss_startstride (&loop);
1232 gfc_conv_loop_setup (&loop);
1234 gfc_mark_ss_chain_used (arrayss, 1);
1235 /* Generate the loop body. */
1236 gfc_start_scalarized_body (&loop, &body);
1238 tmp = build (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1239 convert (TREE_TYPE (resvar), integer_one_node));
1240 tmp = build_v (MODIFY_EXPR, resvar, tmp);
1242 gfc_init_se (&arrayse, NULL);
1243 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1244 arrayse.ss = arrayss;
1245 gfc_conv_expr_val (&arrayse, actual->expr);
1246 tmp = build_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1248 gfc_add_block_to_block (&body, &arrayse.pre);
1249 gfc_add_expr_to_block (&body, tmp);
1250 gfc_add_block_to_block (&body, &arrayse.post);
1252 gfc_trans_scalarizing_loops (&loop, &body);
1254 gfc_add_block_to_block (&se->pre, &loop.pre);
1255 gfc_add_block_to_block (&se->pre, &loop.post);
1256 gfc_cleanup_loop (&loop);
1261 /* Inline implementation of the sum and product intrinsics. */
1263 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1271 gfc_actual_arglist *actual;
1276 gfc_expr *arrayexpr;
1281 gfc_conv_intrinsic_funcall (se, expr);
1285 type = gfc_typenode_for_spec (&expr->ts);
1286 /* Initialize the result. */
1287 resvar = gfc_create_var (type, "val");
1288 if (op == PLUS_EXPR)
1289 tmp = gfc_build_const (type, integer_zero_node);
1291 tmp = gfc_build_const (type, integer_one_node);
1293 gfc_add_modify_expr (&se->pre, resvar, tmp);
1295 /* Walk the arguments. */
1296 actual = expr->value.function.actual;
1297 arrayexpr = actual->expr;
1298 arrayss = gfc_walk_expr (arrayexpr);
1299 assert (arrayss != gfc_ss_terminator);
1301 actual = actual->next->next;
1303 maskexpr = actual->expr;
1306 maskss = gfc_walk_expr (maskexpr);
1307 assert (maskss != gfc_ss_terminator);
1312 /* Initialize the scalarizer. */
1313 gfc_init_loopinfo (&loop);
1314 gfc_add_ss_to_loop (&loop, arrayss);
1316 gfc_add_ss_to_loop (&loop, maskss);
1318 /* Initialize the loop. */
1319 gfc_conv_ss_startstride (&loop);
1320 gfc_conv_loop_setup (&loop);
1322 gfc_mark_ss_chain_used (arrayss, 1);
1324 gfc_mark_ss_chain_used (maskss, 1);
1325 /* Generate the loop body. */
1326 gfc_start_scalarized_body (&loop, &body);
1328 /* If we have a mask, only add this element if the mask is set. */
1331 gfc_init_se (&maskse, NULL);
1332 gfc_copy_loopinfo_to_se (&maskse, &loop);
1334 gfc_conv_expr_val (&maskse, maskexpr);
1335 gfc_add_block_to_block (&body, &maskse.pre);
1337 gfc_start_block (&block);
1340 gfc_init_block (&block);
1342 /* Do the actual summation/product. */
1343 gfc_init_se (&arrayse, NULL);
1344 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1345 arrayse.ss = arrayss;
1346 gfc_conv_expr_val (&arrayse, arrayexpr);
1347 gfc_add_block_to_block (&block, &arrayse.pre);
1349 tmp = build (op, type, resvar, arrayse.expr);
1350 gfc_add_modify_expr (&block, resvar, tmp);
1351 gfc_add_block_to_block (&block, &arrayse.post);
1355 /* We enclose the above in if (mask) {...} . */
1356 tmp = gfc_finish_block (&block);
1358 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1361 tmp = gfc_finish_block (&block);
1362 gfc_add_expr_to_block (&body, tmp);
1364 gfc_trans_scalarizing_loops (&loop, &body);
1365 gfc_add_block_to_block (&se->pre, &loop.pre);
1366 gfc_add_block_to_block (&se->pre, &loop.post);
1367 gfc_cleanup_loop (&loop);
1373 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1377 stmtblock_t ifblock;
1384 gfc_actual_arglist *actual;
1389 gfc_expr *arrayexpr;
1396 gfc_conv_intrinsic_funcall (se, expr);
1400 /* Initialize the result. */
1401 pos = gfc_create_var (gfc_array_index_type, "pos");
1402 type = gfc_typenode_for_spec (&expr->ts);
1404 /* Walk the arguments. */
1405 actual = expr->value.function.actual;
1406 arrayexpr = actual->expr;
1407 arrayss = gfc_walk_expr (arrayexpr);
1408 assert (arrayss != gfc_ss_terminator);
1410 actual = actual->next->next;
1412 maskexpr = actual->expr;
1415 maskss = gfc_walk_expr (maskexpr);
1416 assert (maskss != gfc_ss_terminator);
1421 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1422 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind);
1423 switch (arrayexpr->ts.type)
1426 tmp = gfc_conv_mpf_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1430 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1431 arrayexpr->ts.kind);
1438 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1440 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1441 gfc_add_modify_expr (&se->pre, limit, tmp);
1443 /* Initialize the scalarizer. */
1444 gfc_init_loopinfo (&loop);
1445 gfc_add_ss_to_loop (&loop, arrayss);
1447 gfc_add_ss_to_loop (&loop, maskss);
1449 /* Initialize the loop. */
1450 gfc_conv_ss_startstride (&loop);
1451 gfc_conv_loop_setup (&loop);
1453 assert (loop.dimen == 1);
1455 /* Initialize the position to the first element. If the array has zero
1456 size we need to return zero. Otherwise use the first element of the
1457 array, in case all elements are equal to the limit.
1458 ie. pos = (ubound >= lbound) ? lbound, lbound - 1; */
1459 tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
1460 loop.from[0], gfc_index_one_node));
1461 cond = fold (build (GE_EXPR, boolean_type_node,
1462 loop.to[0], loop.from[0]));
1463 tmp = fold (build (COND_EXPR, gfc_array_index_type, cond,
1464 loop.from[0], tmp));
1465 gfc_add_modify_expr (&loop.pre, pos, tmp);
1467 gfc_mark_ss_chain_used (arrayss, 1);
1469 gfc_mark_ss_chain_used (maskss, 1);
1470 /* Generate the loop body. */
1471 gfc_start_scalarized_body (&loop, &body);
1473 /* If we have a mask, only check this element if the mask is set. */
1476 gfc_init_se (&maskse, NULL);
1477 gfc_copy_loopinfo_to_se (&maskse, &loop);
1479 gfc_conv_expr_val (&maskse, maskexpr);
1480 gfc_add_block_to_block (&body, &maskse.pre);
1482 gfc_start_block (&block);
1485 gfc_init_block (&block);
1487 /* Compare with the current limit. */
1488 gfc_init_se (&arrayse, NULL);
1489 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1490 arrayse.ss = arrayss;
1491 gfc_conv_expr_val (&arrayse, arrayexpr);
1492 gfc_add_block_to_block (&block, &arrayse.pre);
1494 /* We do the following if this is a more extreme value. */
1495 gfc_start_block (&ifblock);
1497 /* Assign the value to the limit... */
1498 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1500 /* Remember where we are. */
1501 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1503 ifbody = gfc_finish_block (&ifblock);
1505 /* If it is a more extreme value. */
1506 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1507 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1508 gfc_add_expr_to_block (&block, tmp);
1512 /* We enclose the above in if (mask) {...}. */
1513 tmp = gfc_finish_block (&block);
1515 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1518 tmp = gfc_finish_block (&block);
1519 gfc_add_expr_to_block (&body, tmp);
1521 gfc_trans_scalarizing_loops (&loop, &body);
1523 gfc_add_block_to_block (&se->pre, &loop.pre);
1524 gfc_add_block_to_block (&se->pre, &loop.post);
1525 gfc_cleanup_loop (&loop);
1527 /* Return a value in the range 1..SIZE(array). */
1528 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1529 gfc_index_one_node));
1530 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, pos, tmp));
1531 /* And convert to the required type. */
1532 se->expr = convert (type, tmp);
1536 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1545 gfc_actual_arglist *actual;
1550 gfc_expr *arrayexpr;
1556 gfc_conv_intrinsic_funcall (se, expr);
1560 type = gfc_typenode_for_spec (&expr->ts);
1561 /* Initialize the result. */
1562 limit = gfc_create_var (type, "limit");
1563 n = gfc_validate_kind (expr->ts.type, expr->ts.kind);
1564 switch (expr->ts.type)
1567 tmp = gfc_conv_mpf_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1571 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1578 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1580 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1581 gfc_add_modify_expr (&se->pre, limit, tmp);
1583 /* Walk the arguments. */
1584 actual = expr->value.function.actual;
1585 arrayexpr = actual->expr;
1586 arrayss = gfc_walk_expr (arrayexpr);
1587 assert (arrayss != gfc_ss_terminator);
1589 actual = actual->next->next;
1591 maskexpr = actual->expr;
1594 maskss = gfc_walk_expr (maskexpr);
1595 assert (maskss != gfc_ss_terminator);
1600 /* Initialize the scalarizer. */
1601 gfc_init_loopinfo (&loop);
1602 gfc_add_ss_to_loop (&loop, arrayss);
1604 gfc_add_ss_to_loop (&loop, maskss);
1606 /* Initialize the loop. */
1607 gfc_conv_ss_startstride (&loop);
1608 gfc_conv_loop_setup (&loop);
1610 gfc_mark_ss_chain_used (arrayss, 1);
1612 gfc_mark_ss_chain_used (maskss, 1);
1613 /* Generate the loop body. */
1614 gfc_start_scalarized_body (&loop, &body);
1616 /* If we have a mask, only add this element if the mask is set. */
1619 gfc_init_se (&maskse, NULL);
1620 gfc_copy_loopinfo_to_se (&maskse, &loop);
1622 gfc_conv_expr_val (&maskse, maskexpr);
1623 gfc_add_block_to_block (&body, &maskse.pre);
1625 gfc_start_block (&block);
1628 gfc_init_block (&block);
1630 /* Compare with the current limit. */
1631 gfc_init_se (&arrayse, NULL);
1632 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1633 arrayse.ss = arrayss;
1634 gfc_conv_expr_val (&arrayse, arrayexpr);
1635 gfc_add_block_to_block (&block, &arrayse.pre);
1637 /* Assign the value to the limit... */
1638 ifbody = build_v (MODIFY_EXPR, limit, arrayse.expr);
1640 /* If it is a more extreme value. */
1641 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1642 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1643 gfc_add_expr_to_block (&block, tmp);
1644 gfc_add_block_to_block (&block, &arrayse.post);
1646 tmp = gfc_finish_block (&block);
1649 /* We enclose the above in if (mask) {...}. */
1650 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1652 gfc_add_expr_to_block (&body, tmp);
1654 gfc_trans_scalarizing_loops (&loop, &body);
1656 gfc_add_block_to_block (&se->pre, &loop.pre);
1657 gfc_add_block_to_block (&se->pre, &loop.post);
1658 gfc_cleanup_loop (&loop);
1663 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
1665 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
1672 arg = gfc_conv_intrinsic_function_args (se, expr);
1673 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1674 arg = TREE_VALUE (arg);
1675 type = TREE_TYPE (arg);
1677 tmp = build (LSHIFT_EXPR, type, convert (type, integer_one_node), arg2);
1678 tmp = build (BIT_AND_EXPR, type, arg, tmp);
1679 tmp = fold (build (NE_EXPR, boolean_type_node, tmp,
1680 convert (type, integer_zero_node)));
1681 type = gfc_typenode_for_spec (&expr->ts);
1682 se->expr = convert (type, tmp);
1685 /* Generate code to perform the specified operation. */
1687 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
1693 arg = gfc_conv_intrinsic_function_args (se, expr);
1694 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1695 arg = TREE_VALUE (arg);
1696 type = TREE_TYPE (arg);
1698 se->expr = fold (build (op, type, arg, arg2));
1703 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
1707 arg = gfc_conv_intrinsic_function_args (se, expr);
1708 arg = TREE_VALUE (arg);
1710 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
1713 /* Set or clear a single bit. */
1715 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
1723 arg = gfc_conv_intrinsic_function_args (se, expr);
1724 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1725 arg = TREE_VALUE (arg);
1726 type = TREE_TYPE (arg);
1728 tmp = fold (build (LSHIFT_EXPR, type,
1729 convert (type, integer_one_node), arg2));
1735 tmp = fold (build1 (BIT_NOT_EXPR, type, tmp));
1737 se->expr = fold (build (op, type, arg, tmp));
1740 /* Extract a sequence of bits.
1741 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
1743 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
1752 arg = gfc_conv_intrinsic_function_args (se, expr);
1753 arg2 = TREE_CHAIN (arg);
1754 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
1755 arg = TREE_VALUE (arg);
1756 arg2 = TREE_VALUE (arg2);
1757 type = TREE_TYPE (arg);
1759 mask = build_int_2 (-1, ~(unsigned HOST_WIDE_INT) 0);
1760 mask = build (LSHIFT_EXPR, type, mask, arg3);
1761 mask = build1 (BIT_NOT_EXPR, type, mask);
1763 tmp = build (RSHIFT_EXPR, type, arg, arg2);
1765 se->expr = fold (build (BIT_AND_EXPR, type, tmp, mask));
1768 /* ISHFT (I, SHIFT) = (shift >= 0) ? i << shift : i >> -shift. */
1770 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
1779 arg = gfc_conv_intrinsic_function_args (se, expr);
1780 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1781 arg = TREE_VALUE (arg);
1782 type = TREE_TYPE (arg);
1784 /* Left shift if positive. */
1785 lshift = build (LSHIFT_EXPR, type, arg, arg2);
1787 /* Right shift if negative. This will perform an arithmetic shift as
1788 we are dealing with signed integers. Section 13.5.7 allows this. */
1789 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1790 rshift = build (RSHIFT_EXPR, type, arg, tmp);
1792 tmp = build (GT_EXPR, boolean_type_node, arg2,
1793 convert (TREE_TYPE (arg2), integer_zero_node));
1794 rshift = build (COND_EXPR, type, tmp, lshift, rshift);
1796 /* Do nothing if shift == 0. */
1797 tmp = build (EQ_EXPR, boolean_type_node, arg2,
1798 convert (TREE_TYPE (arg2), integer_zero_node));
1799 se->expr = build (COND_EXPR, type, tmp, arg, rshift);
1802 /* Circular shift. AKA rotate or barrel shift. */
1804 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
1814 arg = gfc_conv_intrinsic_function_args (se, expr);
1815 arg2 = TREE_CHAIN (arg);
1816 arg3 = TREE_CHAIN (arg2);
1819 /* Use a library function for the 3 parameter version. */
1820 type = TREE_TYPE (TREE_VALUE (arg));
1821 /* Convert all args to the same type otherwise we need loads of library
1822 functions. SIZE and SHIFT cannot have values > BIT_SIZE (I) so the
1823 conversion is safe. */
1824 tmp = convert (type, TREE_VALUE (arg2));
1825 TREE_VALUE (arg2) = tmp;
1826 tmp = convert (type, TREE_VALUE (arg3));
1827 TREE_VALUE (arg3) = tmp;
1829 switch (expr->ts.kind)
1832 tmp = gfor_fndecl_math_ishftc4;
1835 tmp = gfor_fndecl_math_ishftc8;
1840 se->expr = gfc_build_function_call (tmp, arg);
1843 arg = TREE_VALUE (arg);
1844 arg2 = TREE_VALUE (arg2);
1845 type = TREE_TYPE (arg);
1847 /* Rotate left if positive. */
1848 lrot = build (LROTATE_EXPR, type, arg, arg2);
1850 /* Rotate right if negative. */
1851 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1852 rrot = build (RROTATE_EXPR, type, arg, tmp);
1854 tmp = build (GT_EXPR, boolean_type_node, arg2,
1855 convert (TREE_TYPE (arg2), integer_zero_node));
1856 rrot = build (COND_EXPR, type, tmp, lrot, rrot);
1858 /* Do nothing if shift == 0. */
1859 tmp = build (EQ_EXPR, boolean_type_node, arg2,
1860 convert (TREE_TYPE (arg2), integer_zero_node));
1861 se->expr = build (COND_EXPR, type, tmp, arg, rrot);
1864 /* The length of a character string. */
1866 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
1877 arg = expr->value.function.actual->expr;
1879 type = gfc_typenode_for_spec (&expr->ts);
1880 switch (arg->expr_type)
1883 len = build_int_2 (arg->value.character.length, 0);
1887 if (arg->expr_type == EXPR_VARIABLE
1888 && (arg->ref == NULL || (arg->ref->next == NULL
1889 && arg->ref->type == REF_ARRAY)))
1891 /* This doesn't catch all cases.
1892 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
1893 and the surrounding thread. */
1894 sym = arg->symtree->n.sym;
1895 decl = gfc_get_symbol_decl (sym);
1896 if (decl == current_function_decl && sym->attr.function
1897 && (sym->result == sym))
1898 decl = gfc_get_fake_result_decl (sym);
1900 len = sym->ts.cl->backend_decl;
1905 /* Anybody stupid enough to do this deserves inefficient code. */
1906 gfc_init_se (&argse, se);
1907 gfc_conv_expr (&argse, arg);
1908 gfc_add_block_to_block (&se->pre, &argse.pre);
1909 gfc_add_block_to_block (&se->post, &argse.post);
1910 len = argse.string_length;
1914 se->expr = convert (type, len);
1917 /* The length of a character string not including trailing blanks. */
1919 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
1924 args = gfc_conv_intrinsic_function_args (se, expr);
1925 type = gfc_typenode_for_spec (&expr->ts);
1926 se->expr = gfc_build_function_call (gfor_fndecl_string_len_trim, args);
1927 se->expr = convert (type, se->expr);
1931 /* Returns the starting position of a substring within a string. */
1934 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
1941 args = gfc_conv_intrinsic_function_args (se, expr);
1942 type = gfc_typenode_for_spec (&expr->ts);
1943 tmp = gfc_advance_chain (args, 3);
1944 if (TREE_CHAIN (tmp) == NULL_TREE)
1946 back = convert (gfc_logical4_type_node, integer_one_node);
1947 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
1948 TREE_CHAIN (tmp) = back;
1952 back = TREE_CHAIN (tmp);
1953 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
1956 se->expr = gfc_build_function_call (gfor_fndecl_string_index, args);
1957 se->expr = convert (type, se->expr);
1960 /* The ascii value for a single character. */
1962 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
1967 arg = gfc_conv_intrinsic_function_args (se, expr);
1968 arg = TREE_VALUE (TREE_CHAIN (arg));
1969 assert (POINTER_TYPE_P (TREE_TYPE (arg)));
1970 arg = build1 (NOP_EXPR, pchar_type_node, arg);
1971 type = gfc_typenode_for_spec (&expr->ts);
1973 se->expr = gfc_build_indirect_ref (arg);
1974 se->expr = convert (type, se->expr);
1978 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
1981 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
1989 arg = gfc_conv_intrinsic_function_args (se, expr);
1990 tsource = TREE_VALUE (arg);
1991 arg = TREE_CHAIN (arg);
1992 fsource = TREE_VALUE (arg);
1993 arg = TREE_CHAIN (arg);
1994 mask = TREE_VALUE (arg);
1996 type = TREE_TYPE (tsource);
1997 se->expr = fold (build (COND_EXPR, type, mask, tsource, fsource));
2002 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2004 gfc_actual_arglist *actual;
2011 gfc_init_se (&argse, NULL);
2012 actual = expr->value.function.actual;
2014 ss = gfc_walk_expr (actual->expr);
2015 assert (ss != gfc_ss_terminator);
2016 argse.want_pointer = 1;
2017 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2018 gfc_add_block_to_block (&se->pre, &argse.pre);
2019 gfc_add_block_to_block (&se->post, &argse.post);
2020 args = gfc_chainon_list (NULL_TREE, argse.expr);
2022 actual = actual->next;
2025 gfc_init_se (&argse, NULL);
2026 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2027 gfc_add_block_to_block (&se->pre, &argse.pre);
2028 args = gfc_chainon_list (args, argse.expr);
2029 fndecl = gfor_fndecl_size1;
2032 fndecl = gfor_fndecl_size0;
2034 se->expr = gfc_build_function_call (fndecl, args);
2035 type = gfc_typenode_for_spec (&expr->ts);
2036 se->expr = convert (type, se->expr);
2040 /* Intrinsic string comparison functions. */
2043 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2048 args = gfc_conv_intrinsic_function_args (se, expr);
2049 /* Build a call for the comparison. */
2050 se->expr = gfc_build_function_call (gfor_fndecl_compare_string, args);
2052 type = gfc_typenode_for_spec (&expr->ts);
2053 se->expr = build (op, type, se->expr,
2054 convert (TREE_TYPE (se->expr), integer_zero_node));
2057 /* Generate a call to the adjustl/adjustr library function. */
2059 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2067 args = gfc_conv_intrinsic_function_args (se, expr);
2068 len = TREE_VALUE (args);
2070 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2071 var = gfc_conv_string_tmp (se, type, len);
2072 args = tree_cons (NULL_TREE, var, args);
2074 tmp = gfc_build_function_call (fndecl, args);
2075 gfc_add_expr_to_block (&se->pre, tmp);
2077 se->string_length = len;
2081 /* Scalar transfer statement.
2082 TRANSFER (source, mold) = *(typeof<mould> *)&source */
2085 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2087 gfc_actual_arglist *arg;
2095 /* Get a pointer to the source. */
2096 arg = expr->value.function.actual;
2097 ss = gfc_walk_expr (arg->expr);
2098 gfc_init_se (&argse, NULL);
2099 if (ss == gfc_ss_terminator)
2100 gfc_conv_expr_reference (&argse, arg->expr);
2102 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2103 gfc_add_block_to_block (&se->pre, &argse.pre);
2104 gfc_add_block_to_block (&se->post, &argse.post);
2108 type = gfc_typenode_for_spec (&expr->ts);
2109 ptr = convert (build_pointer_type (type), ptr);
2110 if (expr->ts.type == BT_CHARACTER)
2112 gfc_init_se (&argse, NULL);
2113 gfc_conv_expr (&argse, arg->expr);
2114 gfc_add_block_to_block (&se->pre, &argse.pre);
2115 gfc_add_block_to_block (&se->post, &argse.post);
2117 se->string_length = argse.string_length;
2121 se->expr = gfc_build_indirect_ref (ptr);
2126 /* Generate code for the ALLOCATED intrinsic.
2127 Generate inline code that directly check the address of the argument. */
2130 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2132 gfc_actual_arglist *arg1;
2137 gfc_init_se (&arg1se, NULL);
2138 arg1 = expr->value.function.actual;
2139 ss1 = gfc_walk_expr (arg1->expr);
2140 arg1se.descriptor_only = 1;
2141 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2143 tmp = gfc_conv_descriptor_data (arg1se.expr);
2144 tmp = build (NE_EXPR, boolean_type_node, tmp,
2145 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2146 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2150 /* Generate code for the ASSOCIATED intrinsic.
2151 If both POINTER and TARGET are arrays, generate a call to library function
2152 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2153 In other cases, generate inline code that directly compare the address of
2154 POINTER with the address of TARGET. */
2157 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2159 gfc_actual_arglist *arg1;
2160 gfc_actual_arglist *arg2;
2168 gfc_init_se (&arg1se, NULL);
2169 gfc_init_se (&arg2se, NULL);
2170 arg1 = expr->value.function.actual;
2172 ss1 = gfc_walk_expr (arg1->expr);
2176 /* No optional target. */
2177 if (ss1 == gfc_ss_terminator)
2179 /* A pointer to a scalar. */
2180 arg1se.want_pointer = 1;
2181 gfc_conv_expr (&arg1se, arg1->expr);
2186 /* A pointer to an array. */
2187 arg1se.descriptor_only = 1;
2188 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2189 tmp2 = gfc_conv_descriptor_data (arg1se.expr);
2191 tmp = build (NE_EXPR, boolean_type_node, tmp2,
2192 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
2197 /* An optional target. */
2198 ss2 = gfc_walk_expr (arg2->expr);
2199 if (ss1 == gfc_ss_terminator)
2201 /* A pointer to a scalar. */
2202 assert (ss2 == gfc_ss_terminator);
2203 arg1se.want_pointer = 1;
2204 gfc_conv_expr (&arg1se, arg1->expr);
2205 arg2se.want_pointer = 1;
2206 gfc_conv_expr (&arg2se, arg2->expr);
2207 tmp = build (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2212 /* A pointer to an array, call library function _gfor_associated. */
2213 assert (ss2 != gfc_ss_terminator);
2215 arg1se.want_pointer = 1;
2216 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2217 args = gfc_chainon_list (args, arg1se.expr);
2218 arg2se.want_pointer = 1;
2219 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2220 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2221 gfc_add_block_to_block (&se->post, &arg2se.post);
2222 args = gfc_chainon_list (args, arg2se.expr);
2223 fndecl = gfor_fndecl_associated;
2224 se->expr = gfc_build_function_call (fndecl, args);
2227 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2231 /* Scan a string for any one of the characters in a set of characters. */
2234 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2241 args = gfc_conv_intrinsic_function_args (se, expr);
2242 type = gfc_typenode_for_spec (&expr->ts);
2243 tmp = gfc_advance_chain (args, 3);
2244 if (TREE_CHAIN (tmp) == NULL_TREE)
2246 back = convert (gfc_logical4_type_node, integer_one_node);
2247 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2248 TREE_CHAIN (tmp) = back;
2252 back = TREE_CHAIN (tmp);
2253 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2256 se->expr = gfc_build_function_call (gfor_fndecl_string_scan, args);
2257 se->expr = convert (type, se->expr);
2261 /* Verify that a set of characters contains all the characters in a string
2262 by indentifying the position of the first character in a string of
2263 characters that does not appear in a given set of characters. */
2266 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2273 args = gfc_conv_intrinsic_function_args (se, expr);
2274 type = gfc_typenode_for_spec (&expr->ts);
2275 tmp = gfc_advance_chain (args, 3);
2276 if (TREE_CHAIN (tmp) == NULL_TREE)
2278 back = convert (gfc_logical4_type_node, integer_one_node);
2279 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2280 TREE_CHAIN (tmp) = back;
2284 back = TREE_CHAIN (tmp);
2285 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2288 se->expr = gfc_build_function_call (gfor_fndecl_string_verify, args);
2289 se->expr = convert (type, se->expr);
2292 /* Prepare components and related information of a real number which is
2293 the first argument of a elemental functions to manipulate reals. */
2296 void prepare_arg_info (gfc_se * se, gfc_expr * expr,
2297 real_compnt_info * rcs, int all)
2304 tree exponent, fraction;
2308 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
2309 gfc_todo_error ("Non-IEEE floating format");
2311 assert (expr->expr_type == EXPR_FUNCTION);
2313 arg = gfc_conv_intrinsic_function_args (se, expr);
2314 arg = TREE_VALUE (arg);
2315 rcs->type = TREE_TYPE (arg);
2317 /* Force arg'type to integer by unaffected convert */
2318 a1 = expr->value.function.actual->expr;
2319 masktype = gfc_get_int_type (a1->ts.kind);
2320 rcs->mtype = masktype;
2321 tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
2322 arg = gfc_create_var (masktype, "arg");
2323 gfc_add_modify_expr(&se->pre, arg, tmp);
2326 /* Caculate the numbers of bits of exponent, fraction and word */
2327 n = gfc_validate_kind (a1->ts.type, a1->ts.kind);
2328 tmp = build_int_2 (gfc_real_kinds[n].digits - 1, 0);
2329 rcs->fdigits = convert (masktype, tmp);
2330 wbits = build_int_2 (TYPE_PRECISION (rcs->type) - 1, 0);
2331 wbits = convert (masktype, wbits);
2332 rcs->edigits = fold (build (MINUS_EXPR, masktype, wbits, tmp));
2334 /* Form masks for exponent/fraction/sign */
2335 one = gfc_build_const (masktype, integer_one_node);
2336 rcs->smask = fold (build (LSHIFT_EXPR, masktype, one, wbits));
2337 rcs->f1 = fold (build (LSHIFT_EXPR, masktype, one, rcs->fdigits));
2338 rcs->emask = fold (build (MINUS_EXPR, masktype, rcs->smask, rcs->f1));
2339 rcs->fmask = fold (build (MINUS_EXPR, masktype, rcs->f1, one));
2341 tmp = fold (build (MINUS_EXPR, masktype, rcs->edigits, one));
2342 tmp = fold (build (LSHIFT_EXPR, masktype, one, tmp));
2343 rcs->bias = fold (build (MINUS_EXPR, masktype, tmp ,one));
2347 /* exponent, and fraction */
2348 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->emask);
2349 tmp = build (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
2350 exponent = gfc_create_var (masktype, "exponent");
2351 gfc_add_modify_expr(&se->pre, exponent, tmp);
2352 rcs->expn = exponent;
2354 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->fmask);
2355 fraction = gfc_create_var (masktype, "fraction");
2356 gfc_add_modify_expr(&se->pre, fraction, tmp);
2357 rcs->frac = fraction;
2361 /* Build a call to __builtin_clz. */
2364 call_builtin_clz (tree result_type, tree op0)
2366 tree fn, parms, call;
2367 enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
2369 if (op0_mode == TYPE_MODE (integer_type_node))
2370 fn = built_in_decls[BUILT_IN_CLZ];
2371 else if (op0_mode == TYPE_MODE (long_integer_type_node))
2372 fn = built_in_decls[BUILT_IN_CLZL];
2373 else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
2374 fn = built_in_decls[BUILT_IN_CLZLL];
2378 parms = tree_cons (NULL, op0, NULL);
2379 call = gfc_build_function_call (fn, parms);
2381 return convert (result_type, call);
2384 /* Generate code for SPACING (X) intrinsic function. We generate:
2386 t = expn - (BITS_OF_FRACTION)
2387 res = t << (BITS_OF_FRACTION)
2393 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2400 real_compnt_info rcs;
2402 prepare_arg_info (se, expr, &rcs, 0);
2404 masktype = rcs.mtype;
2405 fdigits = rcs.fdigits;
2407 zero = gfc_build_const (masktype, integer_zero_node);
2408 tmp = build (BIT_AND_EXPR, masktype, rcs.emask, arg);
2409 tmp = build (RSHIFT_EXPR, masktype, tmp, fdigits);
2410 tmp = build (MINUS_EXPR, masktype, tmp, fdigits);
2411 cond = build (LE_EXPR, boolean_type_node, tmp, zero);
2412 t1 = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2413 tmp = build (COND_EXPR, masktype, cond, tiny, t1);
2414 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2419 /* Generate code for RRSPACING (X) intrinsic function. We generate:
2421 if (expn == 0 && frac == 0)
2425 sedigits = edigits + 1;
2428 t1 = leadzero (frac);
2429 frac = frac << (t1 + sedigits);
2430 frac = frac >> (sedigits);
2432 t = bias + BITS_OF_FRACTION_OF;
2433 res = (t << BITS_OF_FRACTION_OF) | frac;
2437 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2440 tree tmp, t1, t2, cond, cond2;
2442 tree fdigits, fraction;
2443 real_compnt_info rcs;
2445 prepare_arg_info (se, expr, &rcs, 1);
2446 masktype = rcs.mtype;
2447 fdigits = rcs.fdigits;
2448 fraction = rcs.frac;
2449 one = gfc_build_const (masktype, integer_one_node);
2450 zero = gfc_build_const (masktype, integer_zero_node);
2451 t2 = build (PLUS_EXPR, masktype, rcs.edigits, one);
2453 t1 = call_builtin_clz (masktype, fraction);
2454 tmp = build (PLUS_EXPR, masktype, t1, one);
2455 tmp = build (LSHIFT_EXPR, masktype, fraction, tmp);
2456 tmp = build (RSHIFT_EXPR, masktype, tmp, t2);
2457 cond = build (EQ_EXPR, boolean_type_node, rcs.expn, zero);
2458 fraction = build (COND_EXPR, masktype, cond, tmp, fraction);
2460 tmp = build (PLUS_EXPR, masktype, rcs.bias, fdigits);
2461 tmp = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2462 tmp = build (BIT_IOR_EXPR, masktype, tmp, fraction);
2464 cond2 = build (EQ_EXPR, boolean_type_node, rcs.frac, zero);
2465 cond = build (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
2466 tmp = build (COND_EXPR, masktype, cond,
2467 convert (masktype, integer_zero_node), tmp);
2469 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2473 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
2476 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
2480 args = gfc_conv_intrinsic_function_args (se, expr);
2481 args = TREE_VALUE (args);
2482 args = gfc_build_addr_expr (NULL, args);
2483 args = tree_cons (NULL_TREE, args, NULL_TREE);
2484 se->expr = gfc_build_function_call (gfor_fndecl_si_kind, args);
2487 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
2490 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
2492 gfc_actual_arglist *actual;
2497 for (actual = expr->value.function.actual; actual; actual = actual->next)
2499 gfc_init_se (&argse, se);
2501 /* Pass a NULL pointer for an absent arg. */
2502 if (actual->expr == NULL)
2503 argse.expr = null_pointer_node;
2505 gfc_conv_expr_reference (&argse, actual->expr);
2507 gfc_add_block_to_block (&se->pre, &argse.pre);
2508 gfc_add_block_to_block (&se->post, &argse.post);
2509 args = gfc_chainon_list (args, argse.expr);
2511 se->expr = gfc_build_function_call (gfor_fndecl_sr_kind, args);
2515 /* Generate code for TRIM (A) intrinsic function. */
2518 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
2528 arglist = NULL_TREE;
2530 type = build_pointer_type (gfc_character1_type_node);
2531 var = gfc_create_var (type, "pstr");
2532 addr = gfc_build_addr_expr (ppvoid_type_node, var);
2533 len = gfc_create_var (gfc_int4_type_node, "len");
2535 tmp = gfc_conv_intrinsic_function_args (se, expr);
2536 arglist = gfc_chainon_list (arglist, gfc_build_addr_expr (NULL, len));
2537 arglist = gfc_chainon_list (arglist, addr);
2538 arglist = chainon (arglist, tmp);
2540 tmp = gfc_build_function_call (gfor_fndecl_string_trim, arglist);
2541 gfc_add_expr_to_block (&se->pre, tmp);
2543 /* Free the temporary afterwards, if necessary. */
2544 cond = build (GT_EXPR, boolean_type_node, len,
2545 convert (TREE_TYPE (len), integer_zero_node));
2546 arglist = gfc_chainon_list (NULL_TREE, var);
2547 tmp = gfc_build_function_call (gfor_fndecl_internal_free, arglist);
2548 tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2549 gfc_add_expr_to_block (&se->post, tmp);
2552 se->string_length = len;
2556 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
2559 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
2569 args = gfc_conv_intrinsic_function_args (se, expr);
2570 len = TREE_VALUE (args);
2571 tmp = gfc_advance_chain (args, 2);
2572 ncopies = TREE_VALUE (tmp);
2573 len = fold (build (MULT_EXPR, gfc_int4_type_node, len, ncopies));
2574 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
2575 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
2577 arglist = NULL_TREE;
2578 arglist = gfc_chainon_list (arglist, var);
2579 arglist = chainon (arglist, args);
2580 tmp = gfc_build_function_call (gfor_fndecl_string_repeat, arglist);
2581 gfc_add_expr_to_block (&se->pre, tmp);
2584 se->string_length = len;
2588 /* Generate code for the IARGC intrinsic. If args_only is true this is
2589 actually the COMMAND_ARGUMENT_COUNT intrinsic, so return IARGC - 1. */
2592 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr, bool args_only)
2598 /* Call the library function. This always returns an INTEGER(4). */
2599 fndecl = gfor_fndecl_iargc;
2600 tmp = gfc_build_function_call (fndecl, NULL_TREE);
2602 /* Convert it to the required type. */
2603 type = gfc_typenode_for_spec (&expr->ts);
2604 tmp = fold_convert (type, tmp);
2607 tmp = build (MINUS_EXPR, type, tmp, convert (type, integer_one_node));
2611 /* Generate code for an intrinsic function. Some map directly to library
2612 calls, others get special handling. In some cases the name of the function
2613 used depends on the type specifiers. */
2616 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
2618 gfc_intrinsic_sym *isym;
2622 isym = expr->value.function.isym;
2624 name = &expr->value.function.name[2];
2628 lib = gfc_is_intrinsic_libcall (expr);
2632 se->ignore_optional = 1;
2633 gfc_conv_intrinsic_funcall (se, expr);
2638 switch (expr->value.function.isym->generic_id)
2643 case GFC_ISYM_REPEAT:
2644 gfc_conv_intrinsic_repeat (se, expr);
2648 gfc_conv_intrinsic_trim (se, expr);
2651 case GFC_ISYM_SI_KIND:
2652 gfc_conv_intrinsic_si_kind (se, expr);
2655 case GFC_ISYM_SR_KIND:
2656 gfc_conv_intrinsic_sr_kind (se, expr);
2659 case GFC_ISYM_EXPONENT:
2660 gfc_conv_intrinsic_exponent (se, expr);
2663 case GFC_ISYM_SPACING:
2664 gfc_conv_intrinsic_spacing (se, expr);
2667 case GFC_ISYM_RRSPACING:
2668 gfc_conv_intrinsic_rrspacing (se, expr);
2672 gfc_conv_intrinsic_scan (se, expr);
2675 case GFC_ISYM_VERIFY:
2676 gfc_conv_intrinsic_verify (se, expr);
2679 case GFC_ISYM_ALLOCATED:
2680 gfc_conv_allocated (se, expr);
2683 case GFC_ISYM_ASSOCIATED:
2684 gfc_conv_associated(se, expr);
2688 gfc_conv_intrinsic_abs (se, expr);
2691 case GFC_ISYM_ADJUSTL:
2692 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
2695 case GFC_ISYM_ADJUSTR:
2696 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
2699 case GFC_ISYM_AIMAG:
2700 gfc_conv_intrinsic_imagpart (se, expr);
2704 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
2708 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
2711 case GFC_ISYM_ANINT:
2712 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
2716 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
2719 case GFC_ISYM_BTEST:
2720 gfc_conv_intrinsic_btest (se, expr);
2723 case GFC_ISYM_ACHAR:
2725 gfc_conv_intrinsic_char (se, expr);
2728 case GFC_ISYM_CONVERSION:
2730 case GFC_ISYM_LOGICAL:
2732 gfc_conv_intrinsic_conversion (se, expr);
2735 /* Integer conversions are handled seperately to make sure we get the
2736 correct rounding mode. */
2738 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
2742 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
2745 case GFC_ISYM_CEILING:
2746 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
2749 case GFC_ISYM_FLOOR:
2750 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
2754 gfc_conv_intrinsic_mod (se, expr, 0);
2757 case GFC_ISYM_MODULO:
2758 gfc_conv_intrinsic_mod (se, expr, 1);
2761 case GFC_ISYM_CMPLX:
2762 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
2765 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
2766 gfc_conv_intrinsic_iargc (se, expr, TRUE);
2769 case GFC_ISYM_CONJG:
2770 gfc_conv_intrinsic_conjg (se, expr);
2773 case GFC_ISYM_COUNT:
2774 gfc_conv_intrinsic_count (se, expr);
2778 gfc_conv_intrinsic_dim (se, expr);
2781 case GFC_ISYM_DPROD:
2782 gfc_conv_intrinsic_dprod (se, expr);
2786 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
2789 case GFC_ISYM_IBCLR:
2790 gfc_conv_intrinsic_singlebitop (se, expr, 0);
2793 case GFC_ISYM_IBITS:
2794 gfc_conv_intrinsic_ibits (se, expr);
2797 case GFC_ISYM_IBSET:
2798 gfc_conv_intrinsic_singlebitop (se, expr, 1);
2801 case GFC_ISYM_IACHAR:
2802 case GFC_ISYM_ICHAR:
2803 /* We assume ASCII character sequence. */
2804 gfc_conv_intrinsic_ichar (se, expr);
2807 case GFC_ISYM_IARGC:
2808 gfc_conv_intrinsic_iargc (se, expr, FALSE);
2812 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
2815 case GFC_ISYM_INDEX:
2816 gfc_conv_intrinsic_index (se, expr);
2820 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
2823 case GFC_ISYM_ISHFT:
2824 gfc_conv_intrinsic_ishft (se, expr);
2827 case GFC_ISYM_ISHFTC:
2828 gfc_conv_intrinsic_ishftc (se, expr);
2831 case GFC_ISYM_LBOUND:
2832 gfc_conv_intrinsic_bound (se, expr, 0);
2836 gfc_conv_intrinsic_len (se, expr);
2839 case GFC_ISYM_LEN_TRIM:
2840 gfc_conv_intrinsic_len_trim (se, expr);
2844 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
2848 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
2852 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
2856 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
2860 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
2863 case GFC_ISYM_MAXLOC:
2864 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
2867 case GFC_ISYM_MAXVAL:
2868 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
2871 case GFC_ISYM_MERGE:
2872 gfc_conv_intrinsic_merge (se, expr);
2876 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
2879 case GFC_ISYM_MINLOC:
2880 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
2883 case GFC_ISYM_MINVAL:
2884 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
2888 gfc_conv_intrinsic_not (se, expr);
2891 case GFC_ISYM_PRESENT:
2892 gfc_conv_intrinsic_present (se, expr);
2895 case GFC_ISYM_PRODUCT:
2896 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
2900 gfc_conv_intrinsic_sign (se, expr);
2904 gfc_conv_intrinsic_size (se, expr);
2908 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
2911 case GFC_ISYM_TRANSFER:
2912 gfc_conv_intrinsic_transfer (se, expr);
2915 case GFC_ISYM_UBOUND:
2916 gfc_conv_intrinsic_bound (se, expr, 1);
2919 case GFC_ISYM_DOT_PRODUCT:
2920 case GFC_ISYM_MATMUL:
2921 case GFC_ISYM_IRAND:
2923 case GFC_ISYM_ETIME:
2924 case GFC_ISYM_SECOND:
2925 gfc_conv_intrinsic_funcall (se, expr);
2929 gfc_conv_intrinsic_lib_function (se, expr);
2935 /* This generates code to execute before entering the scalarization loop.
2936 Currently does nothing. */
2939 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
2941 switch (ss->expr->value.function.isym->generic_id)
2943 case GFC_ISYM_UBOUND:
2944 case GFC_ISYM_LBOUND:
2954 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
2955 inside the scalarization loop. */
2958 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
2962 /* The two argument version returns a scalar. */
2963 if (expr->value.function.actual->next->expr)
2966 newss = gfc_get_ss ();
2967 newss->type = GFC_SS_INTRINSIC;
2975 /* Walk an intrinsic array libcall. */
2978 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
2982 assert (expr->rank > 0);
2984 newss = gfc_get_ss ();
2985 newss->type = GFC_SS_FUNCTION;
2988 newss->data.info.dimen = expr->rank;
2994 /* Returns nonzero if the specified intrinsic function call maps directly to a
2995 an external library call. Should only be used for functions that return
2999 gfc_is_intrinsic_libcall (gfc_expr * expr)
3001 assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3002 assert (expr->rank > 0);
3004 switch (expr->value.function.isym->generic_id)
3008 case GFC_ISYM_COUNT:
3009 case GFC_ISYM_MATMUL:
3010 case GFC_ISYM_MAXLOC:
3011 case GFC_ISYM_MAXVAL:
3012 case GFC_ISYM_MINLOC:
3013 case GFC_ISYM_MINVAL:
3014 case GFC_ISYM_PRODUCT:
3016 case GFC_ISYM_SHAPE:
3017 case GFC_ISYM_SPREAD:
3018 case GFC_ISYM_TRANSPOSE:
3019 /* Ignore absent optional parameters. */
3022 case GFC_ISYM_RESHAPE:
3023 case GFC_ISYM_CSHIFT:
3024 case GFC_ISYM_EOSHIFT:
3026 case GFC_ISYM_UNPACK:
3027 /* Pass absent optional parameters. */
3035 /* Walk an intrinsic function. */
3037 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3038 gfc_intrinsic_sym * isym)
3042 if (isym->elemental)
3043 return gfc_walk_elemental_function_args (ss, expr, GFC_SS_SCALAR);
3045 if (expr->rank == 0)
3048 if (gfc_is_intrinsic_libcall (expr))
3049 return gfc_walk_intrinsic_libfunc (ss, expr);
3051 /* Special cases. */
3052 switch (isym->generic_id)
3054 case GFC_ISYM_LBOUND:
3055 case GFC_ISYM_UBOUND:
3056 return gfc_walk_intrinsic_bound (ss, expr);
3059 /* This probably meant someone forgot to add an intrinsic to the above
3060 list(s) when they implemented it, or something's gone horribly wrong.
3062 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3063 expr->value.function.name);
3067 #include "gt-fortran-trans-intrinsic.h"