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. */
366 gfc_set_model_kind (kind);
368 n = gfc_validate_kind (BT_INTEGER, kind);
369 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
370 tmp = gfc_conv_mpfr_to_tree (huge, kind);
371 cond = build (LT_EXPR, boolean_type_node, arg, tmp);
373 mpfr_neg (huge, huge, GFC_RND_MODE);
374 tmp = gfc_conv_mpfr_to_tree (huge, kind);
375 tmp = build (GT_EXPR, boolean_type_node, arg, tmp);
376 cond = build (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
377 itype = gfc_get_int_type (kind);
379 tmp = build_fix_expr (&se->pre, arg, itype, op);
380 tmp = convert (type, tmp);
381 se->expr = build (COND_EXPR, type, cond, tmp, arg);
386 /* Convert to an integer using the specified rounding mode. */
389 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
394 /* Evaluate the argument. */
395 type = gfc_typenode_for_spec (&expr->ts);
396 assert (expr->value.function.actual->expr);
397 arg = gfc_conv_intrinsic_function_args (se, expr);
398 arg = TREE_VALUE (arg);
400 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
402 /* Conversion to a different integer kind. */
403 se->expr = convert (type, arg);
407 /* Conversion from complex to non-complex involves taking the real
408 component of the value. */
409 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
410 && expr->ts.type != BT_COMPLEX)
414 artype = TREE_TYPE (TREE_TYPE (arg));
415 arg = build1 (REALPART_EXPR, artype, arg);
418 se->expr = build_fix_expr (&se->pre, arg, type, op);
423 /* Get the imaginary component of a value. */
426 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
430 arg = gfc_conv_intrinsic_function_args (se, expr);
431 arg = TREE_VALUE (arg);
432 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
436 /* Get the complex conjugate of a value. */
439 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
443 arg = gfc_conv_intrinsic_function_args (se, expr);
444 arg = TREE_VALUE (arg);
445 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
449 /* Initialize function decls for library functions. The external functions
450 are created as required. Builtin functions are added here. */
453 gfc_build_intrinsic_lib_fndecls (void)
455 gfc_intrinsic_map_t *m;
457 /* Add GCC builtin functions. */
458 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
460 if (m->code4 != END_BUILTINS)
461 m->real4_decl = built_in_decls[m->code4];
462 if (m->code8 != END_BUILTINS)
463 m->real8_decl = built_in_decls[m->code8];
468 /* Create a fndecl for a simple intrinsic library function. */
471 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
476 gfc_actual_arglist *actual;
479 char name[GFC_MAX_SYMBOL_LEN + 3];
482 if (ts->type == BT_REAL)
487 pdecl = &m->real4_decl;
490 pdecl = &m->real8_decl;
496 else if (ts->type == BT_COMPLEX)
498 if (!m->complex_available)
504 pdecl = &m->complex4_decl;
507 pdecl = &m->complex8_decl;
521 if (ts->kind != 4 && ts->kind != 8)
523 snprintf (name, sizeof (name), "%s%s%s",
524 ts->type == BT_COMPLEX ? "c" : "",
526 ts->kind == 4 ? "f" : "");
530 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
531 ts->type == BT_COMPLEX ? 'c' : 'r',
535 argtypes = NULL_TREE;
536 for (actual = expr->value.function.actual; actual; actual = actual->next)
538 type = gfc_typenode_for_spec (&actual->expr->ts);
539 argtypes = gfc_chainon_list (argtypes, type);
541 argtypes = gfc_chainon_list (argtypes, void_type_node);
542 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
543 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
545 /* Mark the decl as external. */
546 DECL_EXTERNAL (fndecl) = 1;
547 TREE_PUBLIC (fndecl) = 1;
549 /* Mark it __attribute__((const)), if possible. */
550 TREE_READONLY (fndecl) = m->is_constant;
552 rest_of_decl_compilation (fndecl, 1, 0);
559 /* Convert an intrinsic function into an external or builtin call. */
562 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
564 gfc_intrinsic_map_t *m;
567 gfc_generic_isym_id id;
569 id = expr->value.function.isym->generic_id;
570 /* Find the entry for this function. */
571 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
577 if (m->id == GFC_ISYM_NONE)
579 internal_error ("Intrinsic function %s(%d) not recognized",
580 expr->value.function.name, id);
583 /* Get the decl and generate the call. */
584 args = gfc_conv_intrinsic_function_args (se, expr);
585 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
586 se->expr = gfc_build_function_call (fndecl, args);
589 /* Generate code for EXPONENT(X) intrinsic function. */
592 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
597 args = gfc_conv_intrinsic_function_args (se, expr);
599 a1 = expr->value.function.actual->expr;
603 fndecl = gfor_fndecl_math_exponent4;
606 fndecl = gfor_fndecl_math_exponent8;
612 se->expr = gfc_build_function_call (fndecl, args);
615 /* Evaluate a single upper or lower bound. */
616 /* TODO: bound intrinsic generates way too much unneccessary code. */
619 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
621 gfc_actual_arglist *arg;
622 gfc_actual_arglist *arg2;
632 gfc_init_se (&argse, NULL);
633 arg = expr->value.function.actual;
638 /* Create an implicit second parameter from the loop variable. */
639 assert (!arg2->expr);
640 assert (se->loop->dimen == 1);
641 assert (se->ss->expr == expr);
642 gfc_advance_se_ss_chain (se);
643 bound = se->loop->loopvar[0];
644 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
649 /* use the passed argument. */
650 assert (arg->next->expr);
651 gfc_init_se (&argse, NULL);
652 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
653 gfc_add_block_to_block (&se->pre, &argse.pre);
655 /* Convert from one based to zero based. */
656 bound = fold (build (MINUS_EXPR, gfc_array_index_type, bound,
657 gfc_index_one_node));
660 /* TODO: don't re-evaluate the descriptor on each iteration. */
661 /* Get a descriptor for the first parameter. */
662 ss = gfc_walk_expr (arg->expr);
663 assert (ss != gfc_ss_terminator);
664 argse.want_pointer = 0;
665 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
666 gfc_add_block_to_block (&se->pre, &argse.pre);
667 gfc_add_block_to_block (&se->post, &argse.post);
671 if (INTEGER_CST_P (bound))
673 assert (TREE_INT_CST_HIGH (bound) == 0);
674 i = TREE_INT_CST_LOW (bound);
675 assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
679 if (flag_bounds_check)
681 bound = gfc_evaluate_now (bound, &se->pre);
682 cond = fold (build (LT_EXPR, boolean_type_node, bound,
683 convert (TREE_TYPE (bound), integer_zero_node)));
684 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
685 tmp = fold (build (GE_EXPR, boolean_type_node, bound, tmp));
686 cond = fold(build (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp));
687 gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
692 se->expr = gfc_conv_descriptor_ubound(desc, bound);
694 se->expr = gfc_conv_descriptor_lbound(desc, bound);
696 type = gfc_typenode_for_spec (&expr->ts);
697 se->expr = convert (type, se->expr);
702 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
708 args = gfc_conv_intrinsic_function_args (se, expr);
709 assert (args && TREE_CHAIN (args) == NULL_TREE);
710 val = TREE_VALUE (args);
712 switch (expr->value.function.actual->expr->ts.type)
716 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
720 switch (expr->ts.kind)
731 se->expr = fold (gfc_build_function_call (built_in_decls[n], args));
740 /* Create a complex value from one or two real components. */
743 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
750 type = gfc_typenode_for_spec (&expr->ts);
751 arg = gfc_conv_intrinsic_function_args (se, expr);
752 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
754 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
755 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
757 arg = TREE_VALUE (arg);
758 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
759 imag = convert (TREE_TYPE (type), imag);
762 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
764 se->expr = fold (build (COMPLEX_EXPR, type, real, imag));
767 /* Remainder function MOD(A, P) = A - INT(A / P) * P.
768 MODULO(A, P) = (A==0 .or. !(A>0 .xor. P>0))? MOD(A,P):MOD(A,P)+P. */
769 /* TODO: MOD(x, 0) */
772 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
785 arg = gfc_conv_intrinsic_function_args (se, expr);
786 arg2 = TREE_VALUE (TREE_CHAIN (arg));
787 arg = TREE_VALUE (arg);
788 type = TREE_TYPE (arg);
790 switch (expr->ts.type)
793 /* Integer case is easy, we've got a builtin op. */
794 se->expr = build (TRUNC_MOD_EXPR, type, arg, arg2);
798 /* Real values we have to do the hard way. */
799 arg = gfc_evaluate_now (arg, &se->pre);
800 arg2 = gfc_evaluate_now (arg2, &se->pre);
802 tmp = build (RDIV_EXPR, type, arg, arg2);
803 /* Test if the value is too large to handle sensibly. */
804 gfc_set_model_kind (expr->ts.kind);
806 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind);
807 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
808 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
809 test2 = build (LT_EXPR, boolean_type_node, tmp, test);
811 mpfr_neg (huge, huge, GFC_RND_MODE);
812 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
813 test = build (GT_EXPR, boolean_type_node, tmp, test);
814 test2 = build (TRUTH_AND_EXPR, boolean_type_node, test, test2);
816 itype = gfc_get_int_type (expr->ts.kind);
817 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
818 tmp = convert (type, tmp);
819 tmp = build (COND_EXPR, type, test2, tmp, arg);
820 tmp = build (MULT_EXPR, type, tmp, arg2);
821 se->expr = build (MINUS_EXPR, type, arg, tmp);
831 zero = gfc_build_const (type, integer_zero_node);
832 /* Build !(A > 0 .xor. P > 0). */
833 test = build (GT_EXPR, boolean_type_node, arg, zero);
834 test2 = build (GT_EXPR, boolean_type_node, arg2, zero);
835 test = build (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
836 test = build1 (TRUTH_NOT_EXPR, boolean_type_node, test);
837 /* Build (A == 0) .or. !(A > 0 .xor. P > 0). */
838 test2 = build (EQ_EXPR, boolean_type_node, arg, zero);
839 test = build (TRUTH_OR_EXPR, boolean_type_node, test, test2);
841 se->expr = build (COND_EXPR, type, test, se->expr,
842 build (PLUS_EXPR, type, se->expr, arg2));
846 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
849 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
858 arg = gfc_conv_intrinsic_function_args (se, expr);
859 arg2 = TREE_VALUE (TREE_CHAIN (arg));
860 arg = TREE_VALUE (arg);
861 type = TREE_TYPE (arg);
863 val = build (MINUS_EXPR, type, arg, arg2);
864 val = gfc_evaluate_now (val, &se->pre);
866 zero = gfc_build_const (type, integer_zero_node);
867 tmp = build (LE_EXPR, boolean_type_node, val, zero);
868 se->expr = build (COND_EXPR, type, tmp, zero, val);
872 /* SIGN(A, B) is absolute value of A times sign of B.
873 The real value versions use library functions to ensure the correct
874 handling of negative zero. Integer case implemented as:
875 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
879 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
890 arg = gfc_conv_intrinsic_function_args (se, expr);
891 if (expr->ts.type == BT_REAL)
893 switch (expr->ts.kind)
896 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
899 tmp = built_in_decls[BUILT_IN_COPYSIGN];
904 se->expr = fold (gfc_build_function_call (tmp, arg));
908 arg2 = TREE_VALUE (TREE_CHAIN (arg));
909 arg = TREE_VALUE (arg);
910 type = TREE_TYPE (arg);
911 zero = gfc_build_const (type, integer_zero_node);
913 testa = fold (build (GE_EXPR, boolean_type_node, arg, zero));
914 testb = fold (build (GE_EXPR, boolean_type_node, arg2, zero));
915 tmp = fold (build (TRUTH_XOR_EXPR, boolean_type_node, testa, testb));
916 se->expr = fold (build (COND_EXPR, type, tmp,
917 build1 (NEGATE_EXPR, type, arg), arg));
921 /* Test for the presence of an optional argument. */
924 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
928 arg = expr->value.function.actual->expr;
929 assert (arg->expr_type == EXPR_VARIABLE);
930 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
931 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
935 /* Calculate the double precision product of two single precision values. */
938 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
944 arg = gfc_conv_intrinsic_function_args (se, expr);
945 arg2 = TREE_VALUE (TREE_CHAIN (arg));
946 arg = TREE_VALUE (arg);
948 /* Convert the args to double precision before multiplying. */
949 type = gfc_typenode_for_spec (&expr->ts);
950 arg = convert (type, arg);
951 arg2 = convert (type, arg2);
952 se->expr = build (MULT_EXPR, type, arg, arg2);
956 /* Return a length one character string containing an ascii character. */
959 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
965 arg = gfc_conv_intrinsic_function_args (se, expr);
966 arg = TREE_VALUE (arg);
968 /* We currently don't support character types != 1. */
969 assert (expr->ts.kind == 1);
970 type = gfc_character1_type_node;
971 var = gfc_create_var (type, "char");
973 arg = convert (type, arg);
974 gfc_add_modify_expr (&se->pre, var, arg);
975 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
976 se->string_length = integer_one_node;
980 /* Get the minimum/maximum value of all the parameters.
981 minmax (a1, a2, a3, ...)
994 /* TODO: Mismatching types can occur when specific names are used.
995 These should be handled during resolution. */
997 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1008 arg = gfc_conv_intrinsic_function_args (se, expr);
1009 type = gfc_typenode_for_spec (&expr->ts);
1011 limit = TREE_VALUE (arg);
1012 if (TREE_TYPE (limit) != type)
1013 limit = convert (type, limit);
1014 /* Only evaluate the argument once. */
1015 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1016 limit = gfc_evaluate_now(limit, &se->pre);
1018 mvar = gfc_create_var (type, "M");
1019 elsecase = build_v (MODIFY_EXPR, mvar, limit);
1020 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1022 val = TREE_VALUE (arg);
1023 if (TREE_TYPE (val) != type)
1024 val = convert (type, val);
1026 /* Only evaluate the argument once. */
1027 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1028 val = gfc_evaluate_now(val, &se->pre);
1030 thencase = build_v (MODIFY_EXPR, mvar, convert (type, val));
1032 tmp = build (op, boolean_type_node, val, limit);
1033 tmp = build_v (COND_EXPR, tmp, thencase, elsecase);
1034 gfc_add_expr_to_block (&se->pre, tmp);
1035 elsecase = build_empty_stmt ();
1042 /* Create a symbol node for this intrinsic. The symbol form the frontend
1043 is for the generic name. */
1046 gfc_get_symbol_for_expr (gfc_expr * expr)
1050 /* TODO: Add symbols for intrinsic function to the global namespace. */
1051 assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1052 sym = gfc_new_symbol (expr->value.function.name, NULL);
1055 sym->attr.external = 1;
1056 sym->attr.function = 1;
1057 sym->attr.always_explicit = 1;
1058 sym->attr.proc = PROC_INTRINSIC;
1059 sym->attr.flavor = FL_PROCEDURE;
1063 sym->attr.dimension = 1;
1064 sym->as = gfc_get_array_spec ();
1065 sym->as->type = AS_ASSUMED_SHAPE;
1066 sym->as->rank = expr->rank;
1069 /* TODO: proper argument lists for external intrinsics. */
1073 /* Generate a call to an external intrinsic function. */
1075 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1079 assert (!se->ss || se->ss->expr == expr);
1082 assert (expr->rank > 0);
1084 assert (expr->rank == 0);
1086 sym = gfc_get_symbol_for_expr (expr);
1087 gfc_conv_function_call (se, sym, expr->value.function.actual);
1091 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1111 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1120 gfc_actual_arglist *actual;
1127 gfc_conv_intrinsic_funcall (se, expr);
1131 actual = expr->value.function.actual;
1132 type = gfc_typenode_for_spec (&expr->ts);
1133 /* Initialize the result. */
1134 resvar = gfc_create_var (type, "test");
1136 tmp = convert (type, boolean_true_node);
1138 tmp = convert (type, boolean_false_node);
1139 gfc_add_modify_expr (&se->pre, resvar, tmp);
1141 /* Walk the arguments. */
1142 arrayss = gfc_walk_expr (actual->expr);
1143 assert (arrayss != gfc_ss_terminator);
1145 /* Initialize the scalarizer. */
1146 gfc_init_loopinfo (&loop);
1147 exit_label = gfc_build_label_decl (NULL_TREE);
1148 TREE_USED (exit_label) = 1;
1149 gfc_add_ss_to_loop (&loop, arrayss);
1151 /* Initialize the loop. */
1152 gfc_conv_ss_startstride (&loop);
1153 gfc_conv_loop_setup (&loop);
1155 gfc_mark_ss_chain_used (arrayss, 1);
1156 /* Generate the loop body. */
1157 gfc_start_scalarized_body (&loop, &body);
1159 /* If the condition matches then set the return value. */
1160 gfc_start_block (&block);
1162 tmp = convert (type, boolean_false_node);
1164 tmp = convert (type, boolean_true_node);
1165 gfc_add_modify_expr (&block, resvar, tmp);
1167 /* And break out of the loop. */
1168 tmp = build1_v (GOTO_EXPR, exit_label);
1169 gfc_add_expr_to_block (&block, tmp);
1171 found = gfc_finish_block (&block);
1173 /* Check this element. */
1174 gfc_init_se (&arrayse, NULL);
1175 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1176 arrayse.ss = arrayss;
1177 gfc_conv_expr_val (&arrayse, actual->expr);
1179 gfc_add_block_to_block (&body, &arrayse.pre);
1180 tmp = build (op, boolean_type_node, arrayse.expr,
1181 fold_convert (TREE_TYPE (arrayse.expr),
1182 integer_zero_node));
1183 tmp = build_v (COND_EXPR, tmp, found, build_empty_stmt ());
1184 gfc_add_expr_to_block (&body, tmp);
1185 gfc_add_block_to_block (&body, &arrayse.post);
1187 gfc_trans_scalarizing_loops (&loop, &body);
1189 /* Add the exit label. */
1190 tmp = build1_v (LABEL_EXPR, exit_label);
1191 gfc_add_expr_to_block (&loop.pre, tmp);
1193 gfc_add_block_to_block (&se->pre, &loop.pre);
1194 gfc_add_block_to_block (&se->pre, &loop.post);
1195 gfc_cleanup_loop (&loop);
1200 /* COUNT(A) = Number of true elements in A. */
1202 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1209 gfc_actual_arglist *actual;
1215 gfc_conv_intrinsic_funcall (se, expr);
1219 actual = expr->value.function.actual;
1221 type = gfc_typenode_for_spec (&expr->ts);
1222 /* Initialize the result. */
1223 resvar = gfc_create_var (type, "count");
1224 gfc_add_modify_expr (&se->pre, resvar, convert (type, integer_zero_node));
1226 /* Walk the arguments. */
1227 arrayss = gfc_walk_expr (actual->expr);
1228 assert (arrayss != gfc_ss_terminator);
1230 /* Initialize the scalarizer. */
1231 gfc_init_loopinfo (&loop);
1232 gfc_add_ss_to_loop (&loop, arrayss);
1234 /* Initialize the loop. */
1235 gfc_conv_ss_startstride (&loop);
1236 gfc_conv_loop_setup (&loop);
1238 gfc_mark_ss_chain_used (arrayss, 1);
1239 /* Generate the loop body. */
1240 gfc_start_scalarized_body (&loop, &body);
1242 tmp = build (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1243 convert (TREE_TYPE (resvar), integer_one_node));
1244 tmp = build_v (MODIFY_EXPR, resvar, tmp);
1246 gfc_init_se (&arrayse, NULL);
1247 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1248 arrayse.ss = arrayss;
1249 gfc_conv_expr_val (&arrayse, actual->expr);
1250 tmp = build_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1252 gfc_add_block_to_block (&body, &arrayse.pre);
1253 gfc_add_expr_to_block (&body, tmp);
1254 gfc_add_block_to_block (&body, &arrayse.post);
1256 gfc_trans_scalarizing_loops (&loop, &body);
1258 gfc_add_block_to_block (&se->pre, &loop.pre);
1259 gfc_add_block_to_block (&se->pre, &loop.post);
1260 gfc_cleanup_loop (&loop);
1265 /* Inline implementation of the sum and product intrinsics. */
1267 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1275 gfc_actual_arglist *actual;
1280 gfc_expr *arrayexpr;
1285 gfc_conv_intrinsic_funcall (se, expr);
1289 type = gfc_typenode_for_spec (&expr->ts);
1290 /* Initialize the result. */
1291 resvar = gfc_create_var (type, "val");
1292 if (op == PLUS_EXPR)
1293 tmp = gfc_build_const (type, integer_zero_node);
1295 tmp = gfc_build_const (type, integer_one_node);
1297 gfc_add_modify_expr (&se->pre, resvar, tmp);
1299 /* Walk the arguments. */
1300 actual = expr->value.function.actual;
1301 arrayexpr = actual->expr;
1302 arrayss = gfc_walk_expr (arrayexpr);
1303 assert (arrayss != gfc_ss_terminator);
1305 actual = actual->next->next;
1307 maskexpr = actual->expr;
1310 maskss = gfc_walk_expr (maskexpr);
1311 assert (maskss != gfc_ss_terminator);
1316 /* Initialize the scalarizer. */
1317 gfc_init_loopinfo (&loop);
1318 gfc_add_ss_to_loop (&loop, arrayss);
1320 gfc_add_ss_to_loop (&loop, maskss);
1322 /* Initialize the loop. */
1323 gfc_conv_ss_startstride (&loop);
1324 gfc_conv_loop_setup (&loop);
1326 gfc_mark_ss_chain_used (arrayss, 1);
1328 gfc_mark_ss_chain_used (maskss, 1);
1329 /* Generate the loop body. */
1330 gfc_start_scalarized_body (&loop, &body);
1332 /* If we have a mask, only add this element if the mask is set. */
1335 gfc_init_se (&maskse, NULL);
1336 gfc_copy_loopinfo_to_se (&maskse, &loop);
1338 gfc_conv_expr_val (&maskse, maskexpr);
1339 gfc_add_block_to_block (&body, &maskse.pre);
1341 gfc_start_block (&block);
1344 gfc_init_block (&block);
1346 /* Do the actual summation/product. */
1347 gfc_init_se (&arrayse, NULL);
1348 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1349 arrayse.ss = arrayss;
1350 gfc_conv_expr_val (&arrayse, arrayexpr);
1351 gfc_add_block_to_block (&block, &arrayse.pre);
1353 tmp = build (op, type, resvar, arrayse.expr);
1354 gfc_add_modify_expr (&block, resvar, tmp);
1355 gfc_add_block_to_block (&block, &arrayse.post);
1359 /* We enclose the above in if (mask) {...} . */
1360 tmp = gfc_finish_block (&block);
1362 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1365 tmp = gfc_finish_block (&block);
1366 gfc_add_expr_to_block (&body, tmp);
1368 gfc_trans_scalarizing_loops (&loop, &body);
1369 gfc_add_block_to_block (&se->pre, &loop.pre);
1370 gfc_add_block_to_block (&se->pre, &loop.post);
1371 gfc_cleanup_loop (&loop);
1377 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1381 stmtblock_t ifblock;
1388 gfc_actual_arglist *actual;
1393 gfc_expr *arrayexpr;
1400 gfc_conv_intrinsic_funcall (se, expr);
1404 /* Initialize the result. */
1405 pos = gfc_create_var (gfc_array_index_type, "pos");
1406 type = gfc_typenode_for_spec (&expr->ts);
1408 /* Walk the arguments. */
1409 actual = expr->value.function.actual;
1410 arrayexpr = actual->expr;
1411 arrayss = gfc_walk_expr (arrayexpr);
1412 assert (arrayss != gfc_ss_terminator);
1414 actual = actual->next->next;
1416 maskexpr = actual->expr;
1419 maskss = gfc_walk_expr (maskexpr);
1420 assert (maskss != gfc_ss_terminator);
1425 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1426 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind);
1427 switch (arrayexpr->ts.type)
1430 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1434 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1435 arrayexpr->ts.kind);
1442 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1444 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1445 gfc_add_modify_expr (&se->pre, limit, tmp);
1447 /* Initialize the scalarizer. */
1448 gfc_init_loopinfo (&loop);
1449 gfc_add_ss_to_loop (&loop, arrayss);
1451 gfc_add_ss_to_loop (&loop, maskss);
1453 /* Initialize the loop. */
1454 gfc_conv_ss_startstride (&loop);
1455 gfc_conv_loop_setup (&loop);
1457 assert (loop.dimen == 1);
1459 /* Initialize the position to the first element. If the array has zero
1460 size we need to return zero. Otherwise use the first element of the
1461 array, in case all elements are equal to the limit.
1462 ie. pos = (ubound >= lbound) ? lbound, lbound - 1; */
1463 tmp = fold (build (MINUS_EXPR, gfc_array_index_type,
1464 loop.from[0], gfc_index_one_node));
1465 cond = fold (build (GE_EXPR, boolean_type_node,
1466 loop.to[0], loop.from[0]));
1467 tmp = fold (build (COND_EXPR, gfc_array_index_type, cond,
1468 loop.from[0], tmp));
1469 gfc_add_modify_expr (&loop.pre, pos, tmp);
1471 gfc_mark_ss_chain_used (arrayss, 1);
1473 gfc_mark_ss_chain_used (maskss, 1);
1474 /* Generate the loop body. */
1475 gfc_start_scalarized_body (&loop, &body);
1477 /* If we have a mask, only check this element if the mask is set. */
1480 gfc_init_se (&maskse, NULL);
1481 gfc_copy_loopinfo_to_se (&maskse, &loop);
1483 gfc_conv_expr_val (&maskse, maskexpr);
1484 gfc_add_block_to_block (&body, &maskse.pre);
1486 gfc_start_block (&block);
1489 gfc_init_block (&block);
1491 /* Compare with the current limit. */
1492 gfc_init_se (&arrayse, NULL);
1493 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1494 arrayse.ss = arrayss;
1495 gfc_conv_expr_val (&arrayse, arrayexpr);
1496 gfc_add_block_to_block (&block, &arrayse.pre);
1498 /* We do the following if this is a more extreme value. */
1499 gfc_start_block (&ifblock);
1501 /* Assign the value to the limit... */
1502 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1504 /* Remember where we are. */
1505 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1507 ifbody = gfc_finish_block (&ifblock);
1509 /* If it is a more extreme value. */
1510 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1511 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1512 gfc_add_expr_to_block (&block, tmp);
1516 /* We enclose the above in if (mask) {...}. */
1517 tmp = gfc_finish_block (&block);
1519 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1522 tmp = gfc_finish_block (&block);
1523 gfc_add_expr_to_block (&body, tmp);
1525 gfc_trans_scalarizing_loops (&loop, &body);
1527 gfc_add_block_to_block (&se->pre, &loop.pre);
1528 gfc_add_block_to_block (&se->pre, &loop.post);
1529 gfc_cleanup_loop (&loop);
1531 /* Return a value in the range 1..SIZE(array). */
1532 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1533 gfc_index_one_node));
1534 tmp = fold (build (MINUS_EXPR, gfc_array_index_type, pos, tmp));
1535 /* And convert to the required type. */
1536 se->expr = convert (type, tmp);
1540 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1549 gfc_actual_arglist *actual;
1554 gfc_expr *arrayexpr;
1560 gfc_conv_intrinsic_funcall (se, expr);
1564 type = gfc_typenode_for_spec (&expr->ts);
1565 /* Initialize the result. */
1566 limit = gfc_create_var (type, "limit");
1567 n = gfc_validate_kind (expr->ts.type, expr->ts.kind);
1568 switch (expr->ts.type)
1571 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1575 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1582 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1584 tmp = fold (build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp));
1585 gfc_add_modify_expr (&se->pre, limit, tmp);
1587 /* Walk the arguments. */
1588 actual = expr->value.function.actual;
1589 arrayexpr = actual->expr;
1590 arrayss = gfc_walk_expr (arrayexpr);
1591 assert (arrayss != gfc_ss_terminator);
1593 actual = actual->next->next;
1595 maskexpr = actual->expr;
1598 maskss = gfc_walk_expr (maskexpr);
1599 assert (maskss != gfc_ss_terminator);
1604 /* Initialize the scalarizer. */
1605 gfc_init_loopinfo (&loop);
1606 gfc_add_ss_to_loop (&loop, arrayss);
1608 gfc_add_ss_to_loop (&loop, maskss);
1610 /* Initialize the loop. */
1611 gfc_conv_ss_startstride (&loop);
1612 gfc_conv_loop_setup (&loop);
1614 gfc_mark_ss_chain_used (arrayss, 1);
1616 gfc_mark_ss_chain_used (maskss, 1);
1617 /* Generate the loop body. */
1618 gfc_start_scalarized_body (&loop, &body);
1620 /* If we have a mask, only add this element if the mask is set. */
1623 gfc_init_se (&maskse, NULL);
1624 gfc_copy_loopinfo_to_se (&maskse, &loop);
1626 gfc_conv_expr_val (&maskse, maskexpr);
1627 gfc_add_block_to_block (&body, &maskse.pre);
1629 gfc_start_block (&block);
1632 gfc_init_block (&block);
1634 /* Compare with the current limit. */
1635 gfc_init_se (&arrayse, NULL);
1636 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1637 arrayse.ss = arrayss;
1638 gfc_conv_expr_val (&arrayse, arrayexpr);
1639 gfc_add_block_to_block (&block, &arrayse.pre);
1641 /* Assign the value to the limit... */
1642 ifbody = build_v (MODIFY_EXPR, limit, arrayse.expr);
1644 /* If it is a more extreme value. */
1645 tmp = build (op, boolean_type_node, arrayse.expr, limit);
1646 tmp = build_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1647 gfc_add_expr_to_block (&block, tmp);
1648 gfc_add_block_to_block (&block, &arrayse.post);
1650 tmp = gfc_finish_block (&block);
1653 /* We enclose the above in if (mask) {...}. */
1654 tmp = build_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1656 gfc_add_expr_to_block (&body, tmp);
1658 gfc_trans_scalarizing_loops (&loop, &body);
1660 gfc_add_block_to_block (&se->pre, &loop.pre);
1661 gfc_add_block_to_block (&se->pre, &loop.post);
1662 gfc_cleanup_loop (&loop);
1667 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
1669 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
1676 arg = gfc_conv_intrinsic_function_args (se, expr);
1677 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1678 arg = TREE_VALUE (arg);
1679 type = TREE_TYPE (arg);
1681 tmp = build (LSHIFT_EXPR, type, convert (type, integer_one_node), arg2);
1682 tmp = build (BIT_AND_EXPR, type, arg, tmp);
1683 tmp = fold (build (NE_EXPR, boolean_type_node, tmp,
1684 convert (type, integer_zero_node)));
1685 type = gfc_typenode_for_spec (&expr->ts);
1686 se->expr = convert (type, tmp);
1689 /* Generate code to perform the specified operation. */
1691 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
1697 arg = gfc_conv_intrinsic_function_args (se, expr);
1698 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1699 arg = TREE_VALUE (arg);
1700 type = TREE_TYPE (arg);
1702 se->expr = fold (build (op, type, arg, arg2));
1707 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
1711 arg = gfc_conv_intrinsic_function_args (se, expr);
1712 arg = TREE_VALUE (arg);
1714 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
1717 /* Set or clear a single bit. */
1719 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
1727 arg = gfc_conv_intrinsic_function_args (se, expr);
1728 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1729 arg = TREE_VALUE (arg);
1730 type = TREE_TYPE (arg);
1732 tmp = fold (build (LSHIFT_EXPR, type,
1733 convert (type, integer_one_node), arg2));
1739 tmp = fold (build1 (BIT_NOT_EXPR, type, tmp));
1741 se->expr = fold (build (op, type, arg, tmp));
1744 /* Extract a sequence of bits.
1745 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
1747 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
1756 arg = gfc_conv_intrinsic_function_args (se, expr);
1757 arg2 = TREE_CHAIN (arg);
1758 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
1759 arg = TREE_VALUE (arg);
1760 arg2 = TREE_VALUE (arg2);
1761 type = TREE_TYPE (arg);
1763 mask = build_int_cst (NULL_TREE, -1);
1764 mask = build (LSHIFT_EXPR, type, mask, arg3);
1765 mask = build1 (BIT_NOT_EXPR, type, mask);
1767 tmp = build (RSHIFT_EXPR, type, arg, arg2);
1769 se->expr = fold (build (BIT_AND_EXPR, type, tmp, mask));
1772 /* ISHFT (I, SHIFT) = (shift >= 0) ? i << shift : i >> -shift. */
1774 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
1783 arg = gfc_conv_intrinsic_function_args (se, expr);
1784 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1785 arg = TREE_VALUE (arg);
1786 type = TREE_TYPE (arg);
1788 /* Left shift if positive. */
1789 lshift = build (LSHIFT_EXPR, type, arg, arg2);
1791 /* Right shift if negative. This will perform an arithmetic shift as
1792 we are dealing with signed integers. Section 13.5.7 allows this. */
1793 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1794 rshift = build (RSHIFT_EXPR, type, arg, tmp);
1796 tmp = build (GT_EXPR, boolean_type_node, arg2,
1797 convert (TREE_TYPE (arg2), integer_zero_node));
1798 rshift = build (COND_EXPR, type, tmp, lshift, rshift);
1800 /* Do nothing if shift == 0. */
1801 tmp = build (EQ_EXPR, boolean_type_node, arg2,
1802 convert (TREE_TYPE (arg2), integer_zero_node));
1803 se->expr = build (COND_EXPR, type, tmp, arg, rshift);
1806 /* Circular shift. AKA rotate or barrel shift. */
1808 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
1818 arg = gfc_conv_intrinsic_function_args (se, expr);
1819 arg2 = TREE_CHAIN (arg);
1820 arg3 = TREE_CHAIN (arg2);
1823 /* Use a library function for the 3 parameter version. */
1824 type = TREE_TYPE (TREE_VALUE (arg));
1825 /* Convert all args to the same type otherwise we need loads of library
1826 functions. SIZE and SHIFT cannot have values > BIT_SIZE (I) so the
1827 conversion is safe. */
1828 tmp = convert (type, TREE_VALUE (arg2));
1829 TREE_VALUE (arg2) = tmp;
1830 tmp = convert (type, TREE_VALUE (arg3));
1831 TREE_VALUE (arg3) = tmp;
1833 switch (expr->ts.kind)
1836 tmp = gfor_fndecl_math_ishftc4;
1839 tmp = gfor_fndecl_math_ishftc8;
1844 se->expr = gfc_build_function_call (tmp, arg);
1847 arg = TREE_VALUE (arg);
1848 arg2 = TREE_VALUE (arg2);
1849 type = TREE_TYPE (arg);
1851 /* Rotate left if positive. */
1852 lrot = build (LROTATE_EXPR, type, arg, arg2);
1854 /* Rotate right if negative. */
1855 tmp = build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1856 rrot = build (RROTATE_EXPR, type, arg, tmp);
1858 tmp = build (GT_EXPR, boolean_type_node, arg2,
1859 convert (TREE_TYPE (arg2), integer_zero_node));
1860 rrot = build (COND_EXPR, type, tmp, lrot, rrot);
1862 /* Do nothing if shift == 0. */
1863 tmp = build (EQ_EXPR, boolean_type_node, arg2,
1864 convert (TREE_TYPE (arg2), integer_zero_node));
1865 se->expr = build (COND_EXPR, type, tmp, arg, rrot);
1868 /* The length of a character string. */
1870 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
1881 arg = expr->value.function.actual->expr;
1883 type = gfc_typenode_for_spec (&expr->ts);
1884 switch (arg->expr_type)
1887 len = build_int_cst (NULL_TREE, arg->value.character.length);
1891 if (arg->expr_type == EXPR_VARIABLE
1892 && (arg->ref == NULL || (arg->ref->next == NULL
1893 && arg->ref->type == REF_ARRAY)))
1895 /* This doesn't catch all cases.
1896 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
1897 and the surrounding thread. */
1898 sym = arg->symtree->n.sym;
1899 decl = gfc_get_symbol_decl (sym);
1900 if (decl == current_function_decl && sym->attr.function
1901 && (sym->result == sym))
1902 decl = gfc_get_fake_result_decl (sym);
1904 len = sym->ts.cl->backend_decl;
1909 /* Anybody stupid enough to do this deserves inefficient code. */
1910 gfc_init_se (&argse, se);
1911 gfc_conv_expr (&argse, arg);
1912 gfc_add_block_to_block (&se->pre, &argse.pre);
1913 gfc_add_block_to_block (&se->post, &argse.post);
1914 len = argse.string_length;
1918 se->expr = convert (type, len);
1921 /* The length of a character string not including trailing blanks. */
1923 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
1928 args = gfc_conv_intrinsic_function_args (se, expr);
1929 type = gfc_typenode_for_spec (&expr->ts);
1930 se->expr = gfc_build_function_call (gfor_fndecl_string_len_trim, args);
1931 se->expr = convert (type, se->expr);
1935 /* Returns the starting position of a substring within a string. */
1938 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
1945 args = gfc_conv_intrinsic_function_args (se, expr);
1946 type = gfc_typenode_for_spec (&expr->ts);
1947 tmp = gfc_advance_chain (args, 3);
1948 if (TREE_CHAIN (tmp) == NULL_TREE)
1950 back = convert (gfc_logical4_type_node, integer_one_node);
1951 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
1952 TREE_CHAIN (tmp) = back;
1956 back = TREE_CHAIN (tmp);
1957 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
1960 se->expr = gfc_build_function_call (gfor_fndecl_string_index, args);
1961 se->expr = convert (type, se->expr);
1964 /* The ascii value for a single character. */
1966 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
1971 arg = gfc_conv_intrinsic_function_args (se, expr);
1972 arg = TREE_VALUE (TREE_CHAIN (arg));
1973 assert (POINTER_TYPE_P (TREE_TYPE (arg)));
1974 arg = build1 (NOP_EXPR, pchar_type_node, arg);
1975 type = gfc_typenode_for_spec (&expr->ts);
1977 se->expr = gfc_build_indirect_ref (arg);
1978 se->expr = convert (type, se->expr);
1982 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
1985 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
1993 arg = gfc_conv_intrinsic_function_args (se, expr);
1994 tsource = TREE_VALUE (arg);
1995 arg = TREE_CHAIN (arg);
1996 fsource = TREE_VALUE (arg);
1997 arg = TREE_CHAIN (arg);
1998 mask = TREE_VALUE (arg);
2000 type = TREE_TYPE (tsource);
2001 se->expr = fold (build (COND_EXPR, type, mask, tsource, fsource));
2006 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2008 gfc_actual_arglist *actual;
2015 gfc_init_se (&argse, NULL);
2016 actual = expr->value.function.actual;
2018 ss = gfc_walk_expr (actual->expr);
2019 assert (ss != gfc_ss_terminator);
2020 argse.want_pointer = 1;
2021 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2022 gfc_add_block_to_block (&se->pre, &argse.pre);
2023 gfc_add_block_to_block (&se->post, &argse.post);
2024 args = gfc_chainon_list (NULL_TREE, argse.expr);
2026 actual = actual->next;
2029 gfc_init_se (&argse, NULL);
2030 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2031 gfc_add_block_to_block (&se->pre, &argse.pre);
2032 args = gfc_chainon_list (args, argse.expr);
2033 fndecl = gfor_fndecl_size1;
2036 fndecl = gfor_fndecl_size0;
2038 se->expr = gfc_build_function_call (fndecl, args);
2039 type = gfc_typenode_for_spec (&expr->ts);
2040 se->expr = convert (type, se->expr);
2044 /* Intrinsic string comparison functions. */
2047 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2052 args = gfc_conv_intrinsic_function_args (se, expr);
2053 /* Build a call for the comparison. */
2054 se->expr = gfc_build_function_call (gfor_fndecl_compare_string, args);
2056 type = gfc_typenode_for_spec (&expr->ts);
2057 se->expr = build (op, type, se->expr,
2058 convert (TREE_TYPE (se->expr), integer_zero_node));
2061 /* Generate a call to the adjustl/adjustr library function. */
2063 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2071 args = gfc_conv_intrinsic_function_args (se, expr);
2072 len = TREE_VALUE (args);
2074 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2075 var = gfc_conv_string_tmp (se, type, len);
2076 args = tree_cons (NULL_TREE, var, args);
2078 tmp = gfc_build_function_call (fndecl, args);
2079 gfc_add_expr_to_block (&se->pre, tmp);
2081 se->string_length = len;
2085 /* Scalar transfer statement.
2086 TRANSFER (source, mold) = *(typeof<mould> *)&source */
2089 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2091 gfc_actual_arglist *arg;
2099 /* Get a pointer to the source. */
2100 arg = expr->value.function.actual;
2101 ss = gfc_walk_expr (arg->expr);
2102 gfc_init_se (&argse, NULL);
2103 if (ss == gfc_ss_terminator)
2104 gfc_conv_expr_reference (&argse, arg->expr);
2106 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2107 gfc_add_block_to_block (&se->pre, &argse.pre);
2108 gfc_add_block_to_block (&se->post, &argse.post);
2112 type = gfc_typenode_for_spec (&expr->ts);
2113 ptr = convert (build_pointer_type (type), ptr);
2114 if (expr->ts.type == BT_CHARACTER)
2116 gfc_init_se (&argse, NULL);
2117 gfc_conv_expr (&argse, arg->expr);
2118 gfc_add_block_to_block (&se->pre, &argse.pre);
2119 gfc_add_block_to_block (&se->post, &argse.post);
2121 se->string_length = argse.string_length;
2125 se->expr = gfc_build_indirect_ref (ptr);
2130 /* Generate code for the ALLOCATED intrinsic.
2131 Generate inline code that directly check the address of the argument. */
2134 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2136 gfc_actual_arglist *arg1;
2141 gfc_init_se (&arg1se, NULL);
2142 arg1 = expr->value.function.actual;
2143 ss1 = gfc_walk_expr (arg1->expr);
2144 arg1se.descriptor_only = 1;
2145 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2147 tmp = gfc_conv_descriptor_data (arg1se.expr);
2148 tmp = build (NE_EXPR, boolean_type_node, tmp,
2149 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2150 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2154 /* Generate code for the ASSOCIATED intrinsic.
2155 If both POINTER and TARGET are arrays, generate a call to library function
2156 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2157 In other cases, generate inline code that directly compare the address of
2158 POINTER with the address of TARGET. */
2161 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2163 gfc_actual_arglist *arg1;
2164 gfc_actual_arglist *arg2;
2172 gfc_init_se (&arg1se, NULL);
2173 gfc_init_se (&arg2se, NULL);
2174 arg1 = expr->value.function.actual;
2176 ss1 = gfc_walk_expr (arg1->expr);
2180 /* No optional target. */
2181 if (ss1 == gfc_ss_terminator)
2183 /* A pointer to a scalar. */
2184 arg1se.want_pointer = 1;
2185 gfc_conv_expr (&arg1se, arg1->expr);
2190 /* A pointer to an array. */
2191 arg1se.descriptor_only = 1;
2192 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2193 tmp2 = gfc_conv_descriptor_data (arg1se.expr);
2195 tmp = build (NE_EXPR, boolean_type_node, tmp2,
2196 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
2201 /* An optional target. */
2202 ss2 = gfc_walk_expr (arg2->expr);
2203 if (ss1 == gfc_ss_terminator)
2205 /* A pointer to a scalar. */
2206 assert (ss2 == gfc_ss_terminator);
2207 arg1se.want_pointer = 1;
2208 gfc_conv_expr (&arg1se, arg1->expr);
2209 arg2se.want_pointer = 1;
2210 gfc_conv_expr (&arg2se, arg2->expr);
2211 tmp = build (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2216 /* A pointer to an array, call library function _gfor_associated. */
2217 assert (ss2 != gfc_ss_terminator);
2219 arg1se.want_pointer = 1;
2220 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2221 args = gfc_chainon_list (args, arg1se.expr);
2222 arg2se.want_pointer = 1;
2223 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2224 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2225 gfc_add_block_to_block (&se->post, &arg2se.post);
2226 args = gfc_chainon_list (args, arg2se.expr);
2227 fndecl = gfor_fndecl_associated;
2228 se->expr = gfc_build_function_call (fndecl, args);
2231 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2235 /* Scan a string for any one of the characters in a set of characters. */
2238 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2245 args = gfc_conv_intrinsic_function_args (se, expr);
2246 type = gfc_typenode_for_spec (&expr->ts);
2247 tmp = gfc_advance_chain (args, 3);
2248 if (TREE_CHAIN (tmp) == NULL_TREE)
2250 back = convert (gfc_logical4_type_node, integer_one_node);
2251 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2252 TREE_CHAIN (tmp) = back;
2256 back = TREE_CHAIN (tmp);
2257 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2260 se->expr = gfc_build_function_call (gfor_fndecl_string_scan, args);
2261 se->expr = convert (type, se->expr);
2265 /* Verify that a set of characters contains all the characters in a string
2266 by indentifying the position of the first character in a string of
2267 characters that does not appear in a given set of characters. */
2270 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2277 args = gfc_conv_intrinsic_function_args (se, expr);
2278 type = gfc_typenode_for_spec (&expr->ts);
2279 tmp = gfc_advance_chain (args, 3);
2280 if (TREE_CHAIN (tmp) == NULL_TREE)
2282 back = convert (gfc_logical4_type_node, integer_one_node);
2283 back = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
2284 TREE_CHAIN (tmp) = back;
2288 back = TREE_CHAIN (tmp);
2289 TREE_VALUE (back) = convert (gfc_logical4_type_node, TREE_VALUE (back));
2292 se->expr = gfc_build_function_call (gfor_fndecl_string_verify, args);
2293 se->expr = convert (type, se->expr);
2296 /* Prepare components and related information of a real number which is
2297 the first argument of a elemental functions to manipulate reals. */
2300 void prepare_arg_info (gfc_se * se, gfc_expr * expr,
2301 real_compnt_info * rcs, int all)
2308 tree exponent, fraction;
2312 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
2313 gfc_todo_error ("Non-IEEE floating format");
2315 assert (expr->expr_type == EXPR_FUNCTION);
2317 arg = gfc_conv_intrinsic_function_args (se, expr);
2318 arg = TREE_VALUE (arg);
2319 rcs->type = TREE_TYPE (arg);
2321 /* Force arg'type to integer by unaffected convert */
2322 a1 = expr->value.function.actual->expr;
2323 masktype = gfc_get_int_type (a1->ts.kind);
2324 rcs->mtype = masktype;
2325 tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
2326 arg = gfc_create_var (masktype, "arg");
2327 gfc_add_modify_expr(&se->pre, arg, tmp);
2330 /* Caculate the numbers of bits of exponent, fraction and word */
2331 n = gfc_validate_kind (a1->ts.type, a1->ts.kind);
2332 tmp = build_int_cst (NULL_TREE, gfc_real_kinds[n].digits - 1);
2333 rcs->fdigits = convert (masktype, tmp);
2334 wbits = build_int_cst (NULL_TREE, TYPE_PRECISION (rcs->type) - 1);
2335 wbits = convert (masktype, wbits);
2336 rcs->edigits = fold (build (MINUS_EXPR, masktype, wbits, tmp));
2338 /* Form masks for exponent/fraction/sign */
2339 one = gfc_build_const (masktype, integer_one_node);
2340 rcs->smask = fold (build (LSHIFT_EXPR, masktype, one, wbits));
2341 rcs->f1 = fold (build (LSHIFT_EXPR, masktype, one, rcs->fdigits));
2342 rcs->emask = fold (build (MINUS_EXPR, masktype, rcs->smask, rcs->f1));
2343 rcs->fmask = fold (build (MINUS_EXPR, masktype, rcs->f1, one));
2345 tmp = fold (build (MINUS_EXPR, masktype, rcs->edigits, one));
2346 tmp = fold (build (LSHIFT_EXPR, masktype, one, tmp));
2347 rcs->bias = fold (build (MINUS_EXPR, masktype, tmp ,one));
2351 /* exponent, and fraction */
2352 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->emask);
2353 tmp = build (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
2354 exponent = gfc_create_var (masktype, "exponent");
2355 gfc_add_modify_expr(&se->pre, exponent, tmp);
2356 rcs->expn = exponent;
2358 tmp = build (BIT_AND_EXPR, masktype, arg, rcs->fmask);
2359 fraction = gfc_create_var (masktype, "fraction");
2360 gfc_add_modify_expr(&se->pre, fraction, tmp);
2361 rcs->frac = fraction;
2365 /* Build a call to __builtin_clz. */
2368 call_builtin_clz (tree result_type, tree op0)
2370 tree fn, parms, call;
2371 enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
2373 if (op0_mode == TYPE_MODE (integer_type_node))
2374 fn = built_in_decls[BUILT_IN_CLZ];
2375 else if (op0_mode == TYPE_MODE (long_integer_type_node))
2376 fn = built_in_decls[BUILT_IN_CLZL];
2377 else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
2378 fn = built_in_decls[BUILT_IN_CLZLL];
2382 parms = tree_cons (NULL, op0, NULL);
2383 call = gfc_build_function_call (fn, parms);
2385 return convert (result_type, call);
2388 /* Generate code for SPACING (X) intrinsic function. We generate:
2390 t = expn - (BITS_OF_FRACTION)
2391 res = t << (BITS_OF_FRACTION)
2397 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2404 real_compnt_info rcs;
2406 prepare_arg_info (se, expr, &rcs, 0);
2408 masktype = rcs.mtype;
2409 fdigits = rcs.fdigits;
2411 zero = gfc_build_const (masktype, integer_zero_node);
2412 tmp = build (BIT_AND_EXPR, masktype, rcs.emask, arg);
2413 tmp = build (RSHIFT_EXPR, masktype, tmp, fdigits);
2414 tmp = build (MINUS_EXPR, masktype, tmp, fdigits);
2415 cond = build (LE_EXPR, boolean_type_node, tmp, zero);
2416 t1 = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2417 tmp = build (COND_EXPR, masktype, cond, tiny, t1);
2418 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2423 /* Generate code for RRSPACING (X) intrinsic function. We generate:
2425 if (expn == 0 && frac == 0)
2429 sedigits = edigits + 1;
2432 t1 = leadzero (frac);
2433 frac = frac << (t1 + sedigits);
2434 frac = frac >> (sedigits);
2436 t = bias + BITS_OF_FRACTION_OF;
2437 res = (t << BITS_OF_FRACTION_OF) | frac;
2441 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2444 tree tmp, t1, t2, cond, cond2;
2446 tree fdigits, fraction;
2447 real_compnt_info rcs;
2449 prepare_arg_info (se, expr, &rcs, 1);
2450 masktype = rcs.mtype;
2451 fdigits = rcs.fdigits;
2452 fraction = rcs.frac;
2453 one = gfc_build_const (masktype, integer_one_node);
2454 zero = gfc_build_const (masktype, integer_zero_node);
2455 t2 = build (PLUS_EXPR, masktype, rcs.edigits, one);
2457 t1 = call_builtin_clz (masktype, fraction);
2458 tmp = build (PLUS_EXPR, masktype, t1, one);
2459 tmp = build (LSHIFT_EXPR, masktype, fraction, tmp);
2460 tmp = build (RSHIFT_EXPR, masktype, tmp, t2);
2461 cond = build (EQ_EXPR, boolean_type_node, rcs.expn, zero);
2462 fraction = build (COND_EXPR, masktype, cond, tmp, fraction);
2464 tmp = build (PLUS_EXPR, masktype, rcs.bias, fdigits);
2465 tmp = build (LSHIFT_EXPR, masktype, tmp, fdigits);
2466 tmp = build (BIT_IOR_EXPR, masktype, tmp, fraction);
2468 cond2 = build (EQ_EXPR, boolean_type_node, rcs.frac, zero);
2469 cond = build (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
2470 tmp = build (COND_EXPR, masktype, cond,
2471 convert (masktype, integer_zero_node), tmp);
2473 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2477 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
2480 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
2484 args = gfc_conv_intrinsic_function_args (se, expr);
2485 args = TREE_VALUE (args);
2486 args = gfc_build_addr_expr (NULL, args);
2487 args = tree_cons (NULL_TREE, args, NULL_TREE);
2488 se->expr = gfc_build_function_call (gfor_fndecl_si_kind, args);
2491 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
2494 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
2496 gfc_actual_arglist *actual;
2501 for (actual = expr->value.function.actual; actual; actual = actual->next)
2503 gfc_init_se (&argse, se);
2505 /* Pass a NULL pointer for an absent arg. */
2506 if (actual->expr == NULL)
2507 argse.expr = null_pointer_node;
2509 gfc_conv_expr_reference (&argse, actual->expr);
2511 gfc_add_block_to_block (&se->pre, &argse.pre);
2512 gfc_add_block_to_block (&se->post, &argse.post);
2513 args = gfc_chainon_list (args, argse.expr);
2515 se->expr = gfc_build_function_call (gfor_fndecl_sr_kind, args);
2519 /* Generate code for TRIM (A) intrinsic function. */
2522 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
2532 arglist = NULL_TREE;
2534 type = build_pointer_type (gfc_character1_type_node);
2535 var = gfc_create_var (type, "pstr");
2536 addr = gfc_build_addr_expr (ppvoid_type_node, var);
2537 len = gfc_create_var (gfc_int4_type_node, "len");
2539 tmp = gfc_conv_intrinsic_function_args (se, expr);
2540 arglist = gfc_chainon_list (arglist, gfc_build_addr_expr (NULL, len));
2541 arglist = gfc_chainon_list (arglist, addr);
2542 arglist = chainon (arglist, tmp);
2544 tmp = gfc_build_function_call (gfor_fndecl_string_trim, arglist);
2545 gfc_add_expr_to_block (&se->pre, tmp);
2547 /* Free the temporary afterwards, if necessary. */
2548 cond = build (GT_EXPR, boolean_type_node, len,
2549 convert (TREE_TYPE (len), integer_zero_node));
2550 arglist = gfc_chainon_list (NULL_TREE, var);
2551 tmp = gfc_build_function_call (gfor_fndecl_internal_free, arglist);
2552 tmp = build_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2553 gfc_add_expr_to_block (&se->post, tmp);
2556 se->string_length = len;
2560 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
2563 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
2573 args = gfc_conv_intrinsic_function_args (se, expr);
2574 len = TREE_VALUE (args);
2575 tmp = gfc_advance_chain (args, 2);
2576 ncopies = TREE_VALUE (tmp);
2577 len = fold (build (MULT_EXPR, gfc_int4_type_node, len, ncopies));
2578 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
2579 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
2581 arglist = NULL_TREE;
2582 arglist = gfc_chainon_list (arglist, var);
2583 arglist = chainon (arglist, args);
2584 tmp = gfc_build_function_call (gfor_fndecl_string_repeat, arglist);
2585 gfc_add_expr_to_block (&se->pre, tmp);
2588 se->string_length = len;
2592 /* Generate code for the IARGC intrinsic. If args_only is true this is
2593 actually the COMMAND_ARGUMENT_COUNT intrinsic, so return IARGC - 1. */
2596 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr, bool args_only)
2602 /* Call the library function. This always returns an INTEGER(4). */
2603 fndecl = gfor_fndecl_iargc;
2604 tmp = gfc_build_function_call (fndecl, NULL_TREE);
2606 /* Convert it to the required type. */
2607 type = gfc_typenode_for_spec (&expr->ts);
2608 tmp = fold_convert (type, tmp);
2611 tmp = build (MINUS_EXPR, type, tmp, convert (type, integer_one_node));
2615 /* Generate code for an intrinsic function. Some map directly to library
2616 calls, others get special handling. In some cases the name of the function
2617 used depends on the type specifiers. */
2620 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
2622 gfc_intrinsic_sym *isym;
2626 isym = expr->value.function.isym;
2628 name = &expr->value.function.name[2];
2632 lib = gfc_is_intrinsic_libcall (expr);
2636 se->ignore_optional = 1;
2637 gfc_conv_intrinsic_funcall (se, expr);
2642 switch (expr->value.function.isym->generic_id)
2647 case GFC_ISYM_REPEAT:
2648 gfc_conv_intrinsic_repeat (se, expr);
2652 gfc_conv_intrinsic_trim (se, expr);
2655 case GFC_ISYM_SI_KIND:
2656 gfc_conv_intrinsic_si_kind (se, expr);
2659 case GFC_ISYM_SR_KIND:
2660 gfc_conv_intrinsic_sr_kind (se, expr);
2663 case GFC_ISYM_EXPONENT:
2664 gfc_conv_intrinsic_exponent (se, expr);
2667 case GFC_ISYM_SPACING:
2668 gfc_conv_intrinsic_spacing (se, expr);
2671 case GFC_ISYM_RRSPACING:
2672 gfc_conv_intrinsic_rrspacing (se, expr);
2676 gfc_conv_intrinsic_scan (se, expr);
2679 case GFC_ISYM_VERIFY:
2680 gfc_conv_intrinsic_verify (se, expr);
2683 case GFC_ISYM_ALLOCATED:
2684 gfc_conv_allocated (se, expr);
2687 case GFC_ISYM_ASSOCIATED:
2688 gfc_conv_associated(se, expr);
2692 gfc_conv_intrinsic_abs (se, expr);
2695 case GFC_ISYM_ADJUSTL:
2696 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
2699 case GFC_ISYM_ADJUSTR:
2700 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
2703 case GFC_ISYM_AIMAG:
2704 gfc_conv_intrinsic_imagpart (se, expr);
2708 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
2712 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
2715 case GFC_ISYM_ANINT:
2716 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
2720 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
2723 case GFC_ISYM_BTEST:
2724 gfc_conv_intrinsic_btest (se, expr);
2727 case GFC_ISYM_ACHAR:
2729 gfc_conv_intrinsic_char (se, expr);
2732 case GFC_ISYM_CONVERSION:
2734 case GFC_ISYM_LOGICAL:
2736 gfc_conv_intrinsic_conversion (se, expr);
2739 /* Integer conversions are handled seperately to make sure we get the
2740 correct rounding mode. */
2742 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
2746 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
2749 case GFC_ISYM_CEILING:
2750 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
2753 case GFC_ISYM_FLOOR:
2754 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
2758 gfc_conv_intrinsic_mod (se, expr, 0);
2761 case GFC_ISYM_MODULO:
2762 gfc_conv_intrinsic_mod (se, expr, 1);
2765 case GFC_ISYM_CMPLX:
2766 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
2769 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
2770 gfc_conv_intrinsic_iargc (se, expr, TRUE);
2773 case GFC_ISYM_CONJG:
2774 gfc_conv_intrinsic_conjg (se, expr);
2777 case GFC_ISYM_COUNT:
2778 gfc_conv_intrinsic_count (se, expr);
2782 gfc_conv_intrinsic_dim (se, expr);
2785 case GFC_ISYM_DPROD:
2786 gfc_conv_intrinsic_dprod (se, expr);
2790 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
2793 case GFC_ISYM_IBCLR:
2794 gfc_conv_intrinsic_singlebitop (se, expr, 0);
2797 case GFC_ISYM_IBITS:
2798 gfc_conv_intrinsic_ibits (se, expr);
2801 case GFC_ISYM_IBSET:
2802 gfc_conv_intrinsic_singlebitop (se, expr, 1);
2805 case GFC_ISYM_IACHAR:
2806 case GFC_ISYM_ICHAR:
2807 /* We assume ASCII character sequence. */
2808 gfc_conv_intrinsic_ichar (se, expr);
2811 case GFC_ISYM_IARGC:
2812 gfc_conv_intrinsic_iargc (se, expr, FALSE);
2816 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
2819 case GFC_ISYM_INDEX:
2820 gfc_conv_intrinsic_index (se, expr);
2824 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
2827 case GFC_ISYM_ISHFT:
2828 gfc_conv_intrinsic_ishft (se, expr);
2831 case GFC_ISYM_ISHFTC:
2832 gfc_conv_intrinsic_ishftc (se, expr);
2835 case GFC_ISYM_LBOUND:
2836 gfc_conv_intrinsic_bound (se, expr, 0);
2840 gfc_conv_intrinsic_len (se, expr);
2843 case GFC_ISYM_LEN_TRIM:
2844 gfc_conv_intrinsic_len_trim (se, expr);
2848 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
2852 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
2856 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
2860 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
2864 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
2867 case GFC_ISYM_MAXLOC:
2868 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
2871 case GFC_ISYM_MAXVAL:
2872 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
2875 case GFC_ISYM_MERGE:
2876 gfc_conv_intrinsic_merge (se, expr);
2880 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
2883 case GFC_ISYM_MINLOC:
2884 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
2887 case GFC_ISYM_MINVAL:
2888 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
2892 gfc_conv_intrinsic_not (se, expr);
2895 case GFC_ISYM_PRESENT:
2896 gfc_conv_intrinsic_present (se, expr);
2899 case GFC_ISYM_PRODUCT:
2900 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
2904 gfc_conv_intrinsic_sign (se, expr);
2908 gfc_conv_intrinsic_size (se, expr);
2912 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
2915 case GFC_ISYM_TRANSFER:
2916 gfc_conv_intrinsic_transfer (se, expr);
2919 case GFC_ISYM_UBOUND:
2920 gfc_conv_intrinsic_bound (se, expr, 1);
2923 case GFC_ISYM_DOT_PRODUCT:
2924 case GFC_ISYM_MATMUL:
2925 case GFC_ISYM_IRAND:
2927 case GFC_ISYM_ETIME:
2928 case GFC_ISYM_SECOND:
2929 gfc_conv_intrinsic_funcall (se, expr);
2933 gfc_conv_intrinsic_lib_function (se, expr);
2939 /* This generates code to execute before entering the scalarization loop.
2940 Currently does nothing. */
2943 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
2945 switch (ss->expr->value.function.isym->generic_id)
2947 case GFC_ISYM_UBOUND:
2948 case GFC_ISYM_LBOUND:
2958 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
2959 inside the scalarization loop. */
2962 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
2966 /* The two argument version returns a scalar. */
2967 if (expr->value.function.actual->next->expr)
2970 newss = gfc_get_ss ();
2971 newss->type = GFC_SS_INTRINSIC;
2979 /* Walk an intrinsic array libcall. */
2982 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
2986 assert (expr->rank > 0);
2988 newss = gfc_get_ss ();
2989 newss->type = GFC_SS_FUNCTION;
2992 newss->data.info.dimen = expr->rank;
2998 /* Returns nonzero if the specified intrinsic function call maps directly to a
2999 an external library call. Should only be used for functions that return
3003 gfc_is_intrinsic_libcall (gfc_expr * expr)
3005 assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3006 assert (expr->rank > 0);
3008 switch (expr->value.function.isym->generic_id)
3012 case GFC_ISYM_COUNT:
3013 case GFC_ISYM_MATMUL:
3014 case GFC_ISYM_MAXLOC:
3015 case GFC_ISYM_MAXVAL:
3016 case GFC_ISYM_MINLOC:
3017 case GFC_ISYM_MINVAL:
3018 case GFC_ISYM_PRODUCT:
3020 case GFC_ISYM_SHAPE:
3021 case GFC_ISYM_SPREAD:
3022 case GFC_ISYM_TRANSPOSE:
3023 /* Ignore absent optional parameters. */
3026 case GFC_ISYM_RESHAPE:
3027 case GFC_ISYM_CSHIFT:
3028 case GFC_ISYM_EOSHIFT:
3030 case GFC_ISYM_UNPACK:
3031 /* Pass absent optional parameters. */
3039 /* Walk an intrinsic function. */
3041 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3042 gfc_intrinsic_sym * isym)
3046 if (isym->elemental)
3047 return gfc_walk_elemental_function_args (ss, expr, GFC_SS_SCALAR);
3049 if (expr->rank == 0)
3052 if (gfc_is_intrinsic_libcall (expr))
3053 return gfc_walk_intrinsic_libfunc (ss, expr);
3055 /* Special cases. */
3056 switch (isym->generic_id)
3058 case GFC_ISYM_LBOUND:
3059 case GFC_ISYM_UBOUND:
3060 return gfc_walk_intrinsic_bound (ss, expr);
3063 /* This probably meant someone forgot to add an intrinsic to the above
3064 list(s) when they implemented it, or something's gone horribly wrong.
3066 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3067 expr->value.function.name);
3071 #include "gt-fortran-trans-intrinsic.h"