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, integer_one_node);
232 tmp = build (COND_EXPR, type, cond, intval, tmp);
237 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
238 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
241 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
250 argtype = TREE_TYPE (arg);
251 arg = gfc_evaluate_now (arg, pblock);
253 real_from_string (&r, "0.5");
254 pos = build_real (argtype, r);
256 real_from_string (&r, "-0.5");
257 neg = build_real (argtype, r);
259 tmp = gfc_build_const (argtype, integer_zero_node);
260 cond = fold (build (GT_EXPR, boolean_type_node, arg, tmp));
262 tmp = fold (build (COND_EXPR, argtype, cond, pos, neg));
263 tmp = fold (build (PLUS_EXPR, argtype, arg, tmp));
264 return fold (build1 (FIX_TRUNC_EXPR, type, tmp));
268 /* Convert a real to an integer using a specific rounding mode.
269 Ideally we would just build the corresponding GENERIC node,
270 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
273 build_fix_expr (stmtblock_t * pblock, tree arg, tree type, int op)
278 return build_fixbound_expr (pblock, arg, type, 0);
282 return build_fixbound_expr (pblock, arg, type, 1);
286 return build_round_expr (pblock, arg, type);
289 return build1 (op, type, arg);
294 /* Round a real value using the specified rounding mode.
295 We use a temporary integer of that same kind size as the result.
296 Values larger than can be represented by this kind are unchanged, as
297 will not be accurate enough to represent the rounding.
298 huge = HUGE (KIND (a))
299 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
303 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, int op)
314 kind = expr->ts.kind;
317 /* We have builtin functions for some cases. */
346 /* Evaluate the argument. */
347 assert (expr->value.function.actual->expr);
348 arg = gfc_conv_intrinsic_function_args (se, expr);
350 /* Use a builtin function if one exists. */
351 if (n != END_BUILTINS)
353 tmp = built_in_decls[n];
354 se->expr = gfc_build_function_call (tmp, arg);
358 /* This code is probably redundant, but we'll keep it lying around just
360 type = gfc_typenode_for_spec (&expr->ts);
361 arg = TREE_VALUE (arg);
362 arg = gfc_evaluate_now (arg, &se->pre);
364 /* Test if the value is too large to handle sensibly. */
366 n = gfc_validate_kind (BT_INTEGER, kind);
367 mpf_set_z (huge, gfc_integer_kinds[n].huge);
368 tmp = gfc_conv_mpf_to_tree (huge, kind);
369 cond = build (LT_EXPR, boolean_type_node, arg, tmp);
371 mpf_neg (huge, huge);
372 tmp = gfc_conv_mpf_to_tree (huge, kind);
373 tmp = build (GT_EXPR, boolean_type_node, arg, tmp);
374 cond = build (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
375 itype = gfc_get_int_type (kind);
377 tmp = build_fix_expr (&se->pre, arg, itype, op);
378 tmp = convert (type, tmp);
379 se->expr = build (COND_EXPR, type, cond, tmp, arg);
383 /* Convert to an integer using the specified rounding mode. */
386 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
391 /* Evaluate the argument. */
392 type = gfc_typenode_for_spec (&expr->ts);
393 assert (expr->value.function.actual->expr);
394 arg = gfc_conv_intrinsic_function_args (se, expr);
395 arg = TREE_VALUE (arg);
397 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
399 /* Conversion to a different integer kind. */
400 se->expr = convert (type, arg);
404 /* Conversion from complex to non-complex involves taking the real
405 component of the value. */
406 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
407 && expr->ts.type != BT_COMPLEX)
411 artype = TREE_TYPE (TREE_TYPE (arg));
412 arg = build1 (REALPART_EXPR, artype, arg);
415 se->expr = build_fix_expr (&se->pre, arg, type, op);
420 /* Get the imaginary component of a value. */
423 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
427 arg = gfc_conv_intrinsic_function_args (se, expr);
428 arg = TREE_VALUE (arg);
429 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
433 /* Get the complex conjugate of a value. */
436 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
440 arg = gfc_conv_intrinsic_function_args (se, expr);
441 arg = TREE_VALUE (arg);
442 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
446 /* Initialize function decls for library functions. The external functions
447 are created as required. Builtin functions are added here. */
450 gfc_build_intrinsic_lib_fndecls (void)
452 gfc_intrinsic_map_t *m;
454 /* Add GCC builtin functions. */
455 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
457 if (m->code4 != END_BUILTINS)
458 m->real4_decl = built_in_decls[m->code4];
459 if (m->code8 != END_BUILTINS)
460 m->real8_decl = built_in_decls[m->code8];
465 /* Create a fndecl for a simple intrinsic library function. */
468 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
473 gfc_actual_arglist *actual;
476 char name[GFC_MAX_SYMBOL_LEN + 3];
479 if (ts->type == BT_REAL)
484 pdecl = &m->real4_decl;
487 pdecl = &m->real8_decl;
493 else if (ts->type == BT_COMPLEX)
495 if (!m->complex_available)
501 pdecl = &m->complex4_decl;
504 pdecl = &m->complex8_decl;
518 if (ts->kind != 4 && ts->kind != 8)
520 snprintf (name, sizeof (name), "%s%s%s",
521 ts->type == BT_COMPLEX ? "c" : "",
523 ts->kind == 4 ? "f" : "");
527 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
528 ts->type == BT_COMPLEX ? 'c' : 'r',
532 argtypes = NULL_TREE;
533 for (actual = expr->value.function.actual; actual; actual = actual->next)
535 type = gfc_typenode_for_spec (&actual->expr->ts);
536 argtypes = gfc_chainon_list (argtypes, type);
538 argtypes = gfc_chainon_list (argtypes, void_type_node);
539 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
540 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
542 /* Mark the decl as external. */
543 DECL_EXTERNAL (fndecl) = 1;
544 TREE_PUBLIC (fndecl) = 1;
546 /* Mark it __attribute__((const)), if possible. */
547 TREE_READONLY (fndecl) = m->is_constant;
549 rest_of_decl_compilation (fndecl, NULL, 1, 0);
556 /* Convert an intrinsic function into an external or builtin call. */
559 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
561 gfc_intrinsic_map_t *m;
564 gfc_generic_isym_id id;
566 id = expr->value.function.isym->generic_id;
567 /* Find the entry for this function. */
568 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
574 if (m->id == GFC_ISYM_NONE)
576 internal_error ("Intrinsic function %s(%d) not recognized",
577 expr->value.function.name, id);
580 /* Get the decl and generate the call. */
581 args = gfc_conv_intrinsic_function_args (se, expr);
582 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
583 se->expr = gfc_build_function_call (fndecl, args);
586 /* Generate code for EXPONENT(X) intrinsic function. */
589 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
594 args = gfc_conv_intrinsic_function_args (se, expr);
596 a1 = expr->value.function.actual->expr;
600 fndecl = gfor_fndecl_math_exponent4;
603 fndecl = gfor_fndecl_math_exponent8;
609 se->expr = gfc_build_function_call (fndecl, args);
612 /* Evaluate a single upper or lower bound. */
613 /* TODO: bound intrinsic generates way too much unneccessary code. */
616 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
618 gfc_actual_arglist *arg;
619 gfc_actual_arglist *arg2;
629 gfc_init_se (&argse, NULL);
630 arg = expr->value.function.actual;
635 /* Create an implicit second parameter from the loop variable. */
636 assert (!arg2->expr);
637 assert (se->loop->dimen == 1);
638 assert (se->ss->expr == expr);
639 gfc_advance_se_ss_chain (se);
640 bound = se->loop->loopvar[0];
641 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
646 /* use the passed argument. */
647 assert (arg->next->expr);
648 gfc_init_se (&argse, NULL);
649 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
650 gfc_add_block_to_block (&se->pre, &argse.pre);
652 /* Convert from one based to zero based. */
653 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
657 /* TODO: don't re-evaluate the descriptor on each iteration. */
658 /* Get a descriptor for the first parameter. */
659 ss = gfc_walk_expr (arg->expr);
660 assert (ss != gfc_ss_terminator);
661 argse.want_pointer = 0;
662 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
663 gfc_add_block_to_block (&se->pre, &argse.pre);
664 gfc_add_block_to_block (&se->post, &argse.post);
668 if (INTEGER_CST_P (bound))
670 assert (TREE_INT_CST_HIGH (bound) == 0);
671 i = TREE_INT_CST_LOW (bound);
672 assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
676 if (flag_bounds_check)
678 bound = gfc_evaluate_now (bound, &se->pre);
679 cond = fold (build (LT_EXPR, boolean_type_node, bound,
681 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
682 tmp = fold (build (GE_EXPR, boolean_type_node, bound, tmp));
683 cond = fold(build (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp));
684 gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
689 se->expr = gfc_conv_descriptor_ubound(desc, bound);
691 se->expr = gfc_conv_descriptor_lbound(desc, bound);
693 type = gfc_typenode_for_spec (&expr->ts);
694 se->expr = convert (type, se->expr);
699 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
705 args = gfc_conv_intrinsic_function_args (se, expr);
706 assert (args && TREE_CHAIN (args) == NULL_TREE);
707 val = TREE_VALUE (args);
709 switch (expr->value.function.actual->expr->ts.type)
713 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
717 switch (expr->ts.kind)
720 fndecl = gfor_fndecl_math_cabsf;
723 fndecl = gfor_fndecl_math_cabs;
728 se->expr = gfc_build_function_call (fndecl, args);
737 /* Create a complex value from one or two real components. */
740 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
747 type = gfc_typenode_for_spec (&expr->ts);
748 arg = gfc_conv_intrinsic_function_args (se, expr);
749 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
751 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
752 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
754 arg = TREE_VALUE (arg);
755 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
756 imag = convert (TREE_TYPE (type), imag);
759 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
761 se->expr = fold (build (COMPLEX_EXPR, type, real, imag));
764 /* Remainder function MOD(A, P) = A - INT(A / P) * P.
765 MODULO(A, P) = (A==0 .or. !(A>0 .xor. P>0))? MOD(A,P):MOD(A,P)+P. */
766 /* TODO: MOD(x, 0) */
769 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
782 arg = gfc_conv_intrinsic_function_args (se, expr);
783 arg2 = TREE_VALUE (TREE_CHAIN (arg));
784 arg = TREE_VALUE (arg);
785 type = TREE_TYPE (arg);
787 switch (expr->ts.type)
790 /* Integer case is easy, we've got a builtin op. */
791 se->expr = build (TRUNC_MOD_EXPR, type, arg, arg2);
795 /* Real values we have to do the hard way. */
796 arg = gfc_evaluate_now (arg, &se->pre);
797 arg2 = gfc_evaluate_now (arg2, &se->pre);
799 tmp = build (RDIV_EXPR, type, arg, arg2);
800 /* Test if the value is too large to handle sensibly. */
802 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind);
803 mpf_set_z (huge, gfc_integer_kinds[n].huge);
804 test = gfc_conv_mpf_to_tree (huge, expr->ts.kind);
805 test2 = build (LT_EXPR, boolean_type_node, tmp, test);
807 mpf_neg (huge, huge);
808 test = gfc_conv_mpf_to_tree (huge, expr->ts.kind);
809 test = build (GT_EXPR, boolean_type_node, tmp, test);
810 test2 = build (TRUTH_AND_EXPR, boolean_type_node, test, test2);
812 itype = gfc_get_int_type (expr->ts.kind);
813 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
814 tmp = convert (type, tmp);
815 tmp = build (COND_EXPR, type, test2, tmp, arg);
816 tmp = build (MULT_EXPR, type, tmp, arg2);
817 se->expr = build (MINUS_EXPR, type, arg, tmp);
826 zero = gfc_build_const (type, integer_zero_node);
827 /* Build !(A > 0 .xor. P > 0). */
828 test = build (GT_EXPR, boolean_type_node, arg, zero);
829 test2 = build (GT_EXPR, boolean_type_node, arg2, zero);
830 test = build (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
831 test = build1 (TRUTH_NOT_EXPR, boolean_type_node, test);
832 /* Build (A == 0) .or. !(A > 0 .xor. P > 0). */
833 test2 = build (EQ_EXPR, boolean_type_node, arg, zero);
834 test = build (TRUTH_OR_EXPR, boolean_type_node, test, test2);
836 se->expr = build (COND_EXPR, type, test, se->expr,
837 build (PLUS_EXPR, type, se->expr, arg2));
841 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
844 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
853 arg = gfc_conv_intrinsic_function_args (se, expr);
854 arg2 = TREE_VALUE (TREE_CHAIN (arg));
855 arg = TREE_VALUE (arg);
856 type = TREE_TYPE (arg);
858 val = build (MINUS_EXPR, type, arg, arg2);
859 val = gfc_evaluate_now (val, &se->pre);
861 zero = gfc_build_const (type, integer_zero_node);
862 tmp = build (LE_EXPR, boolean_type_node, val, zero);
863 se->expr = build (COND_EXPR, type, tmp, zero, val);
867 /* SIGN(A, B) is absolute value of A times sign of B.
868 The real value versions use library functions to ensure the correct
869 handling of negative zero. Integer case implemented as:
870 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
874 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
885 arg = gfc_conv_intrinsic_function_args (se, expr);
886 if (expr->ts.type == BT_REAL)
888 switch (expr->ts.kind)
891 tmp = gfor_fndecl_math_sign4;
894 tmp = gfor_fndecl_math_sign8;
899 se->expr = gfc_build_function_call (tmp, arg);
903 arg2 = TREE_VALUE (TREE_CHAIN (arg));
904 arg = TREE_VALUE (arg);
905 type = TREE_TYPE (arg);
906 zero = gfc_build_const (type, integer_zero_node);
908 testa = fold (build (GE_EXPR, boolean_type_node, arg, zero));
909 testb = fold (build (GE_EXPR, boolean_type_node, arg2, zero));
910 tmp = fold (build (TRUTH_XOR_EXPR, boolean_type_node, testa, testb));
911 se->expr = fold (build (COND_EXPR, type, tmp,
912 build1 (NEGATE_EXPR, type, arg), arg));
916 /* Test for the presence of an optional argument. */
919 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
923 arg = expr->value.function.actual->expr;
924 assert (arg->expr_type == EXPR_VARIABLE);
925 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
926 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
930 /* Calculate the double precision product of two single precision values. */
933 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
939 arg = gfc_conv_intrinsic_function_args (se, expr);
940 arg2 = TREE_VALUE (TREE_CHAIN (arg));
941 arg = TREE_VALUE (arg);
943 /* Convert the args to double precision before multiplying. */
944 type = gfc_typenode_for_spec (&expr->ts);
945 arg = convert (type, arg);
946 arg2 = convert (type, arg2);
947 se->expr = build (MULT_EXPR, type, arg, arg2);
951 /* Return a length one character string containing an ascii character. */
954 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
960 arg = gfc_conv_intrinsic_function_args (se, expr);
961 arg = TREE_VALUE (arg);
963 /* We currently don't support character types != 1. */
964 assert (expr->ts.kind == 1);
965 type = gfc_character1_type_node;
966 var = gfc_create_var (type, "char");
968 arg = convert (type, arg);
969 gfc_add_modify_expr (&se->pre, var, arg);
970 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
971 se->string_length = integer_one_node;
975 /* Get the minimum/maximum value of all the parameters.
976 minmax (a1, a2, a3, ...)
989 /* TODO: Mismatching types can occur when specific names are used.
990 These should be handled during resolution. */
992 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1003 arg = gfc_conv_intrinsic_function_args (se, expr);
1004 type = gfc_typenode_for_spec (&expr->ts);
1006 limit = TREE_VALUE (arg);
1007 if (TREE_TYPE (limit) != type)
1008 limit = convert (type, limit);
1009 /* Only evaluate the argument once. */
1010 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1011 limit = gfc_evaluate_now(limit, &se->pre);
1013 mvar = gfc_create_var (type, "M");
1014 elsecase = build_v (MODIFY_EXPR, mvar, limit);
1015 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1017 val = TREE_VALUE (arg);
1018 if (TREE_TYPE (val) != type)
1019 val = convert (type, val);
1021 /* Only evaluate the argument once. */
1022 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1023 val = gfc_evaluate_now(val, &se->pre);
1025 thencase = build_v (MODIFY_EXPR, mvar, convert (type, val));
1027 tmp = build (op, boolean_type_node, val, limit);
1028 tmp = build_v (COND_EXPR, tmp, thencase, elsecase);
1029 gfc_add_expr_to_block (&se->pre, tmp);
1030 elsecase = build_empty_stmt ();
1037 /* Create a symbol node for this intrinsic. The symbol form the frontend
1038 is for the generic name. */
1041 gfc_get_symbol_for_expr (gfc_expr * expr)
1045 /* TODO: Add symbols for intrinsic function to the global namespace. */
1046 assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1047 sym = gfc_new_symbol (expr->value.function.name, NULL);
1050 sym->attr.external = 1;
1051 sym->attr.function = 1;
1052 sym->attr.always_explicit = 1;
1053 sym->attr.proc = PROC_INTRINSIC;
1054 sym->attr.flavor = FL_PROCEDURE;
1058 sym->attr.dimension = 1;
1059 sym->as = gfc_get_array_spec ();
1060 sym->as->type = AS_ASSUMED_SHAPE;
1061 sym->as->rank = expr->rank;
1064 /* TODO: proper argument lists for external intrinsics. */
1068 /* Generate a call to an external intrinsic function. */
1070 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1074 assert (!se->ss || se->ss->expr == expr);
1077 assert (expr->rank > 0);
1079 assert (expr->rank == 0);
1081 sym = gfc_get_symbol_for_expr (expr);
1082 gfc_conv_function_call (se, sym, expr->value.function.actual);
1086 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1106 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1115 gfc_actual_arglist *actual;
1122 gfc_conv_intrinsic_funcall (se, expr);
1126 actual = expr->value.function.actual;
1127 type = gfc_typenode_for_spec (&expr->ts);
1128 /* Initialize the result. */
1129 resvar = gfc_create_var (type, "test");
1131 tmp = convert (type, boolean_true_node);
1133 tmp = convert (type, boolean_false_node);
1134 gfc_add_modify_expr (&se->pre, resvar, tmp);
1136 /* Walk the arguments. */
1137 arrayss = gfc_walk_expr (actual->expr);
1138 assert (arrayss != gfc_ss_terminator);
1140 /* Initialize the scalarizer. */
1141 gfc_init_loopinfo (&loop);
1142 exit_label = gfc_build_label_decl (NULL_TREE);
1143 TREE_USED (exit_label) = 1;
1144 gfc_add_ss_to_loop (&loop, arrayss);
1146 /* Initialize the loop. */
1147 gfc_conv_ss_startstride (&loop);
1148 gfc_conv_loop_setup (&loop);
1150 gfc_mark_ss_chain_used (arrayss, 1);
1151 /* Generate the loop body. */
1152 gfc_start_scalarized_body (&loop, &body);
1154 /* If the condition matches then set the return value. */
1155 gfc_start_block (&block);
1157 tmp = convert (type, boolean_false_node);
1159 tmp = convert (type, boolean_true_node);
1160 gfc_add_modify_expr (&block, resvar, tmp);
1162 /* And break out of the loop. */
1163 tmp = build1_v (GOTO_EXPR, exit_label);
1164 gfc_add_expr_to_block (&block, tmp);
1166 found = gfc_finish_block (&block);
1168 /* Check this element. */
1169 gfc_init_se (&arrayse, NULL);
1170 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1171 arrayse.ss = arrayss;
1172 gfc_conv_expr_val (&arrayse, actual->expr);
1174 gfc_add_block_to_block (&body, &arrayse.pre);
1175 tmp = build (op, boolean_type_node, arrayse.expr, integer_zero_node);
1176 tmp = build_v (COND_EXPR, tmp, found, build_empty_stmt ());
1177 gfc_add_expr_to_block (&body, tmp);
1178 gfc_add_block_to_block (&body, &arrayse.post);
1180 gfc_trans_scalarizing_loops (&loop, &body);
1182 /* Add the exit label. */
1183 tmp = build1_v (LABEL_EXPR, exit_label);
1184 gfc_add_expr_to_block (&loop.pre, tmp);
1186 gfc_add_block_to_block (&se->pre, &loop.pre);
1187 gfc_add_block_to_block (&se->pre, &loop.post);
1188 gfc_cleanup_loop (&loop);
1193 /* COUNT(A) = Number of true elements in A. */
1195 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1202 gfc_actual_arglist *actual;
1208 gfc_conv_intrinsic_funcall (se, expr);
1212 actual = expr->value.function.actual;
1214 type = gfc_typenode_for_spec (&expr->ts);
1215 /* Initialize the result. */
1216 resvar = gfc_create_var (type, "count");
1217 gfc_add_modify_expr (&se->pre, resvar, integer_zero_node);
1219 /* Walk the arguments. */
1220 arrayss = gfc_walk_expr (actual->expr);
1221 assert (arrayss != gfc_ss_terminator);
1223 /* Initialize the scalarizer. */
1224 gfc_init_loopinfo (&loop);
1225 gfc_add_ss_to_loop (&loop, arrayss);
1227 /* Initialize the loop. */
1228 gfc_conv_ss_startstride (&loop);
1229 gfc_conv_loop_setup (&loop);
1231 gfc_mark_ss_chain_used (arrayss, 1);
1232 /* Generate the loop body. */
1233 gfc_start_scalarized_body (&loop, &body);
1235 tmp = build (PLUS_EXPR, TREE_TYPE (resvar), resvar, integer_one_node);
1236 tmp = build_v (MODIFY_EXPR, resvar, tmp);
1238 gfc_init_se (&arrayse, NULL);
1239 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1240 arrayse.ss = arrayss;
1241 gfc_conv_expr_val (&arrayse, actual->expr);
1242 tmp = build_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1244 gfc_add_block_to_block (&body, &arrayse.pre);
1245 gfc_add_expr_to_block (&body, tmp);
1246 gfc_add_block_to_block (&body, &arrayse.post);
1248 gfc_trans_scalarizing_loops (&loop, &body);
1250 gfc_add_block_to_block (&se->pre, &loop.pre);
1251 gfc_add_block_to_block (&se->pre, &loop.post);
1252 gfc_cleanup_loop (&loop);
1257 /* Inline implementation of the sum and product intrinsics. */
1259 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1267 gfc_actual_arglist *actual;
1272 gfc_expr *arrayexpr;
1277 gfc_conv_intrinsic_funcall (se, expr);
1281 type = gfc_typenode_for_spec (&expr->ts);
1282 /* Initialize the result. */
1283 resvar = gfc_create_var (type, "val");
1284 if (op == PLUS_EXPR)
1285 tmp = gfc_build_const (type, integer_zero_node);
1287 tmp = gfc_build_const (type, integer_one_node);
1289 gfc_add_modify_expr (&se->pre, resvar, tmp);
1291 /* Walk the arguments. */
1292 actual = expr->value.function.actual;
1293 arrayexpr = actual->expr;
1294 arrayss = gfc_walk_expr (arrayexpr);
1295 assert (arrayss != gfc_ss_terminator);
1297 actual = actual->next->next;
1299 maskexpr = actual->expr;
1302 maskss = gfc_walk_expr (maskexpr);
1303 assert (maskss != gfc_ss_terminator);
1308 /* Initialize the scalarizer. */
1309 gfc_init_loopinfo (&loop);
1310 gfc_add_ss_to_loop (&loop, arrayss);
1312 gfc_add_ss_to_loop (&loop, maskss);
1314 /* Initialize the loop. */
1315 gfc_conv_ss_startstride (&loop);
1316 gfc_conv_loop_setup (&loop);
1318 gfc_mark_ss_chain_used (arrayss, 1);
1320 gfc_mark_ss_chain_used (maskss, 1);
1321 /* Generate the loop body. */
1322 gfc_start_scalarized_body (&loop, &body);
1324 /* If we have a mask, only add this element if the mask is set. */
1327 gfc_init_se (&maskse, NULL);
1328 gfc_copy_loopinfo_to_se (&maskse, &loop);
1330 gfc_conv_expr_val (&maskse, maskexpr);
1331 gfc_add_block_to_block (&body, &maskse.pre);
1333 gfc_start_block (&block);
1336 gfc_init_block (&block);
1338 /* Do the actual summation/product. */
1339 gfc_init_se (&arrayse, NULL);
1340 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1341 arrayse.ss = arrayss;
1342 gfc_conv_expr_val (&arrayse, arrayexpr);
1343 gfc_add_block_to_block (&block, &arrayse.pre);
1345 tmp = build (op, type, resvar, arrayse.expr);
1346 gfc_add_modify_expr (&block, resvar, tmp);
1347 gfc_add_block_to_block (&block, &arrayse.post);
1351 /* We enclose the above in if (mask) {...} . */
1352 tmp = gfc_finish_block (&block);
1354 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1357 tmp = gfc_finish_block (&block);
1358 gfc_add_expr_to_block (&body, tmp);
1360 gfc_trans_scalarizing_loops (&loop, &body);
1361 gfc_add_block_to_block (&se->pre, &loop.pre);
1362 gfc_add_block_to_block (&se->pre, &loop.post);
1363 gfc_cleanup_loop (&loop);
1369 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1373 stmtblock_t ifblock;
1380 gfc_actual_arglist *actual;
1385 gfc_expr *arrayexpr;
1392 gfc_conv_intrinsic_funcall (se, expr);
1396 /* Initialize the result. */
1397 pos = gfc_create_var (gfc_array_index_type, "pos");
1398 type = gfc_typenode_for_spec (&expr->ts);
1400 /* Walk the arguments. */
1401 actual = expr->value.function.actual;
1402 arrayexpr = actual->expr;
1403 arrayss = gfc_walk_expr (arrayexpr);
1404 assert (arrayss != gfc_ss_terminator);
1406 actual = actual->next->next;
1408 maskexpr = actual->expr;
1411 maskss = gfc_walk_expr (maskexpr);
1412 assert (maskss != gfc_ss_terminator);
1417 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1418 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind);
1419 switch (arrayexpr->ts.type)
1422 tmp = gfc_conv_mpf_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1426 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1427 arrayexpr->ts.kind);
1434 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1436 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1437 gfc_add_modify_expr (&se->pre, limit, tmp);
1439 /* Initialize the scalarizer. */
1440 gfc_init_loopinfo (&loop);
1441 gfc_add_ss_to_loop (&loop, arrayss);
1443 gfc_add_ss_to_loop (&loop, maskss);
1445 /* Initialize the loop. */
1446 gfc_conv_ss_startstride (&loop);
1447 gfc_conv_loop_setup (&loop);
1449 assert (loop.dimen == 1);
1451 /* Initialize the position to the first element. If the array has zero
1452 size we need to return zero. Otherwise use the first element of the
1453 array, in case all elements are equal to the limit.
1454 ie. pos = (ubound >= lbound) ? lbound, lbound - 1; */
1455 tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
1456 loop.from[0], integer_one_node));
1457 cond = fold (build (GE_EXPR, boolean_type_node,
1458 loop.to[0], loop.from[0]));
1459 tmp = fold (build (COND_EXPR, gfc_array_index_type, cond,
1460 loop.from[0], tmp));
1461 gfc_add_modify_expr (&loop.pre, pos, tmp);
1463 gfc_mark_ss_chain_used (arrayss, 1);
1465 gfc_mark_ss_chain_used (maskss, 1);
1466 /* Generate the loop body. */
1467 gfc_start_scalarized_body (&loop, &body);
1469 /* If we have a mask, only check this element if the mask is set. */
1472 gfc_init_se (&maskse, NULL);
1473 gfc_copy_loopinfo_to_se (&maskse, &loop);
1475 gfc_conv_expr_val (&maskse, maskexpr);
1476 gfc_add_block_to_block (&body, &maskse.pre);
1478 gfc_start_block (&block);
1481 gfc_init_block (&block);
1483 /* Compare with the current limit. */
1484 gfc_init_se (&arrayse, NULL);
1485 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1486 arrayse.ss = arrayss;
1487 gfc_conv_expr_val (&arrayse, arrayexpr);
1488 gfc_add_block_to_block (&block, &arrayse.pre);
1490 /* We do the following if this is a more extreme value. */
1491 gfc_start_block (&ifblock);
1493 /* Assign the value to the limit... */
1494 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1496 /* Remember where we are. */
1497 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1499 ifbody = gfc_finish_block (&ifblock);
1501 /* If it is a more extreme value. */
1502 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1503 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1504 gfc_add_expr_to_block (&block, tmp);
1508 /* We enclose the above in if (mask) {...}. */
1509 tmp = gfc_finish_block (&block);
1511 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1514 tmp = gfc_finish_block (&block);
1515 gfc_add_expr_to_block (&body, tmp);
1517 gfc_trans_scalarizing_loops (&loop, &body);
1519 gfc_add_block_to_block (&se->pre, &loop.pre);
1520 gfc_add_block_to_block (&se->pre, &loop.post);
1521 gfc_cleanup_loop (&loop);
1523 /* Return a value in the range 1..SIZE(array). */
1524 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1526 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, pos, tmp));
1527 /* And convert to the required type. */
1528 se->expr = convert (type, tmp);
1532 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1541 gfc_actual_arglist *actual;
1546 gfc_expr *arrayexpr;
1552 gfc_conv_intrinsic_funcall (se, expr);
1556 type = gfc_typenode_for_spec (&expr->ts);
1557 /* Initialize the result. */
1558 limit = gfc_create_var (type, "limit");
1559 n = gfc_validate_kind (expr->ts.type, expr->ts.kind);
1560 switch (expr->ts.type)
1563 tmp = gfc_conv_mpf_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1567 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1574 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1576 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1577 gfc_add_modify_expr (&se->pre, limit, tmp);
1579 /* Walk the arguments. */
1580 actual = expr->value.function.actual;
1581 arrayexpr = actual->expr;
1582 arrayss = gfc_walk_expr (arrayexpr);
1583 assert (arrayss != gfc_ss_terminator);
1585 actual = actual->next->next;
1587 maskexpr = actual->expr;
1590 maskss = gfc_walk_expr (maskexpr);
1591 assert (maskss != gfc_ss_terminator);
1596 /* Initialize the scalarizer. */
1597 gfc_init_loopinfo (&loop);
1598 gfc_add_ss_to_loop (&loop, arrayss);
1600 gfc_add_ss_to_loop (&loop, maskss);
1602 /* Initialize the loop. */
1603 gfc_conv_ss_startstride (&loop);
1604 gfc_conv_loop_setup (&loop);
1606 gfc_mark_ss_chain_used (arrayss, 1);
1608 gfc_mark_ss_chain_used (maskss, 1);
1609 /* Generate the loop body. */
1610 gfc_start_scalarized_body (&loop, &body);
1612 /* If we have a mask, only add this element if the mask is set. */
1615 gfc_init_se (&maskse, NULL);
1616 gfc_copy_loopinfo_to_se (&maskse, &loop);
1618 gfc_conv_expr_val (&maskse, maskexpr);
1619 gfc_add_block_to_block (&body, &maskse.pre);
1621 gfc_start_block (&block);
1624 gfc_init_block (&block);
1626 /* Compare with the current limit. */
1627 gfc_init_se (&arrayse, NULL);
1628 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1629 arrayse.ss = arrayss;
1630 gfc_conv_expr_val (&arrayse, arrayexpr);
1631 gfc_add_block_to_block (&block, &arrayse.pre);
1633 /* Assign the value to the limit... */
1634 ifbody = build_v (MODIFY_EXPR, limit, arrayse.expr);
1636 /* If it is a more extreme value. */
1637 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1638 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1639 gfc_add_expr_to_block (&block, tmp);
1640 gfc_add_block_to_block (&block, &arrayse.post);
1642 tmp = gfc_finish_block (&block);
1645 /* We enclose the above in if (mask) {...}. */
1646 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1648 gfc_add_expr_to_block (&body, tmp);
1650 gfc_trans_scalarizing_loops (&loop, &body);
1652 gfc_add_block_to_block (&se->pre, &loop.pre);
1653 gfc_add_block_to_block (&se->pre, &loop.post);
1654 gfc_cleanup_loop (&loop);
1659 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
1661 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
1668 arg = gfc_conv_intrinsic_function_args (se, expr);
1669 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1670 arg = TREE_VALUE (arg);
1671 type = TREE_TYPE (arg);
1673 tmp = build (LSHIFT_EXPR, type, integer_one_node, arg2);
1674 tmp = build (BIT_AND_EXPR, type, arg, tmp);
1675 tmp = fold (build (NE_EXPR, boolean_type_node, tmp, integer_zero_node));
1676 type = gfc_typenode_for_spec (&expr->ts);
1677 se->expr = convert (type, tmp);
1680 /* Generate code to perform the specified operation. */
1682 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
1688 arg = gfc_conv_intrinsic_function_args (se, expr);
1689 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1690 arg = TREE_VALUE (arg);
1691 type = TREE_TYPE (arg);
1693 se->expr = fold (build (op, type, arg, arg2));
1698 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
1702 arg = gfc_conv_intrinsic_function_args (se, expr);
1703 arg = TREE_VALUE (arg);
1705 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
1708 /* Set or clear a single bit. */
1710 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
1718 arg = gfc_conv_intrinsic_function_args (se, expr);
1719 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1720 arg = TREE_VALUE (arg);
1721 type = TREE_TYPE (arg);
1723 tmp = fold (build (LSHIFT_EXPR, type, integer_one_node, arg2));
1729 tmp = fold (build1 (BIT_NOT_EXPR, type, tmp));
1731 se->expr = fold (build (op, type, arg, tmp));
1734 /* Extract a sequence of bits.
1735 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
1737 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
1746 arg = gfc_conv_intrinsic_function_args (se, expr);
1747 arg2 = TREE_CHAIN (arg);
1748 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
1749 arg = TREE_VALUE (arg);
1750 arg2 = TREE_VALUE (arg2);
1751 type = TREE_TYPE (arg);
1753 mask = build_int_2 (-1, ~(unsigned HOST_WIDE_INT) 0);
1754 mask = build (LSHIFT_EXPR, type, mask, arg3);
1755 mask = build1 (BIT_NOT_EXPR, type, mask);
1757 tmp = build (RSHIFT_EXPR, type, arg, arg2);
1759 se->expr = fold (build (BIT_AND_EXPR, type, tmp, mask));
1762 /* ISHFT (I, SHIFT) = (shift >= 0) ? i << shift : i >> -shift. */
1764 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
1773 arg = gfc_conv_intrinsic_function_args (se, expr);
1774 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1775 arg = TREE_VALUE (arg);
1776 type = TREE_TYPE (arg);
1778 /* Left shift if positive. */
1779 lshift = build (LSHIFT_EXPR, type, arg, arg2);
1781 /* Right shift if negative. This will perform an arithmetic shift as
1782 we are dealing with signed integers. Section 13.5.7 allows this. */
1783 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1784 rshift = build (RSHIFT_EXPR, type, arg, tmp);
1786 tmp = build (GT_EXPR, boolean_type_node, arg2, integer_zero_node);
1787 rshift = build (COND_EXPR, type, tmp, lshift, rshift);
1789 /* Do nothing if shift == 0. */
1790 tmp = build (EQ_EXPR, boolean_type_node, arg2, integer_zero_node);
1791 se->expr = build (COND_EXPR, type, tmp, arg, rshift);
1794 /* Circular shift. AKA rotate or barrel shift. */
1796 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
1806 arg = gfc_conv_intrinsic_function_args (se, expr);
1807 arg2 = TREE_CHAIN (arg);
1808 arg3 = TREE_CHAIN (arg2);
1811 /* Use a library function for the 3 parameter version. */
1812 type = TREE_TYPE (TREE_VALUE (arg));
1813 /* Convert all args to the same type otherwise we need loads of library
1814 functions. SIZE and SHIFT cannot have values > BIT_SIZE (I) so the
1815 conversion is safe. */
1816 tmp = convert (type, TREE_VALUE (arg2));
1817 TREE_VALUE (arg2) = tmp;
1818 tmp = convert (type, TREE_VALUE (arg3));
1819 TREE_VALUE (arg3) = tmp;
1821 switch (expr->ts.kind)
1824 tmp = gfor_fndecl_math_ishftc4;
1827 tmp = gfor_fndecl_math_ishftc8;
1832 se->expr = gfc_build_function_call (tmp, arg);
1835 arg = TREE_VALUE (arg);
1836 arg2 = TREE_VALUE (arg2);
1837 type = TREE_TYPE (arg);
1839 /* Rotate left if positive. */
1840 lrot = build (LROTATE_EXPR, type, arg, arg2);
1842 /* Rotate right if negative. */
1843 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1844 rrot = build (RROTATE_EXPR, type, arg, tmp);
1846 tmp = build (GT_EXPR, boolean_type_node, arg2, integer_zero_node);
1847 rrot = build (COND_EXPR, type, tmp, lrot, rrot);
1849 /* Do nothing if shift == 0. */
1850 tmp = build (EQ_EXPR, boolean_type_node, arg2, integer_zero_node);
1851 se->expr = build (COND_EXPR, type, tmp, arg, rrot);
1854 /* The length of a character string. */
1856 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
1867 arg = expr->value.function.actual->expr;
1869 type = gfc_typenode_for_spec (&expr->ts);
1870 switch (arg->expr_type)
1873 len = build_int_2 (arg->value.character.length, 0);
1877 if (arg->expr_type == EXPR_VARIABLE
1878 && (arg->ref == NULL || (arg->ref->next == NULL
1879 && arg->ref->type == REF_ARRAY)))
1881 /* This doesn't catch all cases.
1882 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
1883 and the surrounding thread. */
1884 sym = arg->symtree->n.sym;
1885 decl = gfc_get_symbol_decl (sym);
1886 if (decl == current_function_decl && sym->attr.function
1887 && (sym->result == sym))
1888 decl = gfc_get_fake_result_decl (sym);
1890 len = sym->ts.cl->backend_decl;
1895 /* Anybody stupid enough to do this deserves inefficient code. */
1896 gfc_init_se (&argse, se);
1897 gfc_conv_expr (&argse, arg);
1898 gfc_add_block_to_block (&se->pre, &argse.pre);
1899 gfc_add_block_to_block (&se->post, &argse.post);
1900 len = argse.string_length;
1904 se->expr = convert (type, len);
1907 /* The length of a character string not including trailing blanks. */
1909 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
1914 args = gfc_conv_intrinsic_function_args (se, expr);
1915 type = gfc_typenode_for_spec (&expr->ts);
1916 se->expr = gfc_build_function_call (gfor_fndecl_string_len_trim, args);
1917 se->expr = convert (type, se->expr);
1921 /* Returns the starting position of a substring within a string. */
1924 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
1931 args = gfc_conv_intrinsic_function_args (se, expr);
1932 type = gfc_typenode_for_spec (&expr->ts);
1933 tmp = gfc_advance_chain (args, 3);
1934 if (TREE_CHAIN (tmp) == NULL_TREE)
1936 back = convert (gfc_logical4_type_node, integer_one_node);
1937 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
1938 TREE_CHAIN (tmp) = back;
1942 back = TREE_CHAIN (tmp);
1943 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
1946 se->expr = gfc_build_function_call (gfor_fndecl_string_index, args);
1947 se->expr = convert (type, se->expr);
1950 /* The ascii value for a single character. */
1952 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
1957 arg = gfc_conv_intrinsic_function_args (se, expr);
1958 arg = TREE_VALUE (TREE_CHAIN (arg));
1959 assert (POINTER_TYPE_P (TREE_TYPE (arg)));
1960 arg = build1 (NOP_EXPR, pchar_type_node, arg);
1961 type = gfc_typenode_for_spec (&expr->ts);
1963 se->expr = gfc_build_indirect_ref (arg);
1964 se->expr = convert (type, se->expr);
1968 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
1971 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
1979 arg = gfc_conv_intrinsic_function_args (se, expr);
1980 tsource = TREE_VALUE (arg);
1981 arg = TREE_CHAIN (arg);
1982 fsource = TREE_VALUE (arg);
1983 arg = TREE_CHAIN (arg);
1984 mask = TREE_VALUE (arg);
1986 type = TREE_TYPE (tsource);
1987 se->expr = fold (build (COND_EXPR, type, mask, tsource, fsource));
1992 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
1994 gfc_actual_arglist *actual;
2001 gfc_init_se (&argse, NULL);
2002 actual = expr->value.function.actual;
2004 ss = gfc_walk_expr (actual->expr);
2005 assert (ss != gfc_ss_terminator);
2006 argse.want_pointer = 1;
2007 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2008 gfc_add_block_to_block (&se->pre, &argse.pre);
2009 gfc_add_block_to_block (&se->post, &argse.post);
2010 args = gfc_chainon_list (NULL_TREE, argse.expr);
2012 actual = actual->next;
2015 gfc_init_se (&argse, NULL);
2016 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2017 gfc_add_block_to_block (&se->pre, &argse.pre);
2018 args = gfc_chainon_list (args, argse.expr);
2019 fndecl = gfor_fndecl_size1;
2022 fndecl = gfor_fndecl_size0;
2024 se->expr = gfc_build_function_call (fndecl, args);
2025 type = gfc_typenode_for_spec (&expr->ts);
2026 se->expr = convert (type, se->expr);
2030 /* Intrinsic string comparison functions. */
2033 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2038 args = gfc_conv_intrinsic_function_args (se, expr);
2039 /* Build a call for the comparison. */
2040 se->expr = gfc_build_function_call (gfor_fndecl_compare_string, args);
2042 type = gfc_typenode_for_spec (&expr->ts);
2043 se->expr = build (op, type, se->expr, integer_zero_node);
2046 /* Generate a call to the adjustl/adjustr library function. */
2048 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2056 args = gfc_conv_intrinsic_function_args (se, expr);
2057 len = TREE_VALUE (args);
2059 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2060 var = gfc_conv_string_tmp (se, type, len);
2061 args = tree_cons (NULL_TREE, var, args);
2063 tmp = gfc_build_function_call (fndecl, args);
2064 gfc_add_expr_to_block (&se->pre, tmp);
2066 se->string_length = len;
2070 /* Scalar transfer statement.
2071 TRANSFER (source, mold) = *(typeof<mould> *)&source */
2074 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2076 gfc_actual_arglist *arg;
2084 /* Get a pointer to the source. */
2085 arg = expr->value.function.actual;
2086 ss = gfc_walk_expr (arg->expr);
2087 gfc_init_se (&argse, NULL);
2088 if (ss == gfc_ss_terminator)
2089 gfc_conv_expr_reference (&argse, arg->expr);
2091 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2092 gfc_add_block_to_block (&se->pre, &argse.pre);
2093 gfc_add_block_to_block (&se->post, &argse.post);
2097 type = gfc_typenode_for_spec (&expr->ts);
2098 ptr = convert (build_pointer_type (type), ptr);
2099 if (expr->ts.type == BT_CHARACTER)
2101 gfc_init_se (&argse, NULL);
2102 gfc_conv_expr (&argse, arg->expr);
2103 gfc_add_block_to_block (&se->pre, &argse.pre);
2104 gfc_add_block_to_block (&se->post, &argse.post);
2106 se->string_length = argse.string_length;
2110 se->expr = gfc_build_indirect_ref (ptr);
2115 /* Generate code for the ALLOCATED intrinsic.
2116 Generate inline code that directly check the address of the argument. */
2119 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2121 gfc_actual_arglist *arg1;
2126 gfc_init_se (&arg1se, NULL);
2127 arg1 = expr->value.function.actual;
2128 ss1 = gfc_walk_expr (arg1->expr);
2129 arg1se.descriptor_only = 1;
2130 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2132 tmp = gfc_conv_descriptor_data (arg1se.expr);
2133 tmp = build (NE_EXPR, boolean_type_node, tmp, null_pointer_node);
2134 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2138 /* Generate code for the ASSOCIATED intrinsic.
2139 If both POINTER and TARGET are arrays, generate a call to library function
2140 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2141 In other cases, generate inline code that directly compare the address of
2142 POINTER with the address of TARGET. */
2145 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2147 gfc_actual_arglist *arg1;
2148 gfc_actual_arglist *arg2;
2156 gfc_init_se (&arg1se, NULL);
2157 gfc_init_se (&arg2se, NULL);
2158 arg1 = expr->value.function.actual;
2160 ss1 = gfc_walk_expr (arg1->expr);
2164 /* No optional target. */
2165 if (ss1 == gfc_ss_terminator)
2167 /* A pointer to a scalar. */
2168 arg1se.want_pointer = 1;
2169 gfc_conv_expr (&arg1se, arg1->expr);
2174 /* A pointer to an array. */
2175 arg1se.descriptor_only = 1;
2176 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2177 tmp2 = gfc_conv_descriptor_data (arg1se.expr);
2179 tmp = build (NE_EXPR, boolean_type_node, tmp2, null_pointer_node);
2184 /* An optional target. */
2185 ss2 = gfc_walk_expr (arg2->expr);
2186 if (ss1 == gfc_ss_terminator)
2188 /* A pointer to a scalar. */
2189 assert (ss2 == gfc_ss_terminator);
2190 arg1se.want_pointer = 1;
2191 gfc_conv_expr (&arg1se, arg1->expr);
2192 arg2se.want_pointer = 1;
2193 gfc_conv_expr (&arg2se, arg2->expr);
2194 tmp = build (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2199 /* A pointer to an array, call library function _gfor_associated. */
2200 assert (ss2 != gfc_ss_terminator);
2202 arg1se.want_pointer = 1;
2203 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2204 args = gfc_chainon_list (args, arg1se.expr);
2205 arg2se.want_pointer = 1;
2206 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2207 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2208 gfc_add_block_to_block (&se->post, &arg2se.post);
2209 args = gfc_chainon_list (args, arg2se.expr);
2210 fndecl = gfor_fndecl_associated;
2211 se->expr = gfc_build_function_call (fndecl, args);
2214 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2218 /* Scan a string for any one of the characters in a set of characters. */
2221 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2228 args = gfc_conv_intrinsic_function_args (se, expr);
2229 type = gfc_typenode_for_spec (&expr->ts);
2230 tmp = gfc_advance_chain (args, 3);
2231 if (TREE_CHAIN (tmp) == NULL_TREE)
2233 back = convert (gfc_logical4_type_node, integer_one_node);
2234 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2235 TREE_CHAIN (tmp) = back;
2239 back = TREE_CHAIN (tmp);
2240 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2243 se->expr = gfc_build_function_call (gfor_fndecl_string_scan, args);
2244 se->expr = convert (type, se->expr);
2248 /* Verify that a set of characters contains all the characters in a string
2249 by indentifying the position of the first character in a string of
2250 characters that does not appear in a given set of characters. */
2253 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2260 args = gfc_conv_intrinsic_function_args (se, expr);
2261 type = gfc_typenode_for_spec (&expr->ts);
2262 tmp = gfc_advance_chain (args, 3);
2263 if (TREE_CHAIN (tmp) == NULL_TREE)
2265 back = convert (gfc_logical4_type_node, integer_one_node);
2266 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2267 TREE_CHAIN (tmp) = back;
2271 back = TREE_CHAIN (tmp);
2272 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2275 se->expr = gfc_build_function_call (gfor_fndecl_string_verify, args);
2276 se->expr = convert (type, se->expr);
2279 /* Prepare components and related information of a real number which is
2280 the first argument of a elemental functions to manipulate reals. */
2283 void prepare_arg_info (gfc_se * se, gfc_expr * expr,
2284 real_compnt_info * rcs, int all)
2291 tree exponent, fraction;
2295 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
2296 gfc_todo_error ("Non-IEEE floating format");
2298 assert (expr->expr_type == EXPR_FUNCTION);
2300 arg = gfc_conv_intrinsic_function_args (se, expr);
2301 arg = TREE_VALUE (arg);
2302 rcs->type = TREE_TYPE (arg);
2304 /* Force arg'type to integer by unaffected convert */
2305 a1 = expr->value.function.actual->expr;
2306 masktype = gfc_get_int_type (a1->ts.kind);
2307 rcs->mtype = masktype;
2308 tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
2309 arg = gfc_create_var (masktype, "arg");
2310 gfc_add_modify_expr(&se->pre, arg, tmp);
2313 /* Caculate the numbers of bits of exponent, fraction and word */
2314 n = gfc_validate_kind (a1->ts.type, a1->ts.kind);
2315 tmp = build_int_2 (gfc_real_kinds[n].digits - 1, 0);
2316 rcs->fdigits = convert (masktype, tmp);
2317 wbits = build_int_2 (TYPE_PRECISION (rcs->type) - 1, 0);
2318 wbits = convert (masktype, wbits);
2319 rcs->edigits = fold (build (MINUS_EXPR, masktype, wbits, tmp));
2321 /* Form masks for exponent/fraction/sign */
2322 one = gfc_build_const (masktype, integer_one_node);
2323 rcs->smask = fold (build (LSHIFT_EXPR, masktype, one, wbits));
2324 rcs->f1 = fold (build (LSHIFT_EXPR, masktype, one, rcs->fdigits));
2325 rcs->emask = fold (build (MINUS_EXPR, masktype, rcs->smask, rcs->f1));
2326 rcs->fmask = fold (build (MINUS_EXPR, masktype, rcs->f1, one));
2328 tmp = fold (build (MINUS_EXPR, masktype, rcs->edigits, one));
2329 tmp = fold (build (LSHIFT_EXPR, masktype, one, tmp));
2330 rcs->bias = fold (build (MINUS_EXPR, masktype, tmp ,one));
2334 /* exponent, and fraction */
2335 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->emask);
2336 tmp = build (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
2337 exponent = gfc_create_var (masktype, "exponent");
2338 gfc_add_modify_expr(&se->pre, exponent, tmp);
2339 rcs->expn = exponent;
2341 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->fmask);
2342 fraction = gfc_create_var (masktype, "fraction");
2343 gfc_add_modify_expr(&se->pre, fraction, tmp);
2344 rcs->frac = fraction;
2348 /* Build a call to __builtin_clz. */
2351 call_builtin_clz (tree result_type, tree op0)
2353 tree fn, parms, call;
2354 enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
2356 if (op0_mode == TYPE_MODE (integer_type_node))
2357 fn = built_in_decls[BUILT_IN_CLZ];
2358 else if (op0_mode == TYPE_MODE (long_integer_type_node))
2359 fn = built_in_decls[BUILT_IN_CLZL];
2360 else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
2361 fn = built_in_decls[BUILT_IN_CLZLL];
2365 parms = tree_cons (NULL, op0, NULL);
2366 call = gfc_build_function_call (fn, parms);
2368 return convert (result_type, call);
2371 /* Generate code for SPACING (X) intrinsic function. We generate:
2373 t = expn - (BITS_OF_FRACTION)
2374 res = t << (BITS_OF_FRACTION)
2380 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2387 real_compnt_info rcs;
2389 prepare_arg_info (se, expr, &rcs, 0);
2391 masktype = rcs.mtype;
2392 fdigits = rcs.fdigits;
2394 zero = gfc_build_const (masktype, integer_zero_node);
2395 tmp = build (BIT_AND_EXPR, masktype, rcs.emask, arg);
2396 tmp = build (RSHIFT_EXPR, masktype, tmp, fdigits);
2397 tmp = build (MINUS_EXPR, masktype, tmp, fdigits);
2398 cond = build (LE_EXPR, boolean_type_node, tmp, zero);
2399 t1 = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2400 tmp = build (COND_EXPR, masktype, cond, tiny, t1);
2401 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2406 /* Generate code for RRSPACING (X) intrinsic function. We generate:
2408 if (expn == 0 && frac == 0)
2412 sedigits = edigits + 1;
2415 t1 = leadzero (frac);
2416 frac = frac << (t1 + sedigits);
2417 frac = frac >> (sedigits);
2419 t = bias + BITS_OF_FRACTION_OF;
2420 res = (t << BITS_OF_FRACTION_OF) | frac;
2424 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2427 tree tmp, t1, t2, cond, cond2;
2429 tree fdigits, fraction;
2430 real_compnt_info rcs;
2432 prepare_arg_info (se, expr, &rcs, 1);
2433 masktype = rcs.mtype;
2434 fdigits = rcs.fdigits;
2435 fraction = rcs.frac;
2436 one = gfc_build_const (masktype, integer_one_node);
2437 zero = gfc_build_const (masktype, integer_zero_node);
2438 t2 = build (PLUS_EXPR, masktype, rcs.edigits, one);
2440 t1 = call_builtin_clz (masktype, fraction);
2441 tmp = build (PLUS_EXPR, masktype, t1, one);
2442 tmp = build (LSHIFT_EXPR, masktype, fraction, tmp);
2443 tmp = build (RSHIFT_EXPR, masktype, tmp, t2);
2444 cond = build (EQ_EXPR, boolean_type_node, rcs.expn, zero);
2445 fraction = build (COND_EXPR, masktype, cond, tmp, fraction);
2447 tmp = build (PLUS_EXPR, masktype, rcs.bias, fdigits);
2448 tmp = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2449 tmp = build (BIT_IOR_EXPR, masktype, tmp, fraction);
2451 cond2 = build (EQ_EXPR, boolean_type_node, rcs.frac, zero);
2452 cond = build (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
2453 tmp = build (COND_EXPR, masktype, cond, integer_zero_node, tmp);
2455 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2459 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
2462 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
2466 args = gfc_conv_intrinsic_function_args (se, expr);
2467 args = TREE_VALUE (args);
2468 args = gfc_build_addr_expr (NULL, args);
2469 args = tree_cons (NULL_TREE, args, NULL_TREE);
2470 se->expr = gfc_build_function_call (gfor_fndecl_si_kind, args);
2473 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
2476 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
2478 gfc_actual_arglist *actual;
2483 for (actual = expr->value.function.actual; actual; actual = actual->next)
2485 gfc_init_se (&argse, se);
2487 /* Pass a NULL pointer for an absent arg. */
2488 if (actual->expr == NULL)
2489 argse.expr = null_pointer_node;
2491 gfc_conv_expr_reference (&argse, actual->expr);
2493 gfc_add_block_to_block (&se->pre, &argse.pre);
2494 gfc_add_block_to_block (&se->post, &argse.post);
2495 args = gfc_chainon_list (args, argse.expr);
2497 se->expr = gfc_build_function_call (gfor_fndecl_sr_kind, args);
2501 /* Generate code for TRIM (A) intrinsic function. */
2504 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
2514 arglist = NULL_TREE;
2516 type = build_pointer_type (gfc_character1_type_node);
2517 var = gfc_create_var (type, "pstr");
2518 addr = gfc_build_addr_expr (ppvoid_type_node, var);
2519 len = gfc_create_var (gfc_int4_type_node, "len");
2521 tmp = gfc_conv_intrinsic_function_args (se, expr);
2522 arglist = gfc_chainon_list (arglist, gfc_build_addr_expr (NULL, len));
2523 arglist = gfc_chainon_list (arglist, addr);
2524 arglist = chainon (arglist, tmp);
2526 tmp = gfc_build_function_call (gfor_fndecl_string_trim, arglist);
2527 gfc_add_expr_to_block (&se->pre, tmp);
2529 /* Free the temporary afterwards, if necessary. */
2530 cond = build (GT_EXPR, boolean_type_node, len, integer_zero_node);
2531 arglist = gfc_chainon_list (NULL_TREE, var);
2532 tmp = gfc_build_function_call (gfor_fndecl_internal_free, arglist);
2533 tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2534 gfc_add_expr_to_block (&se->post, tmp);
2537 se->string_length = len;
2541 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
2544 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
2554 args = gfc_conv_intrinsic_function_args (se, expr);
2555 len = TREE_VALUE (args);
2556 tmp = gfc_advance_chain (args, 2);
2557 ncopies = TREE_VALUE (tmp);
2558 len = fold (build (MULT_EXPR, gfc_int4_type_node, len, ncopies));
2559 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
2560 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
2562 arglist = NULL_TREE;
2563 arglist = gfc_chainon_list (arglist, var);
2564 arglist = chainon (arglist, args);
2565 tmp = gfc_build_function_call (gfor_fndecl_string_repeat, arglist);
2566 gfc_add_expr_to_block (&se->pre, tmp);
2569 se->string_length = len;
2573 /* Generate code for an intrinsic function. Some map directly to library
2574 calls, others get special handling. In some cases the name of the function
2575 used depends on the type specifiers. */
2578 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
2580 gfc_intrinsic_sym *isym;
2584 isym = expr->value.function.isym;
2586 name = &expr->value.function.name[2];
2590 lib = gfc_is_intrinsic_libcall (expr);
2594 se->ignore_optional = 1;
2595 gfc_conv_intrinsic_funcall (se, expr);
2600 switch (expr->value.function.isym->generic_id)
2605 case GFC_ISYM_REPEAT:
2606 gfc_conv_intrinsic_repeat (se, expr);
2610 gfc_conv_intrinsic_trim (se, expr);
2613 case GFC_ISYM_SI_KIND:
2614 gfc_conv_intrinsic_si_kind (se, expr);
2617 case GFC_ISYM_SR_KIND:
2618 gfc_conv_intrinsic_sr_kind (se, expr);
2621 case GFC_ISYM_EXPONENT:
2622 gfc_conv_intrinsic_exponent (se, expr);
2625 case GFC_ISYM_SPACING:
2626 gfc_conv_intrinsic_spacing (se, expr);
2629 case GFC_ISYM_RRSPACING:
2630 gfc_conv_intrinsic_rrspacing (se, expr);
2634 gfc_conv_intrinsic_scan (se, expr);
2637 case GFC_ISYM_VERIFY:
2638 gfc_conv_intrinsic_verify (se, expr);
2641 case GFC_ISYM_ALLOCATED:
2642 gfc_conv_allocated (se, expr);
2645 case GFC_ISYM_ASSOCIATED:
2646 gfc_conv_associated(se, expr);
2650 gfc_conv_intrinsic_abs (se, expr);
2653 case GFC_ISYM_ADJUSTL:
2654 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
2657 case GFC_ISYM_ADJUSTR:
2658 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
2661 case GFC_ISYM_AIMAG:
2662 gfc_conv_intrinsic_imagpart (se, expr);
2666 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
2670 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
2673 case GFC_ISYM_ANINT:
2674 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
2678 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
2681 case GFC_ISYM_BTEST:
2682 gfc_conv_intrinsic_btest (se, expr);
2685 case GFC_ISYM_ACHAR:
2687 gfc_conv_intrinsic_char (se, expr);
2690 case GFC_ISYM_CONVERSION:
2692 case GFC_ISYM_LOGICAL:
2694 gfc_conv_intrinsic_conversion (se, expr);
2697 /* Integer conversions are handled seperately to make sure we get the
2698 correct rounding mode. */
2700 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
2704 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
2707 case GFC_ISYM_CEILING:
2708 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
2711 case GFC_ISYM_FLOOR:
2712 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
2716 gfc_conv_intrinsic_mod (se, expr, 0);
2719 case GFC_ISYM_MODULO:
2720 gfc_conv_intrinsic_mod (se, expr, 1);
2723 case GFC_ISYM_CMPLX:
2724 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
2727 case GFC_ISYM_CONJG:
2728 gfc_conv_intrinsic_conjg (se, expr);
2731 case GFC_ISYM_COUNT:
2732 gfc_conv_intrinsic_count (se, expr);
2736 gfc_conv_intrinsic_dim (se, expr);
2739 case GFC_ISYM_DPROD:
2740 gfc_conv_intrinsic_dprod (se, expr);
2744 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
2747 case GFC_ISYM_IBCLR:
2748 gfc_conv_intrinsic_singlebitop (se, expr, 0);
2751 case GFC_ISYM_IBITS:
2752 gfc_conv_intrinsic_ibits (se, expr);
2755 case GFC_ISYM_IBSET:
2756 gfc_conv_intrinsic_singlebitop (se, expr, 1);
2759 case GFC_ISYM_IACHAR:
2760 case GFC_ISYM_ICHAR:
2761 /* We assume ASCII character sequence. */
2762 gfc_conv_intrinsic_ichar (se, expr);
2766 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
2769 case GFC_ISYM_INDEX:
2770 gfc_conv_intrinsic_index (se, expr);
2774 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
2777 case GFC_ISYM_ISHFT:
2778 gfc_conv_intrinsic_ishft (se, expr);
2781 case GFC_ISYM_ISHFTC:
2782 gfc_conv_intrinsic_ishftc (se, expr);
2785 case GFC_ISYM_LBOUND:
2786 gfc_conv_intrinsic_bound (se, expr, 0);
2790 gfc_conv_intrinsic_len (se, expr);
2793 case GFC_ISYM_LEN_TRIM:
2794 gfc_conv_intrinsic_len_trim (se, expr);
2798 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
2802 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
2806 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
2810 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
2814 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
2817 case GFC_ISYM_MAXLOC:
2818 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
2821 case GFC_ISYM_MAXVAL:
2822 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
2825 case GFC_ISYM_MERGE:
2826 gfc_conv_intrinsic_merge (se, expr);
2830 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
2833 case GFC_ISYM_MINLOC:
2834 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
2837 case GFC_ISYM_MINVAL:
2838 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
2842 gfc_conv_intrinsic_not (se, expr);
2845 case GFC_ISYM_PRESENT:
2846 gfc_conv_intrinsic_present (se, expr);
2849 case GFC_ISYM_PRODUCT:
2850 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
2854 gfc_conv_intrinsic_sign (se, expr);
2858 gfc_conv_intrinsic_size (se, expr);
2862 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
2865 case GFC_ISYM_TRANSFER:
2866 gfc_conv_intrinsic_transfer (se, expr);
2869 case GFC_ISYM_UBOUND:
2870 gfc_conv_intrinsic_bound (se, expr, 1);
2873 case GFC_ISYM_DOT_PRODUCT:
2874 case GFC_ISYM_MATMUL:
2875 case GFC_ISYM_IRAND:
2877 case GFC_ISYM_ETIME:
2878 case GFC_ISYM_SECOND:
2879 gfc_conv_intrinsic_funcall (se, expr);
2883 gfc_conv_intrinsic_lib_function (se, expr);
2889 /* This generates code to execute before entering the scalarization loop.
2890 Currently does nothing. */
2893 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
2895 switch (ss->expr->value.function.isym->generic_id)
2897 case GFC_ISYM_UBOUND:
2898 case GFC_ISYM_LBOUND:
2908 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
2909 inside the scalarization loop. */
2912 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
2916 /* The two argument version returns a scalar. */
2917 if (expr->value.function.actual->next->expr)
2920 newss = gfc_get_ss ();
2921 newss->type = GFC_SS_INTRINSIC;
2929 /* Walk an intrinsic array libcall. */
2932 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
2936 assert (expr->rank > 0);
2938 newss = gfc_get_ss ();
2939 newss->type = GFC_SS_FUNCTION;
2942 newss->data.info.dimen = expr->rank;
2948 /* Returns nonzero if the specified intrinsic function call maps directly to a
2949 an external library call. Should only be used for functions that return
2953 gfc_is_intrinsic_libcall (gfc_expr * expr)
2955 assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
2956 assert (expr->rank > 0);
2958 switch (expr->value.function.isym->generic_id)
2962 case GFC_ISYM_COUNT:
2963 case GFC_ISYM_MATMUL:
2964 case GFC_ISYM_MAXLOC:
2965 case GFC_ISYM_MAXVAL:
2966 case GFC_ISYM_MINLOC:
2967 case GFC_ISYM_MINVAL:
2968 case GFC_ISYM_PRODUCT:
2970 case GFC_ISYM_SHAPE:
2971 case GFC_ISYM_SPREAD:
2972 case GFC_ISYM_TRANSPOSE:
2973 /* Ignore absent optional parameters. */
2976 case GFC_ISYM_RESHAPE:
2977 case GFC_ISYM_CSHIFT:
2978 case GFC_ISYM_EOSHIFT:
2980 case GFC_ISYM_UNPACK:
2981 /* Pass absent optional parameters. */
2989 /* Walk an intrinsic function. */
2991 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
2992 gfc_intrinsic_sym * isym)
2996 if (isym->elemental)
2997 return gfc_walk_elemental_function_args (ss, expr, GFC_SS_SCALAR);
2999 if (expr->rank == 0)
3002 if (gfc_is_intrinsic_libcall (expr))
3003 return gfc_walk_intrinsic_libfunc (ss, expr);
3005 /* Special cases. */
3006 switch (isym->generic_id)
3008 case GFC_ISYM_LBOUND:
3009 case GFC_ISYM_UBOUND:
3010 return gfc_walk_intrinsic_bound (ss, expr);
3013 /* This probably meant someone forgot to add an intrinsic to the above
3014 list(s) when they implemented it, or something's gone horribly wrong.
3016 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3017 expr->value.function.name);
3021 #include "gt-fortran-trans-intrinsic.h"