OSDN Git Service

PR fortran/45304
[pf3gnuchains/gcc-fork.git] / gcc / fortran / trans-intrinsic.c
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>
6
7 This file is part of GCC.
8
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.
13
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.
18
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/>.  */
22
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics.  */
24
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 "diagnostic-core.h"    /* For internal_error.  */
32 #include "toplev.h"     /* For rest_of_decl_compilation.  */
33 #include "flags.h"
34 #include "gfortran.h"
35 #include "arith.h"
36 #include "intrinsic.h"
37 #include "trans.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
41 #include "defaults.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
43 #include "trans-stmt.h"
44
45 /* This maps fortran intrinsic math functions to external library or GCC
46    builtin functions.  */
47 typedef struct GTY(()) gfc_intrinsic_map_t {
48   /* The explicit enum is required to work around inadequacies in the
49      garbage collection/gengtype parsing mechanism.  */
50   enum gfc_isym_id id;
51
52   /* Enum value from the "language-independent", aka C-centric, part
53      of gcc, or END_BUILTINS of no such value set.  */
54   enum built_in_function float_built_in;
55   enum built_in_function double_built_in;
56   enum built_in_function long_double_built_in;
57   enum built_in_function complex_float_built_in;
58   enum built_in_function complex_double_built_in;
59   enum built_in_function complex_long_double_built_in;
60
61   /* True if the naming pattern is to prepend "c" for complex and
62      append "f" for kind=4.  False if the naming pattern is to
63      prepend "_gfortran_" and append "[rc](4|8|10|16)".  */
64   bool libm_name;
65
66   /* True if a complex version of the function exists.  */
67   bool complex_available;
68
69   /* True if the function should be marked const.  */
70   bool is_constant;
71
72   /* The base library name of this function.  */
73   const char *name;
74
75   /* Cache decls created for the various operand types.  */
76   tree real4_decl;
77   tree real8_decl;
78   tree real10_decl;
79   tree real16_decl;
80   tree complex4_decl;
81   tree complex8_decl;
82   tree complex10_decl;
83   tree complex16_decl;
84 }
85 gfc_intrinsic_map_t;
86
87 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
88    defines complex variants of all of the entries in mathbuiltins.def
89    except for atan2.  */
90 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
91   { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
92     BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
93     true, false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
94     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
95
96 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
97   { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
98     BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, BUILT_IN_C ## ID, \
99     BUILT_IN_C ## ID ## L, true, true, true, NAME, NULL_TREE, NULL_TREE, \
100     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
101
102 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
103   { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
104     END_BUILTINS, END_BUILTINS, END_BUILTINS, \
105     false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
106     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
107
108 #define OTHER_BUILTIN(ID, NAME, TYPE) \
109   { GFC_ISYM_NONE, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
110     BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
111     true, false, true, NAME, NULL_TREE, NULL_TREE, \
112     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
113
114 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
115 {
116   /* Functions built into gcc itself (DEFINE_MATH_BUILTIN and
117      DEFINE_MATH_BUILTIN_C), then the built-ins that don't correspond
118      to any GFC_ISYM id directly, which use the OTHER_BUILTIN macro.  */
119 #include "mathbuiltins.def"
120
121   /* Functions in libgfortran.  */
122   LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
123
124   /* End the list.  */
125   LIB_FUNCTION (NONE, NULL, false)
126
127 };
128 #undef OTHER_BUILTIN
129 #undef LIB_FUNCTION
130 #undef DEFINE_MATH_BUILTIN
131 #undef DEFINE_MATH_BUILTIN_C
132
133
134 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
135
136
137 /* Find the correct variant of a given builtin from its argument.  */
138 static tree
139 builtin_decl_for_precision (enum built_in_function base_built_in,
140                             int precision)
141 {
142   int i = END_BUILTINS;
143
144   gfc_intrinsic_map_t *m;
145   for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
146     ;
147
148   if (precision == TYPE_PRECISION (float_type_node))
149     i = m->float_built_in;
150   else if (precision == TYPE_PRECISION (double_type_node))
151     i = m->double_built_in;
152   else if (precision == TYPE_PRECISION (long_double_type_node))
153     i = m->long_double_built_in;
154
155   return (i == END_BUILTINS ? NULL_TREE : built_in_decls[i]);
156 }
157
158
159 static tree
160 builtin_decl_for_float_kind (enum built_in_function double_built_in, int kind)
161 {
162   int i = gfc_validate_kind (BT_REAL, kind, false);
163   return builtin_decl_for_precision (double_built_in,
164                                      gfc_real_kinds[i].mode_precision);
165 }
166
167
168 /* Evaluate the arguments to an intrinsic function.  The value
169    of NARGS may be less than the actual number of arguments in EXPR
170    to allow optional "KIND" arguments that are not included in the
171    generated code to be ignored.  */
172
173 static void
174 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
175                                   tree *argarray, int nargs)
176 {
177   gfc_actual_arglist *actual;
178   gfc_expr *e;
179   gfc_intrinsic_arg  *formal;
180   gfc_se argse;
181   int curr_arg;
182
183   formal = expr->value.function.isym->formal;
184   actual = expr->value.function.actual;
185
186    for (curr_arg = 0; curr_arg < nargs; curr_arg++,
187         actual = actual->next,
188         formal = formal ? formal->next : NULL)
189     {
190       gcc_assert (actual);
191       e = actual->expr;
192       /* Skip omitted optional arguments.  */
193       if (!e)
194         {
195           --curr_arg;
196           continue;
197         }
198
199       /* Evaluate the parameter.  This will substitute scalarized
200          references automatically.  */
201       gfc_init_se (&argse, se);
202
203       if (e->ts.type == BT_CHARACTER)
204         {
205           gfc_conv_expr (&argse, e);
206           gfc_conv_string_parameter (&argse);
207           argarray[curr_arg++] = argse.string_length;
208           gcc_assert (curr_arg < nargs);
209         }
210       else
211         gfc_conv_expr_val (&argse, e);
212
213       /* If an optional argument is itself an optional dummy argument,
214          check its presence and substitute a null if absent.  */
215       if (e->expr_type == EXPR_VARIABLE
216             && e->symtree->n.sym->attr.optional
217             && formal
218             && formal->optional)
219         gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
220
221       gfc_add_block_to_block (&se->pre, &argse.pre);
222       gfc_add_block_to_block (&se->post, &argse.post);
223       argarray[curr_arg] = argse.expr;
224     }
225 }
226
227 /* Count the number of actual arguments to the intrinsic function EXPR
228    including any "hidden" string length arguments.  */
229
230 static unsigned int
231 gfc_intrinsic_argument_list_length (gfc_expr *expr)
232 {
233   int n = 0;
234   gfc_actual_arglist *actual;
235
236   for (actual = expr->value.function.actual; actual; actual = actual->next)
237     {
238       if (!actual->expr)
239         continue;
240
241       if (actual->expr->ts.type == BT_CHARACTER)
242         n += 2;
243       else
244         n++;
245     }
246
247   return n;
248 }
249
250
251 /* Conversions between different types are output by the frontend as
252    intrinsic functions.  We implement these directly with inline code.  */
253
254 static void
255 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
256 {
257   tree type;
258   tree *args;
259   int nargs;
260
261   nargs = gfc_intrinsic_argument_list_length (expr);
262   args = XALLOCAVEC (tree, nargs);
263
264   /* Evaluate all the arguments passed. Whilst we're only interested in the 
265      first one here, there are other parts of the front-end that assume this 
266      and will trigger an ICE if it's not the case.  */
267   type = gfc_typenode_for_spec (&expr->ts);
268   gcc_assert (expr->value.function.actual->expr);
269   gfc_conv_intrinsic_function_args (se, expr, args, nargs);
270
271   /* Conversion between character kinds involves a call to a library
272      function.  */
273   if (expr->ts.type == BT_CHARACTER)
274     {
275       tree fndecl, var, addr, tmp;
276
277       if (expr->ts.kind == 1
278           && expr->value.function.actual->expr->ts.kind == 4)
279         fndecl = gfor_fndecl_convert_char4_to_char1;
280       else if (expr->ts.kind == 4
281                && expr->value.function.actual->expr->ts.kind == 1)
282         fndecl = gfor_fndecl_convert_char1_to_char4;
283       else
284         gcc_unreachable ();
285
286       /* Create the variable storing the converted value.  */
287       type = gfc_get_pchar_type (expr->ts.kind);
288       var = gfc_create_var (type, "str");
289       addr = gfc_build_addr_expr (build_pointer_type (type), var);
290
291       /* Call the library function that will perform the conversion.  */
292       gcc_assert (nargs >= 2);
293       tmp = build_call_expr_loc (input_location,
294                              fndecl, 3, addr, args[0], args[1]);
295       gfc_add_expr_to_block (&se->pre, tmp);
296
297       /* Free the temporary afterwards.  */
298       tmp = gfc_call_free (var);
299       gfc_add_expr_to_block (&se->post, tmp);
300
301       se->expr = var;
302       se->string_length = args[0];
303
304       return;
305     }
306
307   /* Conversion from complex to non-complex involves taking the real
308      component of the value.  */
309   if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
310       && expr->ts.type != BT_COMPLEX)
311     {
312       tree artype;
313
314       artype = TREE_TYPE (TREE_TYPE (args[0]));
315       args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
316     }
317
318   se->expr = convert (type, args[0]);
319 }
320
321 /* This is needed because the gcc backend only implements
322    FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
323    FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
324    Similarly for CEILING.  */
325
326 static tree
327 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
328 {
329   tree tmp;
330   tree cond;
331   tree argtype;
332   tree intval;
333
334   argtype = TREE_TYPE (arg);
335   arg = gfc_evaluate_now (arg, pblock);
336
337   intval = convert (type, arg);
338   intval = gfc_evaluate_now (intval, pblock);
339
340   tmp = convert (argtype, intval);
341   cond = fold_build2 (up ? GE_EXPR : LE_EXPR, boolean_type_node, tmp, arg);
342
343   tmp = fold_build2 (up ? PLUS_EXPR : MINUS_EXPR, type, intval,
344                      build_int_cst (type, 1));
345   tmp = fold_build3 (COND_EXPR, type, cond, intval, tmp);
346   return tmp;
347 }
348
349
350 /* Round to nearest integer, away from zero.  */
351
352 static tree
353 build_round_expr (tree arg, tree restype)
354 {
355   tree argtype;
356   tree fn;
357   bool longlong;
358   int argprec, resprec;
359
360   argtype = TREE_TYPE (arg);
361   argprec = TYPE_PRECISION (argtype);
362   resprec = TYPE_PRECISION (restype);
363
364   /* Depending on the type of the result, choose the long int intrinsic
365      (lround family) or long long intrinsic (llround).  We might also
366      need to convert the result afterwards.  */
367   if (resprec <= LONG_TYPE_SIZE)
368     longlong = false;
369   else if (resprec <= LONG_LONG_TYPE_SIZE)
370     longlong = true;
371   else
372     gcc_unreachable ();
373
374   /* Now, depending on the argument type, we choose between intrinsics.  */
375   if (longlong)
376     fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
377   else
378     fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
379
380   return fold_convert (restype, build_call_expr_loc (input_location,
381                                                  fn, 1, arg));
382 }
383
384
385 /* Convert a real to an integer using a specific rounding mode.
386    Ideally we would just build the corresponding GENERIC node,
387    however the RTL expander only actually supports FIX_TRUNC_EXPR.  */
388
389 static tree
390 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
391                enum rounding_mode op)
392 {
393   switch (op)
394     {
395     case RND_FLOOR:
396       return build_fixbound_expr (pblock, arg, type, 0);
397       break;
398
399     case RND_CEIL:
400       return build_fixbound_expr (pblock, arg, type, 1);
401       break;
402
403     case RND_ROUND:
404       return build_round_expr (arg, type);
405       break;
406
407     case RND_TRUNC:
408       return fold_build1 (FIX_TRUNC_EXPR, type, arg);
409       break;
410
411     default:
412       gcc_unreachable ();
413     }
414 }
415
416
417 /* Round a real value using the specified rounding mode.
418    We use a temporary integer of that same kind size as the result.
419    Values larger than those that can be represented by this kind are
420    unchanged, as they will not be accurate enough to represent the
421    rounding.
422     huge = HUGE (KIND (a))
423     aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
424    */
425
426 static void
427 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
428 {
429   tree type;
430   tree itype;
431   tree arg[2];
432   tree tmp;
433   tree cond;
434   tree decl;
435   mpfr_t huge;
436   int n, nargs;
437   int kind;
438
439   kind = expr->ts.kind;
440   nargs =  gfc_intrinsic_argument_list_length (expr);
441
442   decl = NULL_TREE;
443   /* We have builtin functions for some cases.  */
444   switch (op)
445     {
446     case RND_ROUND:
447       decl = builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
448       break;
449
450     case RND_TRUNC:
451       decl = builtin_decl_for_float_kind (BUILT_IN_TRUNC, kind);
452       break;
453
454     default:
455       gcc_unreachable ();
456     }
457
458   /* Evaluate the argument.  */
459   gcc_assert (expr->value.function.actual->expr);
460   gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
461
462   /* Use a builtin function if one exists.  */
463   if (decl != NULL_TREE)
464     {
465       se->expr = build_call_expr_loc (input_location, decl, 1, arg[0]);
466       return;
467     }
468
469   /* This code is probably redundant, but we'll keep it lying around just
470      in case.  */
471   type = gfc_typenode_for_spec (&expr->ts);
472   arg[0] = gfc_evaluate_now (arg[0], &se->pre);
473
474   /* Test if the value is too large to handle sensibly.  */
475   gfc_set_model_kind (kind);
476   mpfr_init (huge);
477   n = gfc_validate_kind (BT_INTEGER, kind, false);
478   mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
479   tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
480   cond = fold_build2 (LT_EXPR, boolean_type_node, arg[0], tmp);
481
482   mpfr_neg (huge, huge, GFC_RND_MODE);
483   tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
484   tmp = fold_build2 (GT_EXPR, boolean_type_node, arg[0], tmp);
485   cond = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond, tmp);
486   itype = gfc_get_int_type (kind);
487
488   tmp = build_fix_expr (&se->pre, arg[0], itype, op);
489   tmp = convert (type, tmp);
490   se->expr = fold_build3 (COND_EXPR, type, cond, tmp, arg[0]);
491   mpfr_clear (huge);
492 }
493
494
495 /* Convert to an integer using the specified rounding mode.  */
496
497 static void
498 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
499 {
500   tree type;
501   tree *args;
502   int nargs;
503
504   nargs = gfc_intrinsic_argument_list_length (expr);
505   args = XALLOCAVEC (tree, nargs);
506
507   /* Evaluate the argument, we process all arguments even though we only 
508      use the first one for code generation purposes.  */
509   type = gfc_typenode_for_spec (&expr->ts);
510   gcc_assert (expr->value.function.actual->expr);
511   gfc_conv_intrinsic_function_args (se, expr, args, nargs);
512
513   if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
514     {
515       /* Conversion to a different integer kind.  */
516       se->expr = convert (type, args[0]);
517     }
518   else
519     {
520       /* Conversion from complex to non-complex involves taking the real
521          component of the value.  */
522       if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
523           && expr->ts.type != BT_COMPLEX)
524         {
525           tree artype;
526
527           artype = TREE_TYPE (TREE_TYPE (args[0]));
528           args[0] = fold_build1 (REALPART_EXPR, artype, args[0]);
529         }
530
531       se->expr = build_fix_expr (&se->pre, args[0], type, op);
532     }
533 }
534
535
536 /* Get the imaginary component of a value.  */
537
538 static void
539 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
540 {
541   tree arg;
542
543   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
544   se->expr = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
545 }
546
547
548 /* Get the complex conjugate of a value.  */
549
550 static void
551 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
552 {
553   tree arg;
554
555   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
556   se->expr = fold_build1 (CONJ_EXPR, TREE_TYPE (arg), arg);
557 }
558
559
560 /* Initialize function decls for library functions.  The external functions
561    are created as required.  Builtin functions are added here.  */
562
563 void
564 gfc_build_intrinsic_lib_fndecls (void)
565 {
566   gfc_intrinsic_map_t *m;
567
568   /* Add GCC builtin functions.  */
569   for (m = gfc_intrinsic_map;
570        m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
571     {
572       if (m->float_built_in != END_BUILTINS)
573         m->real4_decl = built_in_decls[m->float_built_in];
574       if (m->complex_float_built_in != END_BUILTINS)
575         m->complex4_decl = built_in_decls[m->complex_float_built_in];
576       if (m->double_built_in != END_BUILTINS)
577         m->real8_decl = built_in_decls[m->double_built_in];
578       if (m->complex_double_built_in != END_BUILTINS)
579         m->complex8_decl = built_in_decls[m->complex_double_built_in];
580
581       /* If real(kind=10) exists, it is always long double.  */
582       if (m->long_double_built_in != END_BUILTINS)
583         m->real10_decl = built_in_decls[m->long_double_built_in];
584       if (m->complex_long_double_built_in != END_BUILTINS)
585         m->complex10_decl = built_in_decls[m->complex_long_double_built_in];
586
587       /* For now, we assume that if real(kind=16) exists, it is long double.
588          Later, we will deal with __float128 and break this assumption.  */
589       if (m->long_double_built_in != END_BUILTINS)
590         m->real16_decl = built_in_decls[m->long_double_built_in];
591       if (m->complex_long_double_built_in != END_BUILTINS)
592         m->complex16_decl = built_in_decls[m->complex_long_double_built_in];
593     }
594 }
595
596
597 /* Create a fndecl for a simple intrinsic library function.  */
598
599 static tree
600 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
601 {
602   tree type;
603   tree argtypes;
604   tree fndecl;
605   gfc_actual_arglist *actual;
606   tree *pdecl;
607   gfc_typespec *ts;
608   char name[GFC_MAX_SYMBOL_LEN + 3];
609
610   ts = &expr->ts;
611   if (ts->type == BT_REAL)
612     {
613       switch (ts->kind)
614         {
615         case 4:
616           pdecl = &m->real4_decl;
617           break;
618         case 8:
619           pdecl = &m->real8_decl;
620           break;
621         case 10:
622           pdecl = &m->real10_decl;
623           break;
624         case 16:
625           pdecl = &m->real16_decl;
626           break;
627         default:
628           gcc_unreachable ();
629         }
630     }
631   else if (ts->type == BT_COMPLEX)
632     {
633       gcc_assert (m->complex_available);
634
635       switch (ts->kind)
636         {
637         case 4:
638           pdecl = &m->complex4_decl;
639           break;
640         case 8:
641           pdecl = &m->complex8_decl;
642           break;
643         case 10:
644           pdecl = &m->complex10_decl;
645           break;
646         case 16:
647           pdecl = &m->complex16_decl;
648           break;
649         default:
650           gcc_unreachable ();
651         }
652     }
653   else
654     gcc_unreachable ();
655
656   if (*pdecl)
657     return *pdecl;
658
659   if (m->libm_name)
660     {
661       int n = gfc_validate_kind (BT_REAL, ts->kind, false);
662       if (gfc_real_kinds[n].c_float)
663         snprintf (name, sizeof (name), "%s%s%s",
664                   ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
665       else if (gfc_real_kinds[n].c_double)
666         snprintf (name, sizeof (name), "%s%s",
667                   ts->type == BT_COMPLEX ? "c" : "", m->name);
668       else if (gfc_real_kinds[n].c_long_double)
669         snprintf (name, sizeof (name), "%s%s%s",
670                   ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
671       else
672         gcc_unreachable ();
673     }
674   else
675     {
676       snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
677                 ts->type == BT_COMPLEX ? 'c' : 'r',
678                 ts->kind);
679     }
680
681   argtypes = NULL_TREE;
682   for (actual = expr->value.function.actual; actual; actual = actual->next)
683     {
684       type = gfc_typenode_for_spec (&actual->expr->ts);
685       argtypes = gfc_chainon_list (argtypes, type);
686     }
687   argtypes = chainon (argtypes, void_list_node);
688   type = build_function_type (gfc_typenode_for_spec (ts), argtypes);
689   fndecl = build_decl (input_location,
690                        FUNCTION_DECL, get_identifier (name), type);
691
692   /* Mark the decl as external.  */
693   DECL_EXTERNAL (fndecl) = 1;
694   TREE_PUBLIC (fndecl) = 1;
695
696   /* Mark it __attribute__((const)), if possible.  */
697   TREE_READONLY (fndecl) = m->is_constant;
698
699   rest_of_decl_compilation (fndecl, 1, 0);
700
701   (*pdecl) = fndecl;
702   return fndecl;
703 }
704
705
706 /* Convert an intrinsic function into an external or builtin call.  */
707
708 static void
709 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
710 {
711   gfc_intrinsic_map_t *m;
712   tree fndecl;
713   tree rettype;
714   tree *args;
715   unsigned int num_args;
716   gfc_isym_id id;
717
718   id = expr->value.function.isym->id;
719   /* Find the entry for this function.  */
720   for (m = gfc_intrinsic_map;
721        m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
722     {
723       if (id == m->id)
724         break;
725     }
726
727   if (m->id == GFC_ISYM_NONE)
728     {
729       internal_error ("Intrinsic function %s(%d) not recognized",
730                       expr->value.function.name, id);
731     }
732
733   /* Get the decl and generate the call.  */
734   num_args = gfc_intrinsic_argument_list_length (expr);
735   args = XALLOCAVEC (tree, num_args);
736
737   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
738   fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
739   rettype = TREE_TYPE (TREE_TYPE (fndecl));
740
741   fndecl = build_addr (fndecl, current_function_decl);
742   se->expr = build_call_array_loc (input_location, rettype, fndecl, num_args, args);
743 }
744
745
746 /* If bounds-checking is enabled, create code to verify at runtime that the
747    string lengths for both expressions are the same (needed for e.g. MERGE).
748    If bounds-checking is not enabled, does nothing.  */
749
750 void
751 gfc_trans_same_strlen_check (const char* intr_name, locus* where,
752                              tree a, tree b, stmtblock_t* target)
753 {
754   tree cond;
755   tree name;
756
757   /* If bounds-checking is disabled, do nothing.  */
758   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
759     return;
760
761   /* Compare the two string lengths.  */
762   cond = fold_build2 (NE_EXPR, boolean_type_node, a, b);
763
764   /* Output the runtime-check.  */
765   name = gfc_build_cstring_const (intr_name);
766   name = gfc_build_addr_expr (pchar_type_node, name);
767   gfc_trans_runtime_check (true, false, cond, target, where,
768                            "Unequal character lengths (%ld/%ld) in %s",
769                            fold_convert (long_integer_type_node, a),
770                            fold_convert (long_integer_type_node, b), name);
771 }
772
773
774 /* The EXPONENT(s) intrinsic function is translated into
775        int ret;
776        frexp (s, &ret);
777        return ret;
778  */
779
780 static void
781 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
782 {
783   tree arg, type, res, tmp, frexp;
784
785   frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP,
786                                        expr->value.function.actual->expr->ts.kind);
787
788   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
789
790   res = gfc_create_var (integer_type_node, NULL);
791   tmp = build_call_expr_loc (input_location, frexp, 2, arg,
792                              gfc_build_addr_expr (NULL_TREE, res));
793   gfc_add_expr_to_block (&se->pre, tmp);
794
795   type = gfc_typenode_for_spec (&expr->ts);
796   se->expr = fold_convert (type, res);
797 }
798
799 /* Evaluate a single upper or lower bound.  */
800 /* TODO: bound intrinsic generates way too much unnecessary code.  */
801
802 static void
803 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
804 {
805   gfc_actual_arglist *arg;
806   gfc_actual_arglist *arg2;
807   tree desc;
808   tree type;
809   tree bound;
810   tree tmp;
811   tree cond, cond1, cond3, cond4, size;
812   tree ubound;
813   tree lbound;
814   gfc_se argse;
815   gfc_ss *ss;
816   gfc_array_spec * as;
817
818   arg = expr->value.function.actual;
819   arg2 = arg->next;
820
821   if (se->ss)
822     {
823       /* Create an implicit second parameter from the loop variable.  */
824       gcc_assert (!arg2->expr);
825       gcc_assert (se->loop->dimen == 1);
826       gcc_assert (se->ss->expr == expr);
827       gfc_advance_se_ss_chain (se);
828       bound = se->loop->loopvar[0];
829       bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
830                            se->loop->from[0]);
831     }
832   else
833     {
834       /* use the passed argument.  */
835       gcc_assert (arg->next->expr);
836       gfc_init_se (&argse, NULL);
837       gfc_conv_expr_type (&argse, arg->next->expr, gfc_array_index_type);
838       gfc_add_block_to_block (&se->pre, &argse.pre);
839       bound = argse.expr;
840       /* Convert from one based to zero based.  */
841       bound = fold_build2 (MINUS_EXPR, gfc_array_index_type, bound,
842                            gfc_index_one_node);
843     }
844
845   /* TODO: don't re-evaluate the descriptor on each iteration.  */
846   /* Get a descriptor for the first parameter.  */
847   ss = gfc_walk_expr (arg->expr);
848   gcc_assert (ss != gfc_ss_terminator);
849   gfc_init_se (&argse, NULL);
850   gfc_conv_expr_descriptor (&argse, arg->expr, ss);
851   gfc_add_block_to_block (&se->pre, &argse.pre);
852   gfc_add_block_to_block (&se->post, &argse.post);
853
854   desc = argse.expr;
855
856   if (INTEGER_CST_P (bound))
857     {
858       int hi, low;
859
860       hi = TREE_INT_CST_HIGH (bound);
861       low = TREE_INT_CST_LOW (bound);
862       if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
863         gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
864                    "dimension index", upper ? "UBOUND" : "LBOUND",
865                    &expr->where);
866     }
867   else
868     {
869       if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
870         {
871           bound = gfc_evaluate_now (bound, &se->pre);
872           cond = fold_build2 (LT_EXPR, boolean_type_node,
873                               bound, build_int_cst (TREE_TYPE (bound), 0));
874           tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
875           tmp = fold_build2 (GE_EXPR, boolean_type_node, bound, tmp);
876           cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node, cond, tmp);
877           gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
878                                    gfc_msg_fault);
879         }
880     }
881
882   ubound = gfc_conv_descriptor_ubound_get (desc, bound);
883   lbound = gfc_conv_descriptor_lbound_get (desc, bound);
884   
885   as = gfc_get_full_arrayspec_from_expr (arg->expr);
886
887   /* 13.14.53: Result value for LBOUND
888
889      Case (i): For an array section or for an array expression other than a
890                whole array or array structure component, LBOUND(ARRAY, DIM)
891                has the value 1.  For a whole array or array structure
892                component, LBOUND(ARRAY, DIM) has the value:
893                  (a) equal to the lower bound for subscript DIM of ARRAY if
894                      dimension DIM of ARRAY does not have extent zero
895                      or if ARRAY is an assumed-size array of rank DIM,
896               or (b) 1 otherwise.
897
898      13.14.113: Result value for UBOUND
899
900      Case (i): For an array section or for an array expression other than a
901                whole array or array structure component, UBOUND(ARRAY, DIM)
902                has the value equal to the number of elements in the given
903                dimension; otherwise, it has a value equal to the upper bound
904                for subscript DIM of ARRAY if dimension DIM of ARRAY does
905                not have size zero and has value zero if dimension DIM has
906                size zero.  */
907
908   if (as)
909     {
910       tree stride = gfc_conv_descriptor_stride_get (desc, bound);
911
912       cond1 = fold_build2 (GE_EXPR, boolean_type_node, ubound, lbound);
913
914       cond3 = fold_build2 (GE_EXPR, boolean_type_node, stride,
915                            gfc_index_zero_node);
916       cond3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond3, cond1);
917
918       cond4 = fold_build2 (LT_EXPR, boolean_type_node, stride,
919                            gfc_index_zero_node);
920
921       if (upper)
922         {
923           tree cond5;
924           cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
925
926           cond5 = fold_build2 (EQ_EXPR, boolean_type_node, gfc_index_one_node, lbound);
927           cond5 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, cond4, cond5);
928
929           cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond5);
930
931           se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
932                                   ubound, gfc_index_zero_node);
933         }
934       else
935         {
936           if (as->type == AS_ASSUMED_SIZE)
937             cond = fold_build2 (EQ_EXPR, boolean_type_node, bound,
938                                 build_int_cst (TREE_TYPE (bound),
939                                                arg->expr->rank - 1));
940           else
941             cond = boolean_false_node;
942
943           cond1 = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond3, cond4);
944           cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, cond, cond1);
945
946           se->expr = fold_build3 (COND_EXPR, gfc_array_index_type, cond,
947                                   lbound, gfc_index_one_node);
948         }
949     }
950   else
951     {
952       if (upper)
953         {
954           size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
955           se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, size,
956                                   gfc_index_one_node);
957           se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
958                                   gfc_index_zero_node);
959         }
960       else
961         se->expr = gfc_index_one_node;
962     }
963
964   type = gfc_typenode_for_spec (&expr->ts);
965   se->expr = convert (type, se->expr);
966 }
967
968
969 static void
970 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
971 {
972   tree arg, cabs;
973
974   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
975
976   switch (expr->value.function.actual->expr->ts.type)
977     {
978     case BT_INTEGER:
979     case BT_REAL:
980       se->expr = fold_build1 (ABS_EXPR, TREE_TYPE (arg), arg);
981       break;
982
983     case BT_COMPLEX:
984       cabs = builtin_decl_for_float_kind (BUILT_IN_CABS, expr->ts.kind);
985       se->expr = build_call_expr_loc (input_location, cabs, 1, arg);
986       break;
987
988     default:
989       gcc_unreachable ();
990     }
991 }
992
993
994 /* Create a complex value from one or two real components.  */
995
996 static void
997 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
998 {
999   tree real;
1000   tree imag;
1001   tree type;
1002   tree *args;
1003   unsigned int num_args;
1004
1005   num_args = gfc_intrinsic_argument_list_length (expr);
1006   args = XALLOCAVEC (tree, num_args);
1007
1008   type = gfc_typenode_for_spec (&expr->ts);
1009   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1010   real = convert (TREE_TYPE (type), args[0]);
1011   if (both)
1012     imag = convert (TREE_TYPE (type), args[1]);
1013   else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1014     {
1015       imag = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (args[0])),
1016                           args[0]);
1017       imag = convert (TREE_TYPE (type), imag);
1018     }
1019   else
1020     imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1021
1022   se->expr = fold_build2 (COMPLEX_EXPR, type, real, imag);
1023 }
1024
1025 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1026                       MODULO(A, P) = A - FLOOR (A / P) * P  */
1027 /* TODO: MOD(x, 0)  */
1028
1029 static void
1030 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1031 {
1032   tree type;
1033   tree itype;
1034   tree tmp;
1035   tree test;
1036   tree test2;
1037   tree fmod;
1038   mpfr_t huge;
1039   int n, ikind;
1040   tree args[2];
1041
1042   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1043
1044   switch (expr->ts.type)
1045     {
1046     case BT_INTEGER:
1047       /* Integer case is easy, we've got a builtin op.  */
1048       type = TREE_TYPE (args[0]);
1049
1050       if (modulo)
1051        se->expr = fold_build2 (FLOOR_MOD_EXPR, type, args[0], args[1]);
1052       else
1053        se->expr = fold_build2 (TRUNC_MOD_EXPR, type, args[0], args[1]);
1054       break;
1055
1056     case BT_REAL:
1057       fmod = NULL_TREE;
1058       /* Check if we have a builtin fmod.  */
1059       fmod = builtin_decl_for_float_kind (BUILT_IN_FMOD, expr->ts.kind);
1060
1061       /* Use it if it exists.  */
1062       if (fmod != NULL_TREE)
1063         {
1064           tmp = build_addr (fmod, current_function_decl);
1065           se->expr = build_call_array_loc (input_location,
1066                                        TREE_TYPE (TREE_TYPE (fmod)),
1067                                        tmp, 2, args);
1068           if (modulo == 0)
1069             return;
1070         }
1071
1072       type = TREE_TYPE (args[0]);
1073
1074       args[0] = gfc_evaluate_now (args[0], &se->pre);
1075       args[1] = gfc_evaluate_now (args[1], &se->pre);
1076
1077       /* Definition:
1078          modulo = arg - floor (arg/arg2) * arg2, so
1079                 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2, 
1080          where
1081           test  = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1082          thereby avoiding another division and retaining the accuracy
1083          of the builtin function.  */
1084       if (fmod != NULL_TREE && modulo)
1085         {
1086           tree zero = gfc_build_const (type, integer_zero_node);
1087           tmp = gfc_evaluate_now (se->expr, &se->pre);
1088           test = fold_build2 (LT_EXPR, boolean_type_node, args[0], zero);
1089           test2 = fold_build2 (LT_EXPR, boolean_type_node, args[1], zero);
1090           test2 = fold_build2 (TRUTH_XOR_EXPR, boolean_type_node, test, test2);
1091           test = fold_build2 (NE_EXPR, boolean_type_node, tmp, zero);
1092           test = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1093           test = gfc_evaluate_now (test, &se->pre);
1094           se->expr = fold_build3 (COND_EXPR, type, test,
1095                                   fold_build2 (PLUS_EXPR, type, tmp, args[1]),
1096                                   tmp);
1097           return;
1098         }
1099
1100       /* If we do not have a built_in fmod, the calculation is going to
1101          have to be done longhand.  */
1102       tmp = fold_build2 (RDIV_EXPR, type, args[0], args[1]);
1103
1104       /* Test if the value is too large to handle sensibly.  */
1105       gfc_set_model_kind (expr->ts.kind);
1106       mpfr_init (huge);
1107       n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1108       ikind = expr->ts.kind;
1109       if (n < 0)
1110         {
1111           n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1112           ikind = gfc_max_integer_kind;
1113         }
1114       mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1115       test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1116       test2 = fold_build2 (LT_EXPR, boolean_type_node, tmp, test);
1117
1118       mpfr_neg (huge, huge, GFC_RND_MODE);
1119       test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1120       test = fold_build2 (GT_EXPR, boolean_type_node, tmp, test);
1121       test2 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, test, test2);
1122
1123       itype = gfc_get_int_type (ikind);
1124       if (modulo)
1125        tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1126       else
1127        tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1128       tmp = convert (type, tmp);
1129       tmp = fold_build3 (COND_EXPR, type, test2, tmp, args[0]);
1130       tmp = fold_build2 (MULT_EXPR, type, tmp, args[1]);
1131       se->expr = fold_build2 (MINUS_EXPR, type, args[0], tmp);
1132       mpfr_clear (huge);
1133       break;
1134
1135     default:
1136       gcc_unreachable ();
1137     }
1138 }
1139
1140 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y.  */
1141
1142 static void
1143 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1144 {
1145   tree val;
1146   tree tmp;
1147   tree type;
1148   tree zero;
1149   tree args[2];
1150
1151   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1152   type = TREE_TYPE (args[0]);
1153
1154   val = fold_build2 (MINUS_EXPR, type, args[0], args[1]);
1155   val = gfc_evaluate_now (val, &se->pre);
1156
1157   zero = gfc_build_const (type, integer_zero_node);
1158   tmp = fold_build2 (LE_EXPR, boolean_type_node, val, zero);
1159   se->expr = fold_build3 (COND_EXPR, type, tmp, zero, val);
1160 }
1161
1162
1163 /* SIGN(A, B) is absolute value of A times sign of B.
1164    The real value versions use library functions to ensure the correct
1165    handling of negative zero.  Integer case implemented as:
1166    SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1167   */
1168
1169 static void
1170 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1171 {
1172   tree tmp;
1173   tree type;
1174   tree args[2];
1175
1176   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1177   if (expr->ts.type == BT_REAL)
1178     {
1179       tree abs;
1180
1181       tmp = builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
1182       abs = builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
1183
1184       /* We explicitly have to ignore the minus sign. We do so by using
1185          result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1).  */
1186       if (!gfc_option.flag_sign_zero
1187           && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
1188         {
1189           tree cond, zero;
1190           zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
1191           cond = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
1192           se->expr = fold_build3 (COND_EXPR, TREE_TYPE (args[0]), cond,
1193                                   build_call_expr (abs, 1, args[0]),
1194                                   build_call_expr (tmp, 2, args[0], args[1]));
1195         }
1196       else
1197         se->expr = build_call_expr_loc (input_location, tmp, 2,
1198                                         args[0], args[1]);
1199       return;
1200     }
1201
1202   /* Having excluded floating point types, we know we are now dealing
1203      with signed integer types.  */
1204   type = TREE_TYPE (args[0]);
1205
1206   /* Args[0] is used multiple times below.  */
1207   args[0] = gfc_evaluate_now (args[0], &se->pre);
1208
1209   /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1210      the signs of A and B are the same, and of all ones if they differ.  */
1211   tmp = fold_build2 (BIT_XOR_EXPR, type, args[0], args[1]);
1212   tmp = fold_build2 (RSHIFT_EXPR, type, tmp,
1213                      build_int_cst (type, TYPE_PRECISION (type) - 1));
1214   tmp = gfc_evaluate_now (tmp, &se->pre);
1215
1216   /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1217      is all ones (i.e. -1).  */
1218   se->expr = fold_build2 (BIT_XOR_EXPR, type,
1219                           fold_build2 (PLUS_EXPR, type, args[0], tmp),
1220                           tmp);
1221 }
1222
1223
1224 /* Test for the presence of an optional argument.  */
1225
1226 static void
1227 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1228 {
1229   gfc_expr *arg;
1230
1231   arg = expr->value.function.actual->expr;
1232   gcc_assert (arg->expr_type == EXPR_VARIABLE);
1233   se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
1234   se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
1235 }
1236
1237
1238 /* Calculate the double precision product of two single precision values.  */
1239
1240 static void
1241 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
1242 {
1243   tree type;
1244   tree args[2];
1245
1246   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1247
1248   /* Convert the args to double precision before multiplying.  */
1249   type = gfc_typenode_for_spec (&expr->ts);
1250   args[0] = convert (type, args[0]);
1251   args[1] = convert (type, args[1]);
1252   se->expr = fold_build2 (MULT_EXPR, type, args[0], args[1]);
1253 }
1254
1255
1256 /* Return a length one character string containing an ascii character.  */
1257
1258 static void
1259 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
1260 {
1261   tree arg[2];
1262   tree var;
1263   tree type;
1264   unsigned int num_args;
1265
1266   num_args = gfc_intrinsic_argument_list_length (expr);
1267   gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
1268
1269   type = gfc_get_char_type (expr->ts.kind);
1270   var = gfc_create_var (type, "char");
1271
1272   arg[0] = fold_build1 (NOP_EXPR, type, arg[0]);
1273   gfc_add_modify (&se->pre, var, arg[0]);
1274   se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
1275   se->string_length = integer_one_node;
1276 }
1277
1278
1279 static void
1280 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
1281 {
1282   tree var;
1283   tree len;
1284   tree tmp;
1285   tree cond;
1286   tree fndecl;
1287   tree *args;
1288   unsigned int num_args;
1289
1290   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1291   args = XALLOCAVEC (tree, num_args);
1292
1293   var = gfc_create_var (pchar_type_node, "pstr");
1294   len = gfc_create_var (gfc_get_int_type (8), "len");
1295
1296   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1297   args[0] = gfc_build_addr_expr (NULL_TREE, var);
1298   args[1] = gfc_build_addr_expr (NULL_TREE, len);
1299
1300   fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
1301   tmp = build_call_array_loc (input_location,
1302                           TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
1303                           fndecl, num_args, args);
1304   gfc_add_expr_to_block (&se->pre, tmp);
1305
1306   /* Free the temporary afterwards, if necessary.  */
1307   cond = fold_build2 (GT_EXPR, boolean_type_node,
1308                       len, build_int_cst (TREE_TYPE (len), 0));
1309   tmp = gfc_call_free (var);
1310   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1311   gfc_add_expr_to_block (&se->post, tmp);
1312
1313   se->expr = var;
1314   se->string_length = len;
1315 }
1316
1317
1318 static void
1319 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
1320 {
1321   tree var;
1322   tree len;
1323   tree tmp;
1324   tree cond;
1325   tree fndecl;
1326   tree *args;
1327   unsigned int num_args;
1328
1329   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1330   args = XALLOCAVEC (tree, num_args);
1331
1332   var = gfc_create_var (pchar_type_node, "pstr");
1333   len = gfc_create_var (gfc_charlen_type_node, "len");
1334
1335   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1336   args[0] = gfc_build_addr_expr (NULL_TREE, var);
1337   args[1] = gfc_build_addr_expr (NULL_TREE, len);
1338
1339   fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
1340   tmp = build_call_array_loc (input_location,
1341                           TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
1342                           fndecl, num_args, args);
1343   gfc_add_expr_to_block (&se->pre, tmp);
1344
1345   /* Free the temporary afterwards, if necessary.  */
1346   cond = fold_build2 (GT_EXPR, boolean_type_node,
1347                       len, build_int_cst (TREE_TYPE (len), 0));
1348   tmp = gfc_call_free (var);
1349   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1350   gfc_add_expr_to_block (&se->post, tmp);
1351
1352   se->expr = var;
1353   se->string_length = len;
1354 }
1355
1356
1357 /* Return a character string containing the tty name.  */
1358
1359 static void
1360 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
1361 {
1362   tree var;
1363   tree len;
1364   tree tmp;
1365   tree cond;
1366   tree fndecl;
1367   tree *args;
1368   unsigned int num_args;
1369
1370   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
1371   args = XALLOCAVEC (tree, num_args);
1372
1373   var = gfc_create_var (pchar_type_node, "pstr");
1374   len = gfc_create_var (gfc_charlen_type_node, "len");
1375
1376   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
1377   args[0] = gfc_build_addr_expr (NULL_TREE, var);
1378   args[1] = gfc_build_addr_expr (NULL_TREE, len);
1379
1380   fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
1381   tmp = build_call_array_loc (input_location,
1382                           TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
1383                           fndecl, num_args, args);
1384   gfc_add_expr_to_block (&se->pre, tmp);
1385
1386   /* Free the temporary afterwards, if necessary.  */
1387   cond = fold_build2 (GT_EXPR, boolean_type_node,
1388                       len, build_int_cst (TREE_TYPE (len), 0));
1389   tmp = gfc_call_free (var);
1390   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1391   gfc_add_expr_to_block (&se->post, tmp);
1392
1393   se->expr = var;
1394   se->string_length = len;
1395 }
1396
1397
1398 /* Get the minimum/maximum value of all the parameters.
1399     minmax (a1, a2, a3, ...)
1400     {
1401       mvar = a1;
1402       if (a2 .op. mvar || isnan(mvar))
1403         mvar = a2;
1404       if (a3 .op. mvar || isnan(mvar))
1405         mvar = a3;
1406       ...
1407       return mvar
1408     }
1409  */
1410
1411 /* TODO: Mismatching types can occur when specific names are used.
1412    These should be handled during resolution.  */
1413 static void
1414 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
1415 {
1416   tree tmp;
1417   tree mvar;
1418   tree val;
1419   tree thencase;
1420   tree *args;
1421   tree type;
1422   gfc_actual_arglist *argexpr;
1423   unsigned int i, nargs;
1424
1425   nargs = gfc_intrinsic_argument_list_length (expr);
1426   args = XALLOCAVEC (tree, nargs);
1427
1428   gfc_conv_intrinsic_function_args (se, expr, args, nargs);
1429   type = gfc_typenode_for_spec (&expr->ts);
1430
1431   argexpr = expr->value.function.actual;
1432   if (TREE_TYPE (args[0]) != type)
1433     args[0] = convert (type, args[0]);
1434   /* Only evaluate the argument once.  */
1435   if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
1436     args[0] = gfc_evaluate_now (args[0], &se->pre);
1437
1438   mvar = gfc_create_var (type, "M");
1439   gfc_add_modify (&se->pre, mvar, args[0]);
1440   for (i = 1, argexpr = argexpr->next; i < nargs; i++)
1441     {
1442       tree cond, isnan;
1443
1444       val = args[i]; 
1445
1446       /* Handle absent optional arguments by ignoring the comparison.  */
1447       if (argexpr->expr->expr_type == EXPR_VARIABLE
1448           && argexpr->expr->symtree->n.sym->attr.optional
1449           && TREE_CODE (val) == INDIRECT_REF)
1450         cond = fold_build2_loc (input_location,
1451                                 NE_EXPR, boolean_type_node,
1452                                 TREE_OPERAND (val, 0), 
1453                         build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
1454       else
1455       {
1456         cond = NULL_TREE;
1457
1458         /* Only evaluate the argument once.  */
1459         if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
1460           val = gfc_evaluate_now (val, &se->pre);
1461       }
1462
1463       thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
1464
1465       tmp = fold_build2 (op, boolean_type_node, convert (type, val), mvar);
1466
1467       /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1468          __builtin_isnan might be made dependent on that module being loaded,
1469          to help performance of programs that don't rely on IEEE semantics.  */
1470       if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
1471         {
1472           isnan = build_call_expr_loc (input_location,
1473                                    built_in_decls[BUILT_IN_ISNAN], 1, mvar);
1474           tmp = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, tmp,
1475                              fold_convert (boolean_type_node, isnan));
1476         }
1477       tmp = build3_v (COND_EXPR, tmp, thencase,
1478                       build_empty_stmt (input_location));
1479
1480       if (cond != NULL_TREE)
1481         tmp = build3_v (COND_EXPR, cond, tmp,
1482                         build_empty_stmt (input_location));
1483
1484       gfc_add_expr_to_block (&se->pre, tmp);
1485       argexpr = argexpr->next;
1486     }
1487   se->expr = mvar;
1488 }
1489
1490
1491 /* Generate library calls for MIN and MAX intrinsics for character
1492    variables.  */
1493 static void
1494 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
1495 {
1496   tree *args;
1497   tree var, len, fndecl, tmp, cond, function;
1498   unsigned int nargs;
1499
1500   nargs = gfc_intrinsic_argument_list_length (expr);
1501   args = XALLOCAVEC (tree, nargs + 4);
1502   gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
1503
1504   /* Create the result variables.  */
1505   len = gfc_create_var (gfc_charlen_type_node, "len");
1506   args[0] = gfc_build_addr_expr (NULL_TREE, len);
1507   var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
1508   args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
1509   args[2] = build_int_cst (NULL_TREE, op);
1510   args[3] = build_int_cst (NULL_TREE, nargs / 2);
1511
1512   if (expr->ts.kind == 1)
1513     function = gfor_fndecl_string_minmax;
1514   else if (expr->ts.kind == 4)
1515     function = gfor_fndecl_string_minmax_char4;
1516   else
1517     gcc_unreachable ();
1518
1519   /* Make the function call.  */
1520   fndecl = build_addr (function, current_function_decl);
1521   tmp = build_call_array_loc (input_location,
1522                           TREE_TYPE (TREE_TYPE (function)), fndecl,
1523                           nargs + 4, args);
1524   gfc_add_expr_to_block (&se->pre, tmp);
1525
1526   /* Free the temporary afterwards, if necessary.  */
1527   cond = fold_build2 (GT_EXPR, boolean_type_node,
1528                       len, build_int_cst (TREE_TYPE (len), 0));
1529   tmp = gfc_call_free (var);
1530   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
1531   gfc_add_expr_to_block (&se->post, tmp);
1532
1533   se->expr = var;
1534   se->string_length = len;
1535 }
1536
1537
1538 /* Create a symbol node for this intrinsic.  The symbol from the frontend
1539    has the generic name.  */
1540
1541 static gfc_symbol *
1542 gfc_get_symbol_for_expr (gfc_expr * expr)
1543 {
1544   gfc_symbol *sym;
1545
1546   /* TODO: Add symbols for intrinsic function to the global namespace.  */
1547   gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
1548   sym = gfc_new_symbol (expr->value.function.name, NULL);
1549
1550   sym->ts = expr->ts;
1551   sym->attr.external = 1;
1552   sym->attr.function = 1;
1553   sym->attr.always_explicit = 1;
1554   sym->attr.proc = PROC_INTRINSIC;
1555   sym->attr.flavor = FL_PROCEDURE;
1556   sym->result = sym;
1557   if (expr->rank > 0)
1558     {
1559       sym->attr.dimension = 1;
1560       sym->as = gfc_get_array_spec ();
1561       sym->as->type = AS_ASSUMED_SHAPE;
1562       sym->as->rank = expr->rank;
1563     }
1564
1565   /* TODO: proper argument lists for external intrinsics.  */
1566   return sym;
1567 }
1568
1569 /* Generate a call to an external intrinsic function.  */
1570 static void
1571 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
1572 {
1573   gfc_symbol *sym;
1574   VEC(tree,gc) *append_args;
1575
1576   gcc_assert (!se->ss || se->ss->expr == expr);
1577
1578   if (se->ss)
1579     gcc_assert (expr->rank > 0);
1580   else
1581     gcc_assert (expr->rank == 0);
1582
1583   sym = gfc_get_symbol_for_expr (expr);
1584
1585   /* Calls to libgfortran_matmul need to be appended special arguments,
1586      to be able to call the BLAS ?gemm functions if required and possible.  */
1587   append_args = NULL;
1588   if (expr->value.function.isym->id == GFC_ISYM_MATMUL
1589       && sym->ts.type != BT_LOGICAL)
1590     {
1591       tree cint = gfc_get_int_type (gfc_c_int_kind);
1592
1593       if (gfc_option.flag_external_blas
1594           && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
1595           && (sym->ts.kind == gfc_default_real_kind
1596               || sym->ts.kind == gfc_default_double_kind))
1597         {
1598           tree gemm_fndecl;
1599
1600           if (sym->ts.type == BT_REAL)
1601             {
1602               if (sym->ts.kind == gfc_default_real_kind)
1603                 gemm_fndecl = gfor_fndecl_sgemm;
1604               else
1605                 gemm_fndecl = gfor_fndecl_dgemm;
1606             }
1607           else
1608             {
1609               if (sym->ts.kind == gfc_default_real_kind)
1610                 gemm_fndecl = gfor_fndecl_cgemm;
1611               else
1612                 gemm_fndecl = gfor_fndecl_zgemm;
1613             }
1614
1615           append_args = VEC_alloc (tree, gc, 3);
1616           VEC_quick_push (tree, append_args, build_int_cst (cint, 1));
1617           VEC_quick_push (tree, append_args,
1618                           build_int_cst (cint, gfc_option.blas_matmul_limit));
1619           VEC_quick_push (tree, append_args,
1620                           gfc_build_addr_expr (NULL_TREE, gemm_fndecl));
1621         }
1622       else
1623         {
1624           append_args = VEC_alloc (tree, gc, 3);
1625           VEC_quick_push (tree, append_args, build_int_cst (cint, 0));
1626           VEC_quick_push (tree, append_args, build_int_cst (cint, 0));
1627           VEC_quick_push (tree, append_args, null_pointer_node);
1628         }
1629     }
1630
1631   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
1632                           append_args);
1633   gfc_free (sym);
1634 }
1635
1636 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1637    Implemented as
1638     any(a)
1639     {
1640       forall (i=...)
1641         if (a[i] != 0)
1642           return 1
1643       end forall
1644       return 0
1645     }
1646     all(a)
1647     {
1648       forall (i=...)
1649         if (a[i] == 0)
1650           return 0
1651       end forall
1652       return 1
1653     }
1654  */
1655 static void
1656 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
1657 {
1658   tree resvar;
1659   stmtblock_t block;
1660   stmtblock_t body;
1661   tree type;
1662   tree tmp;
1663   tree found;
1664   gfc_loopinfo loop;
1665   gfc_actual_arglist *actual;
1666   gfc_ss *arrayss;
1667   gfc_se arrayse;
1668   tree exit_label;
1669
1670   if (se->ss)
1671     {
1672       gfc_conv_intrinsic_funcall (se, expr);
1673       return;
1674     }
1675
1676   actual = expr->value.function.actual;
1677   type = gfc_typenode_for_spec (&expr->ts);
1678   /* Initialize the result.  */
1679   resvar = gfc_create_var (type, "test");
1680   if (op == EQ_EXPR)
1681     tmp = convert (type, boolean_true_node);
1682   else
1683     tmp = convert (type, boolean_false_node);
1684   gfc_add_modify (&se->pre, resvar, tmp);
1685
1686   /* Walk the arguments.  */
1687   arrayss = gfc_walk_expr (actual->expr);
1688   gcc_assert (arrayss != gfc_ss_terminator);
1689
1690   /* Initialize the scalarizer.  */
1691   gfc_init_loopinfo (&loop);
1692   exit_label = gfc_build_label_decl (NULL_TREE);
1693   TREE_USED (exit_label) = 1;
1694   gfc_add_ss_to_loop (&loop, arrayss);
1695
1696   /* Initialize the loop.  */
1697   gfc_conv_ss_startstride (&loop);
1698   gfc_conv_loop_setup (&loop, &expr->where);
1699
1700   gfc_mark_ss_chain_used (arrayss, 1);
1701   /* Generate the loop body.  */
1702   gfc_start_scalarized_body (&loop, &body);
1703
1704   /* If the condition matches then set the return value.  */
1705   gfc_start_block (&block);
1706   if (op == EQ_EXPR)
1707     tmp = convert (type, boolean_false_node);
1708   else
1709     tmp = convert (type, boolean_true_node);
1710   gfc_add_modify (&block, resvar, tmp);
1711
1712   /* And break out of the loop.  */
1713   tmp = build1_v (GOTO_EXPR, exit_label);
1714   gfc_add_expr_to_block (&block, tmp);
1715
1716   found = gfc_finish_block (&block);
1717
1718   /* Check this element.  */
1719   gfc_init_se (&arrayse, NULL);
1720   gfc_copy_loopinfo_to_se (&arrayse, &loop);
1721   arrayse.ss = arrayss;
1722   gfc_conv_expr_val (&arrayse, actual->expr);
1723
1724   gfc_add_block_to_block (&body, &arrayse.pre);
1725   tmp = fold_build2 (op, boolean_type_node, arrayse.expr,
1726                      build_int_cst (TREE_TYPE (arrayse.expr), 0));
1727   tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
1728   gfc_add_expr_to_block (&body, tmp);
1729   gfc_add_block_to_block (&body, &arrayse.post);
1730
1731   gfc_trans_scalarizing_loops (&loop, &body);
1732
1733   /* Add the exit label.  */
1734   tmp = build1_v (LABEL_EXPR, exit_label);
1735   gfc_add_expr_to_block (&loop.pre, tmp);
1736
1737   gfc_add_block_to_block (&se->pre, &loop.pre);
1738   gfc_add_block_to_block (&se->pre, &loop.post);
1739   gfc_cleanup_loop (&loop);
1740
1741   se->expr = resvar;
1742 }
1743
1744 /* COUNT(A) = Number of true elements in A.  */
1745 static void
1746 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
1747 {
1748   tree resvar;
1749   tree type;
1750   stmtblock_t body;
1751   tree tmp;
1752   gfc_loopinfo loop;
1753   gfc_actual_arglist *actual;
1754   gfc_ss *arrayss;
1755   gfc_se arrayse;
1756
1757   if (se->ss)
1758     {
1759       gfc_conv_intrinsic_funcall (se, expr);
1760       return;
1761     }
1762
1763   actual = expr->value.function.actual;
1764
1765   type = gfc_typenode_for_spec (&expr->ts);
1766   /* Initialize the result.  */
1767   resvar = gfc_create_var (type, "count");
1768   gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
1769
1770   /* Walk the arguments.  */
1771   arrayss = gfc_walk_expr (actual->expr);
1772   gcc_assert (arrayss != gfc_ss_terminator);
1773
1774   /* Initialize the scalarizer.  */
1775   gfc_init_loopinfo (&loop);
1776   gfc_add_ss_to_loop (&loop, arrayss);
1777
1778   /* Initialize the loop.  */
1779   gfc_conv_ss_startstride (&loop);
1780   gfc_conv_loop_setup (&loop, &expr->where);
1781
1782   gfc_mark_ss_chain_used (arrayss, 1);
1783   /* Generate the loop body.  */
1784   gfc_start_scalarized_body (&loop, &body);
1785
1786   tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (resvar),
1787                      resvar, build_int_cst (TREE_TYPE (resvar), 1));
1788   tmp = build2_v (MODIFY_EXPR, resvar, tmp);
1789
1790   gfc_init_se (&arrayse, NULL);
1791   gfc_copy_loopinfo_to_se (&arrayse, &loop);
1792   arrayse.ss = arrayss;
1793   gfc_conv_expr_val (&arrayse, actual->expr);
1794   tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
1795                   build_empty_stmt (input_location));
1796
1797   gfc_add_block_to_block (&body, &arrayse.pre);
1798   gfc_add_expr_to_block (&body, tmp);
1799   gfc_add_block_to_block (&body, &arrayse.post);
1800
1801   gfc_trans_scalarizing_loops (&loop, &body);
1802
1803   gfc_add_block_to_block (&se->pre, &loop.pre);
1804   gfc_add_block_to_block (&se->pre, &loop.post);
1805   gfc_cleanup_loop (&loop);
1806
1807   se->expr = resvar;
1808 }
1809
1810 /* Inline implementation of the sum and product intrinsics.  */
1811 static void
1812 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op)
1813 {
1814   tree resvar;
1815   tree type;
1816   stmtblock_t body;
1817   stmtblock_t block;
1818   tree tmp;
1819   gfc_loopinfo loop;
1820   gfc_actual_arglist *actual;
1821   gfc_ss *arrayss;
1822   gfc_ss *maskss;
1823   gfc_se arrayse;
1824   gfc_se maskse;
1825   gfc_expr *arrayexpr;
1826   gfc_expr *maskexpr;
1827
1828   if (se->ss)
1829     {
1830       gfc_conv_intrinsic_funcall (se, expr);
1831       return;
1832     }
1833
1834   type = gfc_typenode_for_spec (&expr->ts);
1835   /* Initialize the result.  */
1836   resvar = gfc_create_var (type, "val");
1837   if (op == PLUS_EXPR)
1838     tmp = gfc_build_const (type, integer_zero_node);
1839   else
1840     tmp = gfc_build_const (type, integer_one_node);
1841
1842   gfc_add_modify (&se->pre, resvar, tmp);
1843
1844   /* Walk the arguments.  */
1845   actual = expr->value.function.actual;
1846   arrayexpr = actual->expr;
1847   arrayss = gfc_walk_expr (arrayexpr);
1848   gcc_assert (arrayss != gfc_ss_terminator);
1849
1850   actual = actual->next->next;
1851   gcc_assert (actual);
1852   maskexpr = actual->expr;
1853   if (maskexpr && maskexpr->rank != 0)
1854     {
1855       maskss = gfc_walk_expr (maskexpr);
1856       gcc_assert (maskss != gfc_ss_terminator);
1857     }
1858   else
1859     maskss = NULL;
1860
1861   /* Initialize the scalarizer.  */
1862   gfc_init_loopinfo (&loop);
1863   gfc_add_ss_to_loop (&loop, arrayss);
1864   if (maskss)
1865     gfc_add_ss_to_loop (&loop, maskss);
1866
1867   /* Initialize the loop.  */
1868   gfc_conv_ss_startstride (&loop);
1869   gfc_conv_loop_setup (&loop, &expr->where);
1870
1871   gfc_mark_ss_chain_used (arrayss, 1);
1872   if (maskss)
1873     gfc_mark_ss_chain_used (maskss, 1);
1874   /* Generate the loop body.  */
1875   gfc_start_scalarized_body (&loop, &body);
1876
1877   /* If we have a mask, only add this element if the mask is set.  */
1878   if (maskss)
1879     {
1880       gfc_init_se (&maskse, NULL);
1881       gfc_copy_loopinfo_to_se (&maskse, &loop);
1882       maskse.ss = maskss;
1883       gfc_conv_expr_val (&maskse, maskexpr);
1884       gfc_add_block_to_block (&body, &maskse.pre);
1885
1886       gfc_start_block (&block);
1887     }
1888   else
1889     gfc_init_block (&block);
1890
1891   /* Do the actual summation/product.  */
1892   gfc_init_se (&arrayse, NULL);
1893   gfc_copy_loopinfo_to_se (&arrayse, &loop);
1894   arrayse.ss = arrayss;
1895   gfc_conv_expr_val (&arrayse, arrayexpr);
1896   gfc_add_block_to_block (&block, &arrayse.pre);
1897
1898   tmp = fold_build2 (op, type, resvar, arrayse.expr);
1899   gfc_add_modify (&block, resvar, tmp);
1900   gfc_add_block_to_block (&block, &arrayse.post);
1901
1902   if (maskss)
1903     {
1904       /* We enclose the above in if (mask) {...} .  */
1905       tmp = gfc_finish_block (&block);
1906
1907       tmp = build3_v (COND_EXPR, maskse.expr, tmp,
1908                       build_empty_stmt (input_location));
1909     }
1910   else
1911     tmp = gfc_finish_block (&block);
1912   gfc_add_expr_to_block (&body, tmp);
1913
1914   gfc_trans_scalarizing_loops (&loop, &body);
1915
1916   /* For a scalar mask, enclose the loop in an if statement.  */
1917   if (maskexpr && maskss == NULL)
1918     {
1919       gfc_init_se (&maskse, NULL);
1920       gfc_conv_expr_val (&maskse, maskexpr);
1921       gfc_init_block (&block);
1922       gfc_add_block_to_block (&block, &loop.pre);
1923       gfc_add_block_to_block (&block, &loop.post);
1924       tmp = gfc_finish_block (&block);
1925
1926       tmp = build3_v (COND_EXPR, maskse.expr, tmp,
1927                       build_empty_stmt (input_location));
1928       gfc_add_expr_to_block (&block, tmp);
1929       gfc_add_block_to_block (&se->pre, &block);
1930     }
1931   else
1932     {
1933       gfc_add_block_to_block (&se->pre, &loop.pre);
1934       gfc_add_block_to_block (&se->pre, &loop.post);
1935     }
1936
1937   gfc_cleanup_loop (&loop);
1938
1939   se->expr = resvar;
1940 }
1941
1942
1943 /* Inline implementation of the dot_product intrinsic. This function
1944    is based on gfc_conv_intrinsic_arith (the previous function).  */
1945 static void
1946 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
1947 {
1948   tree resvar;
1949   tree type;
1950   stmtblock_t body;
1951   stmtblock_t block;
1952   tree tmp;
1953   gfc_loopinfo loop;
1954   gfc_actual_arglist *actual;
1955   gfc_ss *arrayss1, *arrayss2;
1956   gfc_se arrayse1, arrayse2;
1957   gfc_expr *arrayexpr1, *arrayexpr2;
1958
1959   type = gfc_typenode_for_spec (&expr->ts);
1960
1961   /* Initialize the result.  */
1962   resvar = gfc_create_var (type, "val");
1963   if (expr->ts.type == BT_LOGICAL)
1964     tmp = build_int_cst (type, 0);
1965   else
1966     tmp = gfc_build_const (type, integer_zero_node);
1967
1968   gfc_add_modify (&se->pre, resvar, tmp);
1969
1970   /* Walk argument #1.  */
1971   actual = expr->value.function.actual;
1972   arrayexpr1 = actual->expr;
1973   arrayss1 = gfc_walk_expr (arrayexpr1);
1974   gcc_assert (arrayss1 != gfc_ss_terminator);
1975
1976   /* Walk argument #2.  */
1977   actual = actual->next;
1978   arrayexpr2 = actual->expr;
1979   arrayss2 = gfc_walk_expr (arrayexpr2);
1980   gcc_assert (arrayss2 != gfc_ss_terminator);
1981
1982   /* Initialize the scalarizer.  */
1983   gfc_init_loopinfo (&loop);
1984   gfc_add_ss_to_loop (&loop, arrayss1);
1985   gfc_add_ss_to_loop (&loop, arrayss2);
1986
1987   /* Initialize the loop.  */
1988   gfc_conv_ss_startstride (&loop);
1989   gfc_conv_loop_setup (&loop, &expr->where);
1990
1991   gfc_mark_ss_chain_used (arrayss1, 1);
1992   gfc_mark_ss_chain_used (arrayss2, 1);
1993
1994   /* Generate the loop body.  */
1995   gfc_start_scalarized_body (&loop, &body);
1996   gfc_init_block (&block);
1997
1998   /* Make the tree expression for [conjg(]array1[)].  */
1999   gfc_init_se (&arrayse1, NULL);
2000   gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2001   arrayse1.ss = arrayss1;
2002   gfc_conv_expr_val (&arrayse1, arrayexpr1);
2003   if (expr->ts.type == BT_COMPLEX)
2004     arrayse1.expr = fold_build1 (CONJ_EXPR, type, arrayse1.expr);
2005   gfc_add_block_to_block (&block, &arrayse1.pre);
2006
2007   /* Make the tree expression for array2.  */
2008   gfc_init_se (&arrayse2, NULL);
2009   gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2010   arrayse2.ss = arrayss2;
2011   gfc_conv_expr_val (&arrayse2, arrayexpr2);
2012   gfc_add_block_to_block (&block, &arrayse2.pre);
2013
2014   /* Do the actual product and sum.  */
2015   if (expr->ts.type == BT_LOGICAL)
2016     {
2017       tmp = fold_build2 (TRUTH_AND_EXPR, type, arrayse1.expr, arrayse2.expr);
2018       tmp = fold_build2 (TRUTH_OR_EXPR, type, resvar, tmp);
2019     }
2020   else
2021     {
2022       tmp = fold_build2 (MULT_EXPR, type, arrayse1.expr, arrayse2.expr);
2023       tmp = fold_build2 (PLUS_EXPR, type, resvar, tmp);
2024     }
2025   gfc_add_modify (&block, resvar, tmp);
2026
2027   /* Finish up the loop block and the loop.  */
2028   tmp = gfc_finish_block (&block);
2029   gfc_add_expr_to_block (&body, tmp);
2030
2031   gfc_trans_scalarizing_loops (&loop, &body);
2032   gfc_add_block_to_block (&se->pre, &loop.pre);
2033   gfc_add_block_to_block (&se->pre, &loop.post);
2034   gfc_cleanup_loop (&loop);
2035
2036   se->expr = resvar;
2037 }
2038
2039
2040 /* Emit code for minloc or maxloc intrinsic.  There are many different cases
2041    we need to handle.  For performance reasons we sometimes create two
2042    loops instead of one, where the second one is much simpler.
2043    Examples for minloc intrinsic:
2044    1) Result is an array, a call is generated
2045    2) Array mask is used and NaNs need to be supported:
2046       limit = Infinity;
2047       pos = 0;
2048       S = from;
2049       while (S <= to) {
2050         if (mask[S]) {
2051           if (pos == 0) pos = S + (1 - from);
2052           if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2053         }
2054         S++;
2055       }
2056       goto lab2;
2057       lab1:;
2058       while (S <= to) {
2059         if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2060         S++;
2061       }
2062       lab2:;
2063    3) NaNs need to be supported, but it is known at compile time or cheaply
2064       at runtime whether array is nonempty or not:
2065       limit = Infinity;
2066       pos = 0;
2067       S = from;
2068       while (S <= to) {
2069         if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2070         S++;
2071       }
2072       if (from <= to) pos = 1;
2073       goto lab2;
2074       lab1:;
2075       while (S <= to) {
2076         if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2077         S++;
2078       }
2079       lab2:;
2080    4) NaNs aren't supported, array mask is used:
2081       limit = infinities_supported ? Infinity : huge (limit);
2082       pos = 0;
2083       S = from;
2084       while (S <= to) {
2085         if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2086         S++;
2087       }
2088       goto lab2;
2089       lab1:;
2090       while (S <= to) {
2091         if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2092         S++;
2093       }
2094       lab2:;
2095    5) Same without array mask:
2096       limit = infinities_supported ? Infinity : huge (limit);
2097       pos = (from <= to) ? 1 : 0;
2098       S = from;
2099       while (S <= to) {
2100         if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2101         S++;
2102       }
2103    For 3) and 5), if mask is scalar, this all goes into a conditional,
2104    setting pos = 0; in the else branch.  */
2105
2106 static void
2107 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
2108 {
2109   stmtblock_t body;
2110   stmtblock_t block;
2111   stmtblock_t ifblock;
2112   stmtblock_t elseblock;
2113   tree limit;
2114   tree type;
2115   tree tmp;
2116   tree cond;
2117   tree elsetmp;
2118   tree ifbody;
2119   tree offset;
2120   tree nonempty;
2121   tree lab1, lab2;
2122   gfc_loopinfo loop;
2123   gfc_actual_arglist *actual;
2124   gfc_ss *arrayss;
2125   gfc_ss *maskss;
2126   gfc_se arrayse;
2127   gfc_se maskse;
2128   gfc_expr *arrayexpr;
2129   gfc_expr *maskexpr;
2130   tree pos;
2131   int n;
2132
2133   if (se->ss)
2134     {
2135       gfc_conv_intrinsic_funcall (se, expr);
2136       return;
2137     }
2138
2139   /* Initialize the result.  */
2140   pos = gfc_create_var (gfc_array_index_type, "pos");
2141   offset = gfc_create_var (gfc_array_index_type, "offset");
2142   type = gfc_typenode_for_spec (&expr->ts);
2143
2144   /* Walk the arguments.  */
2145   actual = expr->value.function.actual;
2146   arrayexpr = actual->expr;
2147   arrayss = gfc_walk_expr (arrayexpr);
2148   gcc_assert (arrayss != gfc_ss_terminator);
2149
2150   actual = actual->next->next;
2151   gcc_assert (actual);
2152   maskexpr = actual->expr;
2153   nonempty = NULL;
2154   if (maskexpr && maskexpr->rank != 0)
2155     {
2156       maskss = gfc_walk_expr (maskexpr);
2157       gcc_assert (maskss != gfc_ss_terminator);
2158     }
2159   else
2160     {
2161       mpz_t asize;
2162       if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2163         {
2164           nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2165           mpz_clear (asize);
2166           nonempty = fold_build2 (GT_EXPR, boolean_type_node, nonempty,
2167                                   gfc_index_zero_node);
2168         }
2169       maskss = NULL;
2170     }
2171
2172   limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
2173   n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
2174   switch (arrayexpr->ts.type)
2175     {
2176     case BT_REAL:
2177       if (HONOR_INFINITIES (DECL_MODE (limit)))
2178         {
2179           REAL_VALUE_TYPE real;
2180           real_inf (&real);
2181           tmp = build_real (TREE_TYPE (limit), real);
2182         }
2183       else
2184         tmp = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2185                                      arrayexpr->ts.kind, 0);
2186       break;
2187
2188     case BT_INTEGER:
2189       tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
2190                                   arrayexpr->ts.kind);
2191       break;
2192
2193     default:
2194       gcc_unreachable ();
2195     }
2196
2197   /* We start with the most negative possible value for MAXLOC, and the most
2198      positive possible value for MINLOC. The most negative possible value is
2199      -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2200      possible value is HUGE in both cases.  */
2201   if (op == GT_EXPR)
2202     tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2203   if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2204     tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp), tmp,
2205                        build_int_cst (type, 1));
2206
2207   gfc_add_modify (&se->pre, limit, tmp);
2208
2209   /* Initialize the scalarizer.  */
2210   gfc_init_loopinfo (&loop);
2211   gfc_add_ss_to_loop (&loop, arrayss);
2212   if (maskss)
2213     gfc_add_ss_to_loop (&loop, maskss);
2214
2215   /* Initialize the loop.  */
2216   gfc_conv_ss_startstride (&loop);
2217   gfc_conv_loop_setup (&loop, &expr->where);
2218
2219   gcc_assert (loop.dimen == 1);
2220   if (nonempty == NULL && maskss == NULL && loop.from[0] && loop.to[0])
2221     nonempty = fold_build2 (LE_EXPR, boolean_type_node, loop.from[0],
2222                             loop.to[0]);
2223
2224   lab1 = NULL;
2225   lab2 = NULL;
2226   /* Initialize the position to zero, following Fortran 2003.  We are free
2227      to do this because Fortran 95 allows the result of an entirely false
2228      mask to be processor dependent.  If we know at compile time the array
2229      is non-empty and no MASK is used, we can initialize to 1 to simplify
2230      the inner loop.  */
2231   if (nonempty != NULL && !HONOR_NANS (DECL_MODE (limit)))
2232     gfc_add_modify (&loop.pre, pos,
2233                     fold_build3 (COND_EXPR, gfc_array_index_type,
2234                                  nonempty, gfc_index_one_node,
2235                                  gfc_index_zero_node));
2236   else
2237     {
2238       gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
2239       lab1 = gfc_build_label_decl (NULL_TREE);
2240       TREE_USED (lab1) = 1;
2241       lab2 = gfc_build_label_decl (NULL_TREE);
2242       TREE_USED (lab2) = 1;
2243     }
2244
2245   gfc_mark_ss_chain_used (arrayss, 1);
2246   if (maskss)
2247     gfc_mark_ss_chain_used (maskss, 1);
2248   /* Generate the loop body.  */
2249   gfc_start_scalarized_body (&loop, &body);
2250
2251   /* If we have a mask, only check this element if the mask is set.  */
2252   if (maskss)
2253     {
2254       gfc_init_se (&maskse, NULL);
2255       gfc_copy_loopinfo_to_se (&maskse, &loop);
2256       maskse.ss = maskss;
2257       gfc_conv_expr_val (&maskse, maskexpr);
2258       gfc_add_block_to_block (&body, &maskse.pre);
2259
2260       gfc_start_block (&block);
2261     }
2262   else
2263     gfc_init_block (&block);
2264
2265   /* Compare with the current limit.  */
2266   gfc_init_se (&arrayse, NULL);
2267   gfc_copy_loopinfo_to_se (&arrayse, &loop);
2268   arrayse.ss = arrayss;
2269   gfc_conv_expr_val (&arrayse, arrayexpr);
2270   gfc_add_block_to_block (&block, &arrayse.pre);
2271
2272   /* We do the following if this is a more extreme value.  */
2273   gfc_start_block (&ifblock);
2274
2275   /* Assign the value to the limit...  */
2276   gfc_add_modify (&ifblock, limit, arrayse.expr);
2277
2278   /* Remember where we are.  An offset must be added to the loop
2279      counter to obtain the required position.  */
2280   if (loop.from[0])
2281     tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2282                        gfc_index_one_node, loop.from[0]);
2283   else
2284     tmp = gfc_index_one_node;
2285
2286   gfc_add_modify (&block, offset, tmp);
2287
2288   if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
2289     {
2290       stmtblock_t ifblock2;
2291       tree ifbody2;
2292
2293       gfc_start_block (&ifblock2);
2294       tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2295                          loop.loopvar[0], offset);
2296       gfc_add_modify (&ifblock2, pos, tmp);
2297       ifbody2 = gfc_finish_block (&ifblock2);
2298       cond = fold_build2 (EQ_EXPR, boolean_type_node, pos,
2299                           gfc_index_zero_node);
2300       tmp = build3_v (COND_EXPR, cond, ifbody2,
2301                       build_empty_stmt (input_location));
2302       gfc_add_expr_to_block (&block, tmp);
2303     }
2304
2305   tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2306                      loop.loopvar[0], offset);
2307   gfc_add_modify (&ifblock, pos, tmp);
2308
2309   if (lab1)
2310     gfc_add_expr_to_block (&ifblock, build1_v (GOTO_EXPR, lab1));
2311
2312   ifbody = gfc_finish_block (&ifblock);
2313
2314   if (!lab1 || HONOR_NANS (DECL_MODE (limit)))
2315     {
2316       if (lab1)
2317         cond = fold_build2 (op == GT_EXPR ? GE_EXPR : LE_EXPR,
2318                             boolean_type_node, arrayse.expr, limit);
2319       else
2320         cond = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2321
2322       ifbody = build3_v (COND_EXPR, cond, ifbody,
2323                          build_empty_stmt (input_location));
2324     }
2325   gfc_add_expr_to_block (&block, ifbody);
2326
2327   if (maskss)
2328     {
2329       /* We enclose the above in if (mask) {...}.  */
2330       tmp = gfc_finish_block (&block);
2331
2332       tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2333                       build_empty_stmt (input_location));
2334     }
2335   else
2336     tmp = gfc_finish_block (&block);
2337   gfc_add_expr_to_block (&body, tmp);
2338
2339   if (lab1)
2340     {
2341       gfc_trans_scalarized_loop_end (&loop, 0, &body);
2342
2343       if (HONOR_NANS (DECL_MODE (limit)))
2344         {
2345           if (nonempty != NULL)
2346             {
2347               ifbody = build2_v (MODIFY_EXPR, pos, gfc_index_one_node);
2348               tmp = build3_v (COND_EXPR, nonempty, ifbody,
2349                               build_empty_stmt (input_location));
2350               gfc_add_expr_to_block (&loop.code[0], tmp);
2351             }
2352         }
2353
2354       gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
2355       gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
2356       gfc_start_block (&body);
2357
2358       /* If we have a mask, only check this element if the mask is set.  */
2359       if (maskss)
2360         {
2361           gfc_init_se (&maskse, NULL);
2362           gfc_copy_loopinfo_to_se (&maskse, &loop);
2363           maskse.ss = maskss;
2364           gfc_conv_expr_val (&maskse, maskexpr);
2365           gfc_add_block_to_block (&body, &maskse.pre);
2366
2367           gfc_start_block (&block);
2368         }
2369       else
2370         gfc_init_block (&block);
2371
2372       /* Compare with the current limit.  */
2373       gfc_init_se (&arrayse, NULL);
2374       gfc_copy_loopinfo_to_se (&arrayse, &loop);
2375       arrayse.ss = arrayss;
2376       gfc_conv_expr_val (&arrayse, arrayexpr);
2377       gfc_add_block_to_block (&block, &arrayse.pre);
2378
2379       /* We do the following if this is a more extreme value.  */
2380       gfc_start_block (&ifblock);
2381
2382       /* Assign the value to the limit...  */
2383       gfc_add_modify (&ifblock, limit, arrayse.expr);
2384
2385       /* Remember where we are.  An offset must be added to the loop
2386          counter to obtain the required position.  */
2387       if (loop.from[0])
2388         tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
2389                            gfc_index_one_node, loop.from[0]);
2390       else
2391         tmp = gfc_index_one_node;
2392
2393       gfc_add_modify (&block, offset, tmp);
2394
2395       tmp = fold_build2 (PLUS_EXPR, TREE_TYPE (pos),
2396                          loop.loopvar[0], offset);
2397       gfc_add_modify (&ifblock, pos, tmp);
2398
2399       ifbody = gfc_finish_block (&ifblock);
2400
2401       cond = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2402
2403       tmp = build3_v (COND_EXPR, cond, ifbody,
2404                       build_empty_stmt (input_location));
2405       gfc_add_expr_to_block (&block, tmp);
2406
2407       if (maskss)
2408         {
2409           /* We enclose the above in if (mask) {...}.  */
2410           tmp = gfc_finish_block (&block);
2411
2412           tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2413                           build_empty_stmt (input_location));
2414         }
2415       else
2416         tmp = gfc_finish_block (&block);
2417       gfc_add_expr_to_block (&body, tmp);
2418       /* Avoid initializing loopvar[0] again, it should be left where
2419          it finished by the first loop.  */
2420       loop.from[0] = loop.loopvar[0];
2421     }
2422
2423   gfc_trans_scalarizing_loops (&loop, &body);
2424
2425   if (lab2)
2426     gfc_add_expr_to_block (&loop.pre, build1_v (LABEL_EXPR, lab2));
2427
2428   /* For a scalar mask, enclose the loop in an if statement.  */
2429   if (maskexpr && maskss == NULL)
2430     {
2431       gfc_init_se (&maskse, NULL);
2432       gfc_conv_expr_val (&maskse, maskexpr);
2433       gfc_init_block (&block);
2434       gfc_add_block_to_block (&block, &loop.pre);
2435       gfc_add_block_to_block (&block, &loop.post);
2436       tmp = gfc_finish_block (&block);
2437
2438       /* For the else part of the scalar mask, just initialize
2439          the pos variable the same way as above.  */
2440
2441       gfc_init_block (&elseblock);
2442       gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
2443       elsetmp = gfc_finish_block (&elseblock);
2444
2445       tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
2446       gfc_add_expr_to_block (&block, tmp);
2447       gfc_add_block_to_block (&se->pre, &block);
2448     }
2449   else
2450     {
2451       gfc_add_block_to_block (&se->pre, &loop.pre);
2452       gfc_add_block_to_block (&se->pre, &loop.post);
2453     }
2454   gfc_cleanup_loop (&loop);
2455
2456   se->expr = convert (type, pos);
2457 }
2458
2459 /* Emit code for minval or maxval intrinsic.  There are many different cases
2460    we need to handle.  For performance reasons we sometimes create two
2461    loops instead of one, where the second one is much simpler.
2462    Examples for minval intrinsic:
2463    1) Result is an array, a call is generated
2464    2) Array mask is used and NaNs need to be supported, rank 1:
2465       limit = Infinity;
2466       nonempty = false;
2467       S = from;
2468       while (S <= to) {
2469         if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
2470         S++;
2471       }
2472       limit = nonempty ? NaN : huge (limit);
2473       lab:
2474       while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
2475    3) NaNs need to be supported, but it is known at compile time or cheaply
2476       at runtime whether array is nonempty or not, rank 1:
2477       limit = Infinity;
2478       S = from;
2479       while (S <= to) { if (a[S] <= limit) goto lab; S++; }
2480       limit = (from <= to) ? NaN : huge (limit);
2481       lab:
2482       while (S <= to) { limit = min (a[S], limit); S++; }
2483    4) Array mask is used and NaNs need to be supported, rank > 1:
2484       limit = Infinity;
2485       nonempty = false;
2486       fast = false;
2487       S1 = from1;
2488       while (S1 <= to1) {
2489         S2 = from2;
2490         while (S2 <= to2) {
2491           if (mask[S1][S2]) {
2492             if (fast) limit = min (a[S1][S2], limit);
2493             else {
2494               nonempty = true;
2495               if (a[S1][S2] <= limit) {
2496                 limit = a[S1][S2];
2497                 fast = true;
2498               }
2499             }
2500           }
2501           S2++;
2502         }
2503         S1++;
2504       }
2505       if (!fast)
2506         limit = nonempty ? NaN : huge (limit);
2507    5) NaNs need to be supported, but it is known at compile time or cheaply
2508       at runtime whether array is nonempty or not, rank > 1:
2509       limit = Infinity;
2510       fast = false;
2511       S1 = from1;
2512       while (S1 <= to1) {
2513         S2 = from2;
2514         while (S2 <= to2) {
2515           if (fast) limit = min (a[S1][S2], limit);
2516           else {
2517             if (a[S1][S2] <= limit) {
2518               limit = a[S1][S2];
2519               fast = true;
2520             }
2521           }
2522           S2++;
2523         }
2524         S1++;
2525       }
2526       if (!fast)
2527         limit = (nonempty_array) ? NaN : huge (limit);
2528    6) NaNs aren't supported, but infinities are.  Array mask is used:
2529       limit = Infinity;
2530       nonempty = false;
2531       S = from;
2532       while (S <= to) {
2533         if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
2534         S++;
2535       }
2536       limit = nonempty ? limit : huge (limit);
2537    7) Same without array mask:
2538       limit = Infinity;
2539       S = from;
2540       while (S <= to) { limit = min (a[S], limit); S++; }
2541       limit = (from <= to) ? limit : huge (limit);
2542    8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
2543       limit = huge (limit);
2544       S = from;
2545       while (S <= to) { limit = min (a[S], limit); S++); }
2546       (or
2547       while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
2548       with array mask instead).
2549    For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
2550    setting limit = huge (limit); in the else branch.  */
2551
2552 static void
2553 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
2554 {
2555   tree limit;
2556   tree type;
2557   tree tmp;
2558   tree ifbody;
2559   tree nonempty;
2560   tree nonempty_var;
2561   tree lab;
2562   tree fast;
2563   tree huge_cst = NULL, nan_cst = NULL;
2564   stmtblock_t body;
2565   stmtblock_t block, block2;
2566   gfc_loopinfo loop;
2567   gfc_actual_arglist *actual;
2568   gfc_ss *arrayss;
2569   gfc_ss *maskss;
2570   gfc_se arrayse;
2571   gfc_se maskse;
2572   gfc_expr *arrayexpr;
2573   gfc_expr *maskexpr;
2574   int n;
2575
2576   if (se->ss)
2577     {
2578       gfc_conv_intrinsic_funcall (se, expr);
2579       return;
2580     }
2581
2582   type = gfc_typenode_for_spec (&expr->ts);
2583   /* Initialize the result.  */
2584   limit = gfc_create_var (type, "limit");
2585   n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
2586   switch (expr->ts.type)
2587     {
2588     case BT_REAL:
2589       huge_cst = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
2590                                         expr->ts.kind, 0);
2591       if (HONOR_INFINITIES (DECL_MODE (limit)))
2592         {
2593           REAL_VALUE_TYPE real;
2594           real_inf (&real);
2595           tmp = build_real (type, real);
2596         }
2597       else
2598         tmp = huge_cst;
2599       if (HONOR_NANS (DECL_MODE (limit)))
2600         {
2601           REAL_VALUE_TYPE real;
2602           real_nan (&real, "", 1, DECL_MODE (limit));
2603           nan_cst = build_real (type, real);
2604         }
2605       break;
2606
2607     case BT_INTEGER:
2608       tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
2609       break;
2610
2611     default:
2612       gcc_unreachable ();
2613     }
2614
2615   /* We start with the most negative possible value for MAXVAL, and the most
2616      positive possible value for MINVAL. The most negative possible value is
2617      -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2618      possible value is HUGE in both cases.  */
2619   if (op == GT_EXPR)
2620     {
2621       tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (tmp), tmp);
2622       if (huge_cst)
2623         huge_cst = fold_build1 (NEGATE_EXPR, TREE_TYPE (huge_cst), huge_cst);
2624     }
2625
2626   if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
2627     tmp = fold_build2 (MINUS_EXPR, TREE_TYPE (tmp),
2628                        tmp, build_int_cst (type, 1));
2629
2630   gfc_add_modify (&se->pre, limit, tmp);
2631
2632   /* Walk the arguments.  */
2633   actual = expr->value.function.actual;
2634   arrayexpr = actual->expr;
2635   arrayss = gfc_walk_expr (arrayexpr);
2636   gcc_assert (arrayss != gfc_ss_terminator);
2637
2638   actual = actual->next->next;
2639   gcc_assert (actual);
2640   maskexpr = actual->expr;
2641   nonempty = NULL;
2642   if (maskexpr && maskexpr->rank != 0)
2643     {
2644       maskss = gfc_walk_expr (maskexpr);
2645       gcc_assert (maskss != gfc_ss_terminator);
2646     }
2647   else
2648     {
2649       mpz_t asize;
2650       if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
2651         {
2652           nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
2653           mpz_clear (asize);
2654           nonempty = fold_build2 (GT_EXPR, boolean_type_node, nonempty,
2655                                   gfc_index_zero_node);
2656         }
2657       maskss = NULL;
2658     }
2659
2660   /* Initialize the scalarizer.  */
2661   gfc_init_loopinfo (&loop);
2662   gfc_add_ss_to_loop (&loop, arrayss);
2663   if (maskss)
2664     gfc_add_ss_to_loop (&loop, maskss);
2665
2666   /* Initialize the loop.  */
2667   gfc_conv_ss_startstride (&loop);
2668   gfc_conv_loop_setup (&loop, &expr->where);
2669
2670   if (nonempty == NULL && maskss == NULL
2671       && loop.dimen == 1 && loop.from[0] && loop.to[0])
2672     nonempty = fold_build2 (LE_EXPR, boolean_type_node, loop.from[0],
2673                             loop.to[0]);
2674   nonempty_var = NULL;
2675   if (nonempty == NULL
2676       && (HONOR_INFINITIES (DECL_MODE (limit))
2677           || HONOR_NANS (DECL_MODE (limit))))
2678     {
2679       nonempty_var = gfc_create_var (boolean_type_node, "nonempty");
2680       gfc_add_modify (&se->pre, nonempty_var, boolean_false_node);
2681       nonempty = nonempty_var;
2682     }
2683   lab = NULL;
2684   fast = NULL;
2685   if (HONOR_NANS (DECL_MODE (limit)))
2686     {
2687       if (loop.dimen == 1)
2688         {
2689           lab = gfc_build_label_decl (NULL_TREE);
2690           TREE_USED (lab) = 1;
2691         }
2692       else
2693         {
2694           fast = gfc_create_var (boolean_type_node, "fast");
2695           gfc_add_modify (&se->pre, fast, boolean_false_node);
2696         }
2697     }
2698
2699   gfc_mark_ss_chain_used (arrayss, 1);
2700   if (maskss)
2701     gfc_mark_ss_chain_used (maskss, 1);
2702   /* Generate the loop body.  */
2703   gfc_start_scalarized_body (&loop, &body);
2704
2705   /* If we have a mask, only add this element if the mask is set.  */
2706   if (maskss)
2707     {
2708       gfc_init_se (&maskse, NULL);
2709       gfc_copy_loopinfo_to_se (&maskse, &loop);
2710       maskse.ss = maskss;
2711       gfc_conv_expr_val (&maskse, maskexpr);
2712       gfc_add_block_to_block (&body, &maskse.pre);
2713
2714       gfc_start_block (&block);
2715     }
2716   else
2717     gfc_init_block (&block);
2718
2719   /* Compare with the current limit.  */
2720   gfc_init_se (&arrayse, NULL);
2721   gfc_copy_loopinfo_to_se (&arrayse, &loop);
2722   arrayse.ss = arrayss;
2723   gfc_conv_expr_val (&arrayse, arrayexpr);
2724   gfc_add_block_to_block (&block, &arrayse.pre);
2725
2726   gfc_init_block (&block2);
2727
2728   if (nonempty_var)
2729     gfc_add_modify (&block2, nonempty_var, boolean_true_node);
2730
2731   if (HONOR_NANS (DECL_MODE (limit)))
2732     {
2733       tmp = fold_build2 (op == GT_EXPR ? GE_EXPR : LE_EXPR,
2734                          boolean_type_node, arrayse.expr, limit);
2735       if (lab)
2736         ifbody = build1_v (GOTO_EXPR, lab);
2737       else
2738         {
2739           stmtblock_t ifblock;
2740
2741           gfc_init_block (&ifblock);
2742           gfc_add_modify (&ifblock, limit, arrayse.expr);
2743           gfc_add_modify (&ifblock, fast, boolean_true_node);
2744           ifbody = gfc_finish_block (&ifblock);
2745         }
2746       tmp = build3_v (COND_EXPR, tmp, ifbody,
2747                       build_empty_stmt (input_location));
2748       gfc_add_expr_to_block (&block2, tmp);
2749     }
2750   else
2751     {
2752       /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2753          signed zeros.  */
2754       if (HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2755         {
2756           tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2757           ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2758           tmp = build3_v (COND_EXPR, tmp, ifbody,
2759                           build_empty_stmt (input_location));
2760           gfc_add_expr_to_block (&block2, tmp);
2761         }
2762       else
2763         {
2764           tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2765                              type, arrayse.expr, limit);
2766           gfc_add_modify (&block2, limit, tmp);
2767         }
2768     }
2769
2770   if (fast)
2771     {
2772       tree elsebody = gfc_finish_block (&block2);
2773
2774       /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2775          signed zeros.  */
2776       if (HONOR_NANS (DECL_MODE (limit))
2777           || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2778         {
2779           tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2780           ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2781           ifbody = build3_v (COND_EXPR, tmp, ifbody,
2782                              build_empty_stmt (input_location));
2783         }
2784       else
2785         {
2786           tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2787                              type, arrayse.expr, limit);
2788           ifbody = build2_v (MODIFY_EXPR, limit, tmp);
2789         }
2790       tmp = build3_v (COND_EXPR, fast, ifbody, elsebody);
2791       gfc_add_expr_to_block (&block, tmp);
2792     }
2793   else
2794     gfc_add_block_to_block (&block, &block2);
2795
2796   gfc_add_block_to_block (&block, &arrayse.post);
2797
2798   tmp = gfc_finish_block (&block);
2799   if (maskss)
2800     /* We enclose the above in if (mask) {...}.  */
2801     tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2802                     build_empty_stmt (input_location));
2803   gfc_add_expr_to_block (&body, tmp);
2804
2805   if (lab)
2806     {
2807       gfc_trans_scalarized_loop_end (&loop, 0, &body);
2808
2809       tmp = fold_build3 (COND_EXPR, type, nonempty, nan_cst, huge_cst);
2810       gfc_add_modify (&loop.code[0], limit, tmp);
2811       gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));
2812
2813       gfc_start_block (&body);
2814
2815       /* If we have a mask, only add this element if the mask is set.  */
2816       if (maskss)
2817         {
2818           gfc_init_se (&maskse, NULL);
2819           gfc_copy_loopinfo_to_se (&maskse, &loop);
2820           maskse.ss = maskss;
2821           gfc_conv_expr_val (&maskse, maskexpr);
2822           gfc_add_block_to_block (&body, &maskse.pre);
2823
2824           gfc_start_block (&block);
2825         }
2826       else
2827         gfc_init_block (&block);
2828
2829       /* Compare with the current limit.  */
2830       gfc_init_se (&arrayse, NULL);
2831       gfc_copy_loopinfo_to_se (&arrayse, &loop);
2832       arrayse.ss = arrayss;
2833       gfc_conv_expr_val (&arrayse, arrayexpr);
2834       gfc_add_block_to_block (&block, &arrayse.pre);
2835
2836       /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
2837          signed zeros.  */
2838       if (HONOR_NANS (DECL_MODE (limit))
2839           || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
2840         {
2841           tmp = fold_build2 (op, boolean_type_node, arrayse.expr, limit);
2842           ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
2843           tmp = build3_v (COND_EXPR, tmp, ifbody,
2844                           build_empty_stmt (input_location));
2845           gfc_add_expr_to_block (&block, tmp);
2846         }
2847       else
2848         {
2849           tmp = fold_build2 (op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
2850                              type, arrayse.expr, limit);
2851           gfc_add_modify (&block, limit, tmp);
2852         }
2853
2854       gfc_add_block_to_block (&block, &arrayse.post);
2855
2856       tmp = gfc_finish_block (&block);
2857       if (maskss)
2858         /* We enclose the above in if (mask) {...}.  */
2859         tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2860                         build_empty_stmt (input_location));
2861       gfc_add_expr_to_block (&body, tmp);
2862       /* Avoid initializing loopvar[0] again, it should be left where
2863          it finished by the first loop.  */
2864       loop.from[0] = loop.loopvar[0];
2865     }
2866   gfc_trans_scalarizing_loops (&loop, &body);
2867
2868   if (fast)
2869     {
2870       tmp = fold_build3 (COND_EXPR, type, nonempty, nan_cst, huge_cst);
2871       ifbody = build2_v (MODIFY_EXPR, limit, tmp);
2872       tmp = build3_v (COND_EXPR, fast, build_empty_stmt (input_location),
2873                       ifbody);
2874       gfc_add_expr_to_block (&loop.pre, tmp);
2875     }
2876   else if (HONOR_INFINITIES (DECL_MODE (limit)) && !lab)
2877     {
2878       tmp = fold_build3 (COND_EXPR, type, nonempty, limit, huge_cst);
2879       gfc_add_modify (&loop.pre, limit, tmp);
2880     }
2881
2882   /* For a scalar mask, enclose the loop in an if statement.  */
2883   if (maskexpr && maskss == NULL)
2884     {
2885       tree else_stmt;
2886
2887       gfc_init_se (&maskse, NULL);
2888       gfc_conv_expr_val (&maskse, maskexpr);
2889       gfc_init_block (&block);
2890       gfc_add_block_to_block (&block, &loop.pre);
2891       gfc_add_block_to_block (&block, &loop.post);
2892       tmp = gfc_finish_block (&block);
2893
2894       if (HONOR_INFINITIES (DECL_MODE (limit)))
2895         else_stmt = build2_v (MODIFY_EXPR, limit, huge_cst);
2896       else
2897         else_stmt = build_empty_stmt (input_location);
2898       tmp = build3_v (COND_EXPR, maskse.expr, tmp, else_stmt);
2899       gfc_add_expr_to_block (&block, tmp);
2900       gfc_add_block_to_block (&se->pre, &block);
2901     }
2902   else
2903     {
2904       gfc_add_block_to_block (&se->pre, &loop.pre);
2905       gfc_add_block_to_block (&se->pre, &loop.post);
2906     }
2907
2908   gfc_cleanup_loop (&loop);
2909
2910   se->expr = limit;
2911 }
2912
2913 /* BTEST (i, pos) = (i & (1 << pos)) != 0.  */
2914 static void
2915 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
2916 {
2917   tree args[2];
2918   tree type;
2919   tree tmp;
2920
2921   gfc_conv_intrinsic_function_args (se, expr, args, 2);
2922   type = TREE_TYPE (args[0]);
2923
2924   tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2925   tmp = fold_build2 (BIT_AND_EXPR, type, args[0], tmp);
2926   tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp,
2927                      build_int_cst (type, 0));
2928   type = gfc_typenode_for_spec (&expr->ts);
2929   se->expr = convert (type, tmp);
2930 }
2931
2932 /* Generate code to perform the specified operation.  */
2933 static void
2934 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
2935 {
2936   tree args[2];
2937
2938   gfc_conv_intrinsic_function_args (se, expr, args, 2);
2939   se->expr = fold_build2 (op, TREE_TYPE (args[0]), args[0], args[1]);
2940 }
2941
2942 /* Bitwise not.  */
2943 static void
2944 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
2945 {
2946   tree arg;
2947
2948   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
2949   se->expr = fold_build1 (BIT_NOT_EXPR, TREE_TYPE (arg), arg);
2950 }
2951
2952 /* Set or clear a single bit.  */
2953 static void
2954 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
2955 {
2956   tree args[2];
2957   tree type;
2958   tree tmp;
2959   enum tree_code op;
2960
2961   gfc_conv_intrinsic_function_args (se, expr, args, 2);
2962   type = TREE_TYPE (args[0]);
2963
2964   tmp = fold_build2 (LSHIFT_EXPR, type, build_int_cst (type, 1), args[1]);
2965   if (set)
2966     op = BIT_IOR_EXPR;
2967   else
2968     {
2969       op = BIT_AND_EXPR;
2970       tmp = fold_build1 (BIT_NOT_EXPR, type, tmp);
2971     }
2972   se->expr = fold_build2 (op, type, args[0], tmp);
2973 }
2974
2975 /* Extract a sequence of bits.
2976     IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN).  */
2977 static void
2978 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
2979 {
2980   tree args[3];
2981   tree type;
2982   tree tmp;
2983   tree mask;
2984
2985   gfc_conv_intrinsic_function_args (se, expr, args, 3);
2986   type = TREE_TYPE (args[0]);
2987
2988   mask = build_int_cst (type, -1);
2989   mask = fold_build2 (LSHIFT_EXPR, type, mask, args[2]);
2990   mask = fold_build1 (BIT_NOT_EXPR, type, mask);
2991
2992   tmp = fold_build2 (RSHIFT_EXPR, type, args[0], args[1]);
2993
2994   se->expr = fold_build2 (BIT_AND_EXPR, type, tmp, mask);
2995 }
2996
2997 /* RSHIFT (I, SHIFT) = I >> SHIFT
2998    LSHIFT (I, SHIFT) = I << SHIFT  */
2999 static void
3000 gfc_conv_intrinsic_rlshift (gfc_se * se, gfc_expr * expr, int right_shift)
3001 {
3002   tree args[2];
3003
3004   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3005
3006   se->expr = fold_build2 (right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
3007                           TREE_TYPE (args[0]), args[0], args[1]);
3008 }
3009
3010 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
3011                         ? 0
3012                         : ((shift >= 0) ? i << shift : i >> -shift)
3013    where all shifts are logical shifts.  */
3014 static void
3015 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
3016 {
3017   tree args[2];
3018   tree type;
3019   tree utype;
3020   tree tmp;
3021   tree width;
3022   tree num_bits;
3023   tree cond;
3024   tree lshift;
3025   tree rshift;
3026
3027   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3028   type = TREE_TYPE (args[0]);
3029   utype = unsigned_type_for (type);
3030
3031   width = fold_build1 (ABS_EXPR, TREE_TYPE (args[1]), args[1]);
3032
3033   /* Left shift if positive.  */
3034   lshift = fold_build2 (LSHIFT_EXPR, type, args[0], width);
3035
3036   /* Right shift if negative.
3037      We convert to an unsigned type because we want a logical shift.
3038      The standard doesn't define the case of shifting negative
3039      numbers, and we try to be compatible with other compilers, most
3040      notably g77, here.  */
3041   rshift = fold_convert (type, fold_build2 (RSHIFT_EXPR, utype, 
3042                                             convert (utype, args[0]), width));
3043
3044   tmp = fold_build2 (GE_EXPR, boolean_type_node, args[1],
3045                      build_int_cst (TREE_TYPE (args[1]), 0));
3046   tmp = fold_build3 (COND_EXPR, type, tmp, lshift, rshift);
3047
3048   /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3049      gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3050      special case.  */
3051   num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
3052   cond = fold_build2 (GE_EXPR, boolean_type_node, width, num_bits);
3053
3054   se->expr = fold_build3 (COND_EXPR, type, cond,
3055                           build_int_cst (type, 0), tmp);
3056 }
3057
3058
3059 /* Circular shift.  AKA rotate or barrel shift.  */
3060
3061 static void
3062 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
3063 {
3064   tree *args;
3065   tree type;
3066   tree tmp;
3067   tree lrot;
3068   tree rrot;
3069   tree zero;
3070   unsigned int num_args;
3071
3072   num_args = gfc_intrinsic_argument_list_length (expr);
3073   args = XALLOCAVEC (tree, num_args);
3074
3075   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3076
3077   if (num_args == 3)
3078     {
3079       /* Use a library function for the 3 parameter version.  */
3080       tree int4type = gfc_get_int_type (4);
3081
3082       type = TREE_TYPE (args[0]);
3083       /* We convert the first argument to at least 4 bytes, and
3084          convert back afterwards.  This removes the need for library
3085          functions for all argument sizes, and function will be
3086          aligned to at least 32 bits, so there's no loss.  */
3087       if (expr->ts.kind < 4)
3088         args[0] = convert (int4type, args[0]);
3089
3090       /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
3091          need loads of library  functions.  They cannot have values >
3092          BIT_SIZE (I) so the conversion is safe.  */
3093       args[1] = convert (int4type, args[1]);
3094       args[2] = convert (int4type, args[2]);
3095
3096       switch (expr->ts.kind)
3097         {
3098         case 1:
3099         case 2:
3100         case 4:
3101           tmp = gfor_fndecl_math_ishftc4;
3102           break;
3103         case 8:
3104           tmp = gfor_fndecl_math_ishftc8;
3105           break;
3106         case 16:
3107           tmp = gfor_fndecl_math_ishftc16;
3108           break;
3109         default:
3110           gcc_unreachable ();
3111         }
3112       se->expr = build_call_expr_loc (input_location,
3113                                   tmp, 3, args[0], args[1], args[2]);
3114       /* Convert the result back to the original type, if we extended
3115          the first argument's width above.  */
3116       if (expr->ts.kind < 4)
3117         se->expr = convert (type, se->expr);
3118
3119       return;
3120     }
3121   type = TREE_TYPE (args[0]);
3122
3123   /* Rotate left if positive.  */
3124   lrot = fold_build2 (LROTATE_EXPR, type, args[0], args[1]);
3125
3126   /* Rotate right if negative.  */
3127   tmp = fold_build1 (NEGATE_EXPR, TREE_TYPE (args[1]), args[1]);
3128   rrot = fold_build2 (RROTATE_EXPR, type, args[0], tmp);
3129
3130   zero = build_int_cst (TREE_TYPE (args[1]), 0);
3131   tmp = fold_build2 (GT_EXPR, boolean_type_node, args[1], zero);
3132   rrot = fold_build3 (COND_EXPR, type, tmp, lrot, rrot);
3133
3134   /* Do nothing if shift == 0.  */
3135   tmp = fold_build2 (EQ_EXPR, boolean_type_node, args[1], zero);
3136   se->expr = fold_build3 (COND_EXPR, type, tmp, args[0], rrot);
3137 }
3138
3139 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
3140                         : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
3141
3142    The conditional expression is necessary because the result of LEADZ(0)
3143    is defined, but the result of __builtin_clz(0) is undefined for most
3144    targets.
3145
3146    For INTEGER kinds smaller than the C 'int' type, we have to subtract the
3147    difference in bit size between the argument of LEADZ and the C int.  */
3148  
3149 static void
3150 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
3151 {
3152   tree arg;
3153   tree arg_type;
3154   tree cond;
3155   tree result_type;
3156   tree leadz;
3157   tree bit_size;
3158   tree tmp;
3159   tree func;
3160   int s, argsize;
3161
3162   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3163   argsize = TYPE_PRECISION (TREE_TYPE (arg));
3164
3165   /* Which variant of __builtin_clz* should we call?  */
3166   if (argsize <= INT_TYPE_SIZE)
3167     {
3168       arg_type = unsigned_type_node;
3169       func = built_in_decls[BUILT_IN_CLZ];
3170     }
3171   else if (argsize <= LONG_TYPE_SIZE)
3172     {
3173       arg_type = long_unsigned_type_node;
3174       func = built_in_decls[BUILT_IN_CLZL];
3175     }
3176   else if (argsize <= LONG_LONG_TYPE_SIZE)
3177     {
3178       arg_type = long_long_unsigned_type_node;
3179       func = built_in_decls[BUILT_IN_CLZLL];
3180     }
3181   else
3182     {
3183       gcc_assert (argsize == 128);
3184       arg_type = gfc_build_uint_type (argsize);
3185       func = gfor_fndecl_clz128;
3186     }
3187
3188   /* Convert the actual argument twice: first, to the unsigned type of the
3189      same size; then, to the proper argument type for the built-in
3190      function.  But the return type is of the default INTEGER kind.  */
3191   arg = fold_convert (gfc_build_uint_type (argsize), arg);
3192   arg = fold_convert (arg_type, arg);
3193   result_type = gfc_get_int_type (gfc_default_integer_kind);
3194
3195   /* Compute LEADZ for the case i .ne. 0.  */
3196   s = TYPE_PRECISION (arg_type) - argsize;
3197   tmp = fold_convert (result_type, build_call_expr (func, 1, arg));
3198   leadz = fold_build2 (MINUS_EXPR, result_type,
3199                        tmp, build_int_cst (result_type, s));
3200
3201   /* Build BIT_SIZE.  */
3202   bit_size = build_int_cst (result_type, argsize);
3203
3204   cond = fold_build2 (EQ_EXPR, boolean_type_node,
3205                       arg, build_int_cst (arg_type, 0));
3206   se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, leadz);
3207 }
3208
3209 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
3210
3211    The conditional expression is necessary because the result of TRAILZ(0)
3212    is defined, but the result of __builtin_ctz(0) is undefined for most
3213    targets.  */
3214  
3215 static void
3216 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
3217 {
3218   tree arg;
3219   tree arg_type;
3220   tree cond;
3221   tree result_type;
3222   tree trailz;
3223   tree bit_size;
3224   tree func;
3225   int argsize;
3226
3227   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3228   argsize = TYPE_PRECISION (TREE_TYPE (arg));
3229
3230   /* Which variant of __builtin_ctz* should we call?  */
3231   if (argsize <= INT_TYPE_SIZE)
3232     {
3233       arg_type = unsigned_type_node;
3234       func = built_in_decls[BUILT_IN_CTZ];
3235     }
3236   else if (argsize <= LONG_TYPE_SIZE)
3237     {
3238       arg_type = long_unsigned_type_node;
3239       func = built_in_decls[BUILT_IN_CTZL];
3240     }
3241   else if (argsize <= LONG_LONG_TYPE_SIZE)
3242     {
3243       arg_type = long_long_unsigned_type_node;
3244       func = built_in_decls[BUILT_IN_CTZLL];
3245     }
3246   else
3247     {
3248       gcc_assert (argsize == 128);
3249       arg_type = gfc_build_uint_type (argsize);
3250       func = gfor_fndecl_ctz128;
3251     }
3252
3253   /* Convert the actual argument twice: first, to the unsigned type of the
3254      same size; then, to the proper argument type for the built-in
3255      function.  But the return type is of the default INTEGER kind.  */
3256   arg = fold_convert (gfc_build_uint_type (argsize), arg);
3257   arg = fold_convert (arg_type, arg);
3258   result_type = gfc_get_int_type (gfc_default_integer_kind);
3259
3260   /* Compute TRAILZ for the case i .ne. 0.  */
3261   trailz = fold_convert (result_type, build_call_expr_loc (input_location,
3262                                                        func, 1, arg));
3263
3264   /* Build BIT_SIZE.  */
3265   bit_size = build_int_cst (result_type, argsize);
3266
3267   cond = fold_build2 (EQ_EXPR, boolean_type_node,
3268                       arg, build_int_cst (arg_type, 0));
3269   se->expr = fold_build3 (COND_EXPR, result_type, cond, bit_size, trailz);
3270 }
3271
3272 /* Process an intrinsic with unspecified argument-types that has an optional
3273    argument (which could be of type character), e.g. EOSHIFT.  For those, we
3274    need to append the string length of the optional argument if it is not
3275    present and the type is really character.
3276    primary specifies the position (starting at 1) of the non-optional argument
3277    specifying the type and optional gives the position of the optional
3278    argument in the arglist.  */
3279
3280 static void
3281 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
3282                                      unsigned primary, unsigned optional)
3283 {
3284   gfc_actual_arglist* prim_arg;
3285   gfc_actual_arglist* opt_arg;
3286   unsigned cur_pos;
3287   gfc_actual_arglist* arg;
3288   gfc_symbol* sym;
3289   VEC(tree,gc) *append_args;
3290
3291   /* Find the two arguments given as position.  */
3292   cur_pos = 0;
3293   prim_arg = NULL;
3294   opt_arg = NULL;
3295   for (arg = expr->value.function.actual; arg; arg = arg->next)
3296     {
3297       ++cur_pos;
3298
3299       if (cur_pos == primary)
3300         prim_arg = arg;
3301       if (cur_pos == optional)
3302         opt_arg = arg;
3303
3304       if (cur_pos >= primary && cur_pos >= optional)
3305         break;
3306     }
3307   gcc_assert (prim_arg);
3308   gcc_assert (prim_arg->expr);
3309   gcc_assert (opt_arg);
3310
3311   /* If we do have type CHARACTER and the optional argument is really absent,
3312      append a dummy 0 as string length.  */
3313   append_args = NULL;
3314   if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
3315     {
3316       tree dummy;
3317
3318       dummy = build_int_cst (gfc_charlen_type_node, 0);
3319       append_args = VEC_alloc (tree, gc, 1);
3320       VEC_quick_push (tree, append_args, dummy);
3321     }
3322
3323   /* Build the call itself.  */
3324   sym = gfc_get_symbol_for_expr (expr);
3325   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
3326                           append_args);
3327   gfc_free (sym);
3328 }
3329
3330
3331 /* The length of a character string.  */
3332 static void
3333 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
3334 {
3335   tree len;
3336   tree type;
3337   tree decl;
3338   gfc_symbol *sym;
3339   gfc_se argse;
3340   gfc_expr *arg;
3341   gfc_ss *ss;
3342
3343   gcc_assert (!se->ss);
3344
3345   arg = expr->value.function.actual->expr;
3346
3347   type = gfc_typenode_for_spec (&expr->ts);
3348   switch (arg->expr_type)
3349     {
3350     case EXPR_CONSTANT:
3351       len = build_int_cst (NULL_TREE, arg->value.character.length);
3352       break;
3353
3354     case EXPR_ARRAY:
3355       /* Obtain the string length from the function used by
3356          trans-array.c(gfc_trans_array_constructor).  */
3357       len = NULL_TREE;
3358       get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
3359       break;
3360
3361     case EXPR_VARIABLE:
3362       if (arg->ref == NULL
3363             || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
3364         {
3365           /* This doesn't catch all cases.
3366              See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
3367              and the surrounding thread.  */
3368           sym = arg->symtree->n.sym;
3369           decl = gfc_get_symbol_decl (sym);
3370           if (decl == current_function_decl && sym->attr.function
3371                 && (sym->result == sym))
3372             decl = gfc_get_fake_result_decl (sym, 0);
3373
3374           len = sym->ts.u.cl->backend_decl;
3375           gcc_assert (len);
3376           break;
3377         }
3378
3379       /* Otherwise fall through.  */
3380
3381     default:
3382       /* Anybody stupid enough to do this deserves inefficient code.  */
3383       ss = gfc_walk_expr (arg);
3384       gfc_init_se (&argse, se);
3385       if (ss == gfc_ss_terminator)
3386         gfc_conv_expr (&argse, arg);
3387       else
3388         gfc_conv_expr_descriptor (&argse, arg, ss);
3389       gfc_add_block_to_block (&se->pre, &argse.pre);
3390       gfc_add_block_to_block (&se->post, &argse.post);
3391       len = argse.string_length;
3392       break;
3393     }
3394   se->expr = convert (type, len);
3395 }
3396
3397 /* The length of a character string not including trailing blanks.  */
3398 static void
3399 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
3400 {
3401   int kind = expr->value.function.actual->expr->ts.kind;
3402   tree args[2], type, fndecl;
3403
3404   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3405   type = gfc_typenode_for_spec (&expr->ts);
3406
3407   if (kind == 1)
3408     fndecl = gfor_fndecl_string_len_trim;
3409   else if (kind == 4)
3410     fndecl = gfor_fndecl_string_len_trim_char4;
3411   else
3412     gcc_unreachable ();
3413
3414   se->expr = build_call_expr_loc (input_location,
3415                               fndecl, 2, args[0], args[1]);
3416   se->expr = convert (type, se->expr);
3417 }
3418
3419
3420 /* Returns the starting position of a substring within a string.  */
3421
3422 static void
3423 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
3424                                       tree function)
3425 {
3426   tree logical4_type_node = gfc_get_logical_type (4);
3427   tree type;
3428   tree fndecl;
3429   tree *args;
3430   unsigned int num_args;
3431
3432   args = XALLOCAVEC (tree, 5);
3433
3434   /* Get number of arguments; characters count double due to the
3435      string length argument. Kind= is not passed to the library
3436      and thus ignored.  */
3437   if (expr->value.function.actual->next->next->expr == NULL)
3438     num_args = 4;
3439   else
3440     num_args = 5;
3441
3442   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3443   type = gfc_typenode_for_spec (&expr->ts);
3444
3445   if (num_args == 4)
3446     args[4] = build_int_cst (logical4_type_node, 0);
3447   else
3448     args[4] = convert (logical4_type_node, args[4]);
3449
3450   fndecl = build_addr (function, current_function_decl);
3451   se->expr = build_call_array_loc (input_location,
3452                                TREE_TYPE (TREE_TYPE (function)), fndecl,
3453                                5, args);
3454   se->expr = convert (type, se->expr);
3455
3456 }
3457
3458 /* The ascii value for a single character.  */
3459 static void
3460 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
3461 {
3462   tree args[2], type, pchartype;
3463
3464   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3465   gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
3466   pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
3467   args[1] = fold_build1 (NOP_EXPR, pchartype, args[1]);
3468   type = gfc_typenode_for_spec (&expr->ts);
3469
3470   se->expr = build_fold_indirect_ref_loc (input_location,
3471                                       args[1]);
3472   se->expr = convert (type, se->expr);
3473 }
3474
3475
3476 /* Intrinsic ISNAN calls __builtin_isnan.  */
3477
3478 static void
3479 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
3480 {
3481   tree arg;
3482
3483   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3484   se->expr = build_call_expr_loc (input_location,
3485                               built_in_decls[BUILT_IN_ISNAN], 1, arg);
3486   STRIP_TYPE_NOPS (se->expr);
3487   se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
3488 }
3489
3490
3491 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
3492    their argument against a constant integer value.  */
3493
3494 static void
3495 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
3496 {
3497   tree arg;
3498
3499   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3500   se->expr = fold_build2 (EQ_EXPR, gfc_typenode_for_spec (&expr->ts),
3501                           arg, build_int_cst (TREE_TYPE (arg), value));
3502 }
3503
3504
3505
3506 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource.  */
3507
3508 static void
3509 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
3510 {
3511   tree tsource;
3512   tree fsource;
3513   tree mask;
3514   tree type;
3515   tree len, len2;
3516   tree *args;
3517   unsigned int num_args;
3518
3519   num_args = gfc_intrinsic_argument_list_length (expr);
3520   args = XALLOCAVEC (tree, num_args);
3521
3522   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
3523   if (expr->ts.type != BT_CHARACTER)
3524     {
3525       tsource = args[0];
3526       fsource = args[1];
3527       mask = args[2];
3528     }
3529   else
3530     {
3531       /* We do the same as in the non-character case, but the argument
3532          list is different because of the string length arguments. We
3533          also have to set the string length for the result.  */
3534       len = args[0];
3535       tsource = args[1];
3536       len2 = args[2];
3537       fsource = args[3];
3538       mask = args[4];
3539
3540       gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
3541                                    &se->pre);
3542       se->string_length = len;
3543     }
3544   type = TREE_TYPE (tsource);
3545   se->expr = fold_build3 (COND_EXPR, type, mask, tsource,
3546                           fold_convert (type, fsource));
3547 }
3548
3549
3550 /* FRACTION (s) is translated into frexp (s, &dummy_int).  */
3551 static void
3552 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
3553 {
3554   tree arg, type, tmp, frexp;
3555
3556   frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3557
3558   type = gfc_typenode_for_spec (&expr->ts);
3559   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3560   tmp = gfc_create_var (integer_type_node, NULL);
3561   se->expr = build_call_expr_loc (input_location, frexp, 2,
3562                                   fold_convert (type, arg),
3563                                   gfc_build_addr_expr (NULL_TREE, tmp));
3564   se->expr = fold_convert (type, se->expr);
3565 }
3566
3567
3568 /* NEAREST (s, dir) is translated into
3569      tmp = copysign (HUGE_VAL, dir);
3570      return nextafter (s, tmp);
3571  */
3572 static void
3573 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
3574 {
3575   tree args[2], type, tmp, nextafter, copysign, huge_val;
3576
3577   nextafter = builtin_decl_for_float_kind (BUILT_IN_NEXTAFTER, expr->ts.kind);
3578   copysign = builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
3579   huge_val = builtin_decl_for_float_kind (BUILT_IN_HUGE_VAL, expr->ts.kind);
3580
3581   type = gfc_typenode_for_spec (&expr->ts);
3582   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3583   tmp = build_call_expr_loc (input_location, copysign, 2,
3584                              build_call_expr_loc (input_location, huge_val, 0),
3585                              fold_convert (type, args[1]));
3586   se->expr = build_call_expr_loc (input_location, nextafter, 2,
3587                                   fold_convert (type, args[0]), tmp);
3588   se->expr = fold_convert (type, se->expr);
3589 }
3590
3591
3592 /* SPACING (s) is translated into
3593     int e;
3594     if (s == 0)
3595       res = tiny;
3596     else
3597     {
3598       frexp (s, &e);
3599       e = e - prec;
3600       e = MAX_EXPR (e, emin);
3601       res = scalbn (1., e);
3602     }
3603     return res;
3604
3605  where prec is the precision of s, gfc_real_kinds[k].digits,
3606        emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
3607    and tiny is tiny(s), gfc_real_kinds[k].tiny.  */
3608
3609 static void
3610 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
3611 {
3612   tree arg, type, prec, emin, tiny, res, e;
3613   tree cond, tmp, frexp, scalbn;
3614   int k;
3615   stmtblock_t block;
3616
3617   k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3618   prec = build_int_cst (NULL_TREE, gfc_real_kinds[k].digits);
3619   emin = build_int_cst (NULL_TREE, gfc_real_kinds[k].min_exponent - 1);
3620   tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
3621
3622   frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3623   scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3624
3625   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3626   arg = gfc_evaluate_now (arg, &se->pre);
3627
3628   type = gfc_typenode_for_spec (&expr->ts);
3629   e = gfc_create_var (integer_type_node, NULL);
3630   res = gfc_create_var (type, NULL);
3631
3632
3633   /* Build the block for s /= 0.  */
3634   gfc_start_block (&block);
3635   tmp = build_call_expr_loc (input_location, frexp, 2, arg,
3636                              gfc_build_addr_expr (NULL_TREE, e));
3637   gfc_add_expr_to_block (&block, tmp);
3638
3639   tmp = fold_build2 (MINUS_EXPR, integer_type_node, e, prec);
3640   gfc_add_modify (&block, e, fold_build2 (MAX_EXPR, integer_type_node,
3641                                           tmp, emin));
3642
3643   tmp = build_call_expr_loc (input_location, scalbn, 2,
3644                          build_real_from_int_cst (type, integer_one_node), e);
3645   gfc_add_modify (&block, res, tmp);
3646
3647   /* Finish by building the IF statement.  */
3648   cond = fold_build2 (EQ_EXPR, boolean_type_node, arg,
3649                       build_real_from_int_cst (type, integer_zero_node));
3650   tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
3651                   gfc_finish_block (&block));
3652
3653   gfc_add_expr_to_block (&se->pre, tmp);
3654   se->expr = res;
3655 }
3656
3657
3658 /* RRSPACING (s) is translated into
3659       int e;
3660       real x;
3661       x = fabs (s);
3662       if (x != 0)
3663       {
3664         frexp (s, &e);
3665         x = scalbn (x, precision - e);
3666       }
3667       return x;
3668
3669  where precision is gfc_real_kinds[k].digits.  */
3670
3671 static void
3672 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
3673 {
3674   tree arg, type, e, x, cond, stmt, tmp, frexp, scalbn, fabs;
3675   int prec, k;
3676   stmtblock_t block;
3677
3678   k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
3679   prec = gfc_real_kinds[k].digits;
3680
3681   frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3682   scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3683   fabs = builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
3684
3685   type = gfc_typenode_for_spec (&expr->ts);
3686   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3687   arg = gfc_evaluate_now (arg, &se->pre);
3688
3689   e = gfc_create_var (integer_type_node, NULL);
3690   x = gfc_create_var (type, NULL);
3691   gfc_add_modify (&se->pre, x,
3692                   build_call_expr_loc (input_location, fabs, 1, arg));
3693
3694
3695   gfc_start_block (&block);
3696   tmp = build_call_expr_loc (input_location, frexp, 2, arg,
3697                              gfc_build_addr_expr (NULL_TREE, e));
3698   gfc_add_expr_to_block (&block, tmp);
3699
3700   tmp = fold_build2 (MINUS_EXPR, integer_type_node,
3701                      build_int_cst (NULL_TREE, prec), e);
3702   tmp = build_call_expr_loc (input_location, scalbn, 2, x, tmp);
3703   gfc_add_modify (&block, x, tmp);
3704   stmt = gfc_finish_block (&block);
3705
3706   cond = fold_build2 (NE_EXPR, boolean_type_node, x,
3707                       build_real_from_int_cst (type, integer_zero_node));
3708   tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
3709   gfc_add_expr_to_block (&se->pre, tmp);
3710
3711   se->expr = fold_convert (type, x);
3712 }
3713
3714
3715 /* SCALE (s, i) is translated into scalbn (s, i).  */
3716 static void
3717 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
3718 {
3719   tree args[2], type, scalbn;
3720
3721   scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3722
3723   type = gfc_typenode_for_spec (&expr->ts);
3724   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3725   se->expr = build_call_expr_loc (input_location, scalbn, 2,
3726                                   fold_convert (type, args[0]),
3727                                   fold_convert (integer_type_node, args[1]));
3728   se->expr = fold_convert (type, se->expr);
3729 }
3730
3731
3732 /* SET_EXPONENT (s, i) is translated into
3733    scalbn (frexp (s, &dummy_int), i).  */
3734 static void
3735 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
3736 {
3737   tree args[2], type, tmp, frexp, scalbn;
3738
3739   frexp = builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
3740   scalbn = builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
3741
3742   type = gfc_typenode_for_spec (&expr->ts);
3743   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3744
3745   tmp = gfc_create_var (integer_type_node, NULL);
3746   tmp = build_call_expr_loc (input_location, frexp, 2,
3747                              fold_convert (type, args[0]),
3748                              gfc_build_addr_expr (NULL_TREE, tmp));
3749   se->expr = build_call_expr_loc (input_location, scalbn, 2, tmp,
3750                                   fold_convert (integer_type_node, args[1]));
3751   se->expr = fold_convert (type, se->expr);
3752 }
3753
3754
3755 static void
3756 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
3757 {
3758   gfc_actual_arglist *actual;
3759   tree arg1;
3760   tree type;
3761   tree fncall0;
3762   tree fncall1;
3763   gfc_se argse;
3764   gfc_ss *ss;
3765
3766   gfc_init_se (&argse, NULL);
3767   actual = expr->value.function.actual;
3768
3769   ss = gfc_walk_expr (actual->expr);
3770   gcc_assert (ss != gfc_ss_terminator);
3771   argse.want_pointer = 1;
3772   argse.data_not_needed = 1;
3773   gfc_conv_expr_descriptor (&argse, actual->expr, ss);
3774   gfc_add_block_to_block (&se->pre, &argse.pre);
3775   gfc_add_block_to_block (&se->post, &argse.post);
3776   arg1 = gfc_evaluate_now (argse.expr, &se->pre);
3777
3778   /* Build the call to size0.  */
3779   fncall0 = build_call_expr_loc (input_location,
3780                              gfor_fndecl_size0, 1, arg1);
3781
3782   actual = actual->next;
3783
3784   if (actual->expr)
3785     {
3786       gfc_init_se (&argse, NULL);
3787       gfc_conv_expr_type (&argse, actual->expr,
3788                           gfc_array_index_type);
3789       gfc_add_block_to_block (&se->pre, &argse.pre);
3790
3791       /* Unusually, for an intrinsic, size does not exclude
3792          an optional arg2, so we must test for it.  */  
3793       if (actual->expr->expr_type == EXPR_VARIABLE
3794             && actual->expr->symtree->n.sym->attr.dummy
3795             && actual->expr->symtree->n.sym->attr.optional)
3796         {
3797           tree tmp;
3798           /* Build the call to size1.  */
3799           fncall1 = build_call_expr_loc (input_location,
3800                                      gfor_fndecl_size1, 2,
3801                                      arg1, argse.expr);
3802
3803           gfc_init_se (&argse, NULL);
3804           argse.want_pointer = 1;
3805           argse.data_not_needed = 1;
3806           gfc_conv_expr (&argse, actual->expr);
3807           gfc_add_block_to_block (&se->pre, &argse.pre);
3808           tmp = fold_build2 (NE_EXPR, boolean_type_node,
3809                              argse.expr, null_pointer_node);
3810           tmp = gfc_evaluate_now (tmp, &se->pre);
3811           se->expr = fold_build3 (COND_EXPR, pvoid_type_node,
3812                                   tmp, fncall1, fncall0);
3813         }
3814       else
3815         {
3816           se->expr = NULL_TREE;
3817           argse.expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3818                                     argse.expr, gfc_index_one_node);
3819         }
3820     }
3821   else if (expr->value.function.actual->expr->rank == 1)
3822     {
3823       argse.expr = gfc_index_zero_node;
3824       se->expr = NULL_TREE;
3825     }
3826   else
3827     se->expr = fncall0;
3828
3829   if (se->expr == NULL_TREE)
3830     {
3831       tree ubound, lbound;
3832
3833       arg1 = build_fold_indirect_ref_loc (input_location,
3834                                       arg1);
3835       ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
3836       lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
3837       se->expr = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3838                               ubound, lbound);
3839       se->expr = fold_build2 (PLUS_EXPR, gfc_array_index_type, se->expr,
3840                               gfc_index_one_node);
3841       se->expr = fold_build2 (MAX_EXPR, gfc_array_index_type, se->expr,
3842                               gfc_index_zero_node);
3843     }
3844
3845   type = gfc_typenode_for_spec (&expr->ts);
3846   se->expr = convert (type, se->expr);
3847 }
3848
3849
3850 /* Helper function to compute the size of a character variable,
3851    excluding the terminating null characters.  The result has
3852    gfc_array_index_type type.  */
3853
3854 static tree
3855 size_of_string_in_bytes (int kind, tree string_length)
3856 {
3857   tree bytesize;
3858   int i = gfc_validate_kind (BT_CHARACTER, kind, false);
3859  
3860   bytesize = build_int_cst (gfc_array_index_type,
3861                             gfc_character_kinds[i].bit_size / 8);
3862
3863   return fold_build2 (MULT_EXPR, gfc_array_index_type, bytesize,
3864                       fold_convert (gfc_array_index_type, string_length));
3865 }
3866
3867
3868 static void
3869 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
3870 {
3871   gfc_expr *arg;
3872   gfc_ss *ss;
3873   gfc_se argse;
3874   tree source_bytes;
3875   tree type;
3876   tree tmp;
3877   tree lower;
3878   tree upper;
3879   int n;
3880
3881   arg = expr->value.function.actual->expr;
3882
3883   gfc_init_se (&argse, NULL);
3884   ss = gfc_walk_expr (arg);
3885
3886   if (ss == gfc_ss_terminator)
3887     {
3888       if (arg->ts.type == BT_CLASS)
3889         gfc_add_component_ref (arg, "$data");
3890
3891       gfc_conv_expr_reference (&argse, arg);
3892
3893       type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
3894                                                  argse.expr));
3895
3896       /* Obtain the source word length.  */
3897       if (arg->ts.type == BT_CHARACTER)
3898         se->expr = size_of_string_in_bytes (arg->ts.kind,
3899                                             argse.string_length);
3900       else
3901         se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type)); 
3902     }
3903   else
3904     {
3905       source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
3906       argse.want_pointer = 0;
3907       gfc_conv_expr_descriptor (&argse, arg, ss);
3908       type = gfc_get_element_type (TREE_TYPE (argse.expr));
3909
3910       /* Obtain the argument's word length.  */
3911       if (arg->ts.type == BT_CHARACTER)
3912         tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3913       else
3914         tmp = fold_convert (gfc_array_index_type,
3915                             size_in_bytes (type)); 
3916       gfc_add_modify (&argse.pre, source_bytes, tmp);
3917
3918       /* Obtain the size of the array in bytes.  */
3919       for (n = 0; n < arg->rank; n++)
3920         {
3921           tree idx;
3922           idx = gfc_rank_cst[n];
3923           lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
3924           upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
3925           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
3926                              upper, lower);
3927           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
3928                              tmp, gfc_index_one_node);
3929           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
3930                              tmp, source_bytes);
3931           gfc_add_modify (&argse.pre, source_bytes, tmp);
3932         }
3933       se->expr = source_bytes;
3934     }
3935
3936   gfc_add_block_to_block (&se->pre, &argse.pre);
3937 }
3938
3939
3940 static void
3941 gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
3942 {
3943   gfc_expr *arg;
3944   gfc_ss *ss;
3945   gfc_se argse,eight;
3946   tree type, result_type, tmp;
3947
3948   arg = expr->value.function.actual->expr;
3949   gfc_init_se (&eight, NULL);
3950   gfc_conv_expr (&eight, gfc_get_int_expr (expr->ts.kind, NULL, 8));
3951   
3952   gfc_init_se (&argse, NULL);
3953   ss = gfc_walk_expr (arg);
3954   result_type = gfc_get_int_type (expr->ts.kind);
3955
3956   if (ss == gfc_ss_terminator)
3957     {
3958       if (arg->ts.type == BT_CLASS)
3959       {
3960         gfc_add_component_ref (arg, "$vptr");
3961         gfc_add_component_ref (arg, "$size");
3962         gfc_conv_expr (&argse, arg);
3963         tmp = fold_convert (result_type, argse.expr);
3964         goto done;
3965       }
3966
3967       gfc_conv_expr_reference (&argse, arg);
3968       type = TREE_TYPE (build_fold_indirect_ref_loc (input_location, 
3969                                                      argse.expr));
3970     }
3971   else
3972     {
3973       argse.want_pointer = 0;
3974       gfc_conv_expr_descriptor (&argse, arg, ss);
3975       type = gfc_get_element_type (TREE_TYPE (argse.expr));
3976     }
3977     
3978   /* Obtain the argument's word length.  */
3979   if (arg->ts.type == BT_CHARACTER)
3980     tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
3981   else
3982     tmp = fold_convert (result_type, size_in_bytes (type)); 
3983
3984 done:
3985   se->expr = fold_build2 (MULT_EXPR, result_type, tmp, eight.expr);
3986   gfc_add_block_to_block (&se->pre, &argse.pre);
3987 }
3988
3989
3990 /* Intrinsic string comparison functions.  */
3991
3992 static void
3993 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
3994 {
3995   tree args[4];
3996
3997   gfc_conv_intrinsic_function_args (se, expr, args, 4);
3998
3999   se->expr
4000     = gfc_build_compare_string (args[0], args[1], args[2], args[3],
4001                                 expr->value.function.actual->expr->ts.kind,
4002                                 op);
4003   se->expr = fold_build2 (op, gfc_typenode_for_spec (&expr->ts), se->expr,
4004                           build_int_cst (TREE_TYPE (se->expr), 0));
4005 }
4006
4007 /* Generate a call to the adjustl/adjustr library function.  */
4008 static void
4009 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
4010 {
4011   tree args[3];
4012   tree len;
4013   tree type;
4014   tree var;
4015   tree tmp;
4016
4017   gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
4018   len = args[1];
4019
4020   type = TREE_TYPE (args[2]);
4021   var = gfc_conv_string_tmp (se, type, len);
4022   args[0] = var;
4023
4024   tmp = build_call_expr_loc (input_location,
4025                          fndecl, 3, args[0], args[1], args[2]);
4026   gfc_add_expr_to_block (&se->pre, tmp);
4027   se->expr = var;
4028   se->string_length = len;
4029 }
4030
4031
4032 /* Generate code for the TRANSFER intrinsic:
4033         For scalar results:
4034           DEST = TRANSFER (SOURCE, MOLD)
4035         where:
4036           typeof<DEST> = typeof<MOLD>
4037         and:
4038           MOLD is scalar.
4039
4040         For array results:
4041           DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
4042         where:
4043           typeof<DEST> = typeof<MOLD>
4044         and:
4045           N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
4046               sizeof (DEST(0) * SIZE).  */
4047 static void
4048 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
4049 {
4050   tree tmp;
4051   tree tmpdecl;
4052   tree ptr;
4053   tree extent;
4054   tree source;
4055   tree source_type;
4056   tree source_bytes;
4057   tree mold_type;
4058   tree dest_word_len;
4059   tree size_words;
4060   tree size_bytes;
4061   tree upper;
4062   tree lower;
4063   tree stmt;
4064   gfc_actual_arglist *arg;
4065   gfc_se argse;
4066   gfc_ss *ss;
4067   gfc_ss_info *info;
4068   stmtblock_t block;
4069   int n;
4070   bool scalar_mold;
4071
4072   info = NULL;
4073   if (se->loop)
4074     info = &se->ss->data.info;
4075
4076   /* Convert SOURCE.  The output from this stage is:-
4077         source_bytes = length of the source in bytes
4078         source = pointer to the source data.  */
4079   arg = expr->value.function.actual;
4080
4081   /* Ensure double transfer through LOGICAL preserves all
4082      the needed bits.  */
4083   if (arg->expr->expr_type == EXPR_FUNCTION
4084         && arg->expr->value.function.esym == NULL
4085         && arg->expr->value.function.isym != NULL
4086         && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
4087         && arg->expr->ts.type == BT_LOGICAL
4088         && expr->ts.type != arg->expr->ts.type)
4089     arg->expr->value.function.name = "__transfer_in_transfer";
4090
4091   gfc_init_se (&argse, NULL);
4092   ss = gfc_walk_expr (arg->expr);
4093
4094   source_bytes = gfc_create_var (gfc_array_index_type, NULL);
4095
4096   /* Obtain the pointer to source and the length of source in bytes.  */
4097   if (ss == gfc_ss_terminator)
4098     {
4099       gfc_conv_expr_reference (&argse, arg->expr);
4100       source = argse.expr;
4101
4102       source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4103                                                         argse.expr));
4104
4105       /* Obtain the source word length.  */
4106       if (arg->expr->ts.type == BT_CHARACTER)
4107         tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4108                                        argse.string_length);
4109       else
4110         tmp = fold_convert (gfc_array_index_type,
4111                             size_in_bytes (source_type)); 
4112     }
4113   else
4114     {
4115       argse.want_pointer = 0;
4116       gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4117       source = gfc_conv_descriptor_data_get (argse.expr);
4118       source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4119
4120       /* Repack the source if not a full variable array.  */
4121       if (arg->expr->expr_type == EXPR_VARIABLE
4122               && arg->expr->ref->u.ar.type != AR_FULL)
4123         {
4124           tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
4125
4126           if (gfc_option.warn_array_temp)
4127             gfc_warning ("Creating array temporary at %L", &expr->where);
4128
4129           source = build_call_expr_loc (input_location,
4130                                     gfor_fndecl_in_pack, 1, tmp);
4131           source = gfc_evaluate_now (source, &argse.pre);
4132
4133           /* Free the temporary.  */
4134           gfc_start_block (&block);
4135           tmp = gfc_call_free (convert (pvoid_type_node, source));
4136           gfc_add_expr_to_block (&block, tmp);
4137           stmt = gfc_finish_block (&block);
4138
4139           /* Clean up if it was repacked.  */
4140           gfc_init_block (&block);
4141           tmp = gfc_conv_array_data (argse.expr);
4142           tmp = fold_build2 (NE_EXPR, boolean_type_node, source, tmp);
4143           tmp = build3_v (COND_EXPR, tmp, stmt,
4144                           build_empty_stmt (input_location));
4145           gfc_add_expr_to_block (&block, tmp);
4146           gfc_add_block_to_block (&block, &se->post);
4147           gfc_init_block (&se->post);
4148           gfc_add_block_to_block (&se->post, &block);
4149         }
4150
4151       /* Obtain the source word length.  */
4152       if (arg->expr->ts.type == BT_CHARACTER)
4153         tmp = size_of_string_in_bytes (arg->expr->ts.kind,
4154                                        argse.string_length);
4155       else
4156         tmp = fold_convert (gfc_array_index_type,
4157                             size_in_bytes (source_type)); 
4158
4159       /* Obtain the size of the array in bytes.  */
4160       extent = gfc_create_var (gfc_array_index_type, NULL);
4161       for (n = 0; n < arg->expr->rank; n++)
4162         {
4163           tree idx;
4164           idx = gfc_rank_cst[n];
4165           gfc_add_modify (&argse.pre, source_bytes, tmp);
4166           lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
4167           upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
4168           tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4169                              upper, lower);
4170           gfc_add_modify (&argse.pre, extent, tmp);
4171           tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4172                              extent, gfc_index_one_node);
4173           tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4174                              tmp, source_bytes);
4175         }
4176     }
4177
4178   gfc_add_modify (&argse.pre, source_bytes, tmp);
4179   gfc_add_block_to_block (&se->pre, &argse.pre);
4180   gfc_add_block_to_block (&se->post, &argse.post);
4181
4182   /* Now convert MOLD.  The outputs are:
4183         mold_type = the TREE type of MOLD
4184         dest_word_len = destination word length in bytes.  */
4185   arg = arg->next;
4186
4187   gfc_init_se (&argse, NULL);
4188   ss = gfc_walk_expr (arg->expr);
4189
4190   scalar_mold = arg->expr->rank == 0;
4191
4192   if (ss == gfc_ss_terminator)
4193     {
4194       gfc_conv_expr_reference (&argse, arg->expr);
4195       mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
4196                                                       argse.expr));
4197     }
4198   else
4199     {
4200       gfc_init_se (&argse, NULL);
4201       argse.want_pointer = 0;
4202       gfc_conv_expr_descriptor (&argse, arg->expr, ss);
4203       mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
4204     }
4205
4206   gfc_add_block_to_block (&se->pre, &argse.pre);
4207   gfc_add_block_to_block (&se->post, &argse.post);
4208
4209   if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
4210     {
4211       /* If this TRANSFER is nested in another TRANSFER, use a type
4212          that preserves all bits.  */
4213       if (arg->expr->ts.type == BT_LOGICAL)
4214         mold_type = gfc_get_int_type (arg->expr->ts.kind);
4215     }
4216
4217   if (arg->expr->ts.type == BT_CHARACTER)
4218     {
4219       tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
4220       mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
4221     }
4222   else
4223     tmp = fold_convert (gfc_array_index_type,
4224                         size_in_bytes (mold_type)); 
4225  
4226   dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
4227   gfc_add_modify (&se->pre, dest_word_len, tmp);
4228
4229   /* Finally convert SIZE, if it is present.  */
4230   arg = arg->next;
4231   size_words = gfc_create_var (gfc_array_index_type, NULL);
4232
4233   if (arg->expr)
4234     {
4235       gfc_init_se (&argse, NULL);
4236       gfc_conv_expr_reference (&argse, arg->expr);
4237       tmp = convert (gfc_array_index_type,
4238                      build_fold_indirect_ref_loc (input_location,
4239                                               argse.expr));
4240       gfc_add_block_to_block (&se->pre, &argse.pre);
4241       gfc_add_block_to_block (&se->post, &argse.post);
4242     }
4243   else
4244     tmp = NULL_TREE;
4245
4246   /* Separate array and scalar results.  */
4247   if (scalar_mold && tmp == NULL_TREE)
4248     goto scalar_transfer;
4249
4250   size_bytes = gfc_create_var (gfc_array_index_type, NULL);
4251   if (tmp != NULL_TREE)
4252     tmp = fold_build2 (MULT_EXPR, gfc_array_index_type,
4253                        tmp, dest_word_len);
4254   else
4255     tmp = source_bytes;
4256
4257   gfc_add_modify (&se->pre, size_bytes, tmp);
4258   gfc_add_modify (&se->pre, size_words,
4259                        fold_build2 (CEIL_DIV_EXPR, gfc_array_index_type,
4260                                     size_bytes, dest_word_len));
4261
4262   /* Evaluate the bounds of the result.  If the loop range exists, we have
4263      to check if it is too large.  If so, we modify loop->to be consistent
4264      with min(size, size(source)).  Otherwise, size is made consistent with
4265      the loop range, so that the right number of bytes is transferred.*/
4266   n = se->loop->order[0];
4267   if (se->loop->to[n] != NULL_TREE)
4268     {
4269       tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4270                          se->loop->to[n], se->loop->from[n]);
4271       tmp = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4272                          tmp, gfc_index_one_node);
4273       tmp = fold_build2 (MIN_EXPR, gfc_array_index_type,
4274                          tmp, size_words);
4275       gfc_add_modify (&se->pre, size_words, tmp);
4276       gfc_add_modify (&se->pre, size_bytes,
4277                            fold_build2 (MULT_EXPR, gfc_array_index_type,
4278                                         size_words, dest_word_len));
4279       upper = fold_build2 (PLUS_EXPR, gfc_array_index_type,
4280                            size_words, se->loop->from[n]);
4281       upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4282                            upper, gfc_index_one_node);
4283     }
4284   else
4285     {
4286       upper = fold_build2 (MINUS_EXPR, gfc_array_index_type,
4287                            size_words, gfc_index_one_node);
4288       se->loop->from[n] = gfc_index_zero_node;
4289     }
4290
4291   se->loop->to[n] = upper;
4292
4293   /* Build a destination descriptor, using the pointer, source, as the
4294      data field.  */
4295   gfc_trans_create_temp_array (&se->pre, &se->post, se->loop,
4296                                info, mold_type, NULL_TREE, false, true, false,
4297                                &expr->where);
4298
4299   /* Cast the pointer to the result.  */
4300   tmp = gfc_conv_descriptor_data_get (info->descriptor);
4301   tmp = fold_convert (pvoid_type_node, tmp);
4302
4303   /* Use memcpy to do the transfer.  */
4304   tmp = build_call_expr_loc (input_location,
4305                          built_in_decls[BUILT_IN_MEMCPY],
4306                          3,
4307                          tmp,
4308                          fold_convert (pvoid_type_node, source),
4309                          fold_build2 (MIN_EXPR, gfc_array_index_type,
4310                                       size_bytes, source_bytes));
4311   gfc_add_expr_to_block (&se->pre, tmp);
4312
4313   se->expr = info->descriptor;
4314   if (expr->ts.type == BT_CHARACTER)
4315     se->string_length = dest_word_len;
4316
4317   return;
4318
4319 /* Deal with scalar results.  */
4320 scalar_transfer:
4321   extent = fold_build2 (MIN_EXPR, gfc_array_index_type,
4322                         dest_word_len, source_bytes);
4323   extent = fold_build2 (MAX_EXPR, gfc_array_index_type,
4324                         extent, gfc_index_zero_node);
4325
4326   if (expr->ts.type == BT_CHARACTER)
4327     {
4328       tree direct;
4329       tree indirect;
4330
4331       ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
4332       tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
4333                                 "transfer");
4334
4335       /* If source is longer than the destination, use a pointer to
4336          the source directly.  */
4337       gfc_init_block (&block);
4338       gfc_add_modify (&block, tmpdecl, ptr);
4339       direct = gfc_finish_block (&block);
4340
4341       /* Otherwise, allocate a string with the length of the destination
4342          and copy the source into it.  */
4343       gfc_init_block (&block);
4344       tmp = gfc_get_pchar_type (expr->ts.kind);
4345       tmp = gfc_call_malloc (&block, tmp, dest_word_len);
4346       gfc_add_modify (&block, tmpdecl,
4347                       fold_convert (TREE_TYPE (ptr), tmp));
4348       tmp = build_call_expr_loc (input_location,
4349                              built_in_decls[BUILT_IN_MEMCPY], 3,
4350                              fold_convert (pvoid_type_node, tmpdecl),
4351                              fold_convert (pvoid_type_node, ptr),
4352                              extent);
4353       gfc_add_expr_to_block (&block, tmp);
4354       indirect = gfc_finish_block (&block);
4355
4356       /* Wrap it up with the condition.  */
4357       tmp = fold_build2 (LE_EXPR, boolean_type_node,
4358                          dest_word_len, source_bytes);
4359       tmp = build3_v (COND_EXPR, tmp, direct, indirect);
4360       gfc_add_expr_to_block (&se->pre, tmp);
4361
4362       se->expr = tmpdecl;
4363       se->string_length = dest_word_len;
4364     }
4365   else
4366     {
4367       tmpdecl = gfc_create_var (mold_type, "transfer");
4368
4369       ptr = convert (build_pointer_type (mold_type), source);
4370
4371       /* Use memcpy to do the transfer.  */
4372       tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
4373       tmp = build_call_expr_loc (input_location,
4374                              built_in_decls[BUILT_IN_MEMCPY], 3,
4375                              fold_convert (pvoid_type_node, tmp),
4376                              fold_convert (pvoid_type_node, ptr),
4377                              extent);
4378       gfc_add_expr_to_block (&se->pre, tmp);
4379
4380       se->expr = tmpdecl;
4381     }
4382 }
4383
4384
4385 /* Generate code for the ALLOCATED intrinsic.
4386    Generate inline code that directly check the address of the argument.  */
4387
4388 static void
4389 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
4390 {
4391   gfc_actual_arglist *arg1;
4392   gfc_se arg1se;
4393   gfc_ss *ss1;
4394   tree tmp;
4395
4396   gfc_init_se (&arg1se, NULL);
4397   arg1 = expr->value.function.actual;
4398   ss1 = gfc_walk_expr (arg1->expr);
4399
4400   if (ss1 == gfc_ss_terminator)
4401     {
4402       /* Allocatable scalar.  */
4403       arg1se.want_pointer = 1;
4404       if (arg1->expr->ts.type == BT_CLASS)
4405         gfc_add_component_ref (arg1->expr, "$data");
4406       gfc_conv_expr (&arg1se, arg1->expr);
4407       tmp = arg1se.expr;
4408     }
4409   else
4410     {
4411       /* Allocatable array.  */
4412       arg1se.descriptor_only = 1;
4413       gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4414       tmp = gfc_conv_descriptor_data_get (arg1se.expr);
4415     }
4416
4417   tmp = fold_build2 (NE_EXPR, boolean_type_node,
4418                      tmp, fold_convert (TREE_TYPE (tmp), null_pointer_node));
4419   se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
4420 }
4421
4422
4423 /* Generate code for the ASSOCIATED intrinsic.
4424    If both POINTER and TARGET are arrays, generate a call to library function
4425    _gfor_associated, and pass descriptors of POINTER and TARGET to it.
4426    In other cases, generate inline code that directly compare the address of
4427    POINTER with the address of TARGET.  */
4428
4429 static void
4430 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
4431 {
4432   gfc_actual_arglist *arg1;
4433   gfc_actual_arglist *arg2;
4434   gfc_se arg1se;
4435   gfc_se arg2se;
4436   tree tmp2;
4437   tree tmp;
4438   tree nonzero_charlen;
4439   tree nonzero_arraylen;
4440   gfc_ss *ss1, *ss2;
4441
4442   gfc_init_se (&arg1se, NULL);
4443   gfc_init_se (&arg2se, NULL);
4444   arg1 = expr->value.function.actual;
4445   if (arg1->expr->ts.type == BT_CLASS)
4446     gfc_add_component_ref (arg1->expr, "$data");
4447   arg2 = arg1->next;
4448   ss1 = gfc_walk_expr (arg1->expr);
4449
4450   if (!arg2->expr)
4451     {
4452       /* No optional target.  */
4453       if (ss1 == gfc_ss_terminator)
4454         {
4455           /* A pointer to a scalar.  */
4456           arg1se.want_pointer = 1;
4457           gfc_conv_expr (&arg1se, arg1->expr);
4458           tmp2 = arg1se.expr;
4459         }
4460       else
4461         {
4462           /* A pointer to an array.  */
4463           gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4464           tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
4465         }
4466       gfc_add_block_to_block (&se->pre, &arg1se.pre);
4467       gfc_add_block_to_block (&se->post, &arg1se.post);
4468       tmp = fold_build2 (NE_EXPR, boolean_type_node, tmp2,
4469                          fold_convert (TREE_TYPE (tmp2), null_pointer_node));
4470       se->expr = tmp;
4471     }
4472   else
4473     {
4474       /* An optional target.  */
4475       if (arg2->expr->ts.type == BT_CLASS)
4476         gfc_add_component_ref (arg2->expr, "$data");
4477       ss2 = gfc_walk_expr (arg2->expr);
4478
4479       nonzero_charlen = NULL_TREE;
4480       if (arg1->expr->ts.type == BT_CHARACTER)
4481         nonzero_charlen = fold_build2 (NE_EXPR, boolean_type_node,
4482                                        arg1->expr->ts.u.cl->backend_decl,
4483                                        integer_zero_node);
4484
4485       if (ss1 == gfc_ss_terminator)
4486         {
4487           /* A pointer to a scalar.  */
4488           gcc_assert (ss2 == gfc_ss_terminator);
4489           arg1se.want_pointer = 1;
4490           gfc_conv_expr (&arg1se, arg1->expr);
4491           arg2se.want_pointer = 1;
4492           gfc_conv_expr (&arg2se, arg2->expr);
4493           gfc_add_block_to_block (&se->pre, &arg1se.pre);
4494           gfc_add_block_to_block (&se->post, &arg1se.post);
4495           tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4496                              arg1se.expr, arg2se.expr);
4497           tmp2 = fold_build2 (NE_EXPR, boolean_type_node,
4498                               arg1se.expr, null_pointer_node);
4499           se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4500                                   tmp, tmp2);
4501         }
4502       else
4503         {
4504           /* An array pointer of zero length is not associated if target is
4505              present.  */
4506           arg1se.descriptor_only = 1;
4507           gfc_conv_expr_lhs (&arg1se, arg1->expr);
4508           tmp = gfc_conv_descriptor_stride_get (arg1se.expr,
4509                                             gfc_rank_cst[arg1->expr->rank - 1]);
4510           nonzero_arraylen = fold_build2 (NE_EXPR, boolean_type_node, tmp,
4511                                           build_int_cst (TREE_TYPE (tmp), 0));
4512
4513           /* A pointer to an array, call library function _gfor_associated.  */
4514           gcc_assert (ss2 != gfc_ss_terminator);
4515           arg1se.want_pointer = 1;
4516           gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
4517
4518           arg2se.want_pointer = 1;
4519           gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
4520           gfc_add_block_to_block (&se->pre, &arg2se.pre);
4521           gfc_add_block_to_block (&se->post, &arg2se.post);
4522           se->expr = build_call_expr_loc (input_location,
4523                                       gfor_fndecl_associated, 2,
4524                                       arg1se.expr, arg2se.expr);
4525           se->expr = convert (boolean_type_node, se->expr);
4526           se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4527                                   se->expr, nonzero_arraylen);
4528         }
4529
4530       /* If target is present zero character length pointers cannot
4531          be associated.  */
4532       if (nonzero_charlen != NULL_TREE)
4533         se->expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
4534                                 se->expr, nonzero_charlen);
4535     }
4536
4537   se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4538 }
4539
4540
4541 /* Generate code for the SAME_TYPE_AS intrinsic.
4542    Generate inline code that directly checks the vindices.  */
4543
4544 static void
4545 gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
4546 {
4547   gfc_expr *a, *b;
4548   gfc_se se1, se2;
4549   tree tmp;
4550
4551   gfc_init_se (&se1, NULL);
4552   gfc_init_se (&se2, NULL);
4553
4554   a = expr->value.function.actual->expr;
4555   b = expr->value.function.actual->next->expr;
4556
4557   if (a->ts.type == BT_CLASS)
4558     {
4559       gfc_add_component_ref (a, "$vptr");
4560       gfc_add_component_ref (a, "$hash");
4561     }
4562   else if (a->ts.type == BT_DERIVED)
4563     a = gfc_get_int_expr (gfc_default_integer_kind, NULL,
4564                           a->ts.u.derived->hash_value);
4565
4566   if (b->ts.type == BT_CLASS)
4567     {
4568       gfc_add_component_ref (b, "$vptr");
4569       gfc_add_component_ref (b, "$hash");
4570     }
4571   else if (b->ts.type == BT_DERIVED)
4572     b = gfc_get_int_expr (gfc_default_integer_kind, NULL,
4573                           b->ts.u.derived->hash_value);
4574
4575   gfc_conv_expr (&se1, a);
4576   gfc_conv_expr (&se2, b);
4577
4578   tmp = fold_build2 (EQ_EXPR, boolean_type_node,
4579                      se1.expr, fold_convert (TREE_TYPE (se1.expr), se2.expr));
4580   se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
4581 }
4582
4583
4584 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function.  */
4585
4586 static void
4587 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
4588 {
4589   tree args[2];
4590
4591   gfc_conv_intrinsic_function_args (se, expr, args, 2);
4592   se->expr = build_call_expr_loc (input_location,
4593                               gfor_fndecl_sc_kind, 2, args[0], args[1]);
4594   se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4595 }
4596
4597
4598 /* Generate code for SELECTED_INT_KIND (R) intrinsic function.  */
4599
4600 static void
4601 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
4602 {
4603   tree arg, type;
4604
4605   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4606
4607   /* The argument to SELECTED_INT_KIND is INTEGER(4).  */
4608   type = gfc_get_int_type (4); 
4609   arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
4610
4611   /* Convert it to the required type.  */
4612   type = gfc_typenode_for_spec (&expr->ts);
4613   se->expr = build_call_expr_loc (input_location,
4614                               gfor_fndecl_si_kind, 1, arg);
4615   se->expr = fold_convert (type, se->expr);
4616 }
4617
4618
4619 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function.  */
4620
4621 static void
4622 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
4623 {
4624   gfc_actual_arglist *actual;
4625   tree type;
4626   gfc_se argse;
4627   VEC(tree,gc) *args = NULL;
4628
4629   for (actual = expr->value.function.actual; actual; actual = actual->next)
4630     {
4631       gfc_init_se (&argse, se);
4632
4633       /* Pass a NULL pointer for an absent arg.  */
4634       if (actual->expr == NULL)
4635         argse.expr = null_pointer_node;
4636       else
4637         {
4638           gfc_typespec ts;
4639           gfc_clear_ts (&ts);
4640
4641           if (actual->expr->ts.kind != gfc_c_int_kind)
4642             {
4643               /* The arguments to SELECTED_REAL_KIND are INTEGER(4).  */
4644               ts.type = BT_INTEGER;
4645               ts.kind = gfc_c_int_kind;
4646               gfc_convert_type (actual->expr, &ts, 2);
4647             }
4648           gfc_conv_expr_reference (&argse, actual->expr);
4649         } 
4650
4651       gfc_add_block_to_block (&se->pre, &argse.pre);
4652       gfc_add_block_to_block (&se->post, &argse.post);
4653       VEC_safe_push (tree, gc, args, argse.expr);
4654     }
4655
4656   /* Convert it to the required type.  */
4657   type = gfc_typenode_for_spec (&expr->ts);
4658   se->expr = build_call_expr_loc_vec (input_location,
4659                                       gfor_fndecl_sr_kind, args);
4660   se->expr = fold_convert (type, se->expr);
4661 }
4662
4663
4664 /* Generate code for TRIM (A) intrinsic function.  */
4665
4666 static void
4667 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
4668 {
4669   tree var;
4670   tree len;
4671   tree addr;
4672   tree tmp;
4673   tree cond;
4674   tree fndecl;
4675   tree function;
4676   tree *args;
4677   unsigned int num_args;
4678
4679   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
4680   args = XALLOCAVEC (tree, num_args);
4681
4682   var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
4683   addr = gfc_build_addr_expr (ppvoid_type_node, var);
4684   len = gfc_create_var (gfc_charlen_type_node, "len");
4685
4686   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
4687   args[0] = gfc_build_addr_expr (NULL_TREE, len);
4688   args[1] = addr;
4689
4690   if (expr->ts.kind == 1)
4691     function = gfor_fndecl_string_trim;
4692   else if (expr->ts.kind == 4)
4693     function = gfor_fndecl_string_trim_char4;
4694   else
4695     gcc_unreachable ();
4696
4697   fndecl = build_addr (function, current_function_decl);
4698   tmp = build_call_array_loc (input_location,
4699                           TREE_TYPE (TREE_TYPE (function)), fndecl,
4700                           num_args, args);
4701   gfc_add_expr_to_block (&se->pre, tmp);
4702
4703   /* Free the temporary afterwards, if necessary.  */
4704   cond = fold_build2 (GT_EXPR, boolean_type_node,
4705                       len, build_int_cst (TREE_TYPE (len), 0));
4706   tmp = gfc_call_free (var);
4707   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
4708   gfc_add_expr_to_block (&se->post, tmp);
4709
4710   se->expr = var;
4711   se->string_length = len;
4712 }
4713
4714
4715 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function.  */
4716
4717 static void
4718 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
4719 {
4720   tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
4721   tree type, cond, tmp, count, exit_label, n, max, largest;
4722   tree size;
4723   stmtblock_t block, body;
4724   int i;
4725
4726   /* We store in charsize the size of a character.  */
4727   i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
4728   size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
4729
4730   /* Get the arguments.  */
4731   gfc_conv_intrinsic_function_args (se, expr, args, 3);
4732   slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
4733   src = args[1];
4734   ncopies = gfc_evaluate_now (args[2], &se->pre);
4735   ncopies_type = TREE_TYPE (ncopies);
4736
4737   /* Check that NCOPIES is not negative.  */
4738   cond = fold_build2 (LT_EXPR, boolean_type_node, ncopies,
4739                       build_int_cst (ncopies_type, 0));
4740   gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4741                            "Argument NCOPIES of REPEAT intrinsic is negative "
4742                            "(its value is %lld)",
4743                            fold_convert (long_integer_type_node, ncopies));
4744
4745   /* If the source length is zero, any non negative value of NCOPIES
4746      is valid, and nothing happens.  */
4747   n = gfc_create_var (ncopies_type, "ncopies");
4748   cond = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4749                       build_int_cst (size_type_node, 0));
4750   tmp = fold_build3 (COND_EXPR, ncopies_type, cond,
4751                      build_int_cst (ncopies_type, 0), ncopies);
4752   gfc_add_modify (&se->pre, n, tmp);
4753   ncopies = n;
4754
4755   /* Check that ncopies is not too large: ncopies should be less than
4756      (or equal to) MAX / slen, where MAX is the maximal integer of
4757      the gfc_charlen_type_node type.  If slen == 0, we need a special
4758      case to avoid the division by zero.  */
4759   i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
4760   max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
4761   max = fold_build2 (TRUNC_DIV_EXPR, size_type_node,
4762                      fold_convert (size_type_node, max), slen);
4763   largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
4764               ? size_type_node : ncopies_type;
4765   cond = fold_build2 (GT_EXPR, boolean_type_node,
4766                       fold_convert (largest, ncopies),
4767                       fold_convert (largest, max));
4768   tmp = fold_build2 (EQ_EXPR, boolean_type_node, slen,
4769                      build_int_cst (size_type_node, 0));
4770   cond = fold_build3 (COND_EXPR, boolean_type_node, tmp, boolean_false_node,
4771                       cond);
4772   gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
4773                            "Argument NCOPIES of REPEAT intrinsic is too large");
4774
4775   /* Compute the destination length.  */
4776   dlen = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4777                       fold_convert (gfc_charlen_type_node, slen),
4778                       fold_convert (gfc_charlen_type_node, ncopies));
4779   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
4780   dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
4781
4782   /* Generate the code to do the repeat operation:
4783        for (i = 0; i < ncopies; i++)
4784          memmove (dest + (i * slen * size), src, slen*size);  */
4785   gfc_start_block (&block);
4786   count = gfc_create_var (ncopies_type, "count");
4787   gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
4788   exit_label = gfc_build_label_decl (NULL_TREE);
4789
4790   /* Start the loop body.  */
4791   gfc_start_block (&body);
4792
4793   /* Exit the loop if count >= ncopies.  */
4794   cond = fold_build2 (GE_EXPR, boolean_type_node, count, ncopies);
4795   tmp = build1_v (GOTO_EXPR, exit_label);
4796   TREE_USED (exit_label) = 1;
4797   tmp = fold_build3 (COND_EXPR, void_type_node, cond, tmp,
4798                      build_empty_stmt (input_location));
4799   gfc_add_expr_to_block (&body, tmp);
4800
4801   /* Call memmove (dest + (i*slen*size), src, slen*size).  */
4802   tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4803                      fold_convert (gfc_charlen_type_node, slen),
4804                      fold_convert (gfc_charlen_type_node, count));
4805   tmp = fold_build2 (MULT_EXPR, gfc_charlen_type_node,
4806                      tmp, fold_convert (gfc_charlen_type_node, size));
4807   tmp = fold_build2 (POINTER_PLUS_EXPR, pvoid_type_node,
4808                      fold_convert (pvoid_type_node, dest),
4809                      fold_convert (sizetype, tmp));
4810   tmp = build_call_expr_loc (input_location,
4811                          built_in_decls[BUILT_IN_MEMMOVE], 3, tmp, src,
4812                          fold_build2 (MULT_EXPR, size_type_node, slen,
4813                                       fold_convert (size_type_node, size)));
4814   gfc_add_expr_to_block (&body, tmp);
4815
4816   /* Increment count.  */
4817   tmp = fold_build2 (PLUS_EXPR, ncopies_type,
4818                      count, build_int_cst (TREE_TYPE (count), 1));
4819   gfc_add_modify (&body, count, tmp);
4820
4821   /* Build the loop.  */
4822   tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
4823   gfc_add_expr_to_block (&block, tmp);
4824
4825   /* Add the exit label.  */
4826   tmp = build1_v (LABEL_EXPR, exit_label);
4827   gfc_add_expr_to_block (&block, tmp);
4828
4829   /* Finish the block.  */
4830   tmp = gfc_finish_block (&block);
4831   gfc_add_expr_to_block (&se->pre, tmp);
4832
4833   /* Set the result value.  */
4834   se->expr = dest;
4835   se->string_length = dlen;
4836 }
4837
4838
4839 /* Generate code for the IARGC intrinsic.  */
4840
4841 static void
4842 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
4843 {
4844   tree tmp;
4845   tree fndecl;
4846   tree type;
4847
4848   /* Call the library function.  This always returns an INTEGER(4).  */
4849   fndecl = gfor_fndecl_iargc;
4850   tmp = build_call_expr_loc (input_location,
4851                          fndecl, 0);
4852
4853   /* Convert it to the required type.  */
4854   type = gfc_typenode_for_spec (&expr->ts);
4855   tmp = fold_convert (type, tmp);
4856
4857   se->expr = tmp;
4858 }
4859
4860
4861 /* The loc intrinsic returns the address of its argument as
4862    gfc_index_integer_kind integer.  */
4863
4864 static void
4865 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
4866 {
4867   tree temp_var;
4868   gfc_expr *arg_expr;
4869   gfc_ss *ss;
4870
4871   gcc_assert (!se->ss);
4872
4873   arg_expr = expr->value.function.actual->expr;
4874   ss = gfc_walk_expr (arg_expr);
4875   if (ss == gfc_ss_terminator)
4876     gfc_conv_expr_reference (se, arg_expr);
4877   else
4878     gfc_conv_array_parameter (se, arg_expr, ss, true, NULL, NULL, NULL);
4879   se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
4880    
4881   /* Create a temporary variable for loc return value.  Without this, 
4882      we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1).  */
4883   temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
4884   gfc_add_modify (&se->pre, temp_var, se->expr);
4885   se->expr = temp_var;
4886 }
4887
4888 /* Generate code for an intrinsic function.  Some map directly to library
4889    calls, others get special handling.  In some cases the name of the function
4890    used depends on the type specifiers.  */
4891
4892 void
4893 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
4894 {
4895   const char *name;
4896   int lib, kind;
4897   tree fndecl;
4898
4899   name = &expr->value.function.name[2];
4900
4901   if (expr->rank > 0 && !expr->inline_noncopying_intrinsic)
4902     {
4903       lib = gfc_is_intrinsic_libcall (expr);
4904       if (lib != 0)
4905         {
4906           if (lib == 1)
4907             se->ignore_optional = 1;
4908
4909           switch (expr->value.function.isym->id)
4910             {
4911             case GFC_ISYM_EOSHIFT:
4912             case GFC_ISYM_PACK:
4913             case GFC_ISYM_RESHAPE:
4914               /* For all of those the first argument specifies the type and the
4915                  third is optional.  */
4916               conv_generic_with_optional_char_arg (se, expr, 1, 3);
4917               break;
4918
4919             default:
4920               gfc_conv_intrinsic_funcall (se, expr);
4921               break;
4922             }
4923
4924           return;
4925         }
4926     }
4927
4928   switch (expr->value.function.isym->id)
4929     {
4930     case GFC_ISYM_NONE:
4931       gcc_unreachable ();
4932
4933     case GFC_ISYM_REPEAT:
4934       gfc_conv_intrinsic_repeat (se, expr);
4935       break;
4936
4937     case GFC_ISYM_TRIM:
4938       gfc_conv_intrinsic_trim (se, expr);
4939       break;
4940
4941     case GFC_ISYM_SC_KIND:
4942       gfc_conv_intrinsic_sc_kind (se, expr);
4943       break;
4944
4945     case GFC_ISYM_SI_KIND:
4946       gfc_conv_intrinsic_si_kind (se, expr);
4947       break;
4948
4949     case GFC_ISYM_SR_KIND:
4950       gfc_conv_intrinsic_sr_kind (se, expr);
4951       break;
4952
4953     case GFC_ISYM_EXPONENT:
4954       gfc_conv_intrinsic_exponent (se, expr);
4955       break;
4956
4957     case GFC_ISYM_SCAN:
4958       kind = expr->value.function.actual->expr->ts.kind;
4959       if (kind == 1)
4960        fndecl = gfor_fndecl_string_scan;
4961       else if (kind == 4)
4962        fndecl = gfor_fndecl_string_scan_char4;
4963       else
4964        gcc_unreachable ();
4965
4966       gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4967       break;
4968
4969     case GFC_ISYM_VERIFY:
4970       kind = expr->value.function.actual->expr->ts.kind;
4971       if (kind == 1)
4972        fndecl = gfor_fndecl_string_verify;
4973       else if (kind == 4)
4974        fndecl = gfor_fndecl_string_verify_char4;
4975       else
4976        gcc_unreachable ();
4977
4978       gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
4979       break;
4980
4981     case GFC_ISYM_ALLOCATED:
4982       gfc_conv_allocated (se, expr);
4983       break;
4984
4985     case GFC_ISYM_ASSOCIATED:
4986       gfc_conv_associated(se, expr);
4987       break;
4988
4989     case GFC_ISYM_SAME_TYPE_AS:
4990       gfc_conv_same_type_as (se, expr);
4991       break;
4992
4993     case GFC_ISYM_ABS:
4994       gfc_conv_intrinsic_abs (se, expr);
4995       break;
4996
4997     case GFC_ISYM_ADJUSTL:
4998       if (expr->ts.kind == 1)
4999        fndecl = gfor_fndecl_adjustl;
5000       else if (expr->ts.kind == 4)
5001        fndecl = gfor_fndecl_adjustl_char4;
5002       else
5003        gcc_unreachable ();
5004
5005       gfc_conv_intrinsic_adjust (se, expr, fndecl);
5006       break;
5007
5008     case GFC_ISYM_ADJUSTR:
5009       if (expr->ts.kind == 1)
5010        fndecl = gfor_fndecl_adjustr;
5011       else if (expr->ts.kind == 4)
5012        fndecl = gfor_fndecl_adjustr_char4;
5013       else
5014        gcc_unreachable ();
5015
5016       gfc_conv_intrinsic_adjust (se, expr, fndecl);
5017       break;
5018
5019     case GFC_ISYM_AIMAG:
5020       gfc_conv_intrinsic_imagpart (se, expr);
5021       break;
5022
5023     case GFC_ISYM_AINT:
5024       gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
5025       break;
5026
5027     case GFC_ISYM_ALL:
5028       gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
5029       break;
5030
5031     case GFC_ISYM_ANINT:
5032       gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
5033       break;
5034
5035     case GFC_ISYM_AND:
5036       gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5037       break;
5038
5039     case GFC_ISYM_ANY:
5040       gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
5041       break;
5042
5043     case GFC_ISYM_BTEST:
5044       gfc_conv_intrinsic_btest (se, expr);
5045       break;
5046
5047     case GFC_ISYM_ACHAR:
5048     case GFC_ISYM_CHAR:
5049       gfc_conv_intrinsic_char (se, expr);
5050       break;
5051
5052     case GFC_ISYM_CONVERSION:
5053     case GFC_ISYM_REAL:
5054     case GFC_ISYM_LOGICAL:
5055     case GFC_ISYM_DBLE:
5056       gfc_conv_intrinsic_conversion (se, expr);
5057       break;
5058
5059       /* Integer conversions are handled separately to make sure we get the
5060          correct rounding mode.  */
5061     case GFC_ISYM_INT:
5062     case GFC_ISYM_INT2:
5063     case GFC_ISYM_INT8:
5064     case GFC_ISYM_LONG:
5065       gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
5066       break;
5067
5068     case GFC_ISYM_NINT:
5069       gfc_conv_intrinsic_int (se, expr, RND_ROUND);
5070       break;
5071
5072     case GFC_ISYM_CEILING:
5073       gfc_conv_intrinsic_int (se, expr, RND_CEIL);
5074       break;
5075
5076     case GFC_ISYM_FLOOR:
5077       gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
5078       break;
5079
5080     case GFC_ISYM_MOD:
5081       gfc_conv_intrinsic_mod (se, expr, 0);
5082       break;
5083
5084     case GFC_ISYM_MODULO:
5085       gfc_conv_intrinsic_mod (se, expr, 1);
5086       break;
5087
5088     case GFC_ISYM_CMPLX:
5089       gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
5090       break;
5091
5092     case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
5093       gfc_conv_intrinsic_iargc (se, expr);
5094       break;
5095
5096     case GFC_ISYM_COMPLEX:
5097       gfc_conv_intrinsic_cmplx (se, expr, 1);
5098       break;
5099
5100     case GFC_ISYM_CONJG:
5101       gfc_conv_intrinsic_conjg (se, expr);
5102       break;
5103
5104     case GFC_ISYM_COUNT:
5105       gfc_conv_intrinsic_count (se, expr);
5106       break;
5107
5108     case GFC_ISYM_CTIME:
5109       gfc_conv_intrinsic_ctime (se, expr);
5110       break;
5111
5112     case GFC_ISYM_DIM:
5113       gfc_conv_intrinsic_dim (se, expr);
5114       break;
5115
5116     case GFC_ISYM_DOT_PRODUCT:
5117       gfc_conv_intrinsic_dot_product (se, expr);
5118       break;
5119
5120     case GFC_ISYM_DPROD:
5121       gfc_conv_intrinsic_dprod (se, expr);
5122       break;
5123
5124     case GFC_ISYM_FDATE:
5125       gfc_conv_intrinsic_fdate (se, expr);
5126       break;
5127
5128     case GFC_ISYM_FRACTION:
5129       gfc_conv_intrinsic_fraction (se, expr);
5130       break;
5131
5132     case GFC_ISYM_IAND:
5133       gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
5134       break;
5135
5136     case GFC_ISYM_IBCLR:
5137       gfc_conv_intrinsic_singlebitop (se, expr, 0);
5138       break;
5139
5140     case GFC_ISYM_IBITS:
5141       gfc_conv_intrinsic_ibits (se, expr);
5142       break;
5143
5144     case GFC_ISYM_IBSET:
5145       gfc_conv_intrinsic_singlebitop (se, expr, 1);
5146       break;
5147
5148     case GFC_ISYM_IACHAR:
5149     case GFC_ISYM_ICHAR:
5150       /* We assume ASCII character sequence.  */
5151       gfc_conv_intrinsic_ichar (se, expr);
5152       break;
5153
5154     case GFC_ISYM_IARGC:
5155       gfc_conv_intrinsic_iargc (se, expr);
5156       break;
5157
5158     case GFC_ISYM_IEOR:
5159       gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
5160       break;
5161
5162     case GFC_ISYM_INDEX:
5163       kind = expr->value.function.actual->expr->ts.kind;
5164       if (kind == 1)
5165        fndecl = gfor_fndecl_string_index;
5166       else if (kind == 4)
5167        fndecl = gfor_fndecl_string_index_char4;
5168       else
5169        gcc_unreachable ();
5170
5171       gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
5172       break;
5173
5174     case GFC_ISYM_IOR:
5175       gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
5176       break;
5177
5178     case GFC_ISYM_IS_IOSTAT_END:
5179       gfc_conv_has_intvalue (se, expr, LIBERROR_END);
5180       break;
5181
5182     case GFC_ISYM_IS_IOSTAT_EOR:
5183       gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
5184       break;
5185
5186     case GFC_ISYM_ISNAN:
5187       gfc_conv_intrinsic_isnan (se, expr);
5188       break;
5189
5190     case GFC_ISYM_LSHIFT:
5191       gfc_conv_intrinsic_rlshift (se, expr, 0);
5192       break;
5193
5194     case GFC_ISYM_RSHIFT:
5195       gfc_conv_intrinsic_rlshift (se, expr, 1);
5196       break;
5197
5198     case GFC_ISYM_ISHFT:
5199       gfc_conv_intrinsic_ishft (se, expr);
5200       break;
5201
5202     case GFC_ISYM_ISHFTC:
5203       gfc_conv_intrinsic_ishftc (se, expr);
5204       break;
5205
5206     case GFC_ISYM_LEADZ:
5207       gfc_conv_intrinsic_leadz (se, expr);
5208       break;
5209
5210     case GFC_ISYM_TRAILZ:
5211       gfc_conv_intrinsic_trailz (se, expr);
5212       break;
5213
5214     case GFC_ISYM_LBOUND:
5215       gfc_conv_intrinsic_bound (se, expr, 0);
5216       break;
5217
5218     case GFC_ISYM_TRANSPOSE:
5219       if (se->ss && se->ss->useflags)
5220         {
5221           gfc_conv_tmp_array_ref (se);
5222           gfc_advance_se_ss_chain (se);
5223         }
5224       else
5225         gfc_conv_array_transpose (se, expr->value.function.actual->expr);
5226       break;
5227
5228     case GFC_ISYM_LEN:
5229       gfc_conv_intrinsic_len (se, expr);
5230       break;
5231
5232     case GFC_ISYM_LEN_TRIM:
5233       gfc_conv_intrinsic_len_trim (se, expr);
5234       break;
5235
5236     case GFC_ISYM_LGE:
5237       gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
5238       break;
5239
5240     case GFC_ISYM_LGT:
5241       gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
5242       break;
5243
5244     case GFC_ISYM_LLE:
5245       gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
5246       break;
5247
5248     case GFC_ISYM_LLT:
5249       gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
5250       break;
5251
5252     case GFC_ISYM_MAX:
5253       if (expr->ts.type == BT_CHARACTER)
5254         gfc_conv_intrinsic_minmax_char (se, expr, 1);
5255       else
5256         gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
5257       break;
5258
5259     case GFC_ISYM_MAXLOC:
5260       gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
5261       break;
5262
5263     case GFC_ISYM_MAXVAL:
5264       gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
5265       break;
5266
5267     case GFC_ISYM_MERGE:
5268       gfc_conv_intrinsic_merge (se, expr);
5269       break;
5270
5271     case GFC_ISYM_MIN:
5272       if (expr->ts.type == BT_CHARACTER)
5273         gfc_conv_intrinsic_minmax_char (se, expr, -1);
5274       else
5275         gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
5276       break;
5277
5278     case GFC_ISYM_MINLOC:
5279       gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
5280       break;
5281
5282     case GFC_ISYM_MINVAL:
5283       gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
5284       break;
5285
5286     case GFC_ISYM_NEAREST:
5287       gfc_conv_intrinsic_nearest (se, expr);
5288       break;
5289
5290     case GFC_ISYM_NOT:
5291       gfc_conv_intrinsic_not (se, expr);
5292       break;
5293
5294     case GFC_ISYM_OR:
5295       gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
5296       break;
5297
5298     case GFC_ISYM_PRESENT:
5299       gfc_conv_intrinsic_present (se, expr);
5300       break;
5301
5302     case GFC_ISYM_PRODUCT:
5303       gfc_conv_intrinsic_arith (se, expr, MULT_EXPR);
5304       break;
5305
5306     case GFC_ISYM_RRSPACING:
5307       gfc_conv_intrinsic_rrspacing (se, expr);
5308       break;
5309
5310     case GFC_ISYM_SET_EXPONENT:
5311       gfc_conv_intrinsic_set_exponent (se, expr);
5312       break;
5313
5314     case GFC_ISYM_SCALE:
5315       gfc_conv_intrinsic_scale (se, expr);
5316       break;
5317
5318     case GFC_ISYM_SIGN:
5319       gfc_conv_intrinsic_sign (se, expr);
5320       break;
5321
5322     case GFC_ISYM_SIZE:
5323       gfc_conv_intrinsic_size (se, expr);
5324       break;
5325
5326     case GFC_ISYM_SIZEOF:
5327     case GFC_ISYM_C_SIZEOF:
5328       gfc_conv_intrinsic_sizeof (se, expr);
5329       break;
5330
5331     case GFC_ISYM_STORAGE_SIZE:
5332       gfc_conv_intrinsic_storage_size (se, expr);
5333       break;
5334
5335     case GFC_ISYM_SPACING:
5336       gfc_conv_intrinsic_spacing (se, expr);
5337       break;
5338
5339     case GFC_ISYM_SUM:
5340       gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR);
5341       break;
5342
5343     case GFC_ISYM_TRANSFER:
5344       if (se->ss && se->ss->useflags)
5345         {
5346           /* Access the previously obtained result.  */
5347           gfc_conv_tmp_array_ref (se);
5348           gfc_advance_se_ss_chain (se);
5349         }
5350       else
5351         gfc_conv_intrinsic_transfer (se, expr);
5352       break;
5353
5354     case GFC_ISYM_TTYNAM:
5355       gfc_conv_intrinsic_ttynam (se, expr);
5356       break;
5357
5358     case GFC_ISYM_UBOUND:
5359       gfc_conv_intrinsic_bound (se, expr, 1);
5360       break;
5361
5362     case GFC_ISYM_XOR:
5363       gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
5364       break;
5365
5366     case GFC_ISYM_LOC:
5367       gfc_conv_intrinsic_loc (se, expr);
5368       break;
5369
5370     case GFC_ISYM_ACCESS:
5371     case GFC_ISYM_CHDIR:
5372     case GFC_ISYM_CHMOD:
5373     case GFC_ISYM_DTIME:
5374     case GFC_ISYM_ETIME:
5375     case GFC_ISYM_EXTENDS_TYPE_OF:
5376     case GFC_ISYM_FGET:
5377     case GFC_ISYM_FGETC:
5378     case GFC_ISYM_FNUM:
5379     case GFC_ISYM_FPUT:
5380     case GFC_ISYM_FPUTC:
5381     case GFC_ISYM_FSTAT:
5382     case GFC_ISYM_FTELL:
5383     case GFC_ISYM_GETCWD:
5384     case GFC_ISYM_GETGID:
5385     case GFC_ISYM_GETPID:
5386     case GFC_ISYM_GETUID:
5387     case GFC_ISYM_HOSTNM:
5388     case GFC_ISYM_KILL:
5389     case GFC_ISYM_IERRNO:
5390     case GFC_ISYM_IRAND:
5391     case GFC_ISYM_ISATTY:
5392     case GFC_ISYM_LINK:
5393     case GFC_ISYM_LSTAT:
5394     case GFC_ISYM_MALLOC:
5395     case GFC_ISYM_MATMUL:
5396     case GFC_ISYM_MCLOCK:
5397     case GFC_ISYM_MCLOCK8:
5398     case GFC_ISYM_RAND:
5399     case GFC_ISYM_RENAME:
5400     case GFC_ISYM_SECOND:
5401     case GFC_ISYM_SECNDS:
5402     case GFC_ISYM_SIGNAL:
5403     case GFC_ISYM_STAT:
5404     case GFC_ISYM_SYMLNK:
5405     case GFC_ISYM_SYSTEM:
5406     case GFC_ISYM_TIME:
5407     case GFC_ISYM_TIME8:
5408     case GFC_ISYM_UMASK:
5409     case GFC_ISYM_UNLINK:
5410       gfc_conv_intrinsic_funcall (se, expr);
5411       break;
5412
5413     case GFC_ISYM_EOSHIFT:
5414     case GFC_ISYM_PACK:
5415     case GFC_ISYM_RESHAPE:
5416       /* For those, expr->rank should always be >0 and thus the if above the
5417          switch should have matched.  */
5418       gcc_unreachable ();
5419       break;
5420
5421     default:
5422       gfc_conv_intrinsic_lib_function (se, expr);
5423       break;
5424     }
5425 }
5426
5427
5428 /* This generates code to execute before entering the scalarization loop.
5429    Currently does nothing.  */
5430
5431 void
5432 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
5433 {
5434   switch (ss->expr->value.function.isym->id)
5435     {
5436     case GFC_ISYM_UBOUND:
5437     case GFC_ISYM_LBOUND:
5438       break;
5439
5440     default:
5441       gcc_unreachable ();
5442     }
5443 }
5444
5445
5446 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
5447    inside the scalarization loop.  */
5448
5449 static gfc_ss *
5450 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
5451 {
5452   gfc_ss *newss;
5453
5454   /* The two argument version returns a scalar.  */
5455   if (expr->value.function.actual->next->expr)
5456     return ss;
5457
5458   newss = gfc_get_ss ();
5459   newss->type = GFC_SS_INTRINSIC;
5460   newss->expr = expr;
5461   newss->next = ss;
5462   newss->data.info.dimen = 1;
5463
5464   return newss;
5465 }
5466
5467
5468 /* Walk an intrinsic array libcall.  */
5469
5470 static gfc_ss *
5471 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
5472 {
5473   gfc_ss *newss;
5474
5475   gcc_assert (expr->rank > 0);
5476
5477   newss = gfc_get_ss ();
5478   newss->type = GFC_SS_FUNCTION;
5479   newss->expr = expr;
5480   newss->next = ss;
5481   newss->data.info.dimen = expr->rank;
5482
5483   return newss;
5484 }
5485
5486
5487 /* Returns nonzero if the specified intrinsic function call maps directly to
5488    an external library call.  Should only be used for functions that return
5489    arrays.  */
5490
5491 int
5492 gfc_is_intrinsic_libcall (gfc_expr * expr)
5493 {
5494   gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
5495   gcc_assert (expr->rank > 0);
5496
5497   switch (expr->value.function.isym->id)
5498     {
5499     case GFC_ISYM_ALL:
5500     case GFC_ISYM_ANY:
5501     case GFC_ISYM_COUNT:
5502     case GFC_ISYM_MATMUL:
5503     case GFC_ISYM_MAXLOC:
5504     case GFC_ISYM_MAXVAL:
5505     case GFC_ISYM_MINLOC:
5506     case GFC_ISYM_MINVAL:
5507     case GFC_ISYM_PRODUCT:
5508     case GFC_ISYM_SUM:
5509     case GFC_ISYM_SHAPE:
5510     case GFC_ISYM_SPREAD:
5511     case GFC_ISYM_TRANSPOSE:
5512       /* Ignore absent optional parameters.  */
5513       return 1;
5514
5515     case GFC_ISYM_RESHAPE:
5516     case GFC_ISYM_CSHIFT:
5517     case GFC_ISYM_EOSHIFT:
5518     case GFC_ISYM_PACK:
5519     case GFC_ISYM_UNPACK:
5520       /* Pass absent optional parameters.  */
5521       return 2;
5522
5523     default:
5524       return 0;
5525     }
5526 }
5527
5528 /* Walk an intrinsic function.  */
5529 gfc_ss *
5530 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
5531                              gfc_intrinsic_sym * isym)
5532 {
5533   gcc_assert (isym);
5534
5535   if (isym->elemental)
5536     return gfc_walk_elemental_function_args (ss, expr->value.function.actual, GFC_SS_SCALAR);
5537
5538   if (expr->rank == 0)
5539     return ss;
5540
5541   if (gfc_is_intrinsic_libcall (expr))
5542     return gfc_walk_intrinsic_libfunc (ss, expr);
5543
5544   /* Special cases.  */
5545   switch (isym->id)
5546     {
5547     case GFC_ISYM_LBOUND:
5548     case GFC_ISYM_UBOUND:
5549       return gfc_walk_intrinsic_bound (ss, expr);
5550
5551     case GFC_ISYM_TRANSFER:
5552       return gfc_walk_intrinsic_libfunc (ss, expr);
5553
5554     default:
5555       /* This probably meant someone forgot to add an intrinsic to the above
5556          list(s) when they implemented it, or something's gone horribly
5557          wrong.  */
5558       gcc_unreachable ();
5559     }
5560 }
5561
5562
5563 tree
5564 gfc_conv_intrinsic_move_alloc (gfc_code *code)
5565 {
5566   if (code->ext.actual->expr->rank == 0)
5567     {
5568       /* Scalar arguments: Generate pointer assignments.  */
5569       gfc_expr *from, *to;
5570       stmtblock_t block;
5571       tree tmp;
5572
5573       from = code->ext.actual->expr;
5574       to = code->ext.actual->next->expr;
5575
5576       gfc_start_block (&block);
5577
5578       if (to->ts.type == BT_CLASS)
5579         tmp = gfc_trans_class_assign (to, from, EXEC_POINTER_ASSIGN);
5580       else
5581         tmp = gfc_trans_pointer_assignment (to, from);
5582       gfc_add_expr_to_block (&block, tmp);
5583
5584       if (from->ts.type == BT_CLASS)
5585         tmp = gfc_trans_class_assign (from, gfc_get_null_expr (NULL),
5586                                       EXEC_POINTER_ASSIGN);
5587       else
5588         tmp = gfc_trans_pointer_assignment (from,
5589                                             gfc_get_null_expr (NULL));
5590       gfc_add_expr_to_block (&block, tmp);
5591
5592       return gfc_finish_block (&block);
5593     }
5594   else
5595     /* Array arguments: Generate library code.  */
5596     return gfc_trans_call (code, false, NULL_TREE, NULL_TREE, false);
5597 }
5598
5599
5600 #include "gt-fortran-trans-intrinsic.h"