* trans-intrinsic.c (gfc_build_intrinsic_lib_fndecls): Fix comment.
[official-gcc.git] / gcc / fortran / trans-intrinsic.c
blob10e0dec8a85f6822b95041d071f31a39cf952b1b
1 /* Intrinsic translation
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
4 Contributed by Paul Brook <paul@nowt.org>
5 and Steven Bosscher <s.bosscher@student.tudelft.nl>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h" /* For UNITS_PER_WORD. */
29 #include "tree.h"
30 #include "ggc.h"
31 #include "toplev.h" /* For rest_of_decl_compilation/internal_error. */
32 #include "flags.h"
33 #include "gfortran.h"
34 #include "arith.h"
35 #include "intrinsic.h"
36 #include "trans.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
39 #include "trans-array.h"
40 #include "defaults.h"
41 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
42 #include "trans-stmt.h"
44 /* This maps fortran intrinsic math functions to external library or GCC
45 builtin functions. */
46 typedef struct GTY(()) gfc_intrinsic_map_t {
47 /* The explicit enum is required to work around inadequacies in the
48 garbage collection/gengtype parsing mechanism. */
49 enum gfc_isym_id id;
51 /* Enum value from the "language-independent", aka C-centric, part
52 of gcc, or END_BUILTINS of no such value set. */
53 enum built_in_function float_built_in;
54 enum built_in_function double_built_in;
55 enum built_in_function long_double_built_in;
56 enum built_in_function complex_float_built_in;
57 enum built_in_function complex_double_built_in;
58 enum built_in_function complex_long_double_built_in;
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](4|8|10|16)". */
63 bool libm_name;
65 /* True if a complex version of the function exists. */
66 bool complex_available;
68 /* True if the function should be marked const. */
69 bool is_constant;
71 /* The base library name of this function. */
72 const char *name;
74 /* Cache decls created for the various operand types. */
75 tree real4_decl;
76 tree real8_decl;
77 tree real10_decl;
78 tree real16_decl;
79 tree complex4_decl;
80 tree complex8_decl;
81 tree complex10_decl;
82 tree complex16_decl;
84 gfc_intrinsic_map_t;
86 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
87 defines complex variants of all of the entries in mathbuiltins.def
88 except for atan2. */
89 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
90 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
91 BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
92 true, false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
93 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
95 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
96 { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
97 BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, BUILT_IN_C ## ID, \
98 BUILT_IN_C ## ID ## L, true, true, true, NAME, NULL_TREE, NULL_TREE, \
99 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
101 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
102 { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
103 END_BUILTINS, END_BUILTINS, END_BUILTINS, \
104 false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
105 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
107 #define OTHER_BUILTIN(ID, NAME, TYPE) \
108 { GFC_ISYM_NONE, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
109 BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
110 true, false, true, NAME, NULL_TREE, NULL_TREE, \
111 NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
113 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
115 /* Functions built into gcc itself (DEFINE_MATH_BUILTIN and
116 DEFINE_MATH_BUILTIN_C), then the built-ins that don't correspond
117 to any GFC_ISYM id directly, which use the OTHER_BUILTIN macro. */
118 #include "mathbuiltins.def"
120 /* Functions in libgfortran. */
121 LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
123 /* End the list. */
124 LIB_FUNCTION (NONE, NULL, false)
127 #undef OTHER_BUILTIN
128 #undef LIB_FUNCTION
129 #undef DEFINE_MATH_BUILTIN
130 #undef DEFINE_MATH_BUILTIN_C
133 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
136 /* Find the correct variant of a given builtin from its argument. */
137 static tree
138 builtin_decl_for_precision (enum built_in_function base_built_in,
139 int precision)
141 int i = END_BUILTINS;
143 gfc_intrinsic_map_t *m;
144 for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
147 if (precision == TYPE_PRECISION (float_type_node))
148 i = m->float_built_in;
149 else if (precision == TYPE_PRECISION (double_type_node))
150 i = m->double_built_in;
151 else if (precision == TYPE_PRECISION (long_double_type_node))
152 i = m->long_double_built_in;
154 return (i == END_BUILTINS ? NULL_TREE : built_in_decls[i]);
158 static tree
159 builtin_decl_for_float_kind (enum built_in_function double_built_in, int kind)
161 int i = gfc_validate_kind (BT_REAL, kind, false);
162 return builtin_decl_for_precision (double_built_in,
163 gfc_real_kinds[i].mode_precision);
167 /* Evaluate the arguments to an intrinsic function. The value
168 of NARGS may be less than the actual number of arguments in EXPR
169 to allow optional "KIND" arguments that are not included in the
170 generated code to be ignored. */
172 static void
173 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
174 tree *argarray, int nargs)
176 gfc_actual_arglist *actual;
177 gfc_expr *e;
178 gfc_intrinsic_arg *formal;
179 gfc_se argse;
180 int curr_arg;
182 formal = expr->value.function.isym->formal;
183 actual = expr->value.function.actual;
185 for (curr_arg = 0; curr_arg < nargs; curr_arg++,
186 actual = actual->next,
187 formal = formal ? formal->next : NULL)
189 gcc_assert (actual);
190 e = actual->expr;
191 /* Skip omitted optional arguments. */
192 if (!e)
194 --curr_arg;
195 continue;
198 /* Evaluate the parameter. This will substitute scalarized
199 references automatically. */
200 gfc_init_se (&argse, se);
202 if (e->ts.type == BT_CHARACTER)
204 gfc_conv_expr (&argse, e);
205 gfc_conv_string_parameter (&argse);
206 argarray[curr_arg++] = argse.string_length;
207 gcc_assert (curr_arg < nargs);
209 else
210 gfc_conv_expr_val (&argse, e);
212 /* If an optional argument is itself an optional dummy argument,
213 check its presence and substitute a null if absent. */
214 if (e->expr_type == EXPR_VARIABLE
215 && e->symtree->n.sym->attr.optional
216 && formal
217 && formal->optional)
218 gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
220 gfc_add_block_to_block (&se->pre, &argse.pre);
221 gfc_add_block_to_block (&se->post, &argse.post);
222 argarray[curr_arg] = argse.expr;
226 /* Count the number of actual arguments to the intrinsic function EXPR
227 including any "hidden" string length arguments. */
229 static unsigned int
230 gfc_intrinsic_argument_list_length (gfc_expr *expr)
232 int n = 0;
233 gfc_actual_arglist *actual;
235 for (actual = expr->value.function.actual; actual; actual = actual->next)
237 if (!actual->expr)
238 continue;
240 if (actual->expr->ts.type == BT_CHARACTER)
241 n += 2;
242 else
243 n++;
246 return n;
250 /* Conversions between different types are output by the frontend as
251 intrinsic functions. We implement these directly with inline code. */
253 static void
254 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
256 tree type;
257 tree *args;
258 int nargs;
260 nargs = gfc_intrinsic_argument_list_length (expr);
261 args = (tree *) alloca (sizeof (tree) * nargs);
263 /* Evaluate all the arguments passed. Whilst we're only interested in the
264 first one here, there are other parts of the front-end that assume this
265 and will trigger an ICE if it's not the case. */
266 type = gfc_typenode_for_spec (&expr->ts);
267 gcc_assert (expr->value.function.actual->expr);
268 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
270 /* Conversion between character kinds involves a call to a library
271 function. */
272 if (expr->ts.type == BT_CHARACTER)
274 tree fndecl, var, addr, tmp;
276 if (expr->ts.kind == 1
277 && expr->value.function.actual->expr->ts.kind == 4)
278 fndecl = gfor_fndecl_convert_char4_to_char1;
279 else if (expr->ts.kind == 4
280 && expr->value.function.actual->expr->ts.kind == 1)
281 fndecl = gfor_fndecl_convert_char1_to_char4;
282 else
283 gcc_unreachable ();
285 /* Create the variable storing the converted value. */
286 type = gfc_get_pchar_type (expr->ts.kind);
287 var = gfc_create_var (type, "str");
288 addr = gfc_build_addr_expr (build_pointer_type (type), var);
290 /* Call the library function that will perform the conversion. */
291 gcc_assert (nargs >= 2);
292 tmp = build_call_expr_loc (input_location,
293 fndecl, 3, addr, args[0], args[1]);
294 gfc_add_expr_to_block (&se->pre, tmp);
296 /* Free the temporary afterwards. */
297 tmp = gfc_call_free (var);
298 gfc_add_expr_to_block (&se->post, tmp);
300 se->expr = var;
301 se->string_length = args[0];
303 return;
306 /* Conversion from complex to non-complex involves taking the real
307 component of the value. */
308 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
309 && expr->ts.type != BT_COMPLEX)
311 tree artype;
313 artype = TREE_TYPE (TREE_TYPE (args[0]));
314 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
317 se->expr = convert (type, args[0]);
320 /* This is needed because the gcc backend only implements
321 FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
322 FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
323 Similarly for CEILING. */
325 static tree
326 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
328 tree tmp;
329 tree cond;
330 tree argtype;
331 tree intval;
333 argtype = TREE_TYPE (arg);
334 arg = gfc_evaluate_now (arg, pblock);
336 intval = convert (type, arg);
337 intval = gfc_evaluate_now (intval, pblock);
339 tmp = convert (argtype, intval);
340 cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
342 tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
343 build_int_cst (type, 1));
344 tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
345 return tmp;
349 /* Round to nearest integer, away from zero. */
351 static tree
352 build_round_expr (tree arg, tree restype)
354 tree argtype;
355 tree fn;
356 bool longlong;
357 int argprec, resprec;
359 argtype = TREE_TYPE (arg);
360 argprec = TYPE_PRECISION (argtype);
361 resprec = TYPE_PRECISION (restype);
363 /* Depending on the type of the result, choose the long int intrinsic
364 (lround family) or long long intrinsic (llround). We might also
365 need to convert the result afterwards. */
366 if (resprec <= LONG_TYPE_SIZE)
367 longlong = false;
368 else if (resprec <= LONG_LONG_TYPE_SIZE)
369 longlong = true;
370 else
371 gcc_unreachable ();
373 /* Now, depending on the argument type, we choose between intrinsics. */
374 if (longlong)
375 fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
376 else
377 fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
379 return fold_convert (restype, build_call_expr_loc (input_location,
380 fn, 1, arg));
384 /* Convert a real to an integer using a specific rounding mode.
385 Ideally we would just build the corresponding GENERIC node,
386 however the RTL expander only actually supports FIX_TRUNC_EXPR. */
388 static tree
389 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
390 enum rounding_mode op)
392 switch (op)
394 case RND_FLOOR:
395 return build_fixbound_expr (pblock, arg, type, 0);
396 break;
398 case RND_CEIL:
399 return build_fixbound_expr (pblock, arg, type, 1);
400 break;
402 case RND_ROUND:
403 return build_round_expr (arg, type);
404 break;
406 case RND_TRUNC:
407 return fold_build1 (FIX_TRUNC_EXPR, type, arg);
408 break;
410 default:
411 gcc_unreachable ();
416 /* Round a real value using the specified rounding mode.
417 We use a temporary integer of that same kind size as the result.
418 Values larger than those that can be represented by this kind are
419 unchanged, as they will not be accurate enough to represent the
420 rounding.
421 huge = HUGE (KIND (a))
422 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
425 static void
426 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
428 tree type;
429 tree itype;
430 tree arg[2];
431 tree tmp;
432 tree cond;
433 tree decl;
434 mpfr_t huge;
435 int n, nargs;
436 int kind;
438 kind = expr->ts.kind;
439 nargs = gfc_intrinsic_argument_list_length (expr);
441 decl = NULL_TREE;
442 /* We have builtin functions for some cases. */
443 switch (op)
445 case RND_ROUND:
446 decl = builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
447 break;
449 case RND_TRUNC:
450 decl = builtin_decl_for_float_kind (BUILT_IN_TRUNC, kind);
451 break;
453 default:
454 gcc_unreachable ();
457 /* Evaluate the argument. */
458 gcc_assert (expr->value.function.actual->expr);
459 gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
461 /* Use a builtin function if one exists. */
462 if (decl != NULL_TREE)
464 se->expr = build_call_expr_loc (input_location, decl, 1, arg[0]);
465 return;
468 /* This code is probably redundant, but we'll keep it lying around just
469 in case. */
470 type = gfc_typenode_for_spec (&expr->ts);
471 arg[0] = gfc_evaluate_now (arg[0], &se->pre);
473 /* Test if the value is too large to handle sensibly. */
474 gfc_set_model_kind (kind);
475 mpfr_init (huge);
476 n = gfc_validate_kind (BT_INTEGER, kind, false);
477 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
478 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
479 cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
481 mpfr_neg (huge, huge, GFC_RND_MODE);
482 tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
483 tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
484 cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
485 itype = gfc_get_int_type (kind);
487 tmp = build_fix_expr (&se->pre, arg[0], itype, op);
488 tmp = convert (type, tmp);
489 se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
490 mpfr_clear (huge);
494 /* Convert to an integer using the specified rounding mode. */
496 static void
497 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
499 tree type;
500 tree *args;
501 int nargs;
503 nargs = gfc_intrinsic_argument_list_length (expr);
504 args = (tree *) alloca (sizeof (tree) * nargs);
506 /* Evaluate the argument, we process all arguments even though we only
507 use the first one for code generation purposes. */
508 type = gfc_typenode_for_spec (&expr->ts);
509 gcc_assert (expr->value.function.actual->expr);
510 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
512 if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
514 /* Conversion to a different integer kind. */
515 se->expr = convert (type, args[0]);
517 else
519 /* Conversion from complex to non-complex involves taking the real
520 component of the value. */
521 if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
522 && expr->ts.type != BT_COMPLEX)
524 tree artype;
526 artype = TREE_TYPE (TREE_TYPE (args[0]));
527 args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
530 se->expr = build_fix_expr (&se->pre, args[0], type, op);
535 /* Get the imaginary component of a value. */
537 static void
538 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
540 tree arg;
542 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
543 se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
547 /* Get the complex conjugate of a value. */
549 static void
550 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
552 tree arg;
554 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
555 se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
559 /* Initialize function decls for library functions. The external functions
560 are created as required. Builtin functions are added here. */
562 void
563 gfc_build_intrinsic_lib_fndecls (void)
565 gfc_intrinsic_map_t *m;
567 /* Add GCC builtin functions. */
568 for (m = gfc_intrinsic_map;
569 m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
571 if (m->float_built_in != END_BUILTINS)
572 m->real4_decl = built_in_decls[m->float_built_in];
573 if (m->complex_float_built_in != END_BUILTINS)
574 m->complex4_decl = built_in_decls[m->complex_float_built_in];
575 if (m->double_built_in != END_BUILTINS)
576 m->real8_decl = built_in_decls[m->double_built_in];
577 if (m->complex_double_built_in != END_BUILTINS)
578 m->complex8_decl = built_in_decls[m->complex_double_built_in];
580 /* If real(kind=10) exists, it is always long double. */
581 if (m->long_double_built_in != END_BUILTINS)
582 m->real10_decl = built_in_decls[m->long_double_built_in];
583 if (m->complex_long_double_built_in != END_BUILTINS)
584 m->complex10_decl = built_in_decls[m->complex_long_double_built_in];
586 /* For now, we assume that if real(kind=16) exists, it is long double.
587 Later, we will deal with __float128 and break this assumption. */
588 if (m->long_double_built_in != END_BUILTINS)
589 m->real16_decl = built_in_decls[m->long_double_built_in];
590 if (m->complex_long_double_built_in != END_BUILTINS)
591 m->complex16_decl = built_in_decls[m->complex_long_double_built_in];
596 /* Create a fndecl for a simple intrinsic library function. */
598 static tree
599 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
601 tree type;
602 tree argtypes;
603 tree fndecl;
604 gfc_actual_arglist *actual;
605 tree *pdecl;
606 gfc_typespec *ts;
607 char name[GFC_MAX_SYMBOL_LEN + 3];
609 ts = &expr->ts;
610 if (ts->type == BT_REAL)
612 switch (ts->kind)
614 case 4:
615 pdecl = &m->real4_decl;
616 break;
617 case 8:
618 pdecl = &m->real8_decl;
619 break;
620 case 10:
621 pdecl = &m->real10_decl;
622 break;
623 case 16:
624 pdecl = &m->real16_decl;
625 break;
626 default:
627 gcc_unreachable ();
630 else if (ts->type == BT_COMPLEX)
632 gcc_assert (m->complex_available);
634 switch (ts->kind)
636 case 4:
637 pdecl = &m->complex4_decl;
638 break;
639 case 8:
640 pdecl = &m->complex8_decl;
641 break;
642 case 10:
643 pdecl = &m->complex10_decl;
644 break;
645 case 16:
646 pdecl = &m->complex16_decl;
647 break;
648 default:
649 gcc_unreachable ();
652 else
653 gcc_unreachable ();
655 if (*pdecl)
656 return *pdecl;
658 if (m->libm_name)
660 int n = gfc_validate_kind (BT_REAL, ts->kind, false);
661 if (gfc_real_kinds[n].c_float)
662 snprintf (name, sizeof (name), "%s%s%s",
663 ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
664 else if (gfc_real_kinds[n].c_double)
665 snprintf (name, sizeof (name), "%s%s",
666 ts->type == BT_COMPLEX ? "c" : "", m->name);
667 else if (gfc_real_kinds[n].c_long_double)
668 snprintf (name, sizeof (name), "%s%s%s",
669 ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
670 else
671 gcc_unreachable ();
673 else
675 snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
676 ts->type == BT_COMPLEX ? 'c' : 'r',
677 ts->kind);
680 argtypes = NULL_TREE;
681 for (actual = expr->value.function.actual; actual; actual = actual->next)
683 type = gfc_typenode_for_spec (&actual->expr->ts);
684 argtypes = gfc_chainon_list (argtypes, type);
686 argtypes = gfc_chainon_list (argtypes, void_type_node);
687 type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
688 fndecl = build_decl (input_location,
689 FUNCTION_DECL, get_identifier (name), type);
691 /* Mark the decl as external. */
692 DECL_EXTERNAL (fndecl) = 1;
693 TREE_PUBLIC (fndecl) = 1;
695 /* Mark it __attribute__((const)), if possible. */
696 TREE_READONLY (fndecl) = m->is_constant;
698 rest_of_decl_compilation (fndecl, 1, 0);
700 (*pdecl) = fndecl;
701 return fndecl;
705 /* Convert an intrinsic function into an external or builtin call. */
707 static void
708 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
710 gfc_intrinsic_map_t *m;
711 tree fndecl;
712 tree rettype;
713 tree *args;
714 unsigned int num_args;
715 gfc_isym_id id;
717 id = expr->value.function.isym->id;
718 /* Find the entry for this function. */
719 for (m = gfc_intrinsic_map;
720 m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
722 if (id == m->id)
723 break;
726 if (m->id == GFC_ISYM_NONE)
728 internal_error ("Intrinsic function %s(%d) not recognized",
729 expr->value.function.name, id);
732 /* Get the decl and generate the call. */
733 num_args = gfc_intrinsic_argument_list_length (expr);
734 args = (tree *) alloca (sizeof (tree) * num_args);
736 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
737 fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
738 rettype = TREE_TYPE (TREE_TYPE (fndecl));
740 fndecl = build_addr (fndecl, current_function_decl);
741 se->expr = build_call_array_loc (input_location, rettype, fndecl, num_args, args);
745 /* If bounds-checking is enabled, create code to verify at runtime that the
746 string lengths for both expressions are the same (needed for e.g. MERGE).
747 If bounds-checking is not enabled, does nothing. */
749 void
750 gfc_trans_same_strlen_check (const char* intr_name, locus* where,
751 tree a, tree b, stmtblock_t* target)
753 tree cond;
754 tree name;
756 /* If bounds-checking is disabled, do nothing. */
757 if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
758 return;
760 /* Compare the two string lengths. */
761 cond = fold_build2 (NE_EXPR, boolean_type_node, a, b);
763 /* Output the runtime-check. */
764 name = gfc_build_cstring_const (intr_name);
765 name = gfc_build_addr_expr (pchar_type_node, name);
766 gfc_trans_runtime_check (true, false, cond, target, where,
767 "Unequal character lengths (%ld/%ld) in %s",
768 fold_convert (long_integer_type_node, a),
769 fold_convert (long_integer_type_node, b), name);
773 /* The EXPONENT(s) intrinsic function is translated into
774 int ret;
775 frexp (s, &ret);
776 return ret;
779 static void
780 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
782 tree arg, type, res, tmp, frexp;
784 frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP,
785 expr->value.function.actual->expr->ts.kind);
787 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
789 res = gfc_create_var (integer_type_node, NULL);
790 tmp = build_call_expr_loc (input_location, frexp, 2, arg,
791 gfc_build_addr_expr (NULL_TREE, res));
792 gfc_add_expr_to_block (&se->pre, tmp);
794 type = gfc_typenode_for_spec (&expr->ts);
795 se->expr = fold_convert (type, res);
798 /* Evaluate a single upper or lower bound. */
799 /* TODO: bound intrinsic generates way too much unnecessary code. */
801 static void
802 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
804 gfc_actual_arglist *arg;
805 gfc_actual_arglist *arg2;
806 tree desc;
807 tree type;
808 tree bound;
809 tree tmp;
810 tree cond, cond1, cond3, cond4, size;
811 tree ubound;
812 tree lbound;
813 gfc_se argse;
814 gfc_ss *ss;
815 gfc_array_spec * as;
817 arg = expr->value.function.actual;
818 arg2 = arg->next;
820 if (se->ss)
822 /* Create an implicit second parameter from the loop variable. */
823 gcc_assert (!arg2->expr);
824 gcc_assert (se->loop->dimen == 1);
825 gcc_assert (se->ss->expr == expr);
826 gfc_advance_se_ss_chain (se);
827 bound = se->loop->loopvar[0];
828 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
829 se->loop->from[0]);
831 else
833 /* use the passed argument. */
834 gcc_assert (arg->next->expr);
835 gfc_init_se (&argse, NULL);
836 gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
837 gfc_add_block_to_block (&se->pre, &argse.pre);
838 bound = argse.expr;
839 /* Convert from one based to zero based. */
840 bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
841 gfc_index_one_node);
844 /* TODO: don't re-evaluate the descriptor on each iteration. */
845 /* Get a descriptor for the first parameter. */
846 ss = gfc_walk_expr (arg->expr);
847 gcc_assert (ss != gfc_ss_terminator);
848 gfc_init_se (&argse, NULL);
849 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
850 gfc_add_block_to_block (&se->pre, &argse.pre);
851 gfc_add_block_to_block (&se->post, &argse.post);
853 desc = argse.expr;
855 if (INTEGER_CST_P (bound))
857 int hi, low;
859 hi = TREE_INT_CST_HIGH (bound);
860 low = TREE_INT_CST_LOW (bound);
861 if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
862 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
863 "dimension index", upper ? "UBOUND" : "LBOUND",
864 &expr->where);
866 else
868 if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
870 bound = gfc_evaluate_now (bound, &se->pre);
871 cond = fold_build2 (LT_EXPR, boolean_type_node,
872 bound, build_int_cst (TREE_TYPE (bound), 0));
873 tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
874 tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
875 cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
876 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
877 gfc_msg_fault);
881 ubound = gfc_conv_descriptor_ubound_get (desc, bound);
882 lbound = gfc_conv_descriptor_lbound_get (desc, bound);
884 as = gfc_get_full_arrayspec_from_expr (arg->expr);
886 /* 13.14.53: Result value for LBOUND
888 Case (i): For an array section or for an array expression other than a
889 whole array or array structure component, LBOUND(ARRAY, DIM)
890 has the value 1. For a whole array or array structure
891 component, LBOUND(ARRAY, DIM) has the value:
892 (a) equal to the lower bound for subscript DIM of ARRAY if
893 dimension DIM of ARRAY does not have extent zero
894 or if ARRAY is an assumed-size array of rank DIM,
895 or (b) 1 otherwise.
897 13.14.113: Result value for UBOUND
899 Case (i): For an array section or for an array expression other than a
900 whole array or array structure component, UBOUND(ARRAY, DIM)
901 has the value equal to the number of elements in the given
902 dimension; otherwise, it has a value equal to the upper bound
903 for subscript DIM of ARRAY if dimension DIM of ARRAY does
904 not have size zero and has value zero if dimension DIM has
905 size zero. */
907 if (as)
909 tree stride = gfc_conv_descriptor_stride_get (desc, bound);
911 cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
913 cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
914 gfc_index_zero_node);
915 cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
917 cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
918 gfc_index_zero_node);
920 if (upper)
922 tree cond5;
923 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
925 cond5 = fold_build2 (EQ_EXPR, boolean_type_node, gfc_index_one_node, lbound);
926 cond5 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond5);
928 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond5);
930 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
931 ubound, gfc_index_zero_node);
933 else
935 if (as->type == AS_ASSUMED_SIZE)
936 cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
937 build_int_cst (TREE_TYPE (bound),
938 arg->expr->rank - 1));
939 else
940 cond = boolean_false_node;
942 cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
943 cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
945 se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
946 lbound, gfc_index_one_node);
949 else
951 if (upper)
953 size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
954 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
955 gfc_index_one_node);
956 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
957 gfc_index_zero_node);
959 else
960 se->expr = gfc_index_one_node;
963 type = gfc_typenode_for_spec (&expr->ts);
964 se->expr = convert (type, se->expr);
968 static void
969 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
971 tree arg, cabs;
973 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
975 switch (expr->value.function.actual->expr->ts.type)
977 case BT_INTEGER:
978 case BT_REAL:
979 se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
980 break;
982 case BT_COMPLEX:
983 cabs = builtin_decl_for_float_kind (BUILT_IN_CABS, expr->ts.kind);
984 se->expr = build_call_expr_loc (input_location, cabs, 1, arg);
985 break;
987 default:
988 gcc_unreachable ();
993 /* Create a complex value from one or two real components. */
995 static void
996 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
998 tree real;
999 tree imag;
1000 tree type;
1001 tree *args;
1002 unsigned int num_args;
1004 num_args = gfc_intrinsic_argument_list_length (expr);
1005 args = (tree *) alloca (sizeof (tree) * num_args);
1007 type = gfc_typenode_for_spec (&expr->ts);
1008 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1009 real = convert (TREE_TYPE (type), args[0]);
1010 if (both)
1011 imag = convert (TREE_TYPE (type), args[1]);
1012 else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1014 imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1015 args[0]);
1016 imag = convert (TREE_TYPE (type), imag);
1018 else
1019 imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1021 se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1024 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1025 MODULO(A, P) = A - FLOOR (A / P) * P */
1026 /* TODO: MOD(x, 0) */
1028 static void
1029 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1031 tree type;
1032 tree itype;
1033 tree tmp;
1034 tree test;
1035 tree test2;
1036 tree fmod;
1037 mpfr_t huge;
1038 int n, ikind;
1039 tree args[2];
1041 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1043 switch (expr->ts.type)
1045 case BT_INTEGER:
1046 /* Integer case is easy, we've got a builtin op. */
1047 type = TREE_TYPE (args[0]);
1049 if (modulo)
1050 se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1051 else
1052 se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1053 break;
1055 case BT_REAL:
1056 fmod = NULL_TREE;
1057 /* Check if we have a builtin fmod. */
1058 fmod = builtin_decl_for_float_kind (BUILT_IN_FMOD, expr->ts.kind);
1060 /* Use it if it exists. */
1061 if (fmod != NULL_TREE)
1063 tmp = build_addr (fmod, current_function_decl);
1064 se->expr = build_call_array_loc (input_location,
1065 TREE_TYPE (TREE_TYPE (fmod)),
1066 tmp, 2, args);
1067 if (modulo == 0)
1068 return;
1071 type = TREE_TYPE (args[0]);
1073 args[0] = gfc_evaluate_now (args[0], &se->pre);
1074 args[1] = gfc_evaluate_now (args[1], &se->pre);
1076 /* Definition:
1077 modulo = arg - floor (arg/arg2) * arg2, so
1078 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1079 where
1080 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1081 thereby avoiding another division and retaining the accuracy
1082 of the builtin function. */
1083 if (fmod != NULL_TREE && modulo)
1085 tree zero = gfc_build_const (type, integer_zero_node);
1086 tmp = gfc_evaluate_now (se->expr, &se->pre);
1087 test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1088 test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1089 test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1090 test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1091 test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1092 test = gfc_evaluate_now (test, &se->pre);
1093 se->expr = fold_build3 (COND_EXPR, type, test,
1094 fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1095 tmp);
1096 return;
1099 /* If we do not have a built_in fmod, the calculation is going to
1100 have to be done longhand. */
1101 tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1103 /* Test if the value is too large to handle sensibly. */
1104 gfc_set_model_kind (expr->ts.kind);
1105 mpfr_init (huge);
1106 n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1107 ikind = expr->ts.kind;
1108 if (n < 0)
1110 n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1111 ikind = gfc_max_integer_kind;
1113 mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1114 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1115 test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1117 mpfr_neg (huge, huge, GFC_RND_MODE);
1118 test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1119 test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1120 test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1122 itype = gfc_get_int_type (ikind);
1123 if (modulo)
1124 tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1125 else
1126 tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1127 tmp = convert (type, tmp);
1128 tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1129 tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1130 se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1131 mpfr_clear (huge);
1132 break;
1134 default:
1135 gcc_unreachable ();
1139 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1141 static void
1142 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1144 tree val;
1145 tree tmp;
1146 tree type;
1147 tree zero;
1148 tree args[2];
1150 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1151 type = TREE_TYPE (args[0]);
1153 val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1154 val = gfc_evaluate_now (val, &se->pre);
1156 zero = gfc_build_const (type, integer_zero_node);
1157 tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1158 se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1162 /* SIGN(A, B) is absolute value of A times sign of B.
1163 The real value versions use library functions to ensure the correct
1164 handling of negative zero. Integer case implemented as:
1165 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1168 static void
1169 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1171 tree tmp;
1172 tree type;
1173 tree args[2];
1175 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1176 if (expr->ts.type == BT_REAL)
1178 tree abs;
1180 tmp = builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
1181 abs = builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
1183 /* We explicitly have to ignore the minus sign. We do so by using
1184 result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1). */
1185 if (!gfc_option.flag_sign_zero
1186 && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
1188 tree cond, zero;
1189 zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
1190 cond = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
1191 se->expr = fold_build3 (COND_EXPR, TREE_TYPE (args[0]), cond,
1192 build_call_expr (abs, 1, args[0]),
1193 build_call_expr (tmp, 2, args[0], args[1]));
1195 else
1196 se->expr = build_call_expr_loc (input_location, tmp, 2,
1197 args[0], args[1]);
1198 return;
1201 /* Having excluded floating point types, we know we are now dealing
1202 with signed integer types. */
1203 type = TREE_TYPE (args[0]);
1205 /* Args[0] is used multiple times below. */
1206 args[0] = gfc_evaluate_now (args[0], &se->pre);
1208 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1209 the signs of A and B are the same, and of all ones if they differ. */
1210 tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1211 tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1212 build_int_cst (type, TYPE_PRECISION (type) - 1));
1213 tmp = gfc_evaluate_now (tmp, &se->pre);
1215 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1216 is all ones (i.e. -1). */
1217 se->expr = fold_build2 (BIT_XOR_EXPR, type,
1218 fold_build2 (PLUS_EXPR, type, args[0], tmp),
1219 tmp);
1223 /* Test for the presence of an optional argument. */
1225 static void
1226 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1228 gfc_expr *arg;
1230 arg = expr->value.function.actual->expr;
1231 gcc_assert (arg->expr_type == EXPR_VARIABLE);
1232 se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1233 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1237 /* Calculate the double precision product of two single precision values. */
1239 static void
1240 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1242 tree type;
1243 tree args[2];
1245 gfc_conv_intrinsic_function_args (se, expr, args, 2);
1247 /* Convert the args to double precision before multiplying. */
1248 type = gfc_typenode_for_spec (&expr->ts);
1249 args[0] = convert (type, args[0]);
1250 args[1] = convert (type, args[1]);
1251 se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1255 /* Return a length one character string containing an ascii character. */
1257 static void
1258 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1260 tree arg[2];
1261 tree var;
1262 tree type;
1263 unsigned int num_args;
1265 num_args = gfc_intrinsic_argument_list_length (expr);
1266 gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1268 type = gfc_get_char_type (expr->ts.kind);
1269 var = gfc_create_var (type, "char");
1271 arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1272 gfc_add_modify (&se->pre, var, arg[0]);
1273 se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1274 se->string_length = integer_one_node;
1278 static void
1279 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1281 tree var;
1282 tree len;
1283 tree tmp;
1284 tree cond;
1285 tree fndecl;
1286 tree *args;
1287 unsigned int num_args;
1289 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1290 args = (tree *) alloca (sizeof (tree) * num_args);
1292 var = gfc_create_var (pchar_type_node, "pstr");
1293 len = gfc_create_var (gfc_get_int_type (8), "len");
1295 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1296 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1297 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1299 fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1300 tmp = build_call_array_loc (input_location,
1301 TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1302 fndecl, num_args, args);
1303 gfc_add_expr_to_block (&se->pre, tmp);
1305 /* Free the temporary afterwards, if necessary. */
1306 cond = fold_build2 (GT_EXPR, boolean_type_node,
1307 len, build_int_cst (TREE_TYPE (len), 0));
1308 tmp = gfc_call_free (var);
1309 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1310 gfc_add_expr_to_block (&se->post, tmp);
1312 se->expr = var;
1313 se->string_length = len;
1317 static void
1318 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1320 tree var;
1321 tree len;
1322 tree tmp;
1323 tree cond;
1324 tree fndecl;
1325 tree *args;
1326 unsigned int num_args;
1328 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1329 args = (tree *) alloca (sizeof (tree) * num_args);
1331 var = gfc_create_var (pchar_type_node, "pstr");
1332 len = gfc_create_var (gfc_get_int_type (4), "len");
1334 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1335 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1336 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1338 fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1339 tmp = build_call_array_loc (input_location,
1340 TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1341 fndecl, num_args, args);
1342 gfc_add_expr_to_block (&se->pre, tmp);
1344 /* Free the temporary afterwards, if necessary. */
1345 cond = fold_build2 (GT_EXPR, boolean_type_node,
1346 len, build_int_cst (TREE_TYPE (len), 0));
1347 tmp = gfc_call_free (var);
1348 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1349 gfc_add_expr_to_block (&se->post, tmp);
1351 se->expr = var;
1352 se->string_length = len;
1356 /* Return a character string containing the tty name. */
1358 static void
1359 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1361 tree var;
1362 tree len;
1363 tree tmp;
1364 tree cond;
1365 tree fndecl;
1366 tree *args;
1367 unsigned int num_args;
1369 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1370 args = (tree *) alloca (sizeof (tree) * num_args);
1372 var = gfc_create_var (pchar_type_node, "pstr");
1373 len = gfc_create_var (gfc_get_int_type (4), "len");
1375 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1376 args[0] = gfc_build_addr_expr (NULL_TREE, var);
1377 args[1] = gfc_build_addr_expr (NULL_TREE, len);
1379 fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1380 tmp = build_call_array_loc (input_location,
1381 TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1382 fndecl, num_args, args);
1383 gfc_add_expr_to_block (&se->pre, tmp);
1385 /* Free the temporary afterwards, if necessary. */
1386 cond = fold_build2 (GT_EXPR, boolean_type_node,
1387 len, build_int_cst (TREE_TYPE (len), 0));
1388 tmp = gfc_call_free (var);
1389 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1390 gfc_add_expr_to_block (&se->post, tmp);
1392 se->expr = var;
1393 se->string_length = len;
1397 /* Get the minimum/maximum value of all the parameters.
1398 minmax (a1, a2, a3, ...)
1400 mvar = a1;
1401 if (a2 .op. mvar || isnan(mvar))
1402 mvar = a2;
1403 if (a3 .op. mvar || isnan(mvar))
1404 mvar = a3;
1406 return mvar
1410 /* TODO: Mismatching types can occur when specific names are used.
1411 These should be handled during resolution. */
1412 static void
1413 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
1415 tree tmp;
1416 tree mvar;
1417 tree val;
1418 tree thencase;
1419 tree *args;
1420 tree type;
1421 gfc_actual_arglist *argexpr;
1422 unsigned int i, nargs;
1424 nargs = gfc_intrinsic_argument_list_length (expr);
1425 args = (tree *) alloca (sizeof (tree) * nargs);
1427 gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1428 type = gfc_typenode_for_spec (&expr->ts);
1430 argexpr = expr->value.function.actual;
1431 if (TREE_TYPE (args[0]) != type)
1432 args[0] = convert (type, args[0]);
1433 /* Only evaluate the argument once. */
1434 if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1435 args[0] = gfc_evaluate_now (args[0], &se->pre);
1437 mvar = gfc_create_var (type, "M");
1438 gfc_add_modify (&se->pre, mvar, args[0]);
1439 for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1441 tree cond, isnan;
1443 val = args[i];
1445 /* Handle absent optional arguments by ignoring the comparison. */
1446 if (argexpr->expr->expr_type == EXPR_VARIABLE
1447 && argexpr->expr->symtree->n.sym->attr.optional
1448 && TREE_CODE (val) == INDIRECT_REF)
1449 cond = fold_build2_loc (input_location,
1450 NE_EXPR, boolean_type_node,
1451 TREE_OPERAND (val, 0),
1452 build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1453 else
1455 cond = NULL_TREE;
1457 /* Only evaluate the argument once. */
1458 if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1459 val = gfc_evaluate_now (val, &se->pre);
1462 thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1464 tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1466 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1467 __builtin_isnan might be made dependent on that module being loaded,
1468 to help performance of programs that don't rely on IEEE semantics. */
1469 if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1471 isnan = build_call_expr_loc (input_location,
1472 built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1473 tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1474 fold_convert (boolean_type_node, isnan));
1476 tmp = build3_v (COND_EXPR, tmp, thencase,
1477 build_empty_stmt (input_location));
1479 if (cond != NULL_TREE)
1480 tmp = build3_v (COND_EXPR, cond, tmp,
1481 build_empty_stmt (input_location));
1483 gfc_add_expr_to_block (&se->pre, tmp);
1484 argexpr = argexpr->next;
1486 se->expr = mvar;
1490 /* Generate library calls for MIN and MAX intrinsics for character
1491 variables. */
1492 static void
1493 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1495 tree *args;
1496 tree var, len, fndecl, tmp, cond, function;
1497 unsigned int nargs;
1499 nargs = gfc_intrinsic_argument_list_length (expr);
1500 args = (tree *) alloca (sizeof (tree) * (nargs + 4));
1501 gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1503 /* Create the result variables. */
1504 len = gfc_create_var (gfc_charlen_type_node, "len");
1505 args[0] = gfc_build_addr_expr (NULL_TREE, len);
1506 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1507 args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1508 args[2] = build_int_cst (NULL_TREE, op);
1509 args[3] = build_int_cst (NULL_TREE, nargs / 2);
1511 if (expr->ts.kind == 1)
1512 function = gfor_fndecl_string_minmax;
1513 else if (expr->ts.kind == 4)
1514 function = gfor_fndecl_string_minmax_char4;
1515 else
1516 gcc_unreachable ();
1518 /* Make the function call. */
1519 fndecl = build_addr (function, current_function_decl);
1520 tmp = build_call_array_loc (input_location,
1521 TREE_TYPE (TREE_TYPE (function)), fndecl,
1522 nargs + 4, args);
1523 gfc_add_expr_to_block (&se->pre, tmp);
1525 /* Free the temporary afterwards, if necessary. */
1526 cond = fold_build2 (GT_EXPR, boolean_type_node,
1527 len, build_int_cst (TREE_TYPE (len), 0));
1528 tmp = gfc_call_free (var);
1529 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1530 gfc_add_expr_to_block (&se->post, tmp);
1532 se->expr = var;
1533 se->string_length = len;
1537 /* Create a symbol node for this intrinsic. The symbol from the frontend
1538 has the generic name. */
1540 static gfc_symbol *
1541 gfc_get_symbol_for_expr (gfc_expr * expr)
1543 gfc_symbol *sym;
1545 /* TODO: Add symbols for intrinsic function to the global namespace. */
1546 gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1547 sym = gfc_new_symbol (expr->value.function.name, NULL);
1549 sym->ts = expr->ts;
1550 sym->attr.external = 1;
1551 sym->attr.function = 1;
1552 sym->attr.always_explicit = 1;
1553 sym->attr.proc = PROC_INTRINSIC;
1554 sym->attr.flavor = FL_PROCEDURE;
1555 sym->result = sym;
1556 if (expr->rank > 0)
1558 sym->attr.dimension = 1;
1559 sym->as = gfc_get_array_spec ();
1560 sym->as->type = AS_ASSUMED_SHAPE;
1561 sym->as->rank = expr->rank;
1564 /* TODO: proper argument lists for external intrinsics. */
1565 return sym;
1568 /* Generate a call to an external intrinsic function. */
1569 static void
1570 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1572 gfc_symbol *sym;
1573 tree append_args;
1575 gcc_assert (!se->ss || se->ss->expr == expr);
1577 if (se->ss)
1578 gcc_assert (expr->rank > 0);
1579 else
1580 gcc_assert (expr->rank == 0);
1582 sym = gfc_get_symbol_for_expr (expr);
1584 /* Calls to libgfortran_matmul need to be appended special arguments,
1585 to be able to call the BLAS ?gemm functions if required and possible. */
1586 append_args = NULL_TREE;
1587 if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1588 && sym->ts.type != BT_LOGICAL)
1590 tree cint = gfc_get_int_type (gfc_c_int_kind);
1592 if (gfc_option.flag_external_blas
1593 && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1594 && (sym->ts.kind == gfc_default_real_kind
1595 || sym->ts.kind == gfc_default_double_kind))
1597 tree gemm_fndecl;
1599 if (sym->ts.type == BT_REAL)
1601 if (sym->ts.kind == gfc_default_real_kind)
1602 gemm_fndecl = gfor_fndecl_sgemm;
1603 else
1604 gemm_fndecl = gfor_fndecl_dgemm;
1606 else
1608 if (sym->ts.kind == gfc_default_real_kind)
1609 gemm_fndecl = gfor_fndecl_cgemm;
1610 else
1611 gemm_fndecl = gfor_fndecl_zgemm;
1614 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 1));
1615 append_args = gfc_chainon_list
1616 (append_args, build_int_cst
1617 (cint, gfc_option.blas_matmul_limit));
1618 append_args = gfc_chainon_list (append_args,
1619 gfc_build_addr_expr (NULL_TREE,
1620 gemm_fndecl));
1622 else
1624 append_args = gfc_chainon_list (NULL_TREE, build_int_cst (cint, 0));
1625 append_args = gfc_chainon_list (append_args, build_int_cst (cint, 0));
1626 append_args = gfc_chainon_list (append_args, null_pointer_node);
1630 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
1631 append_args);
1632 gfc_free (sym);
1635 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1636 Implemented as
1637 any(a)
1639 forall (i=...)
1640 if (a[i] != 0)
1641 return 1
1642 end forall
1643 return 0
1645 all(a)
1647 forall (i=...)
1648 if (a[i] == 0)
1649 return 0
1650 end forall
1651 return 1
1654 static void
1655 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
1657 tree resvar;
1658 stmtblock_t block;
1659 stmtblock_t body;
1660 tree type;
1661 tree tmp;
1662 tree found;
1663 gfc_loopinfo loop;
1664 gfc_actual_arglist *actual;
1665 gfc_ss *arrayss;
1666 gfc_se arrayse;
1667 tree exit_label;
1669 if (se->ss)
1671 gfc_conv_intrinsic_funcall (se, expr);
1672 return;
1675 actual = expr->value.function.actual;
1676 type = gfc_typenode_for_spec (&expr->ts);
1677 /* Initialize the result. */
1678 resvar = gfc_create_var (type, "test");
1679 if (op == EQ_EXPR)
1680 tmp = convert (type, boolean_true_node);
1681 else
1682 tmp = convert (type, boolean_false_node);
1683 gfc_add_modify (&se->pre, resvar, tmp);
1685 /* Walk the arguments. */
1686 arrayss = gfc_walk_expr (actual->expr);
1687 gcc_assert (arrayss != gfc_ss_terminator);
1689 /* Initialize the scalarizer. */
1690 gfc_init_loopinfo (&loop);
1691 exit_label = gfc_build_label_decl (NULL_TREE);
1692 TREE_USED (exit_label) = 1;
1693 gfc_add_ss_to_loop (&loop, arrayss);
1695 /* Initialize the loop. */
1696 gfc_conv_ss_startstride (&loop);
1697 gfc_conv_loop_setup (&loop, &expr->where);
1699 gfc_mark_ss_chain_used (arrayss, 1);
1700 /* Generate the loop body. */
1701 gfc_start_scalarized_body (&loop, &body);
1703 /* If the condition matches then set the return value. */
1704 gfc_start_block (&block);
1705 if (op == EQ_EXPR)
1706 tmp = convert (type, boolean_false_node);
1707 else
1708 tmp = convert (type, boolean_true_node);
1709 gfc_add_modify (&block, resvar, tmp);
1711 /* And break out of the loop. */
1712 tmp = build1_v (GOTO_EXPR, exit_label);
1713 gfc_add_expr_to_block (&block, tmp);
1715 found = gfc_finish_block (&block);
1717 /* Check this element. */
1718 gfc_init_se (&arrayse, NULL);
1719 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1720 arrayse.ss = arrayss;
1721 gfc_conv_expr_val (&arrayse, actual->expr);
1723 gfc_add_block_to_block (&body, &arrayse.pre);
1724 tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1725 build_int_cst (TREE_TYPE (arrayse.expr), 0));
1726 tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
1727 gfc_add_expr_to_block (&body, tmp);
1728 gfc_add_block_to_block (&body, &arrayse.post);
1730 gfc_trans_scalarizing_loops (&loop, &body);
1732 /* Add the exit label. */
1733 tmp = build1_v (LABEL_EXPR, exit_label);
1734 gfc_add_expr_to_block (&loop.pre, tmp);
1736 gfc_add_block_to_block (&se->pre, &loop.pre);
1737 gfc_add_block_to_block (&se->pre, &loop.post);
1738 gfc_cleanup_loop (&loop);
1740 se->expr = resvar;
1743 /* COUNT(A) = Number of true elements in A. */
1744 static void
1745 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1747 tree resvar;
1748 tree type;
1749 stmtblock_t body;
1750 tree tmp;
1751 gfc_loopinfo loop;
1752 gfc_actual_arglist *actual;
1753 gfc_ss *arrayss;
1754 gfc_se arrayse;
1756 if (se->ss)
1758 gfc_conv_intrinsic_funcall (se, expr);
1759 return;
1762 actual = expr->value.function.actual;
1764 type = gfc_typenode_for_spec (&expr->ts);
1765 /* Initialize the result. */
1766 resvar = gfc_create_var (type, "count");
1767 gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1769 /* Walk the arguments. */
1770 arrayss = gfc_walk_expr (actual->expr);
1771 gcc_assert (arrayss != gfc_ss_terminator);
1773 /* Initialize the scalarizer. */
1774 gfc_init_loopinfo (&loop);
1775 gfc_add_ss_to_loop (&loop, arrayss);
1777 /* Initialize the loop. */
1778 gfc_conv_ss_startstride (&loop);
1779 gfc_conv_loop_setup (&loop, &expr->where);
1781 gfc_mark_ss_chain_used (arrayss, 1);
1782 /* Generate the loop body. */
1783 gfc_start_scalarized_body (&loop, &body);
1785 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1786 resvar, build_int_cst (TREE_TYPE (resvar), 1));
1787 tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1789 gfc_init_se (&arrayse, NULL);
1790 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1791 arrayse.ss = arrayss;
1792 gfc_conv_expr_val (&arrayse, actual->expr);
1793 tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
1794 build_empty_stmt (input_location));
1796 gfc_add_block_to_block (&body, &arrayse.pre);
1797 gfc_add_expr_to_block (&body, tmp);
1798 gfc_add_block_to_block (&body, &arrayse.post);
1800 gfc_trans_scalarizing_loops (&loop, &body);
1802 gfc_add_block_to_block (&se->pre, &loop.pre);
1803 gfc_add_block_to_block (&se->pre, &loop.post);
1804 gfc_cleanup_loop (&loop);
1806 se->expr = resvar;
1809 /* Inline implementation of the sum and product intrinsics. */
1810 static void
1811 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
1813 tree resvar;
1814 tree type;
1815 stmtblock_t body;
1816 stmtblock_t block;
1817 tree tmp;
1818 gfc_loopinfo loop;
1819 gfc_actual_arglist *actual;
1820 gfc_ss *arrayss;
1821 gfc_ss *maskss;
1822 gfc_se arrayse;
1823 gfc_se maskse;
1824 gfc_expr *arrayexpr;
1825 gfc_expr *maskexpr;
1827 if (se->ss)
1829 gfc_conv_intrinsic_funcall (se, expr);
1830 return;
1833 type = gfc_typenode_for_spec (&expr->ts);
1834 /* Initialize the result. */
1835 resvar = gfc_create_var (type, "val");
1836 if (op == PLUS_EXPR)
1837 tmp = gfc_build_const (type, integer_zero_node);
1838 else
1839 tmp = gfc_build_const (type, integer_one_node);
1841 gfc_add_modify (&se->pre, resvar, tmp);
1843 /* Walk the arguments. */
1844 actual = expr->value.function.actual;
1845 arrayexpr = actual->expr;
1846 arrayss = gfc_walk_expr (arrayexpr);
1847 gcc_assert (arrayss != gfc_ss_terminator);
1849 actual = actual->next->next;
1850 gcc_assert (actual);
1851 maskexpr = actual->expr;
1852 if (maskexpr && maskexpr->rank != 0)
1854 maskss = gfc_walk_expr (maskexpr);
1855 gcc_assert (maskss != gfc_ss_terminator);
1857 else
1858 maskss = NULL;
1860 /* Initialize the scalarizer. */
1861 gfc_init_loopinfo (&loop);
1862 gfc_add_ss_to_loop (&loop, arrayss);
1863 if (maskss)
1864 gfc_add_ss_to_loop (&loop, maskss);
1866 /* Initialize the loop. */
1867 gfc_conv_ss_startstride (&loop);
1868 gfc_conv_loop_setup (&loop, &expr->where);
1870 gfc_mark_ss_chain_used (arrayss, 1);
1871 if (maskss)
1872 gfc_mark_ss_chain_used (maskss, 1);
1873 /* Generate the loop body. */
1874 gfc_start_scalarized_body (&loop, &body);
1876 /* If we have a mask, only add this element if the mask is set. */
1877 if (maskss)
1879 gfc_init_se (&maskse, NULL);
1880 gfc_copy_loopinfo_to_se (&maskse, &loop);
1881 maskse.ss = maskss;
1882 gfc_conv_expr_val (&maskse, maskexpr);
1883 gfc_add_block_to_block (&body, &maskse.pre);
1885 gfc_start_block (&block);
1887 else
1888 gfc_init_block (&block);
1890 /* Do the actual summation/product. */
1891 gfc_init_se (&arrayse, NULL);
1892 gfc_copy_loopinfo_to_se (&arrayse, &loop);
1893 arrayse.ss = arrayss;
1894 gfc_conv_expr_val (&arrayse, arrayexpr);
1895 gfc_add_block_to_block (&block, &arrayse.pre);
1897 tmp = fold_build2 (op, type, resvar, arrayse.expr);
1898 gfc_add_modify (&block, resvar, tmp);
1899 gfc_add_block_to_block (&block, &arrayse.post);
1901 if (maskss)
1903 /* We enclose the above in if (mask) {...} . */
1904 tmp = gfc_finish_block (&block);
1906 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
1907 build_empty_stmt (input_location));
1909 else
1910 tmp = gfc_finish_block (&block);
1911 gfc_add_expr_to_block (&body, tmp);
1913 gfc_trans_scalarizing_loops (&loop, &body);
1915 /* For a scalar mask, enclose the loop in an if statement. */
1916 if (maskexpr && maskss == NULL)
1918 gfc_init_se (&maskse, NULL);
1919 gfc_conv_expr_val (&maskse, maskexpr);
1920 gfc_init_block (&block);
1921 gfc_add_block_to_block (&block, &loop.pre);
1922 gfc_add_block_to_block (&block, &loop.post);
1923 tmp = gfc_finish_block (&block);
1925 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
1926 build_empty_stmt (input_location));
1927 gfc_add_expr_to_block (&block, tmp);
1928 gfc_add_block_to_block (&se->pre, &block);
1930 else
1932 gfc_add_block_to_block (&se->pre, &loop.pre);
1933 gfc_add_block_to_block (&se->pre, &loop.post);
1936 gfc_cleanup_loop (&loop);
1938 se->expr = resvar;
1942 /* Inline implementation of the dot_product intrinsic. This function
1943 is based on gfc_conv_intrinsic_arith (the previous function). */
1944 static void
1945 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1947 tree resvar;
1948 tree type;
1949 stmtblock_t body;
1950 stmtblock_t block;
1951 tree tmp;
1952 gfc_loopinfo loop;
1953 gfc_actual_arglist *actual;
1954 gfc_ss *arrayss1, *arrayss2;
1955 gfc_se arrayse1, arrayse2;
1956 gfc_expr *arrayexpr1, *arrayexpr2;
1958 type = gfc_typenode_for_spec (&expr->ts);
1960 /* Initialize the result. */
1961 resvar = gfc_create_var (type, "val");
1962 if (expr->ts.type == BT_LOGICAL)
1963 tmp = build_int_cst (type, 0);
1964 else
1965 tmp = gfc_build_const (type, integer_zero_node);
1967 gfc_add_modify (&se->pre, resvar, tmp);
1969 /* Walk argument #1. */
1970 actual = expr->value.function.actual;
1971 arrayexpr1 = actual->expr;
1972 arrayss1 = gfc_walk_expr (arrayexpr1);
1973 gcc_assert (arrayss1 != gfc_ss_terminator);
1975 /* Walk argument #2. */
1976 actual = actual->next;
1977 arrayexpr2 = actual->expr;
1978 arrayss2 = gfc_walk_expr (arrayexpr2);
1979 gcc_assert (arrayss2 != gfc_ss_terminator);
1981 /* Initialize the scalarizer. */
1982 gfc_init_loopinfo (&loop);
1983 gfc_add_ss_to_loop (&loop, arrayss1);
1984 gfc_add_ss_to_loop (&loop, arrayss2);
1986 /* Initialize the loop. */
1987 gfc_conv_ss_startstride (&loop);
1988 gfc_conv_loop_setup (&loop, &expr->where);
1990 gfc_mark_ss_chain_used (arrayss1, 1);
1991 gfc_mark_ss_chain_used (arrayss2, 1);
1993 /* Generate the loop body. */
1994 gfc_start_scalarized_body (&loop, &body);
1995 gfc_init_block (&block);
1997 /* Make the tree expression for [conjg(]array1[)]. */
1998 gfc_init_se (&arrayse1, NULL);
1999 gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2000 arrayse1.ss = arrayss1;
2001 gfc_conv_expr_val (&arrayse1, arrayexpr1);
2002 if (expr->ts.type == BT_COMPLEX)
2003 arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2004 gfc_add_block_to_block (&block, &arrayse1.pre);
2006 /* Make the tree expression for array2. */
2007 gfc_init_se (&arrayse2, NULL);
2008 gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2009 arrayse2.ss = arrayss2;
2010 gfc_conv_expr_val (&arrayse2, arrayexpr2);
2011 gfc_add_block_to_block (&block, &arrayse2.pre);
2013 /* Do the actual product and sum. */
2014 if (expr->ts.type == BT_LOGICAL)
2016 tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2017 tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2019 else
2021 tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2022 tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2024 gfc_add_modify (&block, resvar, tmp);
2026 /* Finish up the loop block and the loop. */
2027 tmp = gfc_finish_block (&block);
2028 gfc_add_expr_to_block (&body, tmp);
2030 gfc_trans_scalarizing_loops (&loop, &body);
2031 gfc_add_block_to_block (&se->pre, &loop.pre);
2032 gfc_add_block_to_block (&se->pre, &loop.post);
2033 gfc_cleanup_loop (&loop);
2035 se->expr = resvar;
2039 /* Emit code for minloc or maxloc intrinsic. There are many different cases
2040 we need to handle. For performance reasons we sometimes create two
2041 loops instead of one, where the second one is much simpler.
2042 Examples for minloc intrinsic:
2043 1) Result is an array, a call is generated
2044 2) Array mask is used and NaNs need to be supported:
2045 limit = Infinity;
2046 pos = 0;
2047 S = from;
2048 while (S <= to) {
2049 if (mask[S]) {
2050 if (pos == 0) pos = S + (1 - from);
2051 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2053 S++;
2055 goto lab2;
2056 lab1:;
2057 while (S <= to) {
2058 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2059 S++;
2061 lab2:;
2062 3) NaNs need to be supported, but it is known at compile time or cheaply
2063 at runtime whether array is nonempty or not:
2064 limit = Infinity;
2065 pos = 0;
2066 S = from;
2067 while (S <= to) {
2068 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2069 S++;
2071 if (from <= to) pos = 1;
2072 goto lab2;
2073 lab1:;
2074 while (S <= to) {
2075 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2076 S++;
2078 lab2:;
2079 4) NaNs aren't supported, array mask is used:
2080 limit = infinities_supported ? Infinity : huge (limit);
2081 pos = 0;
2082 S = from;
2083 while (S <= to) {
2084 if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2085 S++;
2087 goto lab2;
2088 lab1:;
2089 while (S <= to) {
2090 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2091 S++;
2093 lab2:;
2094 5) Same without array mask:
2095 limit = infinities_supported ? Infinity : huge (limit);
2096 pos = (from <= to) ? 1 : 0;
2097 S = from;
2098 while (S <= to) {
2099 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2100 S++;
2102 For 3) and 5), if mask is scalar, this all goes into a conditional,
2103 setting pos = 0; in the else branch. */
2105 static void
2106 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
2108 stmtblock_t body;
2109 stmtblock_t block;
2110 stmtblock_t ifblock;
2111 stmtblock_t elseblock;
2112 tree limit;
2113 tree type;
2114 tree tmp;
2115 tree cond;
2116 tree elsetmp;
2117 tree ifbody;
2118 tree offset;
2119 tree nonempty;
2120 tree lab1, lab2;
2121 gfc_loopinfo loop;
2122 gfc_actual_arglist *actual;
2123 gfc_ss *arrayss;
2124 gfc_ss *maskss;
2125 gfc_se arrayse;
2126 gfc_se maskse;
2127 gfc_expr *arrayexpr;
2128 gfc_expr *maskexpr;
2129 tree pos;
2130 int n;
2132 if (se->ss)
2134 gfc_conv_intrinsic_funcall (se, expr);
2135 return;
2138 /* Initialize the result. */
2139 pos = gfc_create_var (gfc_array_index_type, "pos");
2140 offset = gfc_create_var (gfc_array_index_type, "offset");
2141 type = gfc_typenode_for_spec (&expr->ts);
2143 /* Walk the arguments. */
2144 actual = expr->value.function.actual;
2145 arrayexpr = actual->expr;
2146 arrayss = gfc_walk_expr (arrayexpr);
2147 gcc_assert (arrayss != gfc_ss_terminator);
2149 actual = actual->next->next;
2150 gcc_assert (actual);
2151 maskexpr = actual->expr;
2152 nonempty = NULL;
2153 if (maskexpr && maskexpr->rank != 0)
2155 maskss = gfc_walk_expr (maskexpr);
2156 gcc_assert (maskss != gfc_ss_terminator);
2158 else
2160 mpz_t asize;
2161 if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2163 nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2164 mpz_clear (asize);
2165 nonempty = fold_build2 (GT_EXPR, boolean_type_node, nonempty,
2166 gfc_index_zero_node);
2168 maskss = NULL;
2171 limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2172 n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2173 switch (arrayexpr->ts.type)
2175 case BT_REAL:
2176 if (HONOR_INFINITIES (DECL_MODE (limit)))
2178 REAL_VALUE_TYPE real;
2179 real_inf (&real);
2180 tmp = build_real (TREE_TYPE (limit), real);
2182 else
2183 tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2184 arrayexpr->ts.kind, 0);
2185 break;
2187 case BT_INTEGER:
2188 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2189 arrayexpr->ts.kind);
2190 break;
2192 default:
2193 gcc_unreachable ();
2196 /* We start with the most negative possible value for MAXLOC, and the most
2197 positive possible value for MINLOC. The most negative possible value is
2198 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2199 possible value is HUGE in both cases. */
2200 if (op == GT_EXPR)
2201 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2202 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2203 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2204 build_int_cst (type, 1));
2206 gfc_add_modify (&se->pre, limit, tmp);
2208 /* Initialize the scalarizer. */
2209 gfc_init_loopinfo (&loop);
2210 gfc_add_ss_to_loop (&loop, arrayss);
2211 if (maskss)
2212 gfc_add_ss_to_loop (&loop, maskss);
2214 /* Initialize the loop. */
2215 gfc_conv_ss_startstride (&loop);
2216 gfc_conv_loop_setup (&loop, &expr->where);
2218 gcc_assert (loop.dimen == 1);
2219 if (nonempty == NULL && maskss == NULL && loop.from[0] && loop.to[0])
2220 nonempty = fold_build2 (LE_EXPR, boolean_type_node, loop.from[0],
2221 loop.to[0]);
2223 lab1 = NULL;
2224 lab2 = NULL;
2225 /* Initialize the position to zero, following Fortran 2003. We are free
2226 to do this because Fortran 95 allows the result of an entirely false
2227 mask to be processor dependent. If we know at compile time the array
2228 is non-empty and no MASK is used, we can initialize to 1 to simplify
2229 the inner loop. */
2230 if (nonempty != NULL && !HONOR_NANS (DECL_MODE (limit)))
2231 gfc_add_modify (&loop.pre, pos,
2232 fold_build3 (COND_EXPR, gfc_array_index_type,
2233 nonempty, gfc_index_one_node,
2234 gfc_index_zero_node));
2235 else
2237 gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2238 lab1 = gfc_build_label_decl (NULL_TREE);
2239 TREE_USED (lab1) = 1;
2240 lab2 = gfc_build_label_decl (NULL_TREE);
2241 TREE_USED (lab2) = 1;
2244 gfc_mark_ss_chain_used (arrayss, 1);
2245 if (maskss)
2246 gfc_mark_ss_chain_used (maskss, 1);
2247 /* Generate the loop body. */
2248 gfc_start_scalarized_body (&loop, &body);
2250 /* If we have a mask, only check this element if the mask is set. */
2251 if (maskss)
2253 gfc_init_se (&maskse, NULL);
2254 gfc_copy_loopinfo_to_se (&maskse, &loop);
2255 maskse.ss = maskss;
2256 gfc_conv_expr_val (&maskse, maskexpr);
2257 gfc_add_block_to_block (&body, &maskse.pre);
2259 gfc_start_block (&block);
2261 else
2262 gfc_init_block (&block);
2264 /* Compare with the current limit. */
2265 gfc_init_se (&arrayse, NULL);
2266 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2267 arrayse.ss = arrayss;
2268 gfc_conv_expr_val (&arrayse, arrayexpr);
2269 gfc_add_block_to_block (&block, &arrayse.pre);
2271 /* We do the following if this is a more extreme value. */
2272 gfc_start_block (&ifblock);
2274 /* Assign the value to the limit... */
2275 gfc_add_modify (&ifblock, limit, arrayse.expr);
2277 /* Remember where we are. An offset must be added to the loop
2278 counter to obtain the required position. */
2279 if (loop.from[0])
2280 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2281 gfc_index_one_node, loop.from[0]);
2282 else
2283 tmp = gfc_index_one_node;
2285 gfc_add_modify (&block, offset, tmp);
2287 if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
2289 stmtblock_t ifblock2;
2290 tree ifbody2;
2292 gfc_start_block (&ifblock2);
2293 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2294 loop.loopvar[0], offset);
2295 gfc_add_modify (&ifblock2, pos, tmp);
2296 ifbody2 = gfc_finish_block (&ifblock2);
2297 cond = fold_build2 (EQ_EXPR, boolean_type_node, pos,
2298 gfc_index_zero_node);
2299 tmp = build3_v (COND_EXPR, cond, ifbody2,
2300 build_empty_stmt (input_location));
2301 gfc_add_expr_to_block (&block, tmp);
2304 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2305 loop.loopvar[0], offset);
2306 gfc_add_modify (&ifblock, pos, tmp);
2308 if (lab1)
2309 gfc_add_expr_to_block (&ifblock, build1_v (GOTO_EXPR, lab1));
2311 ifbody = gfc_finish_block (&ifblock);
2313 if (!lab1 || HONOR_NANS (DECL_MODE (limit)))
2315 if (lab1)
2316 cond = fold_build2 (op == GT_EXPR ? GE_EXPR : LE_EXPR,
2317 boolean_type_node, arrayse.expr, limit);
2318 else
2319 cond = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2321 ifbody = build3_v (COND_EXPR, cond, ifbody,
2322 build_empty_stmt (input_location));
2324 gfc_add_expr_to_block (&block, ifbody);
2326 if (maskss)
2328 /* We enclose the above in if (mask) {...}. */
2329 tmp = gfc_finish_block (&block);
2331 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2332 build_empty_stmt (input_location));
2334 else
2335 tmp = gfc_finish_block (&block);
2336 gfc_add_expr_to_block (&body, tmp);
2338 if (lab1)
2340 gfc_trans_scalarized_loop_end (&loop, 0, &body);
2342 if (HONOR_NANS (DECL_MODE (limit)))
2344 if (nonempty != NULL)
2346 ifbody = build2_v (MODIFY_EXPR, pos, gfc_index_one_node);
2347 tmp = build3_v (COND_EXPR, nonempty, ifbody,
2348 build_empty_stmt (input_location));
2349 gfc_add_expr_to_block (&loop.code[0], tmp);
2353 gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
2354 gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
2355 gfc_start_block (&body);
2357 /* If we have a mask, only check this element if the mask is set. */
2358 if (maskss)
2360 gfc_init_se (&maskse, NULL);
2361 gfc_copy_loopinfo_to_se (&maskse, &loop);
2362 maskse.ss = maskss;
2363 gfc_conv_expr_val (&maskse, maskexpr);
2364 gfc_add_block_to_block (&body, &maskse.pre);
2366 gfc_start_block (&block);
2368 else
2369 gfc_init_block (&block);
2371 /* Compare with the current limit. */
2372 gfc_init_se (&arrayse, NULL);
2373 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2374 arrayse.ss = arrayss;
2375 gfc_conv_expr_val (&arrayse, arrayexpr);
2376 gfc_add_block_to_block (&block, &arrayse.pre);
2378 /* We do the following if this is a more extreme value. */
2379 gfc_start_block (&ifblock);
2381 /* Assign the value to the limit... */
2382 gfc_add_modify (&ifblock, limit, arrayse.expr);
2384 /* Remember where we are. An offset must be added to the loop
2385 counter to obtain the required position. */
2386 if (loop.from[0])
2387 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2388 gfc_index_one_node, loop.from[0]);
2389 else
2390 tmp = gfc_index_one_node;
2392 gfc_add_modify (&block, offset, tmp);
2394 tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2395 loop.loopvar[0], offset);
2396 gfc_add_modify (&ifblock, pos, tmp);
2398 ifbody = gfc_finish_block (&ifblock);
2400 cond = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2402 tmp = build3_v (COND_EXPR, cond, ifbody,
2403 build_empty_stmt (input_location));
2404 gfc_add_expr_to_block (&block, tmp);
2406 if (maskss)
2408 /* We enclose the above in if (mask) {...}. */
2409 tmp = gfc_finish_block (&block);
2411 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2412 build_empty_stmt (input_location));
2414 else
2415 tmp = gfc_finish_block (&block);
2416 gfc_add_expr_to_block (&body, tmp);
2417 /* Avoid initializing loopvar[0] again, it should be left where
2418 it finished by the first loop. */
2419 loop.from[0] = loop.loopvar[0];
2422 gfc_trans_scalarizing_loops (&loop, &body);
2424 if (lab2)
2425 gfc_add_expr_to_block (&loop.pre, build1_v (LABEL_EXPR, lab2));
2427 /* For a scalar mask, enclose the loop in an if statement. */
2428 if (maskexpr && maskss == NULL)
2430 gfc_init_se (&maskse, NULL);
2431 gfc_conv_expr_val (&maskse, maskexpr);
2432 gfc_init_block (&block);
2433 gfc_add_block_to_block (&block, &loop.pre);
2434 gfc_add_block_to_block (&block, &loop.post);
2435 tmp = gfc_finish_block (&block);
2437 /* For the else part of the scalar mask, just initialize
2438 the pos variable the same way as above. */
2440 gfc_init_block (&elseblock);
2441 gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2442 elsetmp = gfc_finish_block (&elseblock);
2444 tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2445 gfc_add_expr_to_block (&block, tmp);
2446 gfc_add_block_to_block (&se->pre, &block);
2448 else
2450 gfc_add_block_to_block (&se->pre, &loop.pre);
2451 gfc_add_block_to_block (&se->pre, &loop.post);
2453 gfc_cleanup_loop (&loop);
2455 se->expr = convert (type, pos);
2458 /* Emit code for minval or maxval intrinsic. There are many different cases
2459 we need to handle. For performance reasons we sometimes create two
2460 loops instead of one, where the second one is much simpler.
2461 Examples for minval intrinsic:
2462 1) Result is an array, a call is generated
2463 2) Array mask is used and NaNs need to be supported, rank 1:
2464 limit = Infinity;
2465 nonempty = false;
2466 S = from;
2467 while (S <= to) {
2468 if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
2469 S++;
2471 limit = nonempty ? NaN : huge (limit);
2472 lab:
2473 while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
2474 3) NaNs need to be supported, but it is known at compile time or cheaply
2475 at runtime whether array is nonempty or not, rank 1:
2476 limit = Infinity;
2477 S = from;
2478 while (S <= to) { if (a[S] <= limit) goto lab; S++; }
2479 limit = (from <= to) ? NaN : huge (limit);
2480 lab:
2481 while (S <= to) { limit = min (a[S], limit); S++; }
2482 4) Array mask is used and NaNs need to be supported, rank > 1:
2483 limit = Infinity;
2484 nonempty = false;
2485 fast = false;
2486 S1 = from1;
2487 while (S1 <= to1) {
2488 S2 = from2;
2489 while (S2 <= to2) {
2490 if (mask[S1][S2]) {
2491 if (fast) limit = min (a[S1][S2], limit);
2492 else {
2493 nonempty = true;
2494 if (a[S1][S2] <= limit) {
2495 limit = a[S1][S2];
2496 fast = true;
2500 S2++;
2502 S1++;
2504 if (!fast)
2505 limit = nonempty ? NaN : huge (limit);
2506 5) NaNs need to be supported, but it is known at compile time or cheaply
2507 at runtime whether array is nonempty or not, rank > 1:
2508 limit = Infinity;
2509 fast = false;
2510 S1 = from1;
2511 while (S1 <= to1) {
2512 S2 = from2;
2513 while (S2 <= to2) {
2514 if (fast) limit = min (a[S1][S2], limit);
2515 else {
2516 if (a[S1][S2] <= limit) {
2517 limit = a[S1][S2];
2518 fast = true;
2521 S2++;
2523 S1++;
2525 if (!fast)
2526 limit = (nonempty_array) ? NaN : huge (limit);
2527 6) NaNs aren't supported, but infinities are. Array mask is used:
2528 limit = Infinity;
2529 nonempty = false;
2530 S = from;
2531 while (S <= to) {
2532 if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
2533 S++;
2535 limit = nonempty ? limit : huge (limit);
2536 7) Same without array mask:
2537 limit = Infinity;
2538 S = from;
2539 while (S <= to) { limit = min (a[S], limit); S++; }
2540 limit = (from <= to) ? limit : huge (limit);
2541 8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
2542 limit = huge (limit);
2543 S = from;
2544 while (S <= to) { limit = min (a[S], limit); S++); }
2546 while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
2547 with array mask instead).
2548 For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
2549 setting limit = huge (limit); in the else branch. */
2551 static void
2552 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
2554 tree limit;
2555 tree type;
2556 tree tmp;
2557 tree ifbody;
2558 tree nonempty;
2559 tree nonempty_var;
2560 tree lab;
2561 tree fast;
2562 tree huge_cst = NULL, nan_cst = NULL;
2563 stmtblock_t body;
2564 stmtblock_t block, block2;
2565 gfc_loopinfo loop;
2566 gfc_actual_arglist *actual;
2567 gfc_ss *arrayss;
2568 gfc_ss *maskss;
2569 gfc_se arrayse;
2570 gfc_se maskse;
2571 gfc_expr *arrayexpr;
2572 gfc_expr *maskexpr;
2573 int n;
2575 if (se->ss)
2577 gfc_conv_intrinsic_funcall (se, expr);
2578 return;
2581 type = gfc_typenode_for_spec (&expr->ts);
2582 /* Initialize the result. */
2583 limit = gfc_create_var (type, "limit");
2584 n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2585 switch (expr->ts.type)
2587 case BT_REAL:
2588 huge_cst = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2589 expr->ts.kind, 0);
2590 if (HONOR_INFINITIES (DECL_MODE (limit)))
2592 REAL_VALUE_TYPE real;
2593 real_inf (&real);
2594 tmp = build_real (type, real);
2596 else
2597 tmp = huge_cst;
2598 if (HONOR_NANS (DECL_MODE (limit)))
2600 REAL_VALUE_TYPE real;
2601 real_nan (&real, "", 1, DECL_MODE (limit));
2602 nan_cst = build_real (type, real);
2604 break;
2606 case BT_INTEGER:
2607 tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2608 break;
2610 default:
2611 gcc_unreachable ();
2614 /* We start with the most negative possible value for MAXVAL, and the most
2615 positive possible value for MINVAL. The most negative possible value is
2616 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2617 possible value is HUGE in both cases. */
2618 if (op == GT_EXPR)
2620 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2621 if (huge_cst)
2622 huge_cst = fold_build1 (NEGATE_EXPR, TREE_TYPE (huge_cst), huge_cst);
2625 if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2626 tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2627 tmp, build_int_cst (type, 1));
2629 gfc_add_modify (&se->pre, limit, tmp);
2631 /* Walk the arguments. */
2632 actual = expr->value.function.actual;
2633 arrayexpr = actual->expr;
2634 arrayss = gfc_walk_expr (arrayexpr);
2635 gcc_assert (arrayss != gfc_ss_terminator);
2637 actual = actual->next->next;
2638 gcc_assert (actual);
2639 maskexpr = actual->expr;
2640 nonempty = NULL;
2641 if (maskexpr && maskexpr->rank != 0)
2643 maskss = gfc_walk_expr (maskexpr);
2644 gcc_assert (maskss != gfc_ss_terminator);
2646 else
2648 mpz_t asize;
2649 if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2651 nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2652 mpz_clear (asize);
2653 nonempty = fold_build2 (GT_EXPR, boolean_type_node, nonempty,
2654 gfc_index_zero_node);
2656 maskss = NULL;
2659 /* Initialize the scalarizer. */
2660 gfc_init_loopinfo (&loop);
2661 gfc_add_ss_to_loop (&loop, arrayss);
2662 if (maskss)
2663 gfc_add_ss_to_loop (&loop, maskss);
2665 /* Initialize the loop. */
2666 gfc_conv_ss_startstride (&loop);
2667 gfc_conv_loop_setup (&loop, &expr->where);
2669 if (nonempty == NULL && maskss == NULL
2670 && loop.dimen == 1 && loop.from[0] && loop.to[0])
2671 nonempty = fold_build2 (LE_EXPR, boolean_type_node, loop.from[0],
2672 loop.to[0]);
2673 nonempty_var = NULL;
2674 if (nonempty == NULL
2675 && (HONOR_INFINITIES (DECL_MODE (limit))
2676 || HONOR_NANS (DECL_MODE (limit))))
2678 nonempty_var = gfc_create_var (boolean_type_node, "nonempty");
2679 gfc_add_modify (&se->pre, nonempty_var, boolean_false_node);
2680 nonempty = nonempty_var;
2682 lab = NULL;
2683 fast = NULL;
2684 if (HONOR_NANS (DECL_MODE (limit)))
2686 if (loop.dimen == 1)
2688 lab = gfc_build_label_decl (NULL_TREE);
2689 TREE_USED (lab) = 1;
2691 else
2693 fast = gfc_create_var (boolean_type_node, "fast");
2694 gfc_add_modify (&se->pre, fast, boolean_false_node);
2698 gfc_mark_ss_chain_used (arrayss, 1);
2699 if (maskss)
2700 gfc_mark_ss_chain_used (maskss, 1);
2701 /* Generate the loop body. */
2702 gfc_start_scalarized_body (&loop, &body);
2704 /* If we have a mask, only add this element if the mask is set. */
2705 if (maskss)
2707 gfc_init_se (&maskse, NULL);
2708 gfc_copy_loopinfo_to_se (&maskse, &loop);
2709 maskse.ss = maskss;
2710 gfc_conv_expr_val (&maskse, maskexpr);
2711 gfc_add_block_to_block (&body, &maskse.pre);
2713 gfc_start_block (&block);
2715 else
2716 gfc_init_block (&block);
2718 /* Compare with the current limit. */
2719 gfc_init_se (&arrayse, NULL);
2720 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2721 arrayse.ss = arrayss;
2722 gfc_conv_expr_val (&arrayse, arrayexpr);
2723 gfc_add_block_to_block (&block, &arrayse.pre);
2725 gfc_init_block (&block2);
2727 if (nonempty_var)
2728 gfc_add_modify (&block2, nonempty_var, boolean_true_node);
2730 if (HONOR_NANS (DECL_MODE (limit)))
2732 tmp = fold_build2 (op == GT_EXPR ? GE_EXPR : LE_EXPR,
2733 boolean_type_node, arrayse.expr, limit);
2734 if (lab)
2735 ifbody = build1_v (GOTO_EXPR, lab);
2736 else
2738 stmtblock_t ifblock;
2740 gfc_init_block (&ifblock);
2741 gfc_add_modify (&ifblock, limit, arrayse.expr);
2742 gfc_add_modify (&ifblock, fast, boolean_true_node);
2743 ifbody = gfc_finish_block (&ifblock);
2745 tmp = build3_v (COND_EXPR, tmp, ifbody,
2746 build_empty_stmt (input_location));
2747 gfc_add_expr_to_block (&block2, tmp);
2749 else
2751 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2752 signed zeros. */
2753 if (HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2755 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2756 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2757 tmp = build3_v (COND_EXPR, tmp, ifbody,
2758 build_empty_stmt (input_location));
2759 gfc_add_expr_to_block (&block2, tmp);
2761 else
2763 tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2764 type, arrayse.expr, limit);
2765 gfc_add_modify (&block2, limit, tmp);
2769 if (fast)
2771 tree elsebody = gfc_finish_block (&block2);
2773 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2774 signed zeros. */
2775 if (HONOR_NANS (DECL_MODE (limit))
2776 || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2778 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2779 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2780 ifbody = build3_v (COND_EXPR, tmp, ifbody,
2781 build_empty_stmt (input_location));
2783 else
2785 tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2786 type, arrayse.expr, limit);
2787 ifbody = build2_v (MODIFY_EXPR, limit, tmp);
2789 tmp = build3_v (COND_EXPR, fast, ifbody, elsebody);
2790 gfc_add_expr_to_block (&block, tmp);
2792 else
2793 gfc_add_block_to_block (&block, &block2);
2795 gfc_add_block_to_block (&block, &arrayse.post);
2797 tmp = gfc_finish_block (&block);
2798 if (maskss)
2799 /* We enclose the above in if (mask) {...}. */
2800 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2801 build_empty_stmt (input_location));
2802 gfc_add_expr_to_block (&body, tmp);
2804 if (lab)
2806 gfc_trans_scalarized_loop_end (&loop, 0, &body);
2808 tmp = fold_build3 (COND_EXPR, type, nonempty, nan_cst, huge_cst);
2809 gfc_add_modify (&loop.code[0], limit, tmp);
2810 gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));
2812 gfc_start_block (&body);
2814 /* If we have a mask, only add this element if the mask is set. */
2815 if (maskss)
2817 gfc_init_se (&maskse, NULL);
2818 gfc_copy_loopinfo_to_se (&maskse, &loop);
2819 maskse.ss = maskss;
2820 gfc_conv_expr_val (&maskse, maskexpr);
2821 gfc_add_block_to_block (&body, &maskse.pre);
2823 gfc_start_block (&block);
2825 else
2826 gfc_init_block (&block);
2828 /* Compare with the current limit. */
2829 gfc_init_se (&arrayse, NULL);
2830 gfc_copy_loopinfo_to_se (&arrayse, &loop);
2831 arrayse.ss = arrayss;
2832 gfc_conv_expr_val (&arrayse, arrayexpr);
2833 gfc_add_block_to_block (&block, &arrayse.pre);
2835 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2836 signed zeros. */
2837 if (HONOR_NANS (DECL_MODE (limit))
2838 || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2840 tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2841 ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2842 tmp = build3_v (COND_EXPR, tmp, ifbody,
2843 build_empty_stmt (input_location));
2844 gfc_add_expr_to_block (&block, tmp);
2846 else
2848 tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2849 type, arrayse.expr, limit);
2850 gfc_add_modify (&block, limit, tmp);
2853 gfc_add_block_to_block (&block, &arrayse.post);
2855 tmp = gfc_finish_block (&block);
2856 if (maskss)
2857 /* We enclose the above in if (mask) {...}. */
2858 tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2859 build_empty_stmt (input_location));
2860 gfc_add_expr_to_block (&body, tmp);
2861 /* Avoid initializing loopvar[0] again, it should be left where
2862 it finished by the first loop. */
2863 loop.from[0] = loop.loopvar[0];
2865 gfc_trans_scalarizing_loops (&loop, &body);
2867 if (fast)
2869 tmp = fold_build3 (COND_EXPR, type, nonempty, nan_cst, huge_cst);
2870 ifbody = build2_v (MODIFY_EXPR, limit, tmp);
2871 tmp = build3_v (COND_EXPR, fast, build_empty_stmt (input_location),
2872 ifbody);
2873 gfc_add_expr_to_block (&loop.pre, tmp);
2875 else if (HONOR_INFINITIES (DECL_MODE (limit)) && !lab)
2877 tmp = fold_build3 (COND_EXPR, type, nonempty, limit, huge_cst);
2878 gfc_add_modify (&loop.pre, limit, tmp);
2881 /* For a scalar mask, enclose the loop in an if statement. */
2882 if (maskexpr && maskss == NULL)
2884 tree else_stmt;
2886 gfc_init_se (&maskse, NULL);
2887 gfc_conv_expr_val (&maskse, maskexpr);
2888 gfc_init_block (&block);
2889 gfc_add_block_to_block (&block, &loop.pre);
2890 gfc_add_block_to_block (&block, &loop.post);
2891 tmp = gfc_finish_block (&block);
2893 if (HONOR_INFINITIES (DECL_MODE (limit)))
2894 else_stmt = build2_v (MODIFY_EXPR, limit, huge_cst);
2895 else
2896 else_stmt = build_empty_stmt (input_location);
2897 tmp = build3_v (COND_EXPR, maskse.expr, tmp, else_stmt);
2898 gfc_add_expr_to_block (&block, tmp);
2899 gfc_add_block_to_block (&se->pre, &block);
2901 else
2903 gfc_add_block_to_block (&se->pre, &loop.pre);
2904 gfc_add_block_to_block (&se->pre, &loop.post);
2907 gfc_cleanup_loop (&loop);
2909 se->expr = limit;
2912 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
2913 static void
2914 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2916 tree args[2];
2917 tree type;
2918 tree tmp;
2920 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2921 type = TREE_TYPE (args[0]);
2923 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2924 tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2925 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2926 build_int_cst (type, 0));
2927 type = gfc_typenode_for_spec (&expr->ts);
2928 se->expr = convert (type, tmp);
2931 /* Generate code to perform the specified operation. */
2932 static void
2933 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
2935 tree args[2];
2937 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2938 se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2941 /* Bitwise not. */
2942 static void
2943 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2945 tree arg;
2947 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2948 se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2951 /* Set or clear a single bit. */
2952 static void
2953 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2955 tree args[2];
2956 tree type;
2957 tree tmp;
2958 enum tree_code op;
2960 gfc_conv_intrinsic_function_args (se, expr, args, 2);
2961 type = TREE_TYPE (args[0]);
2963 tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2964 if (set)
2965 op = BIT_IOR_EXPR;
2966 else
2968 op = BIT_AND_EXPR;
2969 tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2971 se->expr = fold_build2 (op, type, args[0], tmp);
2974 /* Extract a sequence of bits.
2975 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
2976 static void
2977 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2979 tree args[3];
2980 tree type;
2981 tree tmp;
2982 tree mask;
2984 gfc_conv_intrinsic_function_args (se, expr, args, 3);
2985 type = TREE_TYPE (args[0]);
2987 mask = build_int_cst (type, -1);
2988 mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2989 mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2991 tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2993 se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2996 /* RSHIFT (I, SHIFT) = I >> SHIFT
2997 LSHIFT (I, SHIFT) = I << SHIFT */
2998 static void
2999 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
3001 tree args[2];
3003 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3005 se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
3006 TREE_TYPE (args[0]), args[0], args[1]);
3009 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
3011 : ((shift >= 0) ? i << shift : i >> -shift)
3012 where all shifts are logical shifts. */
3013 static void
3014 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
3016 tree args[2];
3017 tree type;
3018 tree utype;
3019 tree tmp;
3020 tree width;
3021 tree num_bits;
3022 tree cond;
3023 tree lshift;
3024 tree rshift;
3026 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3027 type = TREE_TYPE (args[0]);
3028 utype = unsigned_type_for (type);
3030 width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
3032 /* Left shift if positive. */
3033 lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
3035 /* Right shift if negative.
3036 We convert to an unsigned type because we want a logical shift.
3037 The standard doesn't define the case of shifting negative
3038 numbers, and we try to be compatible with other compilers, most
3039 notably g77, here. */
3040 rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype,
3041 convert (utype, args[0]), width));
3043 tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
3044 build_int_cst (TREE_TYPE (args[1]), 0));
3045 tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
3047 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3048 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3049 special case. */
3050 num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
3051 cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
3053 se->expr = fold_build3 (COND_EXPR, type, cond,
3054 build_int_cst (type, 0), tmp);
3058 /* Circular shift. AKA rotate or barrel shift. */
3060 static void
3061 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
3063 tree *args;
3064 tree type;
3065 tree tmp;
3066 tree lrot;
3067 tree rrot;
3068 tree zero;
3069 unsigned int num_args;
3071 num_args = gfc_intrinsic_argument_list_length (expr);
3072 args = (tree *) alloca (sizeof (tree) * num_args);
3074 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3076 if (num_args == 3)
3078 /* Use a library function for the 3 parameter version. */
3079 tree int4type = gfc_get_int_type (4);
3081 type = TREE_TYPE (args[0]);
3082 /* We convert the first argument to at least 4 bytes, and
3083 convert back afterwards. This removes the need for library
3084 functions for all argument sizes, and function will be
3085 aligned to at least 32 bits, so there's no loss. */
3086 if (expr->ts.kind < 4)
3087 args[0] = convert (int4type, args[0]);
3089 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
3090 need loads of library functions. They cannot have values >
3091 BIT_SIZE (I) so the conversion is safe. */
3092 args[1] = convert (int4type, args[1]);
3093 args[2] = convert (int4type, args[2]);
3095 switch (expr->ts.kind)
3097 case 1:
3098 case 2:
3099 case 4:
3100 tmp = gfor_fndecl_math_ishftc4;
3101 break;
3102 case 8:
3103 tmp = gfor_fndecl_math_ishftc8;
3104 break;
3105 case 16:
3106 tmp = gfor_fndecl_math_ishftc16;
3107 break;
3108 default:
3109 gcc_unreachable ();
3111 se->expr = build_call_expr_loc (input_location,
3112 tmp, 3, args[0], args[1], args[2]);
3113 /* Convert the result back to the original type, if we extended
3114 the first argument's width above. */
3115 if (expr->ts.kind < 4)
3116 se->expr = convert (type, se->expr);
3118 return;
3120 type = TREE_TYPE (args[0]);
3122 /* Rotate left if positive. */
3123 lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
3125 /* Rotate right if negative. */
3126 tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
3127 rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
3129 zero = build_int_cst (TREE_TYPE (args[1]), 0);
3130 tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
3131 rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
3133 /* Do nothing if shift == 0. */
3134 tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
3135 se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
3138 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
3139 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
3141 The conditional expression is necessary because the result of LEADZ(0)
3142 is defined, but the result of __builtin_clz(0) is undefined for most
3143 targets.
3145 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
3146 difference in bit size between the argument of LEADZ and the C int. */
3148 static void
3149 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
3151 tree arg;
3152 tree arg_type;
3153 tree cond;
3154 tree result_type;
3155 tree leadz;
3156 tree bit_size;
3157 tree tmp;
3158 tree func;
3159 int s, argsize;
3161 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3162 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3164 /* Which variant of __builtin_clz* should we call? */
3165 if (argsize <= INT_TYPE_SIZE)
3167 arg_type = unsigned_type_node;
3168 func = built_in_decls[BUILT_IN_CLZ];
3170 else if (argsize <= LONG_TYPE_SIZE)
3172 arg_type = long_unsigned_type_node;
3173 func = built_in_decls[BUILT_IN_CLZL];
3175 else if (argsize <= LONG_LONG_TYPE_SIZE)
3177 arg_type = long_long_unsigned_type_node;
3178 func = built_in_decls[BUILT_IN_CLZLL];
3180 else
3182 gcc_assert (argsize == 128);
3183 arg_type = gfc_build_uint_type (argsize);
3184 func = gfor_fndecl_clz128;
3187 /* Convert the actual argument twice: first, to the unsigned type of the
3188 same size; then, to the proper argument type for the built-in
3189 function. But the return type is of the default INTEGER kind. */
3190 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3191 arg = fold_convert (arg_type, arg);
3192 result_type = gfc_get_int_type (gfc_default_integer_kind);
3194 /* Compute LEADZ for the case i .ne. 0. */
3195 s = TYPE_PRECISION (arg_type) - argsize;
3196 tmp = fold_convert (result_type, build_call_expr (func, 1, arg));
3197 leadz = fold_build2 (MINUS_EXPR, result_type,
3198 tmp, build_int_cst (result_type, s));
3200 /* Build BIT_SIZE. */
3201 bit_size = build_int_cst (result_type, argsize);
3203 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3204 arg, build_int_cst (arg_type, 0));
3205 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
3208 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
3210 The conditional expression is necessary because the result of TRAILZ(0)
3211 is defined, but the result of __builtin_ctz(0) is undefined for most
3212 targets. */
3214 static void
3215 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
3217 tree arg;
3218 tree arg_type;
3219 tree cond;
3220 tree result_type;
3221 tree trailz;
3222 tree bit_size;
3223 tree func;
3224 int argsize;
3226 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3227 argsize = TYPE_PRECISION (TREE_TYPE (arg));
3229 /* Which variant of __builtin_ctz* should we call? */
3230 if (argsize <= INT_TYPE_SIZE)
3232 arg_type = unsigned_type_node;
3233 func = built_in_decls[BUILT_IN_CTZ];
3235 else if (argsize <= LONG_TYPE_SIZE)
3237 arg_type = long_unsigned_type_node;
3238 func = built_in_decls[BUILT_IN_CTZL];
3240 else if (argsize <= LONG_LONG_TYPE_SIZE)
3242 arg_type = long_long_unsigned_type_node;
3243 func = built_in_decls[BUILT_IN_CTZLL];
3245 else
3247 gcc_assert (argsize == 128);
3248 arg_type = gfc_build_uint_type (argsize);
3249 func = gfor_fndecl_ctz128;
3252 /* Convert the actual argument twice: first, to the unsigned type of the
3253 same size; then, to the proper argument type for the built-in
3254 function. But the return type is of the default INTEGER kind. */
3255 arg = fold_convert (gfc_build_uint_type (argsize), arg);
3256 arg = fold_convert (arg_type, arg);
3257 result_type = gfc_get_int_type (gfc_default_integer_kind);
3259 /* Compute TRAILZ for the case i .ne. 0. */
3260 trailz = fold_convert (result_type, build_call_expr_loc (input_location,
3261 func, 1, arg));
3263 /* Build BIT_SIZE. */
3264 bit_size = build_int_cst (result_type, argsize);
3266 cond = fold_build2 (EQ_EXPR, boolean_type_node,
3267 arg, build_int_cst (arg_type, 0));
3268 se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
3271 /* Process an intrinsic with unspecified argument-types that has an optional
3272 argument (which could be of type character), e.g. EOSHIFT. For those, we
3273 need to append the string length of the optional argument if it is not
3274 present and the type is really character.
3275 primary specifies the position (starting at 1) of the non-optional argument
3276 specifying the type and optional gives the position of the optional
3277 argument in the arglist. */
3279 static void
3280 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
3281 unsigned primary, unsigned optional)
3283 gfc_actual_arglist* prim_arg;
3284 gfc_actual_arglist* opt_arg;
3285 unsigned cur_pos;
3286 gfc_actual_arglist* arg;
3287 gfc_symbol* sym;
3288 tree append_args;
3290 /* Find the two arguments given as position. */
3291 cur_pos = 0;
3292 prim_arg = NULL;
3293 opt_arg = NULL;
3294 for (arg = expr->value.function.actual; arg; arg = arg->next)
3296 ++cur_pos;
3298 if (cur_pos == primary)
3299 prim_arg = arg;
3300 if (cur_pos == optional)
3301 opt_arg = arg;
3303 if (cur_pos >= primary && cur_pos >= optional)
3304 break;
3306 gcc_assert (prim_arg);
3307 gcc_assert (prim_arg->expr);
3308 gcc_assert (opt_arg);
3310 /* If we do have type CHARACTER and the optional argument is really absent,
3311 append a dummy 0 as string length. */
3312 append_args = NULL_TREE;
3313 if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
3315 tree dummy;
3317 dummy = build_int_cst (gfc_charlen_type_node, 0);
3318 append_args = gfc_chainon_list (append_args, dummy);
3321 /* Build the call itself. */
3322 sym = gfc_get_symbol_for_expr (expr);
3323 gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3324 append_args);
3325 gfc_free (sym);
3329 /* The length of a character string. */
3330 static void
3331 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
3333 tree len;
3334 tree type;
3335 tree decl;
3336 gfc_symbol *sym;
3337 gfc_se argse;
3338 gfc_expr *arg;
3339 gfc_ss *ss;
3341 gcc_assert (!se->ss);
3343 arg = expr->value.function.actual->expr;
3345 type = gfc_typenode_for_spec (&expr->ts);
3346 switch (arg->expr_type)
3348 case EXPR_CONSTANT:
3349 len = build_int_cst (NULL_TREE, arg->value.character.length);
3350 break;
3352 case EXPR_ARRAY:
3353 /* Obtain the string length from the function used by
3354 trans-array.c(gfc_trans_array_constructor). */
3355 len = NULL_TREE;
3356 get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
3357 break;
3359 case EXPR_VARIABLE:
3360 if (arg->ref == NULL
3361 || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
3363 /* This doesn't catch all cases.
3364 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
3365 and the surrounding thread. */
3366 sym = arg->symtree->n.sym;
3367 decl = gfc_get_symbol_decl (sym);
3368 if (decl == current_function_decl && sym->attr.function
3369 && (sym->result == sym))
3370 decl = gfc_get_fake_result_decl (sym, 0);
3372 len = sym->ts.u.cl->backend_decl;
3373 gcc_assert (len);
3374 break;
3377 /* Otherwise fall through. */
3379 default:
3380 /* Anybody stupid enough to do this deserves inefficient code. */
3381 ss = gfc_walk_expr (arg);
3382 gfc_init_se (&argse, se);
3383 if (ss == gfc_ss_terminator)
3384 gfc_conv_expr (&argse, arg);
3385 else
3386 gfc_conv_expr_descriptor (&argse, arg, ss);
3387 gfc_add_block_to_block (&se->pre, &argse.pre);
3388 gfc_add_block_to_block (&se->post, &argse.post);
3389 len = argse.string_length;
3390 break;
3392 se->expr = convert (type, len);
3395 /* The length of a character string not including trailing blanks. */
3396 static void
3397 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
3399 int kind = expr->value.function.actual->expr->ts.kind;
3400 tree args[2], type, fndecl;
3402 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3403 type = gfc_typenode_for_spec (&expr->ts);
3405 if (kind == 1)
3406 fndecl = gfor_fndecl_string_len_trim;
3407 else if (kind == 4)
3408 fndecl = gfor_fndecl_string_len_trim_char4;
3409 else
3410 gcc_unreachable ();
3412 se->expr = build_call_expr_loc (input_location,
3413 fndecl, 2, args[0], args[1]);
3414 se->expr = convert (type, se->expr);
3418 /* Returns the starting position of a substring within a string. */
3420 static void
3421 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
3422 tree function)
3424 tree logical4_type_node = gfc_get_logical_type (4);
3425 tree type;
3426 tree fndecl;
3427 tree *args;
3428 unsigned int num_args;
3430 args = (tree *) alloca (sizeof (tree) * 5);
3432 /* Get number of arguments; characters count double due to the
3433 string length argument. Kind= is not passed to the library
3434 and thus ignored. */
3435 if (expr->value.function.actual->next->next->expr == NULL)
3436 num_args = 4;
3437 else
3438 num_args = 5;
3440 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3441 type = gfc_typenode_for_spec (&expr->ts);
3443 if (num_args == 4)
3444 args[4] = build_int_cst (logical4_type_node, 0);
3445 else
3446 args[4] = convert (logical4_type_node, args[4]);
3448 fndecl = build_addr (function, current_function_decl);
3449 se->expr = build_call_array_loc (input_location,
3450 TREE_TYPE (TREE_TYPE (function)), fndecl,
3451 5, args);
3452 se->expr = convert (type, se->expr);
3456 /* The ascii value for a single character. */
3457 static void
3458 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
3460 tree args[2], type, pchartype;
3462 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3463 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
3464 pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
3465 args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
3466 type = gfc_typenode_for_spec (&expr->ts);
3468 se->expr = build_fold_indirect_ref_loc (input_location,
3469 args[1]);
3470 se->expr = convert (type, se->expr);
3474 /* Intrinsic ISNAN calls __builtin_isnan. */
3476 static void
3477 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
3479 tree arg;
3481 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3482 se->expr = build_call_expr_loc (input_location,
3483 built_in_decls[BUILT_IN_ISNAN], 1, arg);
3484 STRIP_TYPE_NOPS (se->expr);
3485 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3489 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
3490 their argument against a constant integer value. */
3492 static void
3493 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
3495 tree arg;
3497 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3498 se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
3499 arg, build_int_cst (TREE_TYPE (arg), value));
3504 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
3506 static void
3507 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
3509 tree tsource;
3510 tree fsource;
3511 tree mask;
3512 tree type;
3513 tree len, len2;
3514 tree *args;
3515 unsigned int num_args;
3517 num_args = gfc_intrinsic_argument_list_length (expr);
3518 args = (tree *) alloca (sizeof (tree) * num_args);
3520 gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3521 if (expr->ts.type != BT_CHARACTER)
3523 tsource = args[0];
3524 fsource = args[1];
3525 mask = args[2];
3527 else
3529 /* We do the same as in the non-character case, but the argument
3530 list is different because of the string length arguments. We
3531 also have to set the string length for the result. */
3532 len = args[0];
3533 tsource = args[1];
3534 len2 = args[2];
3535 fsource = args[3];
3536 mask = args[4];
3538 gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
3539 &se->pre);
3540 se->string_length = len;
3542 type = TREE_TYPE (tsource);
3543 se->expr = fold_build3 (COND_EXPR, type, mask, tsource,
3544 fold_convert (type, fsource));
3548 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
3549 static void
3550 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
3552 tree arg, type, tmp, frexp;
3554 frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3556 type = gfc_typenode_for_spec (&expr->ts);
3557 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3558 tmp = gfc_create_var (integer_type_node, NULL);
3559 se->expr = build_call_expr_loc (input_location, frexp, 2,
3560 fold_convert (type, arg),
3561 gfc_build_addr_expr (NULL_TREE, tmp));
3562 se->expr = fold_convert (type, se->expr);
3566 /* NEAREST (s, dir) is translated into
3567 tmp = copysign (HUGE_VAL, dir);
3568 return nextafter (s, tmp);
3570 static void
3571 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
3573 tree args[2], type, tmp, nextafter, copysign, huge_val;
3575 nextafter = builtin_decl_for_float_kind (BUILT_IN_NEXTAFTER, expr->ts.kind);
3576 copysign = builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
3577 huge_val = builtin_decl_for_float_kind (BUILT_IN_HUGE_VAL, expr->ts.kind);
3579 type = gfc_typenode_for_spec (&expr->ts);
3580 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3581 tmp = build_call_expr_loc (input_location, copysign, 2,
3582 build_call_expr_loc (input_location, huge_val, 0),
3583 fold_convert (type, args[1]));
3584 se->expr = build_call_expr_loc (input_location, nextafter, 2,
3585 fold_convert (type, args[0]), tmp);
3586 se->expr = fold_convert (type, se->expr);
3590 /* SPACING (s) is translated into
3591 int e;
3592 if (s == 0)
3593 res = tiny;
3594 else
3596 frexp (s, &e);
3597 e = e - prec;
3598 e = MAX_EXPR (e, emin);
3599 res = scalbn (1., e);
3601 return res;
3603 where prec is the precision of s, gfc_real_kinds[k].digits,
3604 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
3605 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
3607 static void
3608 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
3610 tree arg, type, prec, emin, tiny, res, e;
3611 tree cond, tmp, frexp, scalbn;
3612 int k;
3613 stmtblock_t block;
3615 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3616 prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
3617 emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
3618 tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
3620 frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3621 scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3623 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3624 arg = gfc_evaluate_now (arg, &se->pre);
3626 type = gfc_typenode_for_spec (&expr->ts);
3627 e = gfc_create_var (integer_type_node, NULL);
3628 res = gfc_create_var (type, NULL);
3631 /* Build the block for s /= 0. */
3632 gfc_start_block (&block);
3633 tmp = build_call_expr_loc (input_location, frexp, 2, arg,
3634 gfc_build_addr_expr (NULL_TREE, e));
3635 gfc_add_expr_to_block (&block, tmp);
3637 tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3638 gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3639 tmp, emin));
3641 tmp = build_call_expr_loc (input_location, scalbn, 2,
3642 build_real_from_int_cst (type, integer_one_node), e);
3643 gfc_add_modify (&block, res, tmp);
3645 /* Finish by building the IF statement. */
3646 cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3647 build_real_from_int_cst (type, integer_zero_node));
3648 tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3649 gfc_finish_block (&block));
3651 gfc_add_expr_to_block (&se->pre, tmp);
3652 se->expr = res;
3656 /* RRSPACING (s) is translated into
3657 int e;
3658 real x;
3659 x = fabs (s);
3660 if (x != 0)
3662 frexp (s, &e);
3663 x = scalbn (x, precision - e);
3665 return x;
3667 where precision is gfc_real_kinds[k].digits. */
3669 static void
3670 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3672 tree arg, type, e, x, cond, stmt, tmp, frexp, scalbn, fabs;
3673 int prec, k;
3674 stmtblock_t block;
3676 k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3677 prec = gfc_real_kinds[k].digits;
3679 frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3680 scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3681 fabs = builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
3683 type = gfc_typenode_for_spec (&expr->ts);
3684 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3685 arg = gfc_evaluate_now (arg, &se->pre);
3687 e = gfc_create_var (integer_type_node, NULL);
3688 x = gfc_create_var (type, NULL);
3689 gfc_add_modify (&se->pre, x,
3690 build_call_expr_loc (input_location, fabs, 1, arg));
3693 gfc_start_block (&block);
3694 tmp = build_call_expr_loc (input_location, frexp, 2, arg,
3695 gfc_build_addr_expr (NULL_TREE, e));
3696 gfc_add_expr_to_block (&block, tmp);
3698 tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3699 build_int_cst (NULL_TREE, prec), e);
3700 tmp = build_call_expr_loc (input_location, scalbn, 2, x, tmp);
3701 gfc_add_modify (&block, x, tmp);
3702 stmt = gfc_finish_block (&block);
3704 cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3705 build_real_from_int_cst (type, integer_zero_node));
3706 tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
3707 gfc_add_expr_to_block (&se->pre, tmp);
3709 se->expr = fold_convert (type, x);
3713 /* SCALE (s, i) is translated into scalbn (s, i). */
3714 static void
3715 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3717 tree args[2], type, scalbn;
3719 scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3721 type = gfc_typenode_for_spec (&expr->ts);
3722 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3723 se->expr = build_call_expr_loc (input_location, scalbn, 2,
3724 fold_convert (type, args[0]),
3725 fold_convert (integer_type_node, args[1]));
3726 se->expr = fold_convert (type, se->expr);
3730 /* SET_EXPONENT (s, i) is translated into
3731 scalbn (frexp (s, &dummy_int), i). */
3732 static void
3733 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3735 tree args[2], type, tmp, frexp, scalbn;
3737 frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3738 scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3740 type = gfc_typenode_for_spec (&expr->ts);
3741 gfc_conv_intrinsic_function_args (se, expr, args, 2);
3743 tmp = gfc_create_var (integer_type_node, NULL);
3744 tmp = build_call_expr_loc (input_location, frexp, 2,
3745 fold_convert (type, args[0]),
3746 gfc_build_addr_expr (NULL_TREE, tmp));
3747 se->expr = build_call_expr_loc (input_location, scalbn, 2, tmp,
3748 fold_convert (integer_type_node, args[1]));
3749 se->expr = fold_convert (type, se->expr);
3753 static void
3754 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3756 gfc_actual_arglist *actual;
3757 tree arg1;
3758 tree type;
3759 tree fncall0;
3760 tree fncall1;
3761 gfc_se argse;
3762 gfc_ss *ss;
3764 gfc_init_se (&argse, NULL);
3765 actual = expr->value.function.actual;
3767 ss = gfc_walk_expr (actual->expr);
3768 gcc_assert (ss != gfc_ss_terminator);
3769 argse.want_pointer = 1;
3770 argse.data_not_needed = 1;
3771 gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3772 gfc_add_block_to_block (&se->pre, &argse.pre);
3773 gfc_add_block_to_block (&se->post, &argse.post);
3774 arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3776 /* Build the call to size0. */
3777 fncall0 = build_call_expr_loc (input_location,
3778 gfor_fndecl_size0, 1, arg1);
3780 actual = actual->next;
3782 if (actual->expr)
3784 gfc_init_se (&argse, NULL);
3785 gfc_conv_expr_type (&argse, actual->expr,
3786 gfc_array_index_type);
3787 gfc_add_block_to_block (&se->pre, &argse.pre);
3789 /* Unusually, for an intrinsic, size does not exclude
3790 an optional arg2, so we must test for it. */
3791 if (actual->expr->expr_type == EXPR_VARIABLE
3792 && actual->expr->symtree->n.sym->attr.dummy
3793 && actual->expr->symtree->n.sym->attr.optional)
3795 tree tmp;
3796 /* Build the call to size1. */
3797 fncall1 = build_call_expr_loc (input_location,
3798 gfor_fndecl_size1, 2,
3799 arg1, argse.expr);
3801 gfc_init_se (&argse, NULL);
3802 argse.want_pointer = 1;
3803 argse.data_not_needed = 1;
3804 gfc_conv_expr (&argse, actual->expr);
3805 gfc_add_block_to_block (&se->pre, &argse.pre);
3806 tmp = fold_build2 (NE_EXPR, boolean_type_node,
3807 argse.expr, null_pointer_node);
3808 tmp = gfc_evaluate_now (tmp, &se->pre);
3809 se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3810 tmp, fncall1, fncall0);
3812 else
3814 se->expr = NULL_TREE;
3815 argse.expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3816 argse.expr, gfc_index_one_node);
3819 else if (expr->value.function.actual->expr->rank == 1)
3821 argse.expr = gfc_index_zero_node;
3822 se->expr = NULL_TREE;
3824 else
3825 se->expr = fncall0;
3827 if (se->expr == NULL_TREE)
3829 tree ubound, lbound;
3831 arg1 = build_fold_indirect_ref_loc (input_location,
3832 arg1);
3833 ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
3834 lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
3835 se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3836 ubound, lbound);
3837 se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
3838 gfc_index_one_node);
3839 se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
3840 gfc_index_zero_node);
3843 type = gfc_typenode_for_spec (&expr->ts);
3844 se->expr = convert (type, se->expr);
3848 /* Helper function to compute the size of a character variable,
3849 excluding the terminating null characters. The result has
3850 gfc_array_index_type type. */
3852 static tree
3853 size_of_string_in_bytes (int kind, tree string_length)
3855 tree bytesize;
3856 int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3858 bytesize = build_int_cst (gfc_array_index_type,
3859 gfc_character_kinds[i].bit_size / 8);
3861 return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3862 fold_convert (gfc_array_index_type, string_length));
3866 static void
3867 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3869 gfc_expr *arg;
3870 gfc_ss *ss;
3871 gfc_se argse;
3872 tree source_bytes;
3873 tree type;
3874 tree tmp;
3875 tree lower;
3876 tree upper;
3877 int n;
3879 arg = expr->value.function.actual->expr;
3881 gfc_init_se (&argse, NULL);
3882 ss = gfc_walk_expr (arg);
3884 if (ss == gfc_ss_terminator)
3886 gfc_conv_expr_reference (&argse, arg);
3888 type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
3889 argse.expr));
3891 /* Obtain the source word length. */
3892 if (arg->ts.type == BT_CHARACTER)
3893 se->expr = size_of_string_in_bytes (arg->ts.kind,
3894 argse.string_length);
3895 else
3896 se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type));
3898 else
3900 source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3901 argse.want_pointer = 0;
3902 gfc_conv_expr_descriptor (&argse, arg, ss);
3903 type = gfc_get_element_type (TREE_TYPE (argse.expr));
3905 /* Obtain the argument's word length. */
3906 if (arg->ts.type == BT_CHARACTER)
3907 tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3908 else
3909 tmp = fold_convert (gfc_array_index_type,
3910 size_in_bytes (type));
3911 gfc_add_modify (&argse.pre, source_bytes, tmp);
3913 /* Obtain the size of the array in bytes. */
3914 for (n = 0; n < arg->rank; n++)
3916 tree idx;
3917 idx = gfc_rank_cst[n];
3918 lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
3919 upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
3920 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3921 upper, lower);
3922 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3923 tmp, gfc_index_one_node);
3924 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3925 tmp, source_bytes);
3926 gfc_add_modify (&argse.pre, source_bytes, tmp);
3928 se->expr = source_bytes;
3931 gfc_add_block_to_block (&se->pre, &argse.pre);
3935 /* Intrinsic string comparison functions. */
3937 static void
3938 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
3940 tree args[4];
3942 gfc_conv_intrinsic_function_args (se, expr, args, 4);
3944 se->expr
3945 = gfc_build_compare_string (args[0], args[1], args[2], args[3],
3946 expr->value.function.actual->expr->ts.kind);
3947 se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
3948 build_int_cst (TREE_TYPE (se->expr), 0));
3951 /* Generate a call to the adjustl/adjustr library function. */
3952 static void
3953 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
3955 tree args[3];
3956 tree len;
3957 tree type;
3958 tree var;
3959 tree tmp;
3961 gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
3962 len = args[1];
3964 type = TREE_TYPE (args[2]);
3965 var = gfc_conv_string_tmp (se, type, len);
3966 args[0] = var;
3968 tmp = build_call_expr_loc (input_location,
3969 fndecl, 3, args[0], args[1], args[2]);
3970 gfc_add_expr_to_block (&se->pre, tmp);
3971 se->expr = var;
3972 se->string_length = len;
3976 /* Generate code for the TRANSFER intrinsic:
3977 For scalar results:
3978 DEST = TRANSFER (SOURCE, MOLD)
3979 where:
3980 typeof<DEST> = typeof<MOLD>
3981 and:
3982 MOLD is scalar.
3984 For array results:
3985 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
3986 where:
3987 typeof<DEST> = typeof<MOLD>
3988 and:
3989 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
3990 sizeof (DEST(0) * SIZE). */
3991 static void
3992 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
3994 tree tmp;
3995 tree tmpdecl;
3996 tree ptr;
3997 tree extent;
3998 tree source;
3999 tree source_type;
4000 tree source_bytes;
4001 tree mold_type;
4002 tree dest_word_len;
4003 tree size_words;
4004 tree size_bytes;
4005 tree upper;
4006 tree lower;
4007 tree stmt;
4008 gfc_actual_arglist *arg;
4009 gfc_se argse;
4010 gfc_ss *ss;
4011 gfc_ss_info *info;
4012 stmtblock_t block;
4013 int n;
4014 bool scalar_mold;
4016 info = NULL;
4017 if (se->loop)
4018 info = &se->ss->data.info;
4020 /* Convert SOURCE. The output from this stage is:-
4021 source_bytes = length of the source in bytes
4022 source = pointer to the source data. */
4023 arg = expr->value.function.actual;
4025 /* Ensure double transfer through LOGICAL preserves all
4026 the needed bits. */
4027 if (arg->expr->expr_type == EXPR_FUNCTION
4028 && arg->expr->value.function.esym == NULL
4029 && arg->expr->value.function.isym != NULL
4030 && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
4031 && arg->expr->ts.type == BT_LOGICAL
4032 && expr->ts.type != arg->expr->ts.type)
4033 arg->expr->value.function.name = "__transfer_in_transfer";
4035 gfc_init_se (&argse, NULL);
4036 ss = gfc_walk_expr (arg->expr);
4038 source_bytes = gfc_create_var (gfc_array_index_type, NULL);
4040 /* Obtain the pointer to source and the length of source in bytes. */
4041 if (ss == gfc_ss_terminator)
4043 gfc_conv_expr_reference (&argse, arg->expr);
4044 source = argse.expr;
4046 source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4047 argse.expr));
4049 /* Obtain the source word length. */
4050 if (arg->expr->ts.type == BT_CHARACTER)
4051 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4052 argse.string_length);
4053 else
4054 tmp = fold_convert (gfc_array_index_type,
4055 size_in_bytes (source_type));
4057 else
4059 argse.want_pointer = 0;
4060 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4061 source = gfc_conv_descriptor_data_get (argse.expr);
4062 source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4064 /* Repack the source if not a full variable array. */
4065 if (arg->expr->expr_type == EXPR_VARIABLE
4066 && arg->expr->ref->u.ar.type != AR_FULL)
4068 tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
4070 if (gfc_option.warn_array_temp)
4071 gfc_warning ("Creating array temporary at %L", &expr->where);
4073 source = build_call_expr_loc (input_location,
4074 gfor_fndecl_in_pack, 1, tmp);
4075 source = gfc_evaluate_now (source, &argse.pre);
4077 /* Free the temporary. */
4078 gfc_start_block (&block);
4079 tmp = gfc_call_free (convert (pvoid_type_node, source));
4080 gfc_add_expr_to_block (&block, tmp);
4081 stmt = gfc_finish_block (&block);
4083 /* Clean up if it was repacked. */
4084 gfc_init_block (&block);
4085 tmp = gfc_conv_array_data (argse.expr);
4086 tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
4087 tmp = build3_v (COND_EXPR, tmp, stmt,
4088 build_empty_stmt (input_location));
4089 gfc_add_expr_to_block (&block, tmp);
4090 gfc_add_block_to_block (&block, &se->post);
4091 gfc_init_block (&se->post);
4092 gfc_add_block_to_block (&se->post, &block);
4095 /* Obtain the source word length. */
4096 if (arg->expr->ts.type == BT_CHARACTER)
4097 tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4098 argse.string_length);
4099 else
4100 tmp = fold_convert (gfc_array_index_type,
4101 size_in_bytes (source_type));
4103 /* Obtain the size of the array in bytes. */
4104 extent = gfc_create_var (gfc_array_index_type, NULL);
4105 for (n = 0; n < arg->expr->rank; n++)
4107 tree idx;
4108 idx = gfc_rank_cst[n];
4109 gfc_add_modify (&argse.pre, source_bytes, tmp);
4110 lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
4111 upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
4112 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4113 upper, lower);
4114 gfc_add_modify (&argse.pre, extent, tmp);
4115 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4116 extent, gfc_index_one_node);
4117 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4118 tmp, source_bytes);
4122 gfc_add_modify (&argse.pre, source_bytes, tmp);
4123 gfc_add_block_to_block (&se->pre, &argse.pre);
4124 gfc_add_block_to_block (&se->post, &argse.post);
4126 /* Now convert MOLD. The outputs are:
4127 mold_type = the TREE type of MOLD
4128 dest_word_len = destination word length in bytes. */
4129 arg = arg->next;
4131 gfc_init_se (&argse, NULL);
4132 ss = gfc_walk_expr (arg->expr);
4134 scalar_mold = arg->expr->rank == 0;
4136 if (ss == gfc_ss_terminator)
4138 gfc_conv_expr_reference (&argse, arg->expr);
4139 mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4140 argse.expr));
4142 else
4144 gfc_init_se (&argse, NULL);
4145 argse.want_pointer = 0;
4146 gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4147 mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4150 gfc_add_block_to_block (&se->pre, &argse.pre);
4151 gfc_add_block_to_block (&se->post, &argse.post);
4153 if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
4155 /* If this TRANSFER is nested in another TRANSFER, use a type
4156 that preserves all bits. */
4157 if (arg->expr->ts.type == BT_LOGICAL)
4158 mold_type = gfc_get_int_type (arg->expr->ts.kind);
4161 if (arg->expr->ts.type == BT_CHARACTER)
4163 tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
4164 mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
4166 else
4167 tmp = fold_convert (gfc_array_index_type,
4168 size_in_bytes (mold_type));
4170 dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
4171 gfc_add_modify (&se->pre, dest_word_len, tmp);
4173 /* Finally convert SIZE, if it is present. */
4174 arg = arg->next;
4175 size_words = gfc_create_var (gfc_array_index_type, NULL);
4177 if (arg->expr)
4179 gfc_init_se (&argse, NULL);
4180 gfc_conv_expr_reference (&argse, arg->expr);
4181 tmp = convert (gfc_array_index_type,
4182 build_fold_indirect_ref_loc (input_location,
4183 argse.expr));
4184 gfc_add_block_to_block (&se->pre, &argse.pre);
4185 gfc_add_block_to_block (&se->post, &argse.post);
4187 else
4188 tmp = NULL_TREE;
4190 /* Separate array and scalar results. */
4191 if (scalar_mold && tmp == NULL_TREE)
4192 goto scalar_transfer;
4194 size_bytes = gfc_create_var (gfc_array_index_type, NULL);
4195 if (tmp != NULL_TREE)
4196 tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4197 tmp, dest_word_len);
4198 else
4199 tmp = source_bytes;
4201 gfc_add_modify (&se->pre, size_bytes, tmp);
4202 gfc_add_modify (&se->pre, size_words,
4203 fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
4204 size_bytes, dest_word_len));
4206 /* Evaluate the bounds of the result. If the loop range exists, we have
4207 to check if it is too large. If so, we modify loop->to be consistent
4208 with min(size, size(source)). Otherwise, size is made consistent with
4209 the loop range, so that the right number of bytes is transferred.*/
4210 n = se->loop->order[0];
4211 if (se->loop->to[n] != NULL_TREE)
4213 tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4214 se->loop->to[n], se->loop->from[n]);
4215 tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4216 tmp, gfc_index_one_node);
4217 tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
4218 tmp, size_words);
4219 gfc_add_modify (&se->pre, size_words, tmp);
4220 gfc_add_modify (&se->pre, size_bytes,
4221 fold_build2 (MULT_EXPR, gfc_array_index_type,
4222 size_words, dest_word_len));
4223 upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4224 size_words, se->loop->from[n]);
4225 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4226 upper, gfc_index_one_node);
4228 else
4230 upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4231 size_words, gfc_index_one_node);
4232 se->loop->from[n] = gfc_index_zero_node;
4235 se->loop->to[n] = upper;
4237 /* Build a destination descriptor, using the pointer, source, as the
4238 data field. */
4239 gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
4240 info, mold_type, NULL_TREE, false, true, false,
4241 &expr->where);
4243 /* Cast the pointer to the result. */
4244 tmp = gfc_conv_descriptor_data_get (info->descriptor);
4245 tmp = fold_convert (pvoid_type_node, tmp);
4247 /* Use memcpy to do the transfer. */
4248 tmp = build_call_expr_loc (input_location,
4249 built_in_decls[BUILT_IN_MEMCPY],
4251 tmp,
4252 fold_convert (pvoid_type_node, source),
4253 fold_build2 (MIN_EXPR, gfc_array_index_type,
4254 size_bytes, source_bytes));
4255 gfc_add_expr_to_block (&se->pre, tmp);
4257 se->expr = info->descriptor;
4258 if (expr->ts.type == BT_CHARACTER)
4259 se->string_length = dest_word_len;
4261 return;
4263 /* Deal with scalar results. */
4264 scalar_transfer:
4265 extent = fold_build2 (MIN_EXPR, gfc_array_index_type,
4266 dest_word_len, source_bytes);
4267 extent = fold_build2 (MAX_EXPR, gfc_array_index_type,
4268 extent, gfc_index_zero_node);
4270 if (expr->ts.type == BT_CHARACTER)
4272 tree direct;
4273 tree indirect;
4275 ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
4276 tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
4277 "transfer");
4279 /* If source is longer than the destination, use a pointer to
4280 the source directly. */
4281 gfc_init_block (&block);
4282 gfc_add_modify (&block, tmpdecl, ptr);
4283 direct = gfc_finish_block (&block);
4285 /* Otherwise, allocate a string with the length of the destination
4286 and copy the source into it. */
4287 gfc_init_block (&block);
4288 tmp = gfc_get_pchar_type (expr->ts.kind);
4289 tmp = gfc_call_malloc (&block, tmp, dest_word_len);
4290 gfc_add_modify (&block, tmpdecl,
4291 fold_convert (TREE_TYPE (ptr), tmp));
4292 tmp = build_call_expr_loc (input_location,
4293 built_in_decls[BUILT_IN_MEMCPY], 3,
4294 fold_convert (pvoid_type_node, tmpdecl),
4295 fold_convert (pvoid_type_node, ptr),
4296 extent);
4297 gfc_add_expr_to_block (&block, tmp);
4298 indirect = gfc_finish_block (&block);
4300 /* Wrap it up with the condition. */
4301 tmp = fold_build2 (LE_EXPR, boolean_type_node,
4302 dest_word_len, source_bytes);
4303 tmp = build3_v (COND_EXPR, tmp, direct, indirect);
4304 gfc_add_expr_to_block (&se->pre, tmp);
4306 se->expr = tmpdecl;
4307 se->string_length = dest_word_len;
4309 else
4311 tmpdecl = gfc_create_var (mold_type, "transfer");
4313 ptr = convert (build_pointer_type (mold_type), source);
4315 /* Use memcpy to do the transfer. */
4316 tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
4317 tmp = build_call_expr_loc (input_location,
4318 built_in_decls[BUILT_IN_MEMCPY], 3,
4319 fold_convert (pvoid_type_node, tmp),
4320 fold_convert (pvoid_type_node, ptr),
4321 extent);
4322 gfc_add_expr_to_block (&se->pre, tmp);
4324 se->expr = tmpdecl;
4329 /* Generate code for the ALLOCATED intrinsic.
4330 Generate inline code that directly check the address of the argument. */
4332 static void
4333 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
4335 gfc_actual_arglist *arg1;
4336 gfc_se arg1se;
4337 gfc_ss *ss1;
4338 tree tmp;
4340 gfc_init_se (&arg1se, NULL);
4341 arg1 = expr->value.function.actual;
4342 ss1 = gfc_walk_expr (arg1->expr);
4344 if (ss1 == gfc_ss_terminator)
4346 /* Allocatable scalar. */
4347 arg1se.want_pointer = 1;
4348 if (arg1->expr->ts.type == BT_CLASS)
4349 gfc_add_component_ref (arg1->expr, "$data");
4350 gfc_conv_expr (&arg1se, arg1->expr);
4351 tmp = arg1se.expr;
4353 else
4355 /* Allocatable array. */
4356 arg1se.descriptor_only = 1;
4357 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4358 tmp = gfc_conv_descriptor_data_get (arg1se.expr);
4361 tmp = fold_build2 (NE_EXPR, boolean_type_node,
4362 tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
4363 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
4367 /* Generate code for the ASSOCIATED intrinsic.
4368 If both POINTER and TARGET are arrays, generate a call to library function
4369 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
4370 In other cases, generate inline code that directly compare the address of
4371 POINTER with the address of TARGET. */
4373 static void
4374 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
4376 gfc_actual_arglist *arg1;
4377 gfc_actual_arglist *arg2;
4378 gfc_se arg1se;
4379 gfc_se arg2se;
4380 tree tmp2;
4381 tree tmp;
4382 tree nonzero_charlen;
4383 tree nonzero_arraylen;
4384 gfc_ss *ss1, *ss2;
4386 gfc_init_se (&arg1se, NULL);
4387 gfc_init_se (&arg2se, NULL);
4388 arg1 = expr->value.function.actual;
4389 if (arg1->expr->ts.type == BT_CLASS)
4390 gfc_add_component_ref (arg1->expr, "$data");
4391 arg2 = arg1->next;
4392 ss1 = gfc_walk_expr (arg1->expr);
4394 if (!arg2->expr)
4396 /* No optional target. */
4397 if (ss1 == gfc_ss_terminator)
4399 /* A pointer to a scalar. */
4400 arg1se.want_pointer = 1;
4401 gfc_conv_expr (&arg1se, arg1->expr);
4402 tmp2 = arg1se.expr;
4404 else
4406 /* A pointer to an array. */
4407 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4408 tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
4410 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4411 gfc_add_block_to_block (&se->post, &arg1se.post);
4412 tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
4413 fold_convert (TREE_TYPE (tmp2), null_pointer_node));
4414 se->expr = tmp;
4416 else
4418 /* An optional target. */
4419 ss2 = gfc_walk_expr (arg2->expr);
4421 nonzero_charlen = NULL_TREE;
4422 if (arg1->expr->ts.type == BT_CHARACTER)
4423 nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
4424 arg1->expr->ts.u.cl->backend_decl,
4425 integer_zero_node);
4427 if (ss1 == gfc_ss_terminator)
4429 /* A pointer to a scalar. */
4430 gcc_assert (ss2 == gfc_ss_terminator);
4431 arg1se.want_pointer = 1;
4432 gfc_conv_expr (&arg1se, arg1->expr);
4433 arg2se.want_pointer = 1;
4434 gfc_conv_expr (&arg2se, arg2->expr);
4435 gfc_add_block_to_block (&se->pre, &arg1se.pre);
4436 gfc_add_block_to_block (&se->post, &arg1se.post);
4437 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4438 arg1se.expr, arg2se.expr);
4439 tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
4440 arg1se.expr, null_pointer_node);
4441 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4442 tmp, tmp2);
4444 else
4446 /* An array pointer of zero length is not associated if target is
4447 present. */
4448 arg1se.descriptor_only = 1;
4449 gfc_conv_expr_lhs (&arg1se, arg1->expr);
4450 tmp = gfc_conv_descriptor_stride_get (arg1se.expr,
4451 gfc_rank_cst[arg1->expr->rank - 1]);
4452 nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
4453 build_int_cst (TREE_TYPE (tmp), 0));
4455 /* A pointer to an array, call library function _gfor_associated. */
4456 gcc_assert (ss2 != gfc_ss_terminator);
4457 arg1se.want_pointer = 1;
4458 gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4460 arg2se.want_pointer = 1;
4461 gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
4462 gfc_add_block_to_block (&se->pre, &arg2se.pre);
4463 gfc_add_block_to_block (&se->post, &arg2se.post);
4464 se->expr = build_call_expr_loc (input_location,
4465 gfor_fndecl_associated, 2,
4466 arg1se.expr, arg2se.expr);
4467 se->expr = convert (boolean_type_node, se->expr);
4468 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4469 se->expr, nonzero_arraylen);
4472 /* If target is present zero character length pointers cannot
4473 be associated. */
4474 if (nonzero_charlen != NULL_TREE)
4475 se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4476 se->expr, nonzero_charlen);
4479 se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4483 /* Generate code for the SAME_TYPE_AS intrinsic.
4484 Generate inline code that directly checks the vindices. */
4486 static void
4487 gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
4489 gfc_expr *a, *b;
4490 gfc_se se1, se2;
4491 tree tmp;
4493 gfc_init_se (&se1, NULL);
4494 gfc_init_se (&se2, NULL);
4496 a = expr->value.function.actual->expr;
4497 b = expr->value.function.actual->next->expr;
4499 if (a->ts.type == BT_CLASS)
4501 gfc_add_component_ref (a, "$vptr");
4502 gfc_add_component_ref (a, "$hash");
4504 else if (a->ts.type == BT_DERIVED)
4505 a = gfc_get_int_expr (gfc_default_integer_kind, NULL,
4506 a->ts.u.derived->hash_value);
4508 if (b->ts.type == BT_CLASS)
4510 gfc_add_component_ref (b, "$vptr");
4511 gfc_add_component_ref (b, "$hash");
4513 else if (b->ts.type == BT_DERIVED)
4514 b = gfc_get_int_expr (gfc_default_integer_kind, NULL,
4515 b->ts.u.derived->hash_value);
4517 gfc_conv_expr (&se1, a);
4518 gfc_conv_expr (&se2, b);
4520 tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4521 se1.expr, fold_convert (TREE_TYPE (se1.expr), se2.expr));
4522 se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
4526 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
4528 static void
4529 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
4531 tree args[2];
4533 gfc_conv_intrinsic_function_args (se, expr, args, 2);
4534 se->expr = build_call_expr_loc (input_location,
4535 gfor_fndecl_sc_kind, 2, args[0], args[1]);
4536 se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4540 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
4542 static void
4543 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
4545 tree arg, type;
4547 gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4549 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
4550 type = gfc_get_int_type (4);
4551 arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
4553 /* Convert it to the required type. */
4554 type = gfc_typenode_for_spec (&expr->ts);
4555 se->expr = build_call_expr_loc (input_location,
4556 gfor_fndecl_si_kind, 1, arg);
4557 se->expr = fold_convert (type, se->expr);
4561 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
4563 static void
4564 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
4566 gfc_actual_arglist *actual;
4567 tree args, type;
4568 gfc_se argse;
4570 args = NULL_TREE;
4571 for (actual = expr->value.function.actual; actual; actual = actual->next)
4573 gfc_init_se (&argse, se);
4575 /* Pass a NULL pointer for an absent arg. */
4576 if (actual->expr == NULL)
4577 argse.expr = null_pointer_node;
4578 else
4580 gfc_typespec ts;
4581 gfc_clear_ts (&ts);
4583 if (actual->expr->ts.kind != gfc_c_int_kind)
4585 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
4586 ts.type = BT_INTEGER;
4587 ts.kind = gfc_c_int_kind;
4588 gfc_convert_type (actual->expr, &ts, 2);
4590 gfc_conv_expr_reference (&argse, actual->expr);
4593 gfc_add_block_to_block (&se->pre, &argse.pre);
4594 gfc_add_block_to_block (&se->post, &argse.post);
4595 args = gfc_chainon_list (args, argse.expr);
4598 /* Convert it to the required type. */
4599 type = gfc_typenode_for_spec (&expr->ts);
4600 se->expr = build_function_call_expr (input_location,
4601 gfor_fndecl_sr_kind, args);
4602 se->expr = fold_convert (type, se->expr);
4606 /* Generate code for TRIM (A) intrinsic function. */
4608 static void
4609 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
4611 tree var;
4612 tree len;
4613 tree addr;
4614 tree tmp;
4615 tree cond;
4616 tree fndecl;
4617 tree function;
4618 tree *args;
4619 unsigned int num_args;
4621 num_args = gfc_intrinsic_argument_list_length (expr) + 2;
4622 args = (tree *) alloca (sizeof (tree) * num_args);
4624 var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
4625 addr = gfc_build_addr_expr (ppvoid_type_node, var);
4626 len = gfc_create_var (gfc_get_int_type (4), "len");
4628 gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
4629 args[0] = gfc_build_addr_expr (NULL_TREE, len);
4630 args[1] = addr;
4632 if (expr->ts.kind == 1)
4633 function = gfor_fndecl_string_trim;
4634 else if (expr->ts.kind == 4)
4635 function = gfor_fndecl_string_trim_char4;
4636 else
4637 gcc_unreachable ();
4639 fndecl = build_addr (function, current_function_decl);
4640 tmp = build_call_array_loc (input_location,
4641 TREE_TYPE (TREE_TYPE (function)), fndecl,
4642 num_args, args);
4643 gfc_add_expr_to_block (&se->pre, tmp);
4645 /* Free the temporary afterwards, if necessary. */
4646 cond = fold_build2 (GT_EXPR, boolean_type_node,
4647 len, build_int_cst (TREE_TYPE (len), 0));
4648 tmp = gfc_call_free (var);
4649 tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
4650 gfc_add_expr_to_block (&se->post, tmp);
4652 se->expr = var;
4653 se->string_length = len;
4657 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
4659 static void
4660 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
4662 tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
4663 tree type, cond, tmp, count, exit_label, n, max, largest;
4664 tree size;
4665 stmtblock_t block, body;
4666 int i;
4668 /* We store in charsize the size of a character. */
4669 i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
4670 size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
4672 /* Get the arguments. */
4673 gfc_conv_intrinsic_function_args (se, expr, args, 3);
4674 slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
4675 src = args[1];
4676 ncopies = gfc_evaluate_now (args[2], &se->pre);
4677 ncopies_type = TREE_TYPE (ncopies);
4679 /* Check that NCOPIES is not negative. */
4680 cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
4681 build_int_cst (ncopies_type, 0));
4682 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4683 "Argument NCOPIES of REPEAT intrinsic is negative "
4684 "(its value is %lld)",
4685 fold_convert (long_integer_type_node, ncopies));
4687 /* If the source length is zero, any non negative value of NCOPIES
4688 is valid, and nothing happens. */
4689 n = gfc_create_var (ncopies_type, "ncopies");
4690 cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4691 build_int_cst (size_type_node, 0));
4692 tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
4693 build_int_cst (ncopies_type, 0), ncopies);
4694 gfc_add_modify (&se->pre, n, tmp);
4695 ncopies = n;
4697 /* Check that ncopies is not too large: ncopies should be less than
4698 (or equal to) MAX / slen, where MAX is the maximal integer of
4699 the gfc_charlen_type_node type. If slen == 0, we need a special
4700 case to avoid the division by zero. */
4701 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
4702 max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
4703 max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
4704 fold_convert (size_type_node, max), slen);
4705 largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
4706 ? size_type_node : ncopies_type;
4707 cond = fold_build2 (GT_EXPR, boolean_type_node,
4708 fold_convert (largest, ncopies),
4709 fold_convert (largest, max));
4710 tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4711 build_int_cst (size_type_node, 0));
4712 cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
4713 cond);
4714 gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4715 "Argument NCOPIES of REPEAT intrinsic is too large");
4717 /* Compute the destination length. */
4718 dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4719 fold_convert (gfc_charlen_type_node, slen),
4720 fold_convert (gfc_charlen_type_node, ncopies));
4721 type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
4722 dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4724 /* Generate the code to do the repeat operation:
4725 for (i = 0; i < ncopies; i++)
4726 memmove (dest + (i * slen * size), src, slen*size); */
4727 gfc_start_block (&block);
4728 count = gfc_create_var (ncopies_type, "count");
4729 gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4730 exit_label = gfc_build_label_decl (NULL_TREE);
4732 /* Start the loop body. */
4733 gfc_start_block (&body);
4735 /* Exit the loop if count >= ncopies. */
4736 cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4737 tmp = build1_v (GOTO_EXPR, exit_label);
4738 TREE_USED (exit_label) = 1;
4739 tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4740 build_empty_stmt (input_location));
4741 gfc_add_expr_to_block (&body, tmp);
4743 /* Call memmove (dest + (i*slen*size), src, slen*size). */
4744 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4745 fold_convert (gfc_charlen_type_node, slen),
4746 fold_convert (gfc_charlen_type_node, count));
4747 tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4748 tmp, fold_convert (gfc_charlen_type_node, size));
4749 tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4750 fold_convert (pvoid_type_node, dest),
4751 fold_convert (sizetype, tmp));
4752 tmp = build_call_expr_loc (input_location,
4753 built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4754 fold_build2 (MULT_EXPR, size_type_node, slen,
4755 fold_convert (size_type_node, size)));
4756 gfc_add_expr_to_block (&body, tmp);
4758 /* Increment count. */
4759 tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4760 count, build_int_cst (TREE_TYPE (count), 1));
4761 gfc_add_modify (&body, count, tmp);
4763 /* Build the loop. */
4764 tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4765 gfc_add_expr_to_block (&block, tmp);
4767 /* Add the exit label. */
4768 tmp = build1_v (LABEL_EXPR, exit_label);
4769 gfc_add_expr_to_block (&block, tmp);
4771 /* Finish the block. */
4772 tmp = gfc_finish_block (&block);
4773 gfc_add_expr_to_block (&se->pre, tmp);
4775 /* Set the result value. */
4776 se->expr = dest;
4777 se->string_length = dlen;
4781 /* Generate code for the IARGC intrinsic. */
4783 static void
4784 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4786 tree tmp;
4787 tree fndecl;
4788 tree type;
4790 /* Call the library function. This always returns an INTEGER(4). */
4791 fndecl = gfor_fndecl_iargc;
4792 tmp = build_call_expr_loc (input_location,
4793 fndecl, 0);
4795 /* Convert it to the required type. */
4796 type = gfc_typenode_for_spec (&expr->ts);
4797 tmp = fold_convert (type, tmp);
4799 se->expr = tmp;
4803 /* The loc intrinsic returns the address of its argument as
4804 gfc_index_integer_kind integer. */
4806 static void
4807 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4809 tree temp_var;
4810 gfc_expr *arg_expr;
4811 gfc_ss *ss;
4813 gcc_assert (!se->ss);
4815 arg_expr = expr->value.function.actual->expr;
4816 ss = gfc_walk_expr (arg_expr);
4817 if (ss == gfc_ss_terminator)
4818 gfc_conv_expr_reference (se, arg_expr);
4819 else
4820 gfc_conv_array_parameter (se, arg_expr, ss, true, NULL, NULL, NULL);
4821 se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4823 /* Create a temporary variable for loc return value. Without this,
4824 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
4825 temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4826 gfc_add_modify (&se->pre, temp_var, se->expr);
4827 se->expr = temp_var;
4830 /* Generate code for an intrinsic function. Some map directly to library
4831 calls, others get special handling. In some cases the name of the function
4832 used depends on the type specifiers. */
4834 void
4835 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4837 const char *name;
4838 int lib, kind;
4839 tree fndecl;
4841 name = &expr->value.function.name[2];
4843 if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4845 lib = gfc_is_intrinsic_libcall (expr);
4846 if (lib != 0)
4848 if (lib == 1)
4849 se->ignore_optional = 1;
4851 switch (expr->value.function.isym->id)
4853 case GFC_ISYM_EOSHIFT:
4854 case GFC_ISYM_PACK:
4855 case GFC_ISYM_RESHAPE:
4856 /* For all of those the first argument specifies the type and the
4857 third is optional. */
4858 conv_generic_with_optional_char_arg (se, expr, 1, 3);
4859 break;
4861 default:
4862 gfc_conv_intrinsic_funcall (se, expr);
4863 break;
4866 return;
4870 switch (expr->value.function.isym->id)
4872 case GFC_ISYM_NONE:
4873 gcc_unreachable ();
4875 case GFC_ISYM_REPEAT:
4876 gfc_conv_intrinsic_repeat (se, expr);
4877 break;
4879 case GFC_ISYM_TRIM:
4880 gfc_conv_intrinsic_trim (se, expr);
4881 break;
4883 case GFC_ISYM_SC_KIND:
4884 gfc_conv_intrinsic_sc_kind (se, expr);
4885 break;
4887 case GFC_ISYM_SI_KIND:
4888 gfc_conv_intrinsic_si_kind (se, expr);
4889 break;
4891 case GFC_ISYM_SR_KIND:
4892 gfc_conv_intrinsic_sr_kind (se, expr);
4893 break;
4895 case GFC_ISYM_EXPONENT:
4896 gfc_conv_intrinsic_exponent (se, expr);
4897 break;
4899 case GFC_ISYM_SCAN:
4900 kind = expr->value.function.actual->expr->ts.kind;
4901 if (kind == 1)
4902 fndecl = gfor_fndecl_string_scan;
4903 else if (kind == 4)
4904 fndecl = gfor_fndecl_string_scan_char4;
4905 else
4906 gcc_unreachable ();
4908 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4909 break;
4911 case GFC_ISYM_VERIFY:
4912 kind = expr->value.function.actual->expr->ts.kind;
4913 if (kind == 1)
4914 fndecl = gfor_fndecl_string_verify;
4915 else if (kind == 4)
4916 fndecl = gfor_fndecl_string_verify_char4;
4917 else
4918 gcc_unreachable ();
4920 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4921 break;
4923 case GFC_ISYM_ALLOCATED:
4924 gfc_conv_allocated (se, expr);
4925 break;
4927 case GFC_ISYM_ASSOCIATED:
4928 gfc_conv_associated(se, expr);
4929 break;
4931 case GFC_ISYM_SAME_TYPE_AS:
4932 gfc_conv_same_type_as (se, expr);
4933 break;
4935 case GFC_ISYM_ABS:
4936 gfc_conv_intrinsic_abs (se, expr);
4937 break;
4939 case GFC_ISYM_ADJUSTL:
4940 if (expr->ts.kind == 1)
4941 fndecl = gfor_fndecl_adjustl;
4942 else if (expr->ts.kind == 4)
4943 fndecl = gfor_fndecl_adjustl_char4;
4944 else
4945 gcc_unreachable ();
4947 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4948 break;
4950 case GFC_ISYM_ADJUSTR:
4951 if (expr->ts.kind == 1)
4952 fndecl = gfor_fndecl_adjustr;
4953 else if (expr->ts.kind == 4)
4954 fndecl = gfor_fndecl_adjustr_char4;
4955 else
4956 gcc_unreachable ();
4958 gfc_conv_intrinsic_adjust (se, expr, fndecl);
4959 break;
4961 case GFC_ISYM_AIMAG:
4962 gfc_conv_intrinsic_imagpart (se, expr);
4963 break;
4965 case GFC_ISYM_AINT:
4966 gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
4967 break;
4969 case GFC_ISYM_ALL:
4970 gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
4971 break;
4973 case GFC_ISYM_ANINT:
4974 gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
4975 break;
4977 case GFC_ISYM_AND:
4978 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
4979 break;
4981 case GFC_ISYM_ANY:
4982 gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
4983 break;
4985 case GFC_ISYM_BTEST:
4986 gfc_conv_intrinsic_btest (se, expr);
4987 break;
4989 case GFC_ISYM_ACHAR:
4990 case GFC_ISYM_CHAR:
4991 gfc_conv_intrinsic_char (se, expr);
4992 break;
4994 case GFC_ISYM_CONVERSION:
4995 case GFC_ISYM_REAL:
4996 case GFC_ISYM_LOGICAL:
4997 case GFC_ISYM_DBLE:
4998 gfc_conv_intrinsic_conversion (se, expr);
4999 break;
5001 /* Integer conversions are handled separately to make sure we get the
5002 correct rounding mode. */
5003 case GFC_ISYM_INT:
5004 case GFC_ISYM_INT2:
5005 case GFC_ISYM_INT8:
5006 case GFC_ISYM_LONG:
5007 gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
5008 break;
5010 case GFC_ISYM_NINT:
5011 gfc_conv_intrinsic_int (se, expr, RND_ROUND);
5012 break;
5014 case GFC_ISYM_CEILING:
5015 gfc_conv_intrinsic_int (se, expr, RND_CEIL);
5016 break;
5018 case GFC_ISYM_FLOOR:
5019 gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
5020 break;
5022 case GFC_ISYM_MOD:
5023 gfc_conv_intrinsic_mod (se, expr, 0);
5024 break;
5026 case GFC_ISYM_MODULO:
5027 gfc_conv_intrinsic_mod (se, expr, 1);
5028 break;
5030 case GFC_ISYM_CMPLX:
5031 gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
5032 break;
5034 case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
5035 gfc_conv_intrinsic_iargc (se, expr);
5036 break;
5038 case GFC_ISYM_COMPLEX:
5039 gfc_conv_intrinsic_cmplx (se, expr, 1);
5040 break;
5042 case GFC_ISYM_CONJG:
5043 gfc_conv_intrinsic_conjg (se, expr);
5044 break;
5046 case GFC_ISYM_COUNT:
5047 gfc_conv_intrinsic_count (se, expr);
5048 break;
5050 case GFC_ISYM_CTIME:
5051 gfc_conv_intrinsic_ctime (se, expr);
5052 break;
5054 case GFC_ISYM_DIM:
5055 gfc_conv_intrinsic_dim (se, expr);
5056 break;
5058 case GFC_ISYM_DOT_PRODUCT:
5059 gfc_conv_intrinsic_dot_product (se, expr);
5060 break;
5062 case GFC_ISYM_DPROD:
5063 gfc_conv_intrinsic_dprod (se, expr);
5064 break;
5066 case GFC_ISYM_FDATE:
5067 gfc_conv_intrinsic_fdate (se, expr);
5068 break;
5070 case GFC_ISYM_FRACTION:
5071 gfc_conv_intrinsic_fraction (se, expr);
5072 break;
5074 case GFC_ISYM_IAND:
5075 gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5076 break;
5078 case GFC_ISYM_IBCLR:
5079 gfc_conv_intrinsic_singlebitop (se, expr, 0);
5080 break;
5082 case GFC_ISYM_IBITS:
5083 gfc_conv_intrinsic_ibits (se, expr);
5084 break;
5086 case GFC_ISYM_IBSET:
5087 gfc_conv_intrinsic_singlebitop (se, expr, 1);
5088 break;
5090 case GFC_ISYM_IACHAR:
5091 case GFC_ISYM_ICHAR:
5092 /* We assume ASCII character sequence. */
5093 gfc_conv_intrinsic_ichar (se, expr);
5094 break;
5096 case GFC_ISYM_IARGC:
5097 gfc_conv_intrinsic_iargc (se, expr);
5098 break;
5100 case GFC_ISYM_IEOR:
5101 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
5102 break;
5104 case GFC_ISYM_INDEX:
5105 kind = expr->value.function.actual->expr->ts.kind;
5106 if (kind == 1)
5107 fndecl = gfor_fndecl_string_index;
5108 else if (kind == 4)
5109 fndecl = gfor_fndecl_string_index_char4;
5110 else
5111 gcc_unreachable ();
5113 gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5114 break;
5116 case GFC_ISYM_IOR:
5117 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
5118 break;
5120 case GFC_ISYM_IS_IOSTAT_END:
5121 gfc_conv_has_intvalue (se, expr, LIBERROR_END);
5122 break;
5124 case GFC_ISYM_IS_IOSTAT_EOR:
5125 gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
5126 break;
5128 case GFC_ISYM_ISNAN:
5129 gfc_conv_intrinsic_isnan (se, expr);
5130 break;
5132 case GFC_ISYM_LSHIFT:
5133 gfc_conv_intrinsic_rlshift (se, expr, 0);
5134 break;
5136 case GFC_ISYM_RSHIFT:
5137 gfc_conv_intrinsic_rlshift (se, expr, 1);
5138 break;
5140 case GFC_ISYM_ISHFT:
5141 gfc_conv_intrinsic_ishft (se, expr);
5142 break;
5144 case GFC_ISYM_ISHFTC:
5145 gfc_conv_intrinsic_ishftc (se, expr);
5146 break;
5148 case GFC_ISYM_LEADZ:
5149 gfc_conv_intrinsic_leadz (se, expr);
5150 break;
5152 case GFC_ISYM_TRAILZ:
5153 gfc_conv_intrinsic_trailz (se, expr);
5154 break;
5156 case GFC_ISYM_LBOUND:
5157 gfc_conv_intrinsic_bound (se, expr, 0);
5158 break;
5160 case GFC_ISYM_TRANSPOSE:
5161 if (se->ss && se->ss->useflags)
5163 gfc_conv_tmp_array_ref (se);
5164 gfc_advance_se_ss_chain (se);
5166 else
5167 gfc_conv_array_transpose (se, expr->value.function.actual->expr);
5168 break;
5170 case GFC_ISYM_LEN:
5171 gfc_conv_intrinsic_len (se, expr);
5172 break;
5174 case GFC_ISYM_LEN_TRIM:
5175 gfc_conv_intrinsic_len_trim (se, expr);
5176 break;
5178 case GFC_ISYM_LGE:
5179 gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
5180 break;
5182 case GFC_ISYM_LGT:
5183 gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
5184 break;
5186 case GFC_ISYM_LLE:
5187 gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
5188 break;
5190 case GFC_ISYM_LLT:
5191 gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
5192 break;
5194 case GFC_ISYM_MAX:
5195 if (expr->ts.type == BT_CHARACTER)
5196 gfc_conv_intrinsic_minmax_char (se, expr, 1);
5197 else
5198 gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
5199 break;
5201 case GFC_ISYM_MAXLOC:
5202 gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
5203 break;
5205 case GFC_ISYM_MAXVAL:
5206 gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
5207 break;
5209 case GFC_ISYM_MERGE:
5210 gfc_conv_intrinsic_merge (se, expr);
5211 break;
5213 case GFC_ISYM_MIN:
5214 if (expr->ts.type == BT_CHARACTER)
5215 gfc_conv_intrinsic_minmax_char (se, expr, -1);
5216 else
5217 gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
5218 break;
5220 case GFC_ISYM_MINLOC:
5221 gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
5222 break;
5224 case GFC_ISYM_MINVAL:
5225 gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
5226 break;
5228 case GFC_ISYM_NEAREST:
5229 gfc_conv_intrinsic_nearest (se, expr);
5230 break;
5232 case GFC_ISYM_NOT:
5233 gfc_conv_intrinsic_not (se, expr);
5234 break;
5236 case GFC_ISYM_OR:
5237 gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
5238 break;
5240 case GFC_ISYM_PRESENT:
5241 gfc_conv_intrinsic_present (se, expr);
5242 break;
5244 case GFC_ISYM_PRODUCT:
5245 gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
5246 break;
5248 case GFC_ISYM_RRSPACING:
5249 gfc_conv_intrinsic_rrspacing (se, expr);
5250 break;
5252 case GFC_ISYM_SET_EXPONENT:
5253 gfc_conv_intrinsic_set_exponent (se, expr);
5254 break;
5256 case GFC_ISYM_SCALE:
5257 gfc_conv_intrinsic_scale (se, expr);
5258 break;
5260 case GFC_ISYM_SIGN:
5261 gfc_conv_intrinsic_sign (se, expr);
5262 break;
5264 case GFC_ISYM_SIZE:
5265 gfc_conv_intrinsic_size (se, expr);
5266 break;
5268 case GFC_ISYM_SIZEOF:
5269 gfc_conv_intrinsic_sizeof (se, expr);
5270 break;
5272 case GFC_ISYM_SPACING:
5273 gfc_conv_intrinsic_spacing (se, expr);
5274 break;
5276 case GFC_ISYM_SUM:
5277 gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
5278 break;
5280 case GFC_ISYM_TRANSFER:
5281 if (se->ss && se->ss->useflags)
5283 /* Access the previously obtained result. */
5284 gfc_conv_tmp_array_ref (se);
5285 gfc_advance_se_ss_chain (se);
5287 else
5288 gfc_conv_intrinsic_transfer (se, expr);
5289 break;
5291 case GFC_ISYM_TTYNAM:
5292 gfc_conv_intrinsic_ttynam (se, expr);
5293 break;
5295 case GFC_ISYM_UBOUND:
5296 gfc_conv_intrinsic_bound (se, expr, 1);
5297 break;
5299 case GFC_ISYM_XOR:
5300 gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
5301 break;
5303 case GFC_ISYM_LOC:
5304 gfc_conv_intrinsic_loc (se, expr);
5305 break;
5307 case GFC_ISYM_ACCESS:
5308 case GFC_ISYM_CHDIR:
5309 case GFC_ISYM_CHMOD:
5310 case GFC_ISYM_DTIME:
5311 case GFC_ISYM_ETIME:
5312 case GFC_ISYM_EXTENDS_TYPE_OF:
5313 case GFC_ISYM_FGET:
5314 case GFC_ISYM_FGETC:
5315 case GFC_ISYM_FNUM:
5316 case GFC_ISYM_FPUT:
5317 case GFC_ISYM_FPUTC:
5318 case GFC_ISYM_FSTAT:
5319 case GFC_ISYM_FTELL:
5320 case GFC_ISYM_GETCWD:
5321 case GFC_ISYM_GETGID:
5322 case GFC_ISYM_GETPID:
5323 case GFC_ISYM_GETUID:
5324 case GFC_ISYM_HOSTNM:
5325 case GFC_ISYM_KILL:
5326 case GFC_ISYM_IERRNO:
5327 case GFC_ISYM_IRAND:
5328 case GFC_ISYM_ISATTY:
5329 case GFC_ISYM_LINK:
5330 case GFC_ISYM_LSTAT:
5331 case GFC_ISYM_MALLOC:
5332 case GFC_ISYM_MATMUL:
5333 case GFC_ISYM_MCLOCK:
5334 case GFC_ISYM_MCLOCK8:
5335 case GFC_ISYM_RAND:
5336 case GFC_ISYM_RENAME:
5337 case GFC_ISYM_SECOND:
5338 case GFC_ISYM_SECNDS:
5339 case GFC_ISYM_SIGNAL:
5340 case GFC_ISYM_STAT:
5341 case GFC_ISYM_SYMLNK:
5342 case GFC_ISYM_SYSTEM:
5343 case GFC_ISYM_TIME:
5344 case GFC_ISYM_TIME8:
5345 case GFC_ISYM_UMASK:
5346 case GFC_ISYM_UNLINK:
5347 gfc_conv_intrinsic_funcall (se, expr);
5348 break;
5350 case GFC_ISYM_EOSHIFT:
5351 case GFC_ISYM_PACK:
5352 case GFC_ISYM_RESHAPE:
5353 /* For those, expr->rank should always be >0 and thus the if above the
5354 switch should have matched. */
5355 gcc_unreachable ();
5356 break;
5358 default:
5359 gfc_conv_intrinsic_lib_function (se, expr);
5360 break;
5365 /* This generates code to execute before entering the scalarization loop.
5366 Currently does nothing. */
5368 void
5369 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
5371 switch (ss->expr->value.function.isym->id)
5373 case GFC_ISYM_UBOUND:
5374 case GFC_ISYM_LBOUND:
5375 break;
5377 default:
5378 gcc_unreachable ();
5383 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
5384 inside the scalarization loop. */
5386 static gfc_ss *
5387 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
5389 gfc_ss *newss;
5391 /* The two argument version returns a scalar. */
5392 if (expr->value.function.actual->next->expr)
5393 return ss;
5395 newss = gfc_get_ss ();
5396 newss->type = GFC_SS_INTRINSIC;
5397 newss->expr = expr;
5398 newss->next = ss;
5399 newss->data.info.dimen = 1;
5401 return newss;
5405 /* Walk an intrinsic array libcall. */
5407 static gfc_ss *
5408 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
5410 gfc_ss *newss;
5412 gcc_assert (expr->rank > 0);
5414 newss = gfc_get_ss ();
5415 newss->type = GFC_SS_FUNCTION;
5416 newss->expr = expr;
5417 newss->next = ss;
5418 newss->data.info.dimen = expr->rank;
5420 return newss;
5424 /* Returns nonzero if the specified intrinsic function call maps directly to
5425 an external library call. Should only be used for functions that return
5426 arrays. */
5429 gfc_is_intrinsic_libcall (gfc_expr * expr)
5431 gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
5432 gcc_assert (expr->rank > 0);
5434 switch (expr->value.function.isym->id)
5436 case GFC_ISYM_ALL:
5437 case GFC_ISYM_ANY:
5438 case GFC_ISYM_COUNT:
5439 case GFC_ISYM_MATMUL:
5440 case GFC_ISYM_MAXLOC:
5441 case GFC_ISYM_MAXVAL:
5442 case GFC_ISYM_MINLOC:
5443 case GFC_ISYM_MINVAL:
5444 case GFC_ISYM_PRODUCT:
5445 case GFC_ISYM_SUM:
5446 case GFC_ISYM_SHAPE:
5447 case GFC_ISYM_SPREAD:
5448 case GFC_ISYM_TRANSPOSE:
5449 /* Ignore absent optional parameters. */
5450 return 1;
5452 case GFC_ISYM_RESHAPE:
5453 case GFC_ISYM_CSHIFT:
5454 case GFC_ISYM_EOSHIFT:
5455 case GFC_ISYM_PACK:
5456 case GFC_ISYM_UNPACK:
5457 /* Pass absent optional parameters. */
5458 return 2;
5460 default:
5461 return 0;
5465 /* Walk an intrinsic function. */
5466 gfc_ss *
5467 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
5468 gfc_intrinsic_sym * isym)
5470 gcc_assert (isym);
5472 if (isym->elemental)
5473 return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
5475 if (expr->rank == 0)
5476 return ss;
5478 if (gfc_is_intrinsic_libcall (expr))
5479 return gfc_walk_intrinsic_libfunc (ss, expr);
5481 /* Special cases. */
5482 switch (isym->id)
5484 case GFC_ISYM_LBOUND:
5485 case GFC_ISYM_UBOUND:
5486 return gfc_walk_intrinsic_bound (ss, expr);
5488 case GFC_ISYM_TRANSFER:
5489 return gfc_walk_intrinsic_libfunc (ss, expr);
5491 default:
5492 /* This probably meant someone forgot to add an intrinsic to the above
5493 list(s) when they implemented it, or something's gone horribly
5494 wrong. */
5495 gcc_unreachable ();
5499 #include "gt-fortran-trans-intrinsic.h"