1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
32 #include "tree-gimple.h"
36 #include "intrinsic.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43 #include "trans-stmt.h"
45 /* This maps fortran intrinsic math functions to external library or GCC
47 typedef struct gfc_intrinsic_map_t GTY(())
49 /* The explicit enum is required to work around inadequacies in the
50 garbage collection/gengtype parsing mechanism. */
51 enum gfc_generic_isym_id id;
53 /* Enum value from the "language-independent", aka C-centric, part
54 of gcc, or END_BUILTINS of no such value set. */
55 /* ??? There are now complex variants in builtins.def, though we
56 don't currently do anything with them. */
57 enum built_in_function code4;
58 enum built_in_function code8;
60 /* True if the naming pattern is to prepend "c" for complex and
61 append "f" for kind=4. False if the naming pattern is to
62 prepend "_gfortran_" and append "[rc][48]". */
65 /* True if a complex version of the function exists. */
66 bool complex_available;
68 /* True if the function should be marked const. */
71 /* The base library name of this function. */
74 /* Cache decls created for the various operand types. */
82 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
83 defines complex variants of all of the entries in mathbuiltins.def
85 #define BUILT_IN_FUNCTION(ID, NAME, HAVE_COMPLEX) \
86 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, true, \
87 HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
89 #define DEFINE_MATH_BUILTIN(id, name, argtype) \
90 BUILT_IN_FUNCTION (id, name, false)
92 /* TODO: Use builtin function for complex intrinsics. */
93 #define DEFINE_MATH_BUILTIN_C(id, name, argtype) \
94 BUILT_IN_FUNCTION (id, name, true)
96 #define LIBM_FUNCTION(ID, NAME, HAVE_COMPLEX) \
97 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, true, HAVE_COMPLEX, true, \
98 NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
100 #define LIBF_FUNCTION(ID, NAME, HAVE_COMPLEX) \
101 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, false, HAVE_COMPLEX, true, \
102 NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
104 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
106 /* Functions built into gcc itself. */
107 #include "mathbuiltins.def"
109 /* Functions in libm. */
110 /* ??? This does exist as BUILT_IN_SCALBN, but doesn't quite fit the
111 pattern for other mathbuiltins.def entries. At present we have no
112 optimizations for this in the common sources. */
113 LIBM_FUNCTION (SCALE, "scalbn", false),
115 /* Functions in libgfortran. */
116 LIBF_FUNCTION (FRACTION, "fraction", false),
117 LIBF_FUNCTION (NEAREST, "nearest", false),
118 LIBF_FUNCTION (SET_EXPONENT, "set_exponent", false),
121 LIBF_FUNCTION (NONE, NULL, false)
123 #undef DEFINE_MATH_BUILTIN
124 #undef DEFINE_MATH_BUILTIN_C
125 #undef BUILT_IN_FUNCTION
129 /* Structure for storing components of a floating number to be used by
130 elemental functions to manipulate reals. */
133 tree arg; /* Variable tree to view convert to integer. */
134 tree expn; /* Variable tree to save exponent. */
135 tree frac; /* Variable tree to save fraction. */
136 tree smask; /* Constant tree of sign's mask. */
137 tree emask; /* Constant tree of exponent's mask. */
138 tree fmask; /* Constant tree of fraction's mask. */
139 tree edigits; /* Constant tree of the number of exponent bits. */
140 tree fdigits; /* Constant tree of the number of fraction bits. */
141 tree f1; /* Constant tree of the f1 defined in the real model. */
142 tree bias; /* Constant tree of the bias of exponent in the memory. */
143 tree type; /* Type tree of arg1. */
144 tree mtype; /* Type tree of integer type. Kind is that of arg1. */
149 /* Evaluate the arguments to an intrinsic function. */
152 gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
154 gfc_actual_arglist *actual;
159 for (actual = expr->value.function.actual; actual; actual = actual->next)
161 /* Skip omitted optional arguments. */
165 /* Evaluate the parameter. This will substitute scalarized
166 references automatically. */
167 gfc_init_se (&argse, se);
169 if (actual->expr->ts.type == BT_CHARACTER)
171 gfc_conv_expr (&argse, actual->expr);
172 gfc_conv_string_parameter (&argse);
173 args = gfc_chainon_list (args, argse.string_length);
176 gfc_conv_expr_val (&argse, actual->expr);
178 gfc_add_block_to_block (&se->pre, &argse.pre);
179 gfc_add_block_to_block (&se->post, &argse.post);
180 args = gfc_chainon_list (args, argse.expr);
186 /* Conversions between different types are output by the frontend as
187 intrinsic functions. We implement these directly with inline code. */
190 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
195 /* Evaluate the argument. */
196 type = gfc_typenode_for_spec (&expr->ts);
197 gcc_assert (expr->value.function.actual->expr);
198 arg = gfc_conv_intrinsic_function_args (se, expr);
199 arg = TREE_VALUE (arg);
201 /* Conversion from complex to non-complex involves taking the real
202 component of the value. */
203 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
204 && expr->ts.type != BT_COMPLEX)
208 artype = TREE_TYPE (TREE_TYPE (arg));
209 arg = build1 (REALPART_EXPR, artype, arg);
212 se->expr = convert (type, arg);
215 /* This is needed because the gcc backend only implements
216 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
217 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
218 Similarly for CEILING. */
221 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
228 argtype = TREE_TYPE (arg);
229 arg = gfc_evaluate_now (arg, pblock);
231 intval = convert (type, arg);
232 intval = gfc_evaluate_now (intval, pblock);
234 tmp = convert (argtype, intval);
235 cond = build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
237 tmp = build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
238 build_int_cst (type, 1));
239 tmp = build3 (COND_EXPR, type, cond, intval, tmp);
244 /* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
245 NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)). */
248 build_round_expr (stmtblock_t * pblock, tree arg, tree type)
257 argtype = TREE_TYPE (arg);
258 arg = gfc_evaluate_now (arg, pblock);
260 real_from_string (&r, "0.5");
261 pos = build_real (argtype, r);
263 real_from_string (&r, "-0.5");
264 neg = build_real (argtype, r);
266 tmp = gfc_build_const (argtype, integer_zero_node);
267 cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
269 tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
270 tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
271 return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
275 /* Convert a real to an integer using a specific rounding mode.
276 Ideally we would just build the corresponding GENERIC node,
277 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
280 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
286 return build_fixbound_expr (pblock, arg, type, 0);
290 return build_fixbound_expr (pblock, arg, type, 1);
294 return build_round_expr (pblock, arg, type);
297 return build1 (op, type, arg);
302 /* Round a real value using the specified rounding mode.
303 We use a temporary integer of that same kind size as the result.
304 Values larger than those that can be represented by this kind are
305 unchanged, as thay will not be accurate enough to represent the
307 huge = HUGE (KIND (a))
308 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
312 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum tree_code op)
323 kind = expr->ts.kind;
326 /* We have builtin functions for some cases. */
359 /* Evaluate the argument. */
360 gcc_assert (expr->value.function.actual->expr);
361 arg = gfc_conv_intrinsic_function_args (se, expr);
363 /* Use a builtin function if one exists. */
364 if (n != END_BUILTINS)
366 tmp = built_in_decls[n];
367 se->expr = gfc_build_function_call (tmp, arg);
371 /* This code is probably redundant, but we'll keep it lying around just
373 type = gfc_typenode_for_spec (&expr->ts);
374 arg = TREE_VALUE (arg);
375 arg = gfc_evaluate_now (arg, &se->pre);
377 /* Test if the value is too large to handle sensibly. */
378 gfc_set_model_kind (kind);
380 n = gfc_validate_kind (BT_INTEGER, kind, false);
381 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
382 tmp = gfc_conv_mpfr_to_tree (huge, kind);
383 cond = build2 (LT_EXPR, boolean_type_node, arg, tmp);
385 mpfr_neg (huge, huge, GFC_RND_MODE);
386 tmp = gfc_conv_mpfr_to_tree (huge, kind);
387 tmp = build2 (GT_EXPR, boolean_type_node, arg, tmp);
388 cond = build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
389 itype = gfc_get_int_type (kind);
391 tmp = build_fix_expr (&se->pre, arg, itype, op);
392 tmp = convert (type, tmp);
393 se->expr = build3 (COND_EXPR, type, cond, tmp, arg);
398 /* Convert to an integer using the specified rounding mode. */
401 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, int op)
406 /* Evaluate the argument. */
407 type = gfc_typenode_for_spec (&expr->ts);
408 gcc_assert (expr->value.function.actual->expr);
409 arg = gfc_conv_intrinsic_function_args (se, expr);
410 arg = TREE_VALUE (arg);
412 if (TREE_CODE (TREE_TYPE (arg)) == INTEGER_TYPE)
414 /* Conversion to a different integer kind. */
415 se->expr = convert (type, arg);
419 /* Conversion from complex to non-complex involves taking the real
420 component of the value. */
421 if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE
422 && expr->ts.type != BT_COMPLEX)
426 artype = TREE_TYPE (TREE_TYPE (arg));
427 arg = build1 (REALPART_EXPR, artype, arg);
430 se->expr = build_fix_expr (&se->pre, arg, type, op);
435 /* Get the imaginary component of a value. */
438 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
442 arg = gfc_conv_intrinsic_function_args (se, expr);
443 arg = TREE_VALUE (arg);
444 se->expr = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
448 /* Get the complex conjugate of a value. */
451 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
455 arg = gfc_conv_intrinsic_function_args (se, expr);
456 arg = TREE_VALUE (arg);
457 se->expr = build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
461 /* Initialize function decls for library functions. The external functions
462 are created as required. Builtin functions are added here. */
465 gfc_build_intrinsic_lib_fndecls (void)
467 gfc_intrinsic_map_t *m;
469 /* Add GCC builtin functions. */
470 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
472 if (m->code4 != END_BUILTINS)
473 m->real4_decl = built_in_decls[m->code4];
474 if (m->code8 != END_BUILTINS)
475 m->real8_decl = built_in_decls[m->code8];
480 /* Create a fndecl for a simple intrinsic library function. */
483 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
488 gfc_actual_arglist *actual;
491 char name[GFC_MAX_SYMBOL_LEN + 3];
494 if (ts->type == BT_REAL)
499 pdecl = &m->real4_decl;
502 pdecl = &m->real8_decl;
508 else if (ts->type == BT_COMPLEX)
510 gcc_assert (m->complex_available);
515 pdecl = &m->complex4_decl;
518 pdecl = &m->complex8_decl;
532 gcc_assert (ts->kind == 4 || ts->kind == 8);
533 snprintf (name, sizeof (name), "%s%s%s",
534 ts->type == BT_COMPLEX ? "c" : "",
536 ts->kind == 4 ? "f" : "");
540 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
541 ts->type == BT_COMPLEX ? 'c' : 'r',
545 argtypes = NULL_TREE;
546 for (actual = expr->value.function.actual; actual; actual = actual->next)
548 type = gfc_typenode_for_spec (&actual->expr->ts);
549 argtypes = gfc_chainon_list (argtypes, type);
551 argtypes = gfc_chainon_list (argtypes, void_type_node);
552 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
553 fndecl = build_decl (FUNCTION_DECL, get_identifier (name), type);
555 /* Mark the decl as external. */
556 DECL_EXTERNAL (fndecl) = 1;
557 TREE_PUBLIC (fndecl) = 1;
559 /* Mark it __attribute__((const)), if possible. */
560 TREE_READONLY (fndecl) = m->is_constant;
562 rest_of_decl_compilation (fndecl, 1, 0);
569 /* Convert an intrinsic function into an external or builtin call. */
572 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
574 gfc_intrinsic_map_t *m;
577 gfc_generic_isym_id id;
579 id = expr->value.function.isym->generic_id;
580 /* Find the entry for this function. */
581 for (m = gfc_intrinsic_map; m->id != GFC_ISYM_NONE; m++)
587 if (m->id == GFC_ISYM_NONE)
589 internal_error ("Intrinsic function %s(%d) not recognized",
590 expr->value.function.name, id);
593 /* Get the decl and generate the call. */
594 args = gfc_conv_intrinsic_function_args (se, expr);
595 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
596 se->expr = gfc_build_function_call (fndecl, args);
599 /* Generate code for EXPONENT(X) intrinsic function. */
602 gfc_conv_intrinsic_exponent (gfc_se * se, gfc_expr * expr)
607 args = gfc_conv_intrinsic_function_args (se, expr);
609 a1 = expr->value.function.actual->expr;
613 fndecl = gfor_fndecl_math_exponent4;
616 fndecl = gfor_fndecl_math_exponent8;
622 se->expr = gfc_build_function_call (fndecl, args);
625 /* Evaluate a single upper or lower bound. */
626 /* TODO: bound intrinsic generates way too much unnecessary code. */
629 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
631 gfc_actual_arglist *arg;
632 gfc_actual_arglist *arg2;
642 arg = expr->value.function.actual;
647 /* Create an implicit second parameter from the loop variable. */
648 gcc_assert (!arg2->expr);
649 gcc_assert (se->loop->dimen == 1);
650 gcc_assert (se->ss->expr == expr);
651 gfc_advance_se_ss_chain (se);
652 bound = se->loop->loopvar[0];
653 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
658 /* use the passed argument. */
659 gcc_assert (arg->next->expr);
660 gfc_init_se (&argse, NULL);
661 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
662 gfc_add_block_to_block (&se->pre, &argse.pre);
664 /* Convert from one based to zero based. */
665 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
669 /* TODO: don't re-evaluate the descriptor on each iteration. */
670 /* Get a descriptor for the first parameter. */
671 ss = gfc_walk_expr (arg->expr);
672 gcc_assert (ss != gfc_ss_terminator);
673 gfc_init_se (&argse, NULL);
674 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
675 gfc_add_block_to_block (&se->pre, &argse.pre);
676 gfc_add_block_to_block (&se->post, &argse.post);
680 if (INTEGER_CST_P (bound))
682 gcc_assert (TREE_INT_CST_HIGH (bound) == 0);
683 i = TREE_INT_CST_LOW (bound);
684 gcc_assert (i >= 0 && i < GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)));
688 if (flag_bounds_check)
690 bound = gfc_evaluate_now (bound, &se->pre);
691 cond = fold_build2 (LT_EXPR, boolean_type_node,
692 bound, build_int_cst (TREE_TYPE (bound), 0));
693 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
694 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
695 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
696 gfc_trans_runtime_check (cond, gfc_strconst_fault, &se->pre);
701 se->expr = gfc_conv_descriptor_ubound(desc, bound);
703 se->expr = gfc_conv_descriptor_lbound(desc, bound);
705 type = gfc_typenode_for_spec (&expr->ts);
706 se->expr = convert (type, se->expr);
711 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
717 args = gfc_conv_intrinsic_function_args (se, expr);
718 gcc_assert (args && TREE_CHAIN (args) == NULL_TREE);
719 val = TREE_VALUE (args);
721 switch (expr->value.function.actual->expr->ts.type)
725 se->expr = build1 (ABS_EXPR, TREE_TYPE (val), val);
729 switch (expr->ts.kind)
740 se->expr = fold (gfc_build_function_call (built_in_decls[n], args));
749 /* Create a complex value from one or two real components. */
752 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
759 type = gfc_typenode_for_spec (&expr->ts);
760 arg = gfc_conv_intrinsic_function_args (se, expr);
761 real = convert (TREE_TYPE (type), TREE_VALUE (arg));
763 imag = convert (TREE_TYPE (type), TREE_VALUE (TREE_CHAIN (arg)));
764 else if (TREE_CODE (TREE_TYPE (TREE_VALUE (arg))) == COMPLEX_TYPE)
766 arg = TREE_VALUE (arg);
767 imag = build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
768 imag = convert (TREE_TYPE (type), imag);
771 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
773 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
776 /* Remainder function MOD(A, P) = A - INT(A / P) * P
777 MODULO(A, P) = A - FLOOR (A / P) * P */
778 /* TODO: MOD(x, 0) */
781 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
793 arg = gfc_conv_intrinsic_function_args (se, expr);
794 arg2 = TREE_VALUE (TREE_CHAIN (arg));
795 arg = TREE_VALUE (arg);
796 type = TREE_TYPE (arg);
798 switch (expr->ts.type)
801 /* Integer case is easy, we've got a builtin op. */
803 se->expr = build2 (FLOOR_MOD_EXPR, type, arg, arg2);
805 se->expr = build2 (TRUNC_MOD_EXPR, type, arg, arg2);
809 /* Real values we have to do the hard way. */
810 arg = gfc_evaluate_now (arg, &se->pre);
811 arg2 = gfc_evaluate_now (arg2, &se->pre);
813 tmp = build2 (RDIV_EXPR, type, arg, arg2);
814 /* Test if the value is too large to handle sensibly. */
815 gfc_set_model_kind (expr->ts.kind);
817 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, false);
818 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
819 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
820 test2 = build2 (LT_EXPR, boolean_type_node, tmp, test);
822 mpfr_neg (huge, huge, GFC_RND_MODE);
823 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind);
824 test = build2 (GT_EXPR, boolean_type_node, tmp, test);
825 test2 = build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
827 itype = gfc_get_int_type (expr->ts.kind);
829 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_FLOOR_EXPR);
831 tmp = build_fix_expr (&se->pre, tmp, itype, FIX_TRUNC_EXPR);
832 tmp = convert (type, tmp);
833 tmp = build3 (COND_EXPR, type, test2, tmp, arg);
834 tmp = build2 (MULT_EXPR, type, tmp, arg2);
835 se->expr = build2 (MINUS_EXPR, type, arg, tmp);
844 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
847 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
856 arg = gfc_conv_intrinsic_function_args (se, expr);
857 arg2 = TREE_VALUE (TREE_CHAIN (arg));
858 arg = TREE_VALUE (arg);
859 type = TREE_TYPE (arg);
861 val = build2 (MINUS_EXPR, type, arg, arg2);
862 val = gfc_evaluate_now (val, &se->pre);
864 zero = gfc_build_const (type, integer_zero_node);
865 tmp = build2 (LE_EXPR, boolean_type_node, val, zero);
866 se->expr = build3 (COND_EXPR, type, tmp, zero, val);
870 /* SIGN(A, B) is absolute value of A times sign of B.
871 The real value versions use library functions to ensure the correct
872 handling of negative zero. Integer case implemented as:
873 SIGN(A, B) = ((a >= 0) .xor. (b >= 0)) ? a : -a
877 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
888 arg = gfc_conv_intrinsic_function_args (se, expr);
889 if (expr->ts.type == BT_REAL)
891 switch (expr->ts.kind)
894 tmp = built_in_decls[BUILT_IN_COPYSIGNF];
897 tmp = built_in_decls[BUILT_IN_COPYSIGN];
902 se->expr = fold (gfc_build_function_call (tmp, arg));
906 arg2 = TREE_VALUE (TREE_CHAIN (arg));
907 arg = TREE_VALUE (arg);
908 type = TREE_TYPE (arg);
909 zero = gfc_build_const (type, integer_zero_node);
911 testa = fold_build2 (GE_EXPR, boolean_type_node, arg, zero);
912 testb = fold_build2 (GE_EXPR, boolean_type_node, arg2, zero);
913 tmp = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, testa, testb);
914 se->expr = fold_build3 (COND_EXPR, type, tmp,
915 build1 (NEGATE_EXPR, type, arg), arg);
919 /* Test for the presence of an optional argument. */
922 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
926 arg = expr->value.function.actual->expr;
927 gcc_assert (arg->expr_type == EXPR_VARIABLE);
928 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
929 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
933 /* Calculate the double precision product of two single precision values. */
936 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
942 arg = gfc_conv_intrinsic_function_args (se, expr);
943 arg2 = TREE_VALUE (TREE_CHAIN (arg));
944 arg = TREE_VALUE (arg);
946 /* Convert the args to double precision before multiplying. */
947 type = gfc_typenode_for_spec (&expr->ts);
948 arg = convert (type, arg);
949 arg2 = convert (type, arg2);
950 se->expr = build2 (MULT_EXPR, type, arg, arg2);
954 /* Return a length one character string containing an ascii character. */
957 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
963 arg = gfc_conv_intrinsic_function_args (se, expr);
964 arg = TREE_VALUE (arg);
966 /* We currently don't support character types != 1. */
967 gcc_assert (expr->ts.kind == 1);
968 type = gfc_character1_type_node;
969 var = gfc_create_var (type, "char");
971 arg = convert (type, arg);
972 gfc_add_modify_expr (&se->pre, var, arg);
973 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
974 se->string_length = integer_one_node;
978 /* Get the minimum/maximum value of all the parameters.
979 minmax (a1, a2, a3, ...)
992 /* TODO: Mismatching types can occur when specific names are used.
993 These should be handled during resolution. */
995 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
1006 arg = gfc_conv_intrinsic_function_args (se, expr);
1007 type = gfc_typenode_for_spec (&expr->ts);
1009 limit = TREE_VALUE (arg);
1010 if (TREE_TYPE (limit) != type)
1011 limit = convert (type, limit);
1012 /* Only evaluate the argument once. */
1013 if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
1014 limit = gfc_evaluate_now(limit, &se->pre);
1016 mvar = gfc_create_var (type, "M");
1017 elsecase = build2_v (MODIFY_EXPR, mvar, limit);
1018 for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
1020 val = TREE_VALUE (arg);
1021 if (TREE_TYPE (val) != type)
1022 val = convert (type, val);
1024 /* Only evaluate the argument once. */
1025 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1026 val = gfc_evaluate_now(val, &se->pre);
1028 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1030 tmp = build2 (op, boolean_type_node, val, limit);
1031 tmp = build3_v (COND_EXPR, tmp, thencase, elsecase);
1032 gfc_add_expr_to_block (&se->pre, tmp);
1033 elsecase = build_empty_stmt ();
1040 /* Create a symbol node for this intrinsic. The symbol from the frontend
1041 has the generic name. */
1044 gfc_get_symbol_for_expr (gfc_expr * expr)
1048 /* TODO: Add symbols for intrinsic function to the global namespace. */
1049 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1050 sym = gfc_new_symbol (expr->value.function.name, NULL);
1053 sym->attr.external = 1;
1054 sym->attr.function = 1;
1055 sym->attr.always_explicit = 1;
1056 sym->attr.proc = PROC_INTRINSIC;
1057 sym->attr.flavor = FL_PROCEDURE;
1061 sym->attr.dimension = 1;
1062 sym->as = gfc_get_array_spec ();
1063 sym->as->type = AS_ASSUMED_SHAPE;
1064 sym->as->rank = expr->rank;
1067 /* TODO: proper argument lists for external intrinsics. */
1071 /* Generate a call to an external intrinsic function. */
1073 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1077 gcc_assert (!se->ss || se->ss->expr == expr);
1080 gcc_assert (expr->rank > 0);
1082 gcc_assert (expr->rank == 0);
1084 sym = gfc_get_symbol_for_expr (expr);
1085 gfc_conv_function_call (se, sym, expr->value.function.actual);
1089 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1109 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, int op)
1118 gfc_actual_arglist *actual;
1125 gfc_conv_intrinsic_funcall (se, expr);
1129 actual = expr->value.function.actual;
1130 type = gfc_typenode_for_spec (&expr->ts);
1131 /* Initialize the result. */
1132 resvar = gfc_create_var (type, "test");
1134 tmp = convert (type, boolean_true_node);
1136 tmp = convert (type, boolean_false_node);
1137 gfc_add_modify_expr (&se->pre, resvar, tmp);
1139 /* Walk the arguments. */
1140 arrayss = gfc_walk_expr (actual->expr);
1141 gcc_assert (arrayss != gfc_ss_terminator);
1143 /* Initialize the scalarizer. */
1144 gfc_init_loopinfo (&loop);
1145 exit_label = gfc_build_label_decl (NULL_TREE);
1146 TREE_USED (exit_label) = 1;
1147 gfc_add_ss_to_loop (&loop, arrayss);
1149 /* Initialize the loop. */
1150 gfc_conv_ss_startstride (&loop);
1151 gfc_conv_loop_setup (&loop);
1153 gfc_mark_ss_chain_used (arrayss, 1);
1154 /* Generate the loop body. */
1155 gfc_start_scalarized_body (&loop, &body);
1157 /* If the condition matches then set the return value. */
1158 gfc_start_block (&block);
1160 tmp = convert (type, boolean_false_node);
1162 tmp = convert (type, boolean_true_node);
1163 gfc_add_modify_expr (&block, resvar, tmp);
1165 /* And break out of the loop. */
1166 tmp = build1_v (GOTO_EXPR, exit_label);
1167 gfc_add_expr_to_block (&block, tmp);
1169 found = gfc_finish_block (&block);
1171 /* Check this element. */
1172 gfc_init_se (&arrayse, NULL);
1173 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1174 arrayse.ss = arrayss;
1175 gfc_conv_expr_val (&arrayse, actual->expr);
1177 gfc_add_block_to_block (&body, &arrayse.pre);
1178 tmp = build2 (op, boolean_type_node, arrayse.expr,
1179 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1180 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt ());
1181 gfc_add_expr_to_block (&body, tmp);
1182 gfc_add_block_to_block (&body, &arrayse.post);
1184 gfc_trans_scalarizing_loops (&loop, &body);
1186 /* Add the exit label. */
1187 tmp = build1_v (LABEL_EXPR, exit_label);
1188 gfc_add_expr_to_block (&loop.pre, tmp);
1190 gfc_add_block_to_block (&se->pre, &loop.pre);
1191 gfc_add_block_to_block (&se->pre, &loop.post);
1192 gfc_cleanup_loop (&loop);
1197 /* COUNT(A) = Number of true elements in A. */
1199 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1206 gfc_actual_arglist *actual;
1212 gfc_conv_intrinsic_funcall (se, expr);
1216 actual = expr->value.function.actual;
1218 type = gfc_typenode_for_spec (&expr->ts);
1219 /* Initialize the result. */
1220 resvar = gfc_create_var (type, "count");
1221 gfc_add_modify_expr (&se->pre, resvar, build_int_cst (type, 0));
1223 /* Walk the arguments. */
1224 arrayss = gfc_walk_expr (actual->expr);
1225 gcc_assert (arrayss != gfc_ss_terminator);
1227 /* Initialize the scalarizer. */
1228 gfc_init_loopinfo (&loop);
1229 gfc_add_ss_to_loop (&loop, arrayss);
1231 /* Initialize the loop. */
1232 gfc_conv_ss_startstride (&loop);
1233 gfc_conv_loop_setup (&loop);
1235 gfc_mark_ss_chain_used (arrayss, 1);
1236 /* Generate the loop body. */
1237 gfc_start_scalarized_body (&loop, &body);
1239 tmp = build2 (PLUS_EXPR, TREE_TYPE (resvar), resvar,
1240 build_int_cst (TREE_TYPE (resvar), 1));
1241 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1243 gfc_init_se (&arrayse, NULL);
1244 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1245 arrayse.ss = arrayss;
1246 gfc_conv_expr_val (&arrayse, actual->expr);
1247 tmp = build3_v (COND_EXPR, arrayse.expr, tmp, build_empty_stmt ());
1249 gfc_add_block_to_block (&body, &arrayse.pre);
1250 gfc_add_expr_to_block (&body, tmp);
1251 gfc_add_block_to_block (&body, &arrayse.post);
1253 gfc_trans_scalarizing_loops (&loop, &body);
1255 gfc_add_block_to_block (&se->pre, &loop.pre);
1256 gfc_add_block_to_block (&se->pre, &loop.post);
1257 gfc_cleanup_loop (&loop);
1262 /* Inline implementation of the sum and product intrinsics. */
1264 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, int op)
1272 gfc_actual_arglist *actual;
1277 gfc_expr *arrayexpr;
1282 gfc_conv_intrinsic_funcall (se, expr);
1286 type = gfc_typenode_for_spec (&expr->ts);
1287 /* Initialize the result. */
1288 resvar = gfc_create_var (type, "val");
1289 if (op == PLUS_EXPR)
1290 tmp = gfc_build_const (type, integer_zero_node);
1292 tmp = gfc_build_const (type, integer_one_node);
1294 gfc_add_modify_expr (&se->pre, resvar, tmp);
1296 /* Walk the arguments. */
1297 actual = expr->value.function.actual;
1298 arrayexpr = actual->expr;
1299 arrayss = gfc_walk_expr (arrayexpr);
1300 gcc_assert (arrayss != gfc_ss_terminator);
1302 actual = actual->next->next;
1303 gcc_assert (actual);
1304 maskexpr = actual->expr;
1307 maskss = gfc_walk_expr (maskexpr);
1308 gcc_assert (maskss != gfc_ss_terminator);
1313 /* Initialize the scalarizer. */
1314 gfc_init_loopinfo (&loop);
1315 gfc_add_ss_to_loop (&loop, arrayss);
1317 gfc_add_ss_to_loop (&loop, maskss);
1319 /* Initialize the loop. */
1320 gfc_conv_ss_startstride (&loop);
1321 gfc_conv_loop_setup (&loop);
1323 gfc_mark_ss_chain_used (arrayss, 1);
1325 gfc_mark_ss_chain_used (maskss, 1);
1326 /* Generate the loop body. */
1327 gfc_start_scalarized_body (&loop, &body);
1329 /* If we have a mask, only add this element if the mask is set. */
1332 gfc_init_se (&maskse, NULL);
1333 gfc_copy_loopinfo_to_se (&maskse, &loop);
1335 gfc_conv_expr_val (&maskse, maskexpr);
1336 gfc_add_block_to_block (&body, &maskse.pre);
1338 gfc_start_block (&block);
1341 gfc_init_block (&block);
1343 /* Do the actual summation/product. */
1344 gfc_init_se (&arrayse, NULL);
1345 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1346 arrayse.ss = arrayss;
1347 gfc_conv_expr_val (&arrayse, arrayexpr);
1348 gfc_add_block_to_block (&block, &arrayse.pre);
1350 tmp = build2 (op, type, resvar, arrayse.expr);
1351 gfc_add_modify_expr (&block, resvar, tmp);
1352 gfc_add_block_to_block (&block, &arrayse.post);
1356 /* We enclose the above in if (mask) {...} . */
1357 tmp = gfc_finish_block (&block);
1359 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1362 tmp = gfc_finish_block (&block);
1363 gfc_add_expr_to_block (&body, tmp);
1365 gfc_trans_scalarizing_loops (&loop, &body);
1366 gfc_add_block_to_block (&se->pre, &loop.pre);
1367 gfc_add_block_to_block (&se->pre, &loop.post);
1368 gfc_cleanup_loop (&loop);
1374 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, int op)
1378 stmtblock_t ifblock;
1385 gfc_actual_arglist *actual;
1390 gfc_expr *arrayexpr;
1397 gfc_conv_intrinsic_funcall (se, expr);
1401 /* Initialize the result. */
1402 pos = gfc_create_var (gfc_array_index_type, "pos");
1403 type = gfc_typenode_for_spec (&expr->ts);
1405 /* Walk the arguments. */
1406 actual = expr->value.function.actual;
1407 arrayexpr = actual->expr;
1408 arrayss = gfc_walk_expr (arrayexpr);
1409 gcc_assert (arrayss != gfc_ss_terminator);
1411 actual = actual->next->next;
1412 gcc_assert (actual);
1413 maskexpr = actual->expr;
1416 maskss = gfc_walk_expr (maskexpr);
1417 gcc_assert (maskss != gfc_ss_terminator);
1422 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
1423 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
1424 switch (arrayexpr->ts.type)
1427 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, arrayexpr->ts.kind);
1431 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
1432 arrayexpr->ts.kind);
1439 /* Most negative(+HUGE) for maxval, most negative (-HUGE) for minval. */
1441 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1442 gfc_add_modify_expr (&se->pre, limit, tmp);
1444 /* Initialize the scalarizer. */
1445 gfc_init_loopinfo (&loop);
1446 gfc_add_ss_to_loop (&loop, arrayss);
1448 gfc_add_ss_to_loop (&loop, maskss);
1450 /* Initialize the loop. */
1451 gfc_conv_ss_startstride (&loop);
1452 gfc_conv_loop_setup (&loop);
1454 gcc_assert (loop.dimen == 1);
1456 /* Initialize the position to the first element. If the array has zero
1457 size we need to return zero. Otherwise use the first element of the
1458 array, in case all elements are equal to the limit.
1459 i.e. pos = (ubound >= lbound) ? lbound, lbound - 1; */
1460 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
1461 loop.from[0], gfc_index_one_node);
1462 cond = fold_build2 (GE_EXPR, boolean_type_node,
1463 loop.to[0], loop.from[0]);
1464 tmp = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
1466 gfc_add_modify_expr (&loop.pre, pos, tmp);
1468 gfc_mark_ss_chain_used (arrayss, 1);
1470 gfc_mark_ss_chain_used (maskss, 1);
1471 /* Generate the loop body. */
1472 gfc_start_scalarized_body (&loop, &body);
1474 /* If we have a mask, only check this element if the mask is set. */
1477 gfc_init_se (&maskse, NULL);
1478 gfc_copy_loopinfo_to_se (&maskse, &loop);
1480 gfc_conv_expr_val (&maskse, maskexpr);
1481 gfc_add_block_to_block (&body, &maskse.pre);
1483 gfc_start_block (&block);
1486 gfc_init_block (&block);
1488 /* Compare with the current limit. */
1489 gfc_init_se (&arrayse, NULL);
1490 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1491 arrayse.ss = arrayss;
1492 gfc_conv_expr_val (&arrayse, arrayexpr);
1493 gfc_add_block_to_block (&block, &arrayse.pre);
1495 /* We do the following if this is a more extreme value. */
1496 gfc_start_block (&ifblock);
1498 /* Assign the value to the limit... */
1499 gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
1501 /* Remember where we are. */
1502 gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
1504 ifbody = gfc_finish_block (&ifblock);
1506 /* If it is a more extreme value. */
1507 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
1508 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1509 gfc_add_expr_to_block (&block, tmp);
1513 /* We enclose the above in if (mask) {...}. */
1514 tmp = gfc_finish_block (&block);
1516 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1519 tmp = gfc_finish_block (&block);
1520 gfc_add_expr_to_block (&body, tmp);
1522 gfc_trans_scalarizing_loops (&loop, &body);
1524 gfc_add_block_to_block (&se->pre, &loop.pre);
1525 gfc_add_block_to_block (&se->pre, &loop.post);
1526 gfc_cleanup_loop (&loop);
1528 /* Return a value in the range 1..SIZE(array). */
1529 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
1530 gfc_index_one_node);
1531 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
1532 /* And convert to the required type. */
1533 se->expr = convert (type, tmp);
1537 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, int op)
1546 gfc_actual_arglist *actual;
1551 gfc_expr *arrayexpr;
1557 gfc_conv_intrinsic_funcall (se, expr);
1561 type = gfc_typenode_for_spec (&expr->ts);
1562 /* Initialize the result. */
1563 limit = gfc_create_var (type, "limit");
1564 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
1565 switch (expr->ts.type)
1568 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge, expr->ts.kind);
1572 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
1579 /* Most negative(-HUGE) for maxval, most positive (-HUGE) for minval. */
1581 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
1582 gfc_add_modify_expr (&se->pre, limit, tmp);
1584 /* Walk the arguments. */
1585 actual = expr->value.function.actual;
1586 arrayexpr = actual->expr;
1587 arrayss = gfc_walk_expr (arrayexpr);
1588 gcc_assert (arrayss != gfc_ss_terminator);
1590 actual = actual->next->next;
1591 gcc_assert (actual);
1592 maskexpr = actual->expr;
1595 maskss = gfc_walk_expr (maskexpr);
1596 gcc_assert (maskss != gfc_ss_terminator);
1601 /* Initialize the scalarizer. */
1602 gfc_init_loopinfo (&loop);
1603 gfc_add_ss_to_loop (&loop, arrayss);
1605 gfc_add_ss_to_loop (&loop, maskss);
1607 /* Initialize the loop. */
1608 gfc_conv_ss_startstride (&loop);
1609 gfc_conv_loop_setup (&loop);
1611 gfc_mark_ss_chain_used (arrayss, 1);
1613 gfc_mark_ss_chain_used (maskss, 1);
1614 /* Generate the loop body. */
1615 gfc_start_scalarized_body (&loop, &body);
1617 /* If we have a mask, only add this element if the mask is set. */
1620 gfc_init_se (&maskse, NULL);
1621 gfc_copy_loopinfo_to_se (&maskse, &loop);
1623 gfc_conv_expr_val (&maskse, maskexpr);
1624 gfc_add_block_to_block (&body, &maskse.pre);
1626 gfc_start_block (&block);
1629 gfc_init_block (&block);
1631 /* Compare with the current limit. */
1632 gfc_init_se (&arrayse, NULL);
1633 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1634 arrayse.ss = arrayss;
1635 gfc_conv_expr_val (&arrayse, arrayexpr);
1636 gfc_add_block_to_block (&block, &arrayse.pre);
1638 /* Assign the value to the limit... */
1639 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
1641 /* If it is a more extreme value. */
1642 tmp = build2 (op, boolean_type_node, arrayse.expr, limit);
1643 tmp = build3_v (COND_EXPR, tmp, ifbody, build_empty_stmt ());
1644 gfc_add_expr_to_block (&block, tmp);
1645 gfc_add_block_to_block (&block, &arrayse.post);
1647 tmp = gfc_finish_block (&block);
1649 /* We enclose the above in if (mask) {...}. */
1650 tmp = build3_v (COND_EXPR, maskse.expr, tmp, build_empty_stmt ());
1651 gfc_add_expr_to_block (&body, tmp);
1653 gfc_trans_scalarizing_loops (&loop, &body);
1655 gfc_add_block_to_block (&se->pre, &loop.pre);
1656 gfc_add_block_to_block (&se->pre, &loop.post);
1657 gfc_cleanup_loop (&loop);
1662 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
1664 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
1671 arg = gfc_conv_intrinsic_function_args (se, expr);
1672 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1673 arg = TREE_VALUE (arg);
1674 type = TREE_TYPE (arg);
1676 tmp = build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
1677 tmp = build2 (BIT_AND_EXPR, type, arg, tmp);
1678 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
1679 build_int_cst (type, 0));
1680 type = gfc_typenode_for_spec (&expr->ts);
1681 se->expr = convert (type, tmp);
1684 /* Generate code to perform the specified operation. */
1686 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, int op)
1692 arg = gfc_conv_intrinsic_function_args (se, expr);
1693 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1694 arg = TREE_VALUE (arg);
1695 type = TREE_TYPE (arg);
1697 se->expr = fold_build2 (op, type, arg, arg2);
1702 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
1706 arg = gfc_conv_intrinsic_function_args (se, expr);
1707 arg = TREE_VALUE (arg);
1709 se->expr = build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
1712 /* Set or clear a single bit. */
1714 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
1722 arg = gfc_conv_intrinsic_function_args (se, expr);
1723 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1724 arg = TREE_VALUE (arg);
1725 type = TREE_TYPE (arg);
1727 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), arg2);
1733 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
1735 se->expr = fold_build2 (op, type, arg, tmp);
1738 /* Extract a sequence of bits.
1739 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
1741 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
1750 arg = gfc_conv_intrinsic_function_args (se, expr);
1751 arg2 = TREE_CHAIN (arg);
1752 arg3 = TREE_VALUE (TREE_CHAIN (arg2));
1753 arg = TREE_VALUE (arg);
1754 arg2 = TREE_VALUE (arg2);
1755 type = TREE_TYPE (arg);
1757 mask = build_int_cst (NULL_TREE, -1);
1758 mask = build2 (LSHIFT_EXPR, type, mask, arg3);
1759 mask = build1 (BIT_NOT_EXPR, type, mask);
1761 tmp = build2 (RSHIFT_EXPR, type, arg, arg2);
1763 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
1766 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
1768 : ((shift >= 0) ? i << shift : i >> -shift)
1769 where all shifts are logical shifts. */
1771 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
1784 arg = gfc_conv_intrinsic_function_args (se, expr);
1785 arg2 = TREE_VALUE (TREE_CHAIN (arg));
1786 arg = TREE_VALUE (arg);
1787 type = TREE_TYPE (arg);
1788 utype = gfc_unsigned_type (type);
1790 width = fold_build1 (ABS_EXPR, TREE_TYPE (arg2), arg2);
1792 /* Left shift if positive. */
1793 lshift = fold_build2 (LSHIFT_EXPR, type, arg, width);
1795 /* Right shift if negative.
1796 We convert to an unsigned type because we want a logical shift.
1797 The standard doesn't define the case of shifting negative
1798 numbers, and we try to be compatible with other compilers, most
1799 notably g77, here. */
1800 rshift = fold_convert (type, build2 (RSHIFT_EXPR, utype,
1801 convert (utype, arg), width));
1803 tmp = fold_build2 (GE_EXPR, boolean_type_node, arg2,
1804 build_int_cst (TREE_TYPE (arg2), 0));
1805 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
1807 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
1808 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
1810 num_bits = build_int_cst (TREE_TYPE (arg2), TYPE_PRECISION (type));
1811 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
1813 se->expr = fold_build3 (COND_EXPR, type, cond,
1814 build_int_cst (type, 0), tmp);
1817 /* Circular shift. AKA rotate or barrel shift. */
1819 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
1830 arg = gfc_conv_intrinsic_function_args (se, expr);
1831 arg2 = TREE_CHAIN (arg);
1832 arg3 = TREE_CHAIN (arg2);
1835 /* Use a library function for the 3 parameter version. */
1836 tree int4type = gfc_get_int_type (4);
1838 type = TREE_TYPE (TREE_VALUE (arg));
1839 /* We convert the first argument to at least 4 bytes, and
1840 convert back afterwards. This removes the need for library
1841 functions for all argument sizes, and function will be
1842 aligned to at least 32 bits, so there's no loss. */
1843 if (expr->ts.kind < 4)
1845 tmp = convert (int4type, TREE_VALUE (arg));
1846 TREE_VALUE (arg) = tmp;
1848 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
1849 need loads of library functions. They cannot have values >
1850 BIT_SIZE (I) so the conversion is safe. */
1851 TREE_VALUE (arg2) = convert (int4type, TREE_VALUE (arg2));
1852 TREE_VALUE (arg3) = convert (int4type, TREE_VALUE (arg3));
1854 switch (expr->ts.kind)
1859 tmp = gfor_fndecl_math_ishftc4;
1862 tmp = gfor_fndecl_math_ishftc8;
1867 se->expr = gfc_build_function_call (tmp, arg);
1868 /* Convert the result back to the original type, if we extended
1869 the first argument's width above. */
1870 if (expr->ts.kind < 4)
1871 se->expr = convert (type, se->expr);
1875 arg = TREE_VALUE (arg);
1876 arg2 = TREE_VALUE (arg2);
1877 type = TREE_TYPE (arg);
1879 /* Rotate left if positive. */
1880 lrot = fold_build2 (LROTATE_EXPR, type, arg, arg2);
1882 /* Rotate right if negative. */
1883 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (arg2), arg2);
1884 rrot = fold_build2 (RROTATE_EXPR, type, arg, tmp);
1886 zero = build_int_cst (TREE_TYPE (arg2), 0);
1887 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg2, zero);
1888 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
1890 /* Do nothing if shift == 0. */
1891 tmp = fold_build2 (EQ_EXPR, boolean_type_node, arg2, zero);
1892 se->expr = fold_build3 (COND_EXPR, type, tmp, arg, rrot);
1895 /* The length of a character string. */
1897 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
1906 gcc_assert (!se->ss);
1908 arg = expr->value.function.actual->expr;
1910 type = gfc_typenode_for_spec (&expr->ts);
1911 switch (arg->expr_type)
1914 len = build_int_cst (NULL_TREE, arg->value.character.length);
1918 if (arg->expr_type == EXPR_VARIABLE
1919 && (arg->ref == NULL || (arg->ref->next == NULL
1920 && arg->ref->type == REF_ARRAY)))
1922 /* This doesn't catch all cases.
1923 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
1924 and the surrounding thread. */
1925 sym = arg->symtree->n.sym;
1926 decl = gfc_get_symbol_decl (sym);
1927 if (decl == current_function_decl && sym->attr.function
1928 && (sym->result == sym))
1929 decl = gfc_get_fake_result_decl (sym);
1931 len = sym->ts.cl->backend_decl;
1936 /* Anybody stupid enough to do this deserves inefficient code. */
1937 gfc_init_se (&argse, se);
1938 gfc_conv_expr (&argse, arg);
1939 gfc_add_block_to_block (&se->pre, &argse.pre);
1940 gfc_add_block_to_block (&se->post, &argse.post);
1941 len = argse.string_length;
1945 se->expr = convert (type, len);
1948 /* The length of a character string not including trailing blanks. */
1950 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
1955 args = gfc_conv_intrinsic_function_args (se, expr);
1956 type = gfc_typenode_for_spec (&expr->ts);
1957 se->expr = gfc_build_function_call (gfor_fndecl_string_len_trim, args);
1958 se->expr = convert (type, se->expr);
1962 /* Returns the starting position of a substring within a string. */
1965 gfc_conv_intrinsic_index (gfc_se * se, gfc_expr * expr)
1967 tree logical4_type_node = gfc_get_logical_type (4);
1973 args = gfc_conv_intrinsic_function_args (se, expr);
1974 type = gfc_typenode_for_spec (&expr->ts);
1975 tmp = gfc_advance_chain (args, 3);
1976 if (TREE_CHAIN (tmp) == NULL_TREE)
1978 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
1980 TREE_CHAIN (tmp) = back;
1984 back = TREE_CHAIN (tmp);
1985 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
1988 se->expr = gfc_build_function_call (gfor_fndecl_string_index, args);
1989 se->expr = convert (type, se->expr);
1992 /* The ascii value for a single character. */
1994 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
1999 arg = gfc_conv_intrinsic_function_args (se, expr);
2000 arg = TREE_VALUE (TREE_CHAIN (arg));
2001 gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
2002 arg = build1 (NOP_EXPR, pchar_type_node, arg);
2003 type = gfc_typenode_for_spec (&expr->ts);
2005 se->expr = gfc_build_indirect_ref (arg);
2006 se->expr = convert (type, se->expr);
2010 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
2013 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
2022 arg = gfc_conv_intrinsic_function_args (se, expr);
2023 if (expr->ts.type != BT_CHARACTER)
2025 tsource = TREE_VALUE (arg);
2026 arg = TREE_CHAIN (arg);
2027 fsource = TREE_VALUE (arg);
2028 mask = TREE_VALUE (TREE_CHAIN (arg));
2032 /* We do the same as in the non-character case, but the argument
2033 list is different because of the string length arguments. We
2034 also have to set the string length for the result. */
2035 len = TREE_VALUE (arg);
2036 arg = TREE_CHAIN (arg);
2037 tsource = TREE_VALUE (arg);
2038 arg = TREE_CHAIN (TREE_CHAIN (arg));
2039 fsource = TREE_VALUE (arg);
2040 mask = TREE_VALUE (TREE_CHAIN (arg));
2042 se->string_length = len;
2044 type = TREE_TYPE (tsource);
2045 se->expr = fold_build3 (COND_EXPR, type, mask, tsource, fsource);
2050 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
2052 gfc_actual_arglist *actual;
2059 gfc_init_se (&argse, NULL);
2060 actual = expr->value.function.actual;
2062 ss = gfc_walk_expr (actual->expr);
2063 gcc_assert (ss != gfc_ss_terminator);
2064 argse.want_pointer = 1;
2065 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
2066 gfc_add_block_to_block (&se->pre, &argse.pre);
2067 gfc_add_block_to_block (&se->post, &argse.post);
2068 args = gfc_chainon_list (NULL_TREE, argse.expr);
2070 actual = actual->next;
2073 gfc_init_se (&argse, NULL);
2074 gfc_conv_expr_type (&argse, actual->expr, gfc_array_index_type);
2075 gfc_add_block_to_block (&se->pre, &argse.pre);
2076 args = gfc_chainon_list (args, argse.expr);
2077 fndecl = gfor_fndecl_size1;
2080 fndecl = gfor_fndecl_size0;
2082 se->expr = gfc_build_function_call (fndecl, args);
2083 type = gfc_typenode_for_spec (&expr->ts);
2084 se->expr = convert (type, se->expr);
2088 /* Intrinsic string comparison functions. */
2091 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, int op)
2096 args = gfc_conv_intrinsic_function_args (se, expr);
2097 /* Build a call for the comparison. */
2098 se->expr = gfc_build_function_call (gfor_fndecl_compare_string, args);
2100 type = gfc_typenode_for_spec (&expr->ts);
2101 se->expr = build2 (op, type, se->expr,
2102 build_int_cst (TREE_TYPE (se->expr), 0));
2105 /* Generate a call to the adjustl/adjustr library function. */
2107 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
2115 args = gfc_conv_intrinsic_function_args (se, expr);
2116 len = TREE_VALUE (args);
2118 type = TREE_TYPE (TREE_VALUE (TREE_CHAIN (args)));
2119 var = gfc_conv_string_tmp (se, type, len);
2120 args = tree_cons (NULL_TREE, var, args);
2122 tmp = gfc_build_function_call (fndecl, args);
2123 gfc_add_expr_to_block (&se->pre, tmp);
2125 se->string_length = len;
2129 /* Scalar transfer statement.
2130 TRANSFER (source, mold) = *(typeof<mould> *)&source */
2133 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
2135 gfc_actual_arglist *arg;
2141 gcc_assert (!se->ss);
2143 /* Get a pointer to the source. */
2144 arg = expr->value.function.actual;
2145 ss = gfc_walk_expr (arg->expr);
2146 gfc_init_se (&argse, NULL);
2147 if (ss == gfc_ss_terminator)
2148 gfc_conv_expr_reference (&argse, arg->expr);
2150 gfc_conv_array_parameter (&argse, arg->expr, ss, 1);
2151 gfc_add_block_to_block (&se->pre, &argse.pre);
2152 gfc_add_block_to_block (&se->post, &argse.post);
2156 type = gfc_typenode_for_spec (&expr->ts);
2157 ptr = convert (build_pointer_type (type), ptr);
2158 if (expr->ts.type == BT_CHARACTER)
2160 gfc_init_se (&argse, NULL);
2161 gfc_conv_expr (&argse, arg->expr);
2162 gfc_add_block_to_block (&se->pre, &argse.pre);
2163 gfc_add_block_to_block (&se->post, &argse.post);
2165 se->string_length = argse.string_length;
2169 se->expr = gfc_build_indirect_ref (ptr);
2174 /* Generate code for the ALLOCATED intrinsic.
2175 Generate inline code that directly check the address of the argument. */
2178 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
2180 gfc_actual_arglist *arg1;
2185 gfc_init_se (&arg1se, NULL);
2186 arg1 = expr->value.function.actual;
2187 ss1 = gfc_walk_expr (arg1->expr);
2188 arg1se.descriptor_only = 1;
2189 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2191 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
2192 tmp = build2 (NE_EXPR, boolean_type_node, tmp,
2193 fold_convert (TREE_TYPE (tmp), null_pointer_node));
2194 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
2198 /* Generate code for the ASSOCIATED intrinsic.
2199 If both POINTER and TARGET are arrays, generate a call to library function
2200 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
2201 In other cases, generate inline code that directly compare the address of
2202 POINTER with the address of TARGET. */
2205 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
2207 gfc_actual_arglist *arg1;
2208 gfc_actual_arglist *arg2;
2216 gfc_init_se (&arg1se, NULL);
2217 gfc_init_se (&arg2se, NULL);
2218 arg1 = expr->value.function.actual;
2220 ss1 = gfc_walk_expr (arg1->expr);
2224 /* No optional target. */
2225 if (ss1 == gfc_ss_terminator)
2227 /* A pointer to a scalar. */
2228 arg1se.want_pointer = 1;
2229 gfc_conv_expr (&arg1se, arg1->expr);
2234 /* A pointer to an array. */
2235 arg1se.descriptor_only = 1;
2236 gfc_conv_expr_lhs (&arg1se, arg1->expr);
2237 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
2239 tmp = build2 (NE_EXPR, boolean_type_node, tmp2,
2240 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
2245 /* An optional target. */
2246 ss2 = gfc_walk_expr (arg2->expr);
2247 if (ss1 == gfc_ss_terminator)
2249 /* A pointer to a scalar. */
2250 gcc_assert (ss2 == gfc_ss_terminator);
2251 arg1se.want_pointer = 1;
2252 gfc_conv_expr (&arg1se, arg1->expr);
2253 arg2se.want_pointer = 1;
2254 gfc_conv_expr (&arg2se, arg2->expr);
2255 tmp = build2 (EQ_EXPR, boolean_type_node, arg1se.expr, arg2se.expr);
2260 /* A pointer to an array, call library function _gfor_associated. */
2261 gcc_assert (ss2 != gfc_ss_terminator);
2263 arg1se.want_pointer = 1;
2264 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
2265 args = gfc_chainon_list (args, arg1se.expr);
2266 arg2se.want_pointer = 1;
2267 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
2268 gfc_add_block_to_block (&se->pre, &arg2se.pre);
2269 gfc_add_block_to_block (&se->post, &arg2se.post);
2270 args = gfc_chainon_list (args, arg2se.expr);
2271 fndecl = gfor_fndecl_associated;
2272 se->expr = gfc_build_function_call (fndecl, args);
2275 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2279 /* Scan a string for any one of the characters in a set of characters. */
2282 gfc_conv_intrinsic_scan (gfc_se * se, gfc_expr * expr)
2284 tree logical4_type_node = gfc_get_logical_type (4);
2290 args = gfc_conv_intrinsic_function_args (se, expr);
2291 type = gfc_typenode_for_spec (&expr->ts);
2292 tmp = gfc_advance_chain (args, 3);
2293 if (TREE_CHAIN (tmp) == NULL_TREE)
2295 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2297 TREE_CHAIN (tmp) = back;
2301 back = TREE_CHAIN (tmp);
2302 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2305 se->expr = gfc_build_function_call (gfor_fndecl_string_scan, args);
2306 se->expr = convert (type, se->expr);
2310 /* Verify that a set of characters contains all the characters in a string
2311 by identifying the position of the first character in a string of
2312 characters that does not appear in a given set of characters. */
2315 gfc_conv_intrinsic_verify (gfc_se * se, gfc_expr * expr)
2317 tree logical4_type_node = gfc_get_logical_type (4);
2323 args = gfc_conv_intrinsic_function_args (se, expr);
2324 type = gfc_typenode_for_spec (&expr->ts);
2325 tmp = gfc_advance_chain (args, 3);
2326 if (TREE_CHAIN (tmp) == NULL_TREE)
2328 back = tree_cons (NULL_TREE, build_int_cst (logical4_type_node, 0),
2330 TREE_CHAIN (tmp) = back;
2334 back = TREE_CHAIN (tmp);
2335 TREE_VALUE (back) = convert (logical4_type_node, TREE_VALUE (back));
2338 se->expr = gfc_build_function_call (gfor_fndecl_string_verify, args);
2339 se->expr = convert (type, se->expr);
2342 /* Prepare components and related information of a real number which is
2343 the first argument of a elemental functions to manipulate reals. */
2346 prepare_arg_info (gfc_se * se, gfc_expr * expr,
2347 real_compnt_info * rcs, int all)
2354 tree exponent, fraction;
2358 if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
2359 gfc_todo_error ("Non-IEEE floating format");
2361 gcc_assert (expr->expr_type == EXPR_FUNCTION);
2363 arg = gfc_conv_intrinsic_function_args (se, expr);
2364 arg = TREE_VALUE (arg);
2365 rcs->type = TREE_TYPE (arg);
2367 /* Force arg'type to integer by unaffected convert */
2368 a1 = expr->value.function.actual->expr;
2369 masktype = gfc_get_int_type (a1->ts.kind);
2370 rcs->mtype = masktype;
2371 tmp = build1 (VIEW_CONVERT_EXPR, masktype, arg);
2372 arg = gfc_create_var (masktype, "arg");
2373 gfc_add_modify_expr(&se->pre, arg, tmp);
2376 /* Calculate the numbers of bits of exponent, fraction and word */
2377 n = gfc_validate_kind (a1->ts.type, a1->ts.kind, false);
2378 tmp = build_int_cst (NULL_TREE, gfc_real_kinds[n].digits - 1);
2379 rcs->fdigits = convert (masktype, tmp);
2380 wbits = build_int_cst (NULL_TREE, TYPE_PRECISION (rcs->type) - 1);
2381 wbits = convert (masktype, wbits);
2382 rcs->edigits = fold_build2 (MINUS_EXPR, masktype, wbits, tmp);
2384 /* Form masks for exponent/fraction/sign */
2385 one = gfc_build_const (masktype, integer_one_node);
2386 rcs->smask = fold_build2 (LSHIFT_EXPR, masktype, one, wbits);
2387 rcs->f1 = fold_build2 (LSHIFT_EXPR, masktype, one, rcs->fdigits);
2388 rcs->emask = fold_build2 (MINUS_EXPR, masktype, rcs->smask, rcs->f1);
2389 rcs->fmask = fold_build2 (MINUS_EXPR, masktype, rcs->f1, one);
2391 tmp = fold_build2 (MINUS_EXPR, masktype, rcs->edigits, one);
2392 tmp = fold_build2 (LSHIFT_EXPR, masktype, one, tmp);
2393 rcs->bias = fold_build2 (MINUS_EXPR, masktype, tmp ,one);
2397 /* exponent, and fraction */
2398 tmp = build2 (BIT_AND_EXPR, masktype, arg, rcs->emask);
2399 tmp = build2 (RSHIFT_EXPR, masktype, tmp, rcs->fdigits);
2400 exponent = gfc_create_var (masktype, "exponent");
2401 gfc_add_modify_expr(&se->pre, exponent, tmp);
2402 rcs->expn = exponent;
2404 tmp = build2 (BIT_AND_EXPR, masktype, arg, rcs->fmask);
2405 fraction = gfc_create_var (masktype, "fraction");
2406 gfc_add_modify_expr(&se->pre, fraction, tmp);
2407 rcs->frac = fraction;
2411 /* Build a call to __builtin_clz. */
2414 call_builtin_clz (tree result_type, tree op0)
2416 tree fn, parms, call;
2417 enum machine_mode op0_mode = TYPE_MODE (TREE_TYPE (op0));
2419 if (op0_mode == TYPE_MODE (integer_type_node))
2420 fn = built_in_decls[BUILT_IN_CLZ];
2421 else if (op0_mode == TYPE_MODE (long_integer_type_node))
2422 fn = built_in_decls[BUILT_IN_CLZL];
2423 else if (op0_mode == TYPE_MODE (long_long_integer_type_node))
2424 fn = built_in_decls[BUILT_IN_CLZLL];
2428 parms = tree_cons (NULL, op0, NULL);
2429 call = gfc_build_function_call (fn, parms);
2431 return convert (result_type, call);
2435 /* Generate code for SPACING (X) intrinsic function.
2436 SPACING (X) = POW (2, e-p)
2440 t = expn - fdigits // e - p.
2441 res = t << fdigits // Form the exponent. Fraction is zero.
2442 if (t < 0) // The result is out of range. Denormalized case.
2447 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
2454 real_compnt_info rcs;
2456 prepare_arg_info (se, expr, &rcs, 0);
2458 masktype = rcs.mtype;
2459 fdigits = rcs.fdigits;
2461 zero = gfc_build_const (masktype, integer_zero_node);
2462 tmp = build2 (BIT_AND_EXPR, masktype, rcs.emask, arg);
2463 tmp = build2 (RSHIFT_EXPR, masktype, tmp, fdigits);
2464 tmp = build2 (MINUS_EXPR, masktype, tmp, fdigits);
2465 cond = build2 (LE_EXPR, boolean_type_node, tmp, zero);
2466 t1 = build2 (LSHIFT_EXPR, masktype, tmp, fdigits);
2467 tmp = build3 (COND_EXPR, masktype, cond, tiny, t1);
2468 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2473 /* Generate code for RRSPACING (X) intrinsic function.
2474 RRSPACING (X) = |X * POW (2, -e)| * POW (2, p) = |FRACTION (X)| * POW (2, p)
2476 So the result's exponent is p. And if X is normalized, X's fraction part
2477 is the result's fraction. If X is denormalized, to get the X's fraction we
2478 shift X's fraction part to left until the first '1' is removed.
2482 if (expn == 0 && frac == 0)
2486 // edigits is the number of exponent bits. Add the sign bit.
2487 sedigits = edigits + 1;
2489 if (expn == 0) // Denormalized case.
2491 t1 = leadzero (frac);
2492 frac = frac << (t1 + 1); //Remove the first '1'.
2493 frac = frac >> (sedigits); //Form the fraction.
2496 //fdigits is the number of fraction bits. Form the exponent.
2499 res = (t << fdigits) | frac;
2504 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
2507 tree tmp, t1, t2, cond, cond2;
2509 tree fdigits, fraction;
2510 real_compnt_info rcs;
2512 prepare_arg_info (se, expr, &rcs, 1);
2513 masktype = rcs.mtype;
2514 fdigits = rcs.fdigits;
2515 fraction = rcs.frac;
2516 one = gfc_build_const (masktype, integer_one_node);
2517 zero = gfc_build_const (masktype, integer_zero_node);
2518 t2 = fold_build2 (PLUS_EXPR, masktype, rcs.edigits, one);
2520 t1 = call_builtin_clz (masktype, fraction);
2521 tmp = build2 (PLUS_EXPR, masktype, t1, one);
2522 tmp = build2 (LSHIFT_EXPR, masktype, fraction, tmp);
2523 tmp = build2 (RSHIFT_EXPR, masktype, tmp, t2);
2524 cond = build2 (EQ_EXPR, boolean_type_node, rcs.expn, zero);
2525 fraction = build3 (COND_EXPR, masktype, cond, tmp, fraction);
2527 tmp = fold_build2 (PLUS_EXPR, masktype, rcs.bias, fdigits);
2528 tmp = fold_build2 (LSHIFT_EXPR, masktype, tmp, fdigits);
2529 tmp = build2 (BIT_IOR_EXPR, masktype, tmp, fraction);
2531 cond2 = build2 (EQ_EXPR, boolean_type_node, rcs.frac, zero);
2532 cond = build2 (TRUTH_ANDIF_EXPR, boolean_type_node, cond, cond2);
2533 tmp = build3 (COND_EXPR, masktype, cond,
2534 build_int_cst (masktype, 0), tmp);
2536 tmp = build1 (VIEW_CONVERT_EXPR, rcs.type, tmp);
2540 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
2543 gfc_conv_intrinsic_si_kind (gfc_se * se, gfc_expr * expr)
2547 args = gfc_conv_intrinsic_function_args (se, expr);
2548 args = TREE_VALUE (args);
2549 args = gfc_build_addr_expr (NULL, args);
2550 args = tree_cons (NULL_TREE, args, NULL_TREE);
2551 se->expr = gfc_build_function_call (gfor_fndecl_si_kind, args);
2554 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
2557 gfc_conv_intrinsic_sr_kind (gfc_se * se, gfc_expr * expr)
2559 gfc_actual_arglist *actual;
2564 for (actual = expr->value.function.actual; actual; actual = actual->next)
2566 gfc_init_se (&argse, se);
2568 /* Pass a NULL pointer for an absent arg. */
2569 if (actual->expr == NULL)
2570 argse.expr = null_pointer_node;
2572 gfc_conv_expr_reference (&argse, actual->expr);
2574 gfc_add_block_to_block (&se->pre, &argse.pre);
2575 gfc_add_block_to_block (&se->post, &argse.post);
2576 args = gfc_chainon_list (args, argse.expr);
2578 se->expr = gfc_build_function_call (gfor_fndecl_sr_kind, args);
2582 /* Generate code for TRIM (A) intrinsic function. */
2585 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
2587 tree gfc_int4_type_node = gfc_get_int_type (4);
2596 arglist = NULL_TREE;
2598 type = build_pointer_type (gfc_character1_type_node);
2599 var = gfc_create_var (type, "pstr");
2600 addr = gfc_build_addr_expr (ppvoid_type_node, var);
2601 len = gfc_create_var (gfc_int4_type_node, "len");
2603 tmp = gfc_conv_intrinsic_function_args (se, expr);
2604 arglist = gfc_chainon_list (arglist, gfc_build_addr_expr (NULL, len));
2605 arglist = gfc_chainon_list (arglist, addr);
2606 arglist = chainon (arglist, tmp);
2608 tmp = gfc_build_function_call (gfor_fndecl_string_trim, arglist);
2609 gfc_add_expr_to_block (&se->pre, tmp);
2611 /* Free the temporary afterwards, if necessary. */
2612 cond = build2 (GT_EXPR, boolean_type_node, len,
2613 build_int_cst (TREE_TYPE (len), 0));
2614 arglist = gfc_chainon_list (NULL_TREE, var);
2615 tmp = gfc_build_function_call (gfor_fndecl_internal_free, arglist);
2616 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt ());
2617 gfc_add_expr_to_block (&se->post, tmp);
2620 se->string_length = len;
2624 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
2627 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
2629 tree gfc_int4_type_node = gfc_get_int_type (4);
2638 args = gfc_conv_intrinsic_function_args (se, expr);
2639 len = TREE_VALUE (args);
2640 tmp = gfc_advance_chain (args, 2);
2641 ncopies = TREE_VALUE (tmp);
2642 len = fold_build2 (MULT_EXPR, gfc_int4_type_node, len, ncopies);
2643 type = gfc_get_character_type (expr->ts.kind, expr->ts.cl);
2644 var = gfc_conv_string_tmp (se, build_pointer_type (type), len);
2646 arglist = NULL_TREE;
2647 arglist = gfc_chainon_list (arglist, var);
2648 arglist = chainon (arglist, args);
2649 tmp = gfc_build_function_call (gfor_fndecl_string_repeat, arglist);
2650 gfc_add_expr_to_block (&se->pre, tmp);
2653 se->string_length = len;
2657 /* Generate code for the IARGC intrinsic. */
2660 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
2666 /* Call the library function. This always returns an INTEGER(4). */
2667 fndecl = gfor_fndecl_iargc;
2668 tmp = gfc_build_function_call (fndecl, NULL_TREE);
2670 /* Convert it to the required type. */
2671 type = gfc_typenode_for_spec (&expr->ts);
2672 tmp = fold_convert (type, tmp);
2677 /* Generate code for an intrinsic function. Some map directly to library
2678 calls, others get special handling. In some cases the name of the function
2679 used depends on the type specifiers. */
2682 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
2684 gfc_intrinsic_sym *isym;
2688 isym = expr->value.function.isym;
2690 name = &expr->value.function.name[2];
2694 lib = gfc_is_intrinsic_libcall (expr);
2698 se->ignore_optional = 1;
2699 gfc_conv_intrinsic_funcall (se, expr);
2704 switch (expr->value.function.isym->generic_id)
2709 case GFC_ISYM_REPEAT:
2710 gfc_conv_intrinsic_repeat (se, expr);
2714 gfc_conv_intrinsic_trim (se, expr);
2717 case GFC_ISYM_SI_KIND:
2718 gfc_conv_intrinsic_si_kind (se, expr);
2721 case GFC_ISYM_SR_KIND:
2722 gfc_conv_intrinsic_sr_kind (se, expr);
2725 case GFC_ISYM_EXPONENT:
2726 gfc_conv_intrinsic_exponent (se, expr);
2729 case GFC_ISYM_SPACING:
2730 gfc_conv_intrinsic_spacing (se, expr);
2733 case GFC_ISYM_RRSPACING:
2734 gfc_conv_intrinsic_rrspacing (se, expr);
2738 gfc_conv_intrinsic_scan (se, expr);
2741 case GFC_ISYM_VERIFY:
2742 gfc_conv_intrinsic_verify (se, expr);
2745 case GFC_ISYM_ALLOCATED:
2746 gfc_conv_allocated (se, expr);
2749 case GFC_ISYM_ASSOCIATED:
2750 gfc_conv_associated(se, expr);
2754 gfc_conv_intrinsic_abs (se, expr);
2757 case GFC_ISYM_ADJUSTL:
2758 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustl);
2761 case GFC_ISYM_ADJUSTR:
2762 gfc_conv_intrinsic_adjust (se, expr, gfor_fndecl_adjustr);
2765 case GFC_ISYM_AIMAG:
2766 gfc_conv_intrinsic_imagpart (se, expr);
2770 gfc_conv_intrinsic_aint (se, expr, FIX_TRUNC_EXPR);
2774 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
2777 case GFC_ISYM_ANINT:
2778 gfc_conv_intrinsic_aint (se, expr, FIX_ROUND_EXPR);
2782 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
2785 case GFC_ISYM_BTEST:
2786 gfc_conv_intrinsic_btest (se, expr);
2789 case GFC_ISYM_ACHAR:
2791 gfc_conv_intrinsic_char (se, expr);
2794 case GFC_ISYM_CONVERSION:
2796 case GFC_ISYM_LOGICAL:
2798 gfc_conv_intrinsic_conversion (se, expr);
2801 /* Integer conversions are handled separately to make sure we get the
2802 correct rounding mode. */
2804 gfc_conv_intrinsic_int (se, expr, FIX_TRUNC_EXPR);
2808 gfc_conv_intrinsic_int (se, expr, FIX_ROUND_EXPR);
2811 case GFC_ISYM_CEILING:
2812 gfc_conv_intrinsic_int (se, expr, FIX_CEIL_EXPR);
2815 case GFC_ISYM_FLOOR:
2816 gfc_conv_intrinsic_int (se, expr, FIX_FLOOR_EXPR);
2820 gfc_conv_intrinsic_mod (se, expr, 0);
2823 case GFC_ISYM_MODULO:
2824 gfc_conv_intrinsic_mod (se, expr, 1);
2827 case GFC_ISYM_CMPLX:
2828 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
2831 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
2832 gfc_conv_intrinsic_iargc (se, expr);
2835 case GFC_ISYM_CONJG:
2836 gfc_conv_intrinsic_conjg (se, expr);
2839 case GFC_ISYM_COUNT:
2840 gfc_conv_intrinsic_count (se, expr);
2844 gfc_conv_intrinsic_dim (se, expr);
2847 case GFC_ISYM_DPROD:
2848 gfc_conv_intrinsic_dprod (se, expr);
2852 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
2855 case GFC_ISYM_IBCLR:
2856 gfc_conv_intrinsic_singlebitop (se, expr, 0);
2859 case GFC_ISYM_IBITS:
2860 gfc_conv_intrinsic_ibits (se, expr);
2863 case GFC_ISYM_IBSET:
2864 gfc_conv_intrinsic_singlebitop (se, expr, 1);
2867 case GFC_ISYM_IACHAR:
2868 case GFC_ISYM_ICHAR:
2869 /* We assume ASCII character sequence. */
2870 gfc_conv_intrinsic_ichar (se, expr);
2873 case GFC_ISYM_IARGC:
2874 gfc_conv_intrinsic_iargc (se, expr);
2878 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
2881 case GFC_ISYM_INDEX:
2882 gfc_conv_intrinsic_index (se, expr);
2886 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
2889 case GFC_ISYM_ISHFT:
2890 gfc_conv_intrinsic_ishft (se, expr);
2893 case GFC_ISYM_ISHFTC:
2894 gfc_conv_intrinsic_ishftc (se, expr);
2897 case GFC_ISYM_LBOUND:
2898 gfc_conv_intrinsic_bound (se, expr, 0);
2902 gfc_conv_intrinsic_len (se, expr);
2905 case GFC_ISYM_LEN_TRIM:
2906 gfc_conv_intrinsic_len_trim (se, expr);
2910 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
2914 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
2918 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
2922 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
2926 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
2929 case GFC_ISYM_MAXLOC:
2930 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
2933 case GFC_ISYM_MAXVAL:
2934 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
2937 case GFC_ISYM_MERGE:
2938 gfc_conv_intrinsic_merge (se, expr);
2942 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
2945 case GFC_ISYM_MINLOC:
2946 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
2949 case GFC_ISYM_MINVAL:
2950 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
2954 gfc_conv_intrinsic_not (se, expr);
2957 case GFC_ISYM_PRESENT:
2958 gfc_conv_intrinsic_present (se, expr);
2961 case GFC_ISYM_PRODUCT:
2962 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
2966 gfc_conv_intrinsic_sign (se, expr);
2970 gfc_conv_intrinsic_size (se, expr);
2974 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
2977 case GFC_ISYM_TRANSFER:
2978 gfc_conv_intrinsic_transfer (se, expr);
2981 case GFC_ISYM_UBOUND:
2982 gfc_conv_intrinsic_bound (se, expr, 1);
2985 case GFC_ISYM_CHDIR:
2986 case GFC_ISYM_DOT_PRODUCT:
2987 case GFC_ISYM_ETIME:
2989 case GFC_ISYM_FSTAT:
2990 case GFC_ISYM_GETCWD:
2991 case GFC_ISYM_GETGID:
2992 case GFC_ISYM_GETPID:
2993 case GFC_ISYM_GETUID:
2994 case GFC_ISYM_HOSTNM:
2996 case GFC_ISYM_IERRNO:
2997 case GFC_ISYM_IRAND:
2998 case GFC_ISYM_ISATTY:
3000 case GFC_ISYM_MATMUL:
3002 case GFC_ISYM_RENAME:
3003 case GFC_ISYM_SECOND:
3005 case GFC_ISYM_SYMLNK:
3006 case GFC_ISYM_SYSTEM:
3008 case GFC_ISYM_TIME8:
3009 case GFC_ISYM_UMASK:
3010 case GFC_ISYM_UNLINK:
3011 gfc_conv_intrinsic_funcall (se, expr);
3015 gfc_conv_intrinsic_lib_function (se, expr);
3021 /* This generates code to execute before entering the scalarization loop.
3022 Currently does nothing. */
3025 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
3027 switch (ss->expr->value.function.isym->generic_id)
3029 case GFC_ISYM_UBOUND:
3030 case GFC_ISYM_LBOUND:
3039 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
3040 inside the scalarization loop. */
3043 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
3047 /* The two argument version returns a scalar. */
3048 if (expr->value.function.actual->next->expr)
3051 newss = gfc_get_ss ();
3052 newss->type = GFC_SS_INTRINSIC;
3060 /* Walk an intrinsic array libcall. */
3063 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
3067 gcc_assert (expr->rank > 0);
3069 newss = gfc_get_ss ();
3070 newss->type = GFC_SS_FUNCTION;
3073 newss->data.info.dimen = expr->rank;
3079 /* Returns nonzero if the specified intrinsic function call maps directly to a
3080 an external library call. Should only be used for functions that return
3084 gfc_is_intrinsic_libcall (gfc_expr * expr)
3086 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
3087 gcc_assert (expr->rank > 0);
3089 switch (expr->value.function.isym->generic_id)
3093 case GFC_ISYM_COUNT:
3094 case GFC_ISYM_MATMUL:
3095 case GFC_ISYM_MAXLOC:
3096 case GFC_ISYM_MAXVAL:
3097 case GFC_ISYM_MINLOC:
3098 case GFC_ISYM_MINVAL:
3099 case GFC_ISYM_PRODUCT:
3101 case GFC_ISYM_SHAPE:
3102 case GFC_ISYM_SPREAD:
3103 case GFC_ISYM_TRANSPOSE:
3104 /* Ignore absent optional parameters. */
3107 case GFC_ISYM_RESHAPE:
3108 case GFC_ISYM_CSHIFT:
3109 case GFC_ISYM_EOSHIFT:
3111 case GFC_ISYM_UNPACK:
3112 /* Pass absent optional parameters. */
3120 /* Walk an intrinsic function. */
3122 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
3123 gfc_intrinsic_sym * isym)
3127 if (isym->elemental)
3128 return gfc_walk_elemental_function_args (ss, expr, GFC_SS_SCALAR);
3130 if (expr->rank == 0)
3133 if (gfc_is_intrinsic_libcall (expr))
3134 return gfc_walk_intrinsic_libfunc (ss, expr);
3136 /* Special cases. */
3137 switch (isym->generic_id)
3139 case GFC_ISYM_LBOUND:
3140 case GFC_ISYM_UBOUND:
3141 return gfc_walk_intrinsic_bound (ss, expr);
3144 /* This probably meant someone forgot to add an intrinsic to the above
3145 list(s) when they implemented it, or something's gone horribly wrong.
3147 gfc_todo_error ("Scalarization of non-elemental intrinsic: %s",
3148 expr->value.function.name);
3152 #include "gt-fortran-trans-intrinsic.h"