OSDN Git Service

2012-01-27 Tobias Burnus <burnus@net-b.de>
[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    2011, 2012
4    Free Software Foundation, Inc.
5    Contributed by Paul Brook <paul@nowt.org>
6    and Steven Bosscher <s.bosscher@student.tudelft.nl>
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics.  */
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"         /* For UNITS_PER_WORD.  */
30 #include "tree.h"
31 #include "ggc.h"
32 #include "diagnostic-core.h"    /* For internal_error.  */
33 #include "toplev.h"     /* For rest_of_decl_compilation.  */
34 #include "flags.h"
35 #include "gfortran.h"
36 #include "arith.h"
37 #include "intrinsic.h"
38 #include "trans.h"
39 #include "trans-const.h"
40 #include "trans-types.h"
41 #include "trans-array.h"
42 #include "defaults.h"
43 /* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */
44 #include "trans-stmt.h"
45
46 /* This maps fortran intrinsic math functions to external library or GCC
47    builtin functions.  */
48 typedef struct GTY(()) gfc_intrinsic_map_t {
49   /* The explicit enum is required to work around inadequacies in the
50      garbage collection/gengtype parsing mechanism.  */
51   enum gfc_isym_id id;
52
53   /* Enum value from the "language-independent", aka C-centric, part
54      of gcc, or END_BUILTINS of no such value set.  */
55   enum built_in_function float_built_in;
56   enum built_in_function double_built_in;
57   enum built_in_function long_double_built_in;
58   enum built_in_function complex_float_built_in;
59   enum built_in_function complex_double_built_in;
60   enum built_in_function complex_long_double_built_in;
61
62   /* True if the naming pattern is to prepend "c" for complex and
63      append "f" for kind=4.  False if the naming pattern is to
64      prepend "_gfortran_" and append "[rc](4|8|10|16)".  */
65   bool libm_name;
66
67   /* True if a complex version of the function exists.  */
68   bool complex_available;
69
70   /* True if the function should be marked const.  */
71   bool is_constant;
72
73   /* The base library name of this function.  */
74   const char *name;
75
76   /* Cache decls created for the various operand types.  */
77   tree real4_decl;
78   tree real8_decl;
79   tree real10_decl;
80   tree real16_decl;
81   tree complex4_decl;
82   tree complex8_decl;
83   tree complex10_decl;
84   tree complex16_decl;
85 }
86 gfc_intrinsic_map_t;
87
88 /* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
89    defines complex variants of all of the entries in mathbuiltins.def
90    except for atan2.  */
91 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
92   { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
93     BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
94     true, false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
95     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
96
97 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
98   { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
99     BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, BUILT_IN_C ## ID, \
100     BUILT_IN_C ## ID ## L, true, true, true, NAME, NULL_TREE, NULL_TREE, \
101     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
102
103 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
104   { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
105     END_BUILTINS, END_BUILTINS, END_BUILTINS, \
106     false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
107     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }
108
109 #define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
110   { GFC_ISYM_NONE, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
111     BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
112     true, false, CONST, NAME, NULL_TREE, NULL_TREE, \
113     NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},
114
115 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
116 {
117   /* Functions built into gcc itself (DEFINE_MATH_BUILTIN and
118      DEFINE_MATH_BUILTIN_C), then the built-ins that don't correspond
119      to any GFC_ISYM id directly, which use the OTHER_BUILTIN macro.  */
120 #include "mathbuiltins.def"
121
122   /* Functions in libgfortran.  */
123   LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),
124
125   /* End the list.  */
126   LIB_FUNCTION (NONE, NULL, false)
127
128 };
129 #undef OTHER_BUILTIN
130 #undef LIB_FUNCTION
131 #undef DEFINE_MATH_BUILTIN
132 #undef DEFINE_MATH_BUILTIN_C
133
134
135 enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };
136
137
138 /* Find the correct variant of a given builtin from its argument.  */
139 static tree
140 builtin_decl_for_precision (enum built_in_function base_built_in,
141                             int precision)
142 {
143   enum built_in_function i = END_BUILTINS;
144
145   gfc_intrinsic_map_t *m;
146   for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
147     ;
148
149   if (precision == TYPE_PRECISION (float_type_node))
150     i = m->float_built_in;
151   else if (precision == TYPE_PRECISION (double_type_node))
152     i = m->double_built_in;
153   else if (precision == TYPE_PRECISION (long_double_type_node))
154     i = m->long_double_built_in;
155   else if (precision == TYPE_PRECISION (float128_type_node))
156     {
157       /* Special treatment, because it is not exactly a built-in, but
158          a library function.  */
159       return m->real16_decl;
160     }
161
162   return (i == END_BUILTINS ? NULL_TREE : builtin_decl_explicit (i));
163 }
164
165
166 tree
167 gfc_builtin_decl_for_float_kind (enum built_in_function double_built_in,
168                                  int kind)
169 {
170   int i = gfc_validate_kind (BT_REAL, kind, false);
171
172   if (gfc_real_kinds[i].c_float128)
173     {
174       /* For __float128, the story is a bit different, because we return
175          a decl to a library function rather than a built-in.  */
176       gfc_intrinsic_map_t *m; 
177       for (m = gfc_intrinsic_map; m->double_built_in != double_built_in ; m++)
178         ;
179
180       return m->real16_decl;
181     }
182
183   return builtin_decl_for_precision (double_built_in,
184                                      gfc_real_kinds[i].mode_precision);
185 }
186
187
188 /* Evaluate the arguments to an intrinsic function.  The value
189    of NARGS may be less than the actual number of arguments in EXPR
190    to allow optional "KIND" arguments that are not included in the
191    generated code to be ignored.  */
192
193 static void
194 gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
195                                   tree *argarray, int nargs)
196 {
197   gfc_actual_arglist *actual;
198   gfc_expr *e;
199   gfc_intrinsic_arg  *formal;
200   gfc_se argse;
201   int curr_arg;
202
203   formal = expr->value.function.isym->formal;
204   actual = expr->value.function.actual;
205
206    for (curr_arg = 0; curr_arg < nargs; curr_arg++,
207         actual = actual->next,
208         formal = formal ? formal->next : NULL)
209     {
210       gcc_assert (actual);
211       e = actual->expr;
212       /* Skip omitted optional arguments.  */
213       if (!e)
214         {
215           --curr_arg;
216           continue;
217         }
218
219       /* Evaluate the parameter.  This will substitute scalarized
220          references automatically.  */
221       gfc_init_se (&argse, se);
222
223       if (e->ts.type == BT_CHARACTER)
224         {
225           gfc_conv_expr (&argse, e);
226           gfc_conv_string_parameter (&argse);
227           argarray[curr_arg++] = argse.string_length;
228           gcc_assert (curr_arg < nargs);
229         }
230       else
231         gfc_conv_expr_val (&argse, e);
232
233       /* If an optional argument is itself an optional dummy argument,
234          check its presence and substitute a null if absent.  */
235       if (e->expr_type == EXPR_VARIABLE
236             && e->symtree->n.sym->attr.optional
237             && formal
238             && formal->optional)
239         gfc_conv_missing_dummy (&argse, e, formal->ts, 0);
240
241       gfc_add_block_to_block (&se->pre, &argse.pre);
242       gfc_add_block_to_block (&se->post, &argse.post);
243       argarray[curr_arg] = argse.expr;
244     }
245 }
246
247 /* Count the number of actual arguments to the intrinsic function EXPR
248    including any "hidden" string length arguments.  */
249
250 static unsigned int
251 gfc_intrinsic_argument_list_length (gfc_expr *expr)
252 {
253   int n = 0;
254   gfc_actual_arglist *actual;
255
256   for (actual = expr->value.function.actual; actual; actual = actual->next)
257     {
258       if (!actual->expr)
259         continue;
260
261       if (actual->expr->ts.type == BT_CHARACTER)
262         n += 2;
263       else
264         n++;
265     }
266
267   return n;
268 }
269
270
271 /* Conversions between different types are output by the frontend as
272    intrinsic functions.  We implement these directly with inline code.  */
273
274 static void
275 gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
276 {
277   tree type;
278   tree *args;
279   int nargs;
280
281   nargs = gfc_intrinsic_argument_list_length (expr);
282   args = XALLOCAVEC (tree, nargs);
283
284   /* Evaluate all the arguments passed. Whilst we're only interested in the 
285      first one here, there are other parts of the front-end that assume this 
286      and will trigger an ICE if it's not the case.  */
287   type = gfc_typenode_for_spec (&expr->ts);
288   gcc_assert (expr->value.function.actual->expr);
289   gfc_conv_intrinsic_function_args (se, expr, args, nargs);
290
291   /* Conversion between character kinds involves a call to a library
292      function.  */
293   if (expr->ts.type == BT_CHARACTER)
294     {
295       tree fndecl, var, addr, tmp;
296
297       if (expr->ts.kind == 1
298           && expr->value.function.actual->expr->ts.kind == 4)
299         fndecl = gfor_fndecl_convert_char4_to_char1;
300       else if (expr->ts.kind == 4
301                && expr->value.function.actual->expr->ts.kind == 1)
302         fndecl = gfor_fndecl_convert_char1_to_char4;
303       else
304         gcc_unreachable ();
305
306       /* Create the variable storing the converted value.  */
307       type = gfc_get_pchar_type (expr->ts.kind);
308       var = gfc_create_var (type, "str");
309       addr = gfc_build_addr_expr (build_pointer_type (type), var);
310
311       /* Call the library function that will perform the conversion.  */
312       gcc_assert (nargs >= 2);
313       tmp = build_call_expr_loc (input_location,
314                              fndecl, 3, addr, args[0], args[1]);
315       gfc_add_expr_to_block (&se->pre, tmp);
316
317       /* Free the temporary afterwards.  */
318       tmp = gfc_call_free (var);
319       gfc_add_expr_to_block (&se->post, tmp);
320
321       se->expr = var;
322       se->string_length = args[0];
323
324       return;
325     }
326
327   /* Conversion from complex to non-complex involves taking the real
328      component of the value.  */
329   if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
330       && expr->ts.type != BT_COMPLEX)
331     {
332       tree artype;
333
334       artype = TREE_TYPE (TREE_TYPE (args[0]));
335       args[0] = fold_build1_loc (input_location, REALPART_EXPR, artype,
336                                  args[0]);
337     }
338
339   se->expr = convert (type, args[0]);
340 }
341
342 /* This is needed because the gcc backend only implements
343    FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
344    FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
345    Similarly for CEILING.  */
346
347 static tree
348 build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
349 {
350   tree tmp;
351   tree cond;
352   tree argtype;
353   tree intval;
354
355   argtype = TREE_TYPE (arg);
356   arg = gfc_evaluate_now (arg, pblock);
357
358   intval = convert (type, arg);
359   intval = gfc_evaluate_now (intval, pblock);
360
361   tmp = convert (argtype, intval);
362   cond = fold_build2_loc (input_location, up ? GE_EXPR : LE_EXPR,
363                           boolean_type_node, tmp, arg);
364
365   tmp = fold_build2_loc (input_location, up ? PLUS_EXPR : MINUS_EXPR, type,
366                          intval, build_int_cst (type, 1));
367   tmp = fold_build3_loc (input_location, COND_EXPR, type, cond, intval, tmp);
368   return tmp;
369 }
370
371
372 /* Round to nearest integer, away from zero.  */
373
374 static tree
375 build_round_expr (tree arg, tree restype)
376 {
377   tree argtype;
378   tree fn;
379   bool longlong;
380   int argprec, resprec;
381
382   argtype = TREE_TYPE (arg);
383   argprec = TYPE_PRECISION (argtype);
384   resprec = TYPE_PRECISION (restype);
385
386   /* Depending on the type of the result, choose the long int intrinsic
387      (lround family) or long long intrinsic (llround).  We might also
388      need to convert the result afterwards.  */
389   if (resprec <= LONG_TYPE_SIZE)
390     longlong = false;
391   else if (resprec <= LONG_LONG_TYPE_SIZE)
392     longlong = true;
393   else
394     gcc_unreachable ();
395
396   /* Now, depending on the argument type, we choose between intrinsics.  */
397   if (longlong)
398     fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
399   else
400     fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
401
402   return fold_convert (restype, build_call_expr_loc (input_location,
403                                                  fn, 1, arg));
404 }
405
406
407 /* Convert a real to an integer using a specific rounding mode.
408    Ideally we would just build the corresponding GENERIC node,
409    however the RTL expander only actually supports FIX_TRUNC_EXPR.  */
410
411 static tree
412 build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
413                enum rounding_mode op)
414 {
415   switch (op)
416     {
417     case RND_FLOOR:
418       return build_fixbound_expr (pblock, arg, type, 0);
419       break;
420
421     case RND_CEIL:
422       return build_fixbound_expr (pblock, arg, type, 1);
423       break;
424
425     case RND_ROUND:
426       return build_round_expr (arg, type);
427       break;
428
429     case RND_TRUNC:
430       return fold_build1_loc (input_location, FIX_TRUNC_EXPR, type, arg);
431       break;
432
433     default:
434       gcc_unreachable ();
435     }
436 }
437
438
439 /* Round a real value using the specified rounding mode.
440    We use a temporary integer of that same kind size as the result.
441    Values larger than those that can be represented by this kind are
442    unchanged, as they will not be accurate enough to represent the
443    rounding.
444     huge = HUGE (KIND (a))
445     aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
446    */
447
448 static void
449 gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
450 {
451   tree type;
452   tree itype;
453   tree arg[2];
454   tree tmp;
455   tree cond;
456   tree decl;
457   mpfr_t huge;
458   int n, nargs;
459   int kind;
460
461   kind = expr->ts.kind;
462   nargs = gfc_intrinsic_argument_list_length (expr);
463
464   decl = NULL_TREE;
465   /* We have builtin functions for some cases.  */
466   switch (op)
467     {
468     case RND_ROUND:
469       decl = gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
470       break;
471
472     case RND_TRUNC:
473       decl = gfc_builtin_decl_for_float_kind (BUILT_IN_TRUNC, kind);
474       break;
475
476     default:
477       gcc_unreachable ();
478     }
479
480   /* Evaluate the argument.  */
481   gcc_assert (expr->value.function.actual->expr);
482   gfc_conv_intrinsic_function_args (se, expr, arg, nargs);
483
484   /* Use a builtin function if one exists.  */
485   if (decl != NULL_TREE)
486     {
487       se->expr = build_call_expr_loc (input_location, decl, 1, arg[0]);
488       return;
489     }
490
491   /* This code is probably redundant, but we'll keep it lying around just
492      in case.  */
493   type = gfc_typenode_for_spec (&expr->ts);
494   arg[0] = gfc_evaluate_now (arg[0], &se->pre);
495
496   /* Test if the value is too large to handle sensibly.  */
497   gfc_set_model_kind (kind);
498   mpfr_init (huge);
499   n = gfc_validate_kind (BT_INTEGER, kind, false);
500   mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
501   tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
502   cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, arg[0],
503                           tmp);
504
505   mpfr_neg (huge, huge, GFC_RND_MODE);
506   tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
507   tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, arg[0],
508                          tmp);
509   cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node,
510                           cond, tmp);
511   itype = gfc_get_int_type (kind);
512
513   tmp = build_fix_expr (&se->pre, arg[0], itype, op);
514   tmp = convert (type, tmp);
515   se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, tmp,
516                               arg[0]);
517   mpfr_clear (huge);
518 }
519
520
521 /* Convert to an integer using the specified rounding mode.  */
522
523 static void
524 gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
525 {
526   tree type;
527   tree *args;
528   int nargs;
529
530   nargs = gfc_intrinsic_argument_list_length (expr);
531   args = XALLOCAVEC (tree, nargs);
532
533   /* Evaluate the argument, we process all arguments even though we only 
534      use the first one for code generation purposes.  */
535   type = gfc_typenode_for_spec (&expr->ts);
536   gcc_assert (expr->value.function.actual->expr);
537   gfc_conv_intrinsic_function_args (se, expr, args, nargs);
538
539   if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
540     {
541       /* Conversion to a different integer kind.  */
542       se->expr = convert (type, args[0]);
543     }
544   else
545     {
546       /* Conversion from complex to non-complex involves taking the real
547          component of the value.  */
548       if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
549           && expr->ts.type != BT_COMPLEX)
550         {
551           tree artype;
552
553           artype = TREE_TYPE (TREE_TYPE (args[0]));
554           args[0] = fold_build1_loc (input_location, REALPART_EXPR, artype,
555                                      args[0]);
556         }
557
558       se->expr = build_fix_expr (&se->pre, args[0], type, op);
559     }
560 }
561
562
563 /* Get the imaginary component of a value.  */
564
565 static void
566 gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
567 {
568   tree arg;
569
570   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
571   se->expr = fold_build1_loc (input_location, IMAGPART_EXPR,
572                               TREE_TYPE (TREE_TYPE (arg)), arg);
573 }
574
575
576 /* Get the complex conjugate of a value.  */
577
578 static void
579 gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
580 {
581   tree arg;
582
583   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
584   se->expr = fold_build1_loc (input_location, CONJ_EXPR, TREE_TYPE (arg), arg);
585 }
586
587
588
589 static tree
590 define_quad_builtin (const char *name, tree type, bool is_const)
591 {
592   tree fndecl;
593   fndecl = build_decl (input_location, FUNCTION_DECL, get_identifier (name),
594                        type);
595
596   /* Mark the decl as external.  */
597   DECL_EXTERNAL (fndecl) = 1;
598   TREE_PUBLIC (fndecl) = 1;
599
600   /* Mark it __attribute__((const)).  */
601   TREE_READONLY (fndecl) = is_const;
602
603   rest_of_decl_compilation (fndecl, 1, 0);
604
605   return fndecl;
606 }
607
608
609
610 /* Initialize function decls for library functions.  The external functions
611    are created as required.  Builtin functions are added here.  */
612
613 void
614 gfc_build_intrinsic_lib_fndecls (void)
615 {
616   gfc_intrinsic_map_t *m;
617   tree quad_decls[END_BUILTINS + 1];
618
619   if (gfc_real16_is_float128)
620   {
621     /* If we have soft-float types, we create the decls for their
622        C99-like library functions.  For now, we only handle __float128
623        q-suffixed functions.  */
624
625     tree type, complex_type, func_1, func_2, func_cabs, func_frexp;
626     tree func_lround, func_llround, func_scalbn, func_cpow;
627
628     memset (quad_decls, 0, sizeof(tree) * (END_BUILTINS + 1));
629
630     type = float128_type_node;
631     complex_type = complex_float128_type_node;
632     /* type (*) (type) */
633     func_1 = build_function_type_list (type, type, NULL_TREE);
634     /* long (*) (type) */
635     func_lround = build_function_type_list (long_integer_type_node,
636                                             type, NULL_TREE);
637     /* long long (*) (type) */
638     func_llround = build_function_type_list (long_long_integer_type_node,
639                                              type, NULL_TREE);
640     /* type (*) (type, type) */
641     func_2 = build_function_type_list (type, type, type, NULL_TREE);
642     /* type (*) (type, &int) */
643     func_frexp
644       = build_function_type_list (type,
645                                   type,
646                                   build_pointer_type (integer_type_node),
647                                   NULL_TREE);
648     /* type (*) (type, int) */
649     func_scalbn = build_function_type_list (type,
650                                             type, integer_type_node, NULL_TREE);
651     /* type (*) (complex type) */
652     func_cabs = build_function_type_list (type, complex_type, NULL_TREE);
653     /* complex type (*) (complex type, complex type) */
654     func_cpow
655       = build_function_type_list (complex_type,
656                                   complex_type, complex_type, NULL_TREE);
657
658 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE)
659 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE)
660 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX)
661
662     /* Only these built-ins are actually needed here. These are used directly
663        from the code, when calling builtin_decl_for_precision() or
664        builtin_decl_for_float_type(). The others are all constructed by
665        gfc_get_intrinsic_lib_fndecl().  */
666 #define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
667   quad_decls[BUILT_IN_ ## ID] = define_quad_builtin (NAME "q", func_ ## TYPE, CONST);
668
669 #include "mathbuiltins.def"
670
671 #undef OTHER_BUILTIN
672 #undef LIB_FUNCTION
673 #undef DEFINE_MATH_BUILTIN
674 #undef DEFINE_MATH_BUILTIN_C
675
676   }
677
678   /* Add GCC builtin functions.  */
679   for (m = gfc_intrinsic_map;
680        m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
681     {
682       if (m->float_built_in != END_BUILTINS)
683         m->real4_decl = builtin_decl_explicit (m->float_built_in);
684       if (m->complex_float_built_in != END_BUILTINS)
685         m->complex4_decl = builtin_decl_explicit (m->complex_float_built_in);
686       if (m->double_built_in != END_BUILTINS)
687         m->real8_decl = builtin_decl_explicit (m->double_built_in);
688       if (m->complex_double_built_in != END_BUILTINS)
689         m->complex8_decl = builtin_decl_explicit (m->complex_double_built_in);
690
691       /* If real(kind=10) exists, it is always long double.  */
692       if (m->long_double_built_in != END_BUILTINS)
693         m->real10_decl = builtin_decl_explicit (m->long_double_built_in);
694       if (m->complex_long_double_built_in != END_BUILTINS)
695         m->complex10_decl
696           = builtin_decl_explicit (m->complex_long_double_built_in);
697
698       if (!gfc_real16_is_float128)
699         {
700           if (m->long_double_built_in != END_BUILTINS)
701             m->real16_decl = builtin_decl_explicit (m->long_double_built_in);
702           if (m->complex_long_double_built_in != END_BUILTINS)
703             m->complex16_decl
704               = builtin_decl_explicit (m->complex_long_double_built_in);
705         }
706       else if (quad_decls[m->double_built_in] != NULL_TREE)
707         {
708           /* Quad-precision function calls are constructed when first
709              needed by builtin_decl_for_precision(), except for those
710              that will be used directly (define by OTHER_BUILTIN).  */
711           m->real16_decl = quad_decls[m->double_built_in];
712         }
713       else if (quad_decls[m->complex_double_built_in] != NULL_TREE)
714         {
715           /* Same thing for the complex ones.  */
716           m->complex16_decl = quad_decls[m->double_built_in];
717         }
718     }
719 }
720
721
722 /* Create a fndecl for a simple intrinsic library function.  */
723
724 static tree
725 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
726 {
727   tree type;
728   VEC(tree,gc) *argtypes;
729   tree fndecl;
730   gfc_actual_arglist *actual;
731   tree *pdecl;
732   gfc_typespec *ts;
733   char name[GFC_MAX_SYMBOL_LEN + 3];
734
735   ts = &expr->ts;
736   if (ts->type == BT_REAL)
737     {
738       switch (ts->kind)
739         {
740         case 4:
741           pdecl = &m->real4_decl;
742           break;
743         case 8:
744           pdecl = &m->real8_decl;
745           break;
746         case 10:
747           pdecl = &m->real10_decl;
748           break;
749         case 16:
750           pdecl = &m->real16_decl;
751           break;
752         default:
753           gcc_unreachable ();
754         }
755     }
756   else if (ts->type == BT_COMPLEX)
757     {
758       gcc_assert (m->complex_available);
759
760       switch (ts->kind)
761         {
762         case 4:
763           pdecl = &m->complex4_decl;
764           break;
765         case 8:
766           pdecl = &m->complex8_decl;
767           break;
768         case 10:
769           pdecl = &m->complex10_decl;
770           break;
771         case 16:
772           pdecl = &m->complex16_decl;
773           break;
774         default:
775           gcc_unreachable ();
776         }
777     }
778   else
779     gcc_unreachable ();
780
781   if (*pdecl)
782     return *pdecl;
783
784   if (m->libm_name)
785     {
786       int n = gfc_validate_kind (BT_REAL, ts->kind, false);
787       if (gfc_real_kinds[n].c_float)
788         snprintf (name, sizeof (name), "%s%s%s",
789                   ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
790       else if (gfc_real_kinds[n].c_double)
791         snprintf (name, sizeof (name), "%s%s",
792                   ts->type == BT_COMPLEX ? "c" : "", m->name);
793       else if (gfc_real_kinds[n].c_long_double)
794         snprintf (name, sizeof (name), "%s%s%s",
795                   ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
796       else if (gfc_real_kinds[n].c_float128)
797         snprintf (name, sizeof (name), "%s%s%s",
798                   ts->type == BT_COMPLEX ? "c" : "", m->name, "q");
799       else
800         gcc_unreachable ();
801     }
802   else
803     {
804       snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
805                 ts->type == BT_COMPLEX ? 'c' : 'r',
806                 ts->kind);
807     }
808
809   argtypes = NULL;
810   for (actual = expr->value.function.actual; actual; actual = actual->next)
811     {
812       type = gfc_typenode_for_spec (&actual->expr->ts);
813       VEC_safe_push (tree, gc, argtypes, type);
814     }
815   type = build_function_type_vec (gfc_typenode_for_spec (ts), argtypes);
816   fndecl = build_decl (input_location,
817                        FUNCTION_DECL, get_identifier (name), type);
818
819   /* Mark the decl as external.  */
820   DECL_EXTERNAL (fndecl) = 1;
821   TREE_PUBLIC (fndecl) = 1;
822
823   /* Mark it __attribute__((const)), if possible.  */
824   TREE_READONLY (fndecl) = m->is_constant;
825
826   rest_of_decl_compilation (fndecl, 1, 0);
827
828   (*pdecl) = fndecl;
829   return fndecl;
830 }
831
832
833 /* Convert an intrinsic function into an external or builtin call.  */
834
835 static void
836 gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
837 {
838   gfc_intrinsic_map_t *m;
839   tree fndecl;
840   tree rettype;
841   tree *args;
842   unsigned int num_args;
843   gfc_isym_id id;
844
845   id = expr->value.function.isym->id;
846   /* Find the entry for this function.  */
847   for (m = gfc_intrinsic_map;
848        m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
849     {
850       if (id == m->id)
851         break;
852     }
853
854   if (m->id == GFC_ISYM_NONE)
855     {
856       internal_error ("Intrinsic function %s(%d) not recognized",
857                       expr->value.function.name, id);
858     }
859
860   /* Get the decl and generate the call.  */
861   num_args = gfc_intrinsic_argument_list_length (expr);
862   args = XALLOCAVEC (tree, num_args);
863
864   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
865   fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
866   rettype = TREE_TYPE (TREE_TYPE (fndecl));
867
868   fndecl = build_addr (fndecl, current_function_decl);
869   se->expr = build_call_array_loc (input_location, rettype, fndecl, num_args, args);
870 }
871
872
873 /* If bounds-checking is enabled, create code to verify at runtime that the
874    string lengths for both expressions are the same (needed for e.g. MERGE).
875    If bounds-checking is not enabled, does nothing.  */
876
877 void
878 gfc_trans_same_strlen_check (const char* intr_name, locus* where,
879                              tree a, tree b, stmtblock_t* target)
880 {
881   tree cond;
882   tree name;
883
884   /* If bounds-checking is disabled, do nothing.  */
885   if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
886     return;
887
888   /* Compare the two string lengths.  */
889   cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, a, b);
890
891   /* Output the runtime-check.  */
892   name = gfc_build_cstring_const (intr_name);
893   name = gfc_build_addr_expr (pchar_type_node, name);
894   gfc_trans_runtime_check (true, false, cond, target, where,
895                            "Unequal character lengths (%ld/%ld) in %s",
896                            fold_convert (long_integer_type_node, a),
897                            fold_convert (long_integer_type_node, b), name);
898 }
899
900
901 /* The EXPONENT(s) intrinsic function is translated into
902        int ret;
903        frexp (s, &ret);
904        return ret;
905  */
906
907 static void
908 gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
909 {
910   tree arg, type, res, tmp, frexp;
911
912   frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP,
913                                        expr->value.function.actual->expr->ts.kind);
914
915   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
916
917   res = gfc_create_var (integer_type_node, NULL);
918   tmp = build_call_expr_loc (input_location, frexp, 2, arg,
919                              gfc_build_addr_expr (NULL_TREE, res));
920   gfc_add_expr_to_block (&se->pre, tmp);
921
922   type = gfc_typenode_for_spec (&expr->ts);
923   se->expr = fold_convert (type, res);
924 }
925
926
927 /* Convert the last ref of a scalar coarray from an AR_ELEMENT to an
928    AR_FULL, suitable for the scalarizer.  */
929
930 static gfc_ss *
931 walk_coarray (gfc_expr *e)
932 {
933   gfc_ss *ss;
934
935   gcc_assert (gfc_get_corank (e) > 0);
936
937   ss = gfc_walk_expr (e);
938
939   /* Fix scalar coarray.  */
940   if (ss == gfc_ss_terminator)
941     {
942       gfc_ref *ref;
943
944       ref = e->ref;
945       while (ref)
946         {
947           if (ref->type == REF_ARRAY
948               && ref->u.ar.codimen > 0)
949             break;
950
951           ref = ref->next;
952         }
953
954       gcc_assert (ref != NULL);
955       if (ref->u.ar.type == AR_ELEMENT)
956         ref->u.ar.type = AR_SECTION;
957       ss = gfc_reverse_ss (gfc_walk_array_ref (ss, e, ref));
958     }
959
960   return ss;
961 }
962
963
964 static void
965 trans_this_image (gfc_se * se, gfc_expr *expr)
966 {
967   stmtblock_t loop;
968   tree type, desc, dim_arg, cond, tmp, m, loop_var, exit_label, min_var,
969        lbound, ubound, extent, ml;
970   gfc_se argse;
971   gfc_ss *ss;
972   int rank, corank;
973
974   /* The case -fcoarray=single is handled elsewhere.  */
975   gcc_assert (gfc_option.coarray != GFC_FCOARRAY_SINGLE);
976
977   gfc_init_coarray_decl (false);
978
979   /* Argument-free version: THIS_IMAGE().  */
980   if (expr->value.function.actual->expr == NULL)
981     {
982       se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind),
983                                gfort_gvar_caf_this_image);
984       return;
985     }
986
987   /* Coarray-argument version: THIS_IMAGE(coarray [, dim]).  */
988
989   type = gfc_get_int_type (gfc_default_integer_kind);
990   corank = gfc_get_corank (expr->value.function.actual->expr);
991   rank = expr->value.function.actual->expr->rank;
992
993   /* Obtain the descriptor of the COARRAY.  */
994   gfc_init_se (&argse, NULL);
995   ss = walk_coarray (expr->value.function.actual->expr);
996   gcc_assert (ss != gfc_ss_terminator);
997   argse.want_coarray = 1;
998   gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss);
999   gfc_add_block_to_block (&se->pre, &argse.pre);
1000   gfc_add_block_to_block (&se->post, &argse.post);
1001   desc = argse.expr;
1002
1003   if (se->ss)
1004     {
1005       /* Create an implicit second parameter from the loop variable.  */
1006       gcc_assert (!expr->value.function.actual->next->expr);
1007       gcc_assert (corank > 0);
1008       gcc_assert (se->loop->dimen == 1);
1009       gcc_assert (se->ss->info->expr == expr);
1010
1011       dim_arg = se->loop->loopvar[0];
1012       dim_arg = fold_build2_loc (input_location, PLUS_EXPR,
1013                                  gfc_array_index_type, dim_arg,
1014                                  build_int_cst (TREE_TYPE (dim_arg), 1));
1015       gfc_advance_se_ss_chain (se);
1016     }
1017   else
1018     {
1019       /* Use the passed DIM= argument.  */
1020       gcc_assert (expr->value.function.actual->next->expr);
1021       gfc_init_se (&argse, NULL);
1022       gfc_conv_expr_type (&argse, expr->value.function.actual->next->expr,
1023                           gfc_array_index_type);
1024       gfc_add_block_to_block (&se->pre, &argse.pre);
1025       dim_arg = argse.expr;
1026
1027       if (INTEGER_CST_P (dim_arg))
1028         {
1029           int hi, co_dim;
1030
1031           hi = TREE_INT_CST_HIGH (dim_arg);
1032           co_dim = TREE_INT_CST_LOW (dim_arg);
1033           if (hi || co_dim < 1
1034               || co_dim > GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc)))
1035             gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
1036                        "dimension index", expr->value.function.isym->name,
1037                        &expr->where);
1038         }
1039      else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1040         {
1041           dim_arg = gfc_evaluate_now (dim_arg, &se->pre);
1042           cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1043                                   dim_arg,
1044                                   build_int_cst (TREE_TYPE (dim_arg), 1));
1045           tmp = gfc_rank_cst[GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))];
1046           tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1047                                  dim_arg, tmp);
1048           cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
1049                                   boolean_type_node, cond, tmp);
1050           gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
1051                                    gfc_msg_fault);
1052         }
1053     }
1054
1055   /* Used algorithm; cf. Fortran 2008, C.10. Note, due to the scalarizer,
1056      one always has a dim_arg argument.
1057
1058      m = this_image() - 1
1059      if (corank == 1)
1060        {
1061          sub(1) = m + lcobound(corank)
1062          return;
1063        }
1064      i = rank
1065      min_var = min (rank + corank - 2, rank + dim_arg - 1)
1066      for (;;)
1067        {
1068          extent = gfc_extent(i)
1069          ml = m
1070          m  = m/extent
1071          if (i >= min_var) 
1072            goto exit_label
1073          i++
1074        }
1075      exit_label:
1076      sub(dim_arg) = (dim_arg < corank) ? ml - m*extent + lcobound(dim_arg)
1077                                        : m + lcobound(corank)
1078   */
1079
1080   /* this_image () - 1.  */
1081   tmp = fold_convert (type, gfort_gvar_caf_this_image);
1082   tmp = fold_build2_loc (input_location, MINUS_EXPR, type, tmp,
1083                        build_int_cst (type, 1));
1084   if (corank == 1)
1085     {
1086       /* sub(1) = m + lcobound(corank).  */
1087       lbound = gfc_conv_descriptor_lbound_get (desc,
1088                         build_int_cst (TREE_TYPE (gfc_array_index_type),
1089                                        corank+rank-1));
1090       lbound = fold_convert (type, lbound);
1091       tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp, lbound);
1092
1093       se->expr = tmp;
1094       return;
1095     }
1096
1097   m = gfc_create_var (type, NULL); 
1098   ml = gfc_create_var (type, NULL); 
1099   loop_var = gfc_create_var (integer_type_node, NULL); 
1100   min_var = gfc_create_var (integer_type_node, NULL); 
1101
1102   /* m = this_image () - 1.  */
1103   gfc_add_modify (&se->pre, m, tmp);
1104
1105   /* min_var = min (rank + corank-2, rank + dim_arg - 1).  */
1106   tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
1107                          fold_convert (integer_type_node, dim_arg),
1108                          build_int_cst (integer_type_node, rank - 1));
1109   tmp = fold_build2_loc (input_location, MIN_EXPR, integer_type_node,
1110                          build_int_cst (integer_type_node, rank + corank - 2),
1111                          tmp);
1112   gfc_add_modify (&se->pre, min_var, tmp);
1113
1114   /* i = rank.  */
1115   tmp = build_int_cst (integer_type_node, rank);
1116   gfc_add_modify (&se->pre, loop_var, tmp);
1117
1118   exit_label = gfc_build_label_decl (NULL_TREE);
1119   TREE_USED (exit_label) = 1;
1120
1121   /* Loop body.  */
1122   gfc_init_block (&loop);
1123
1124   /* ml = m.  */
1125   gfc_add_modify (&loop, ml, m);
1126
1127   /* extent = ...  */
1128   lbound = gfc_conv_descriptor_lbound_get (desc, loop_var);
1129   ubound = gfc_conv_descriptor_ubound_get (desc, loop_var);
1130   extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1131   extent = fold_convert (type, extent);
1132
1133   /* m = m/extent.  */
1134   gfc_add_modify (&loop, m, 
1135                   fold_build2_loc (input_location, TRUNC_DIV_EXPR, type,
1136                           m, extent));
1137
1138   /* Exit condition:  if (i >= min_var) goto exit_label.  */
1139   cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, loop_var,
1140                   min_var);
1141   tmp = build1_v (GOTO_EXPR, exit_label);
1142   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
1143                          build_empty_stmt (input_location));
1144   gfc_add_expr_to_block (&loop, tmp);
1145
1146   /* Increment loop variable: i++.  */
1147   gfc_add_modify (&loop, loop_var,
1148                   fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
1149                                    loop_var,
1150                                    build_int_cst (integer_type_node, 1)));
1151
1152   /* Making the loop... actually loop!  */
1153   tmp = gfc_finish_block (&loop);
1154   tmp = build1_v (LOOP_EXPR, tmp);
1155   gfc_add_expr_to_block (&se->pre, tmp);
1156
1157   /* The exit label.  */
1158   tmp = build1_v (LABEL_EXPR, exit_label);
1159   gfc_add_expr_to_block (&se->pre, tmp);
1160
1161   /*  sub(co_dim) = (co_dim < corank) ? ml - m*extent + lcobound(dim_arg)
1162                                       : m + lcobound(corank) */
1163
1164   cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, dim_arg,
1165                           build_int_cst (TREE_TYPE (dim_arg), corank));
1166
1167   lbound = gfc_conv_descriptor_lbound_get (desc,
1168                 fold_build2_loc (input_location, PLUS_EXPR,
1169                                  gfc_array_index_type, dim_arg,
1170                                  build_int_cst (TREE_TYPE (dim_arg), rank-1)));
1171   lbound = fold_convert (type, lbound);
1172
1173   tmp = fold_build2_loc (input_location, MINUS_EXPR, type, ml,
1174                          fold_build2_loc (input_location, MULT_EXPR, type,
1175                                           m, extent));
1176   tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp, lbound);
1177
1178   se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, tmp,
1179                               fold_build2_loc (input_location, PLUS_EXPR, type,
1180                                                m, lbound));
1181 }
1182
1183
1184 static void
1185 trans_image_index (gfc_se * se, gfc_expr *expr)
1186 {
1187   tree num_images, cond, coindex, type, lbound, ubound, desc, subdesc,
1188        tmp, invalid_bound;
1189   gfc_se argse, subse;
1190   gfc_ss *ss, *subss;
1191   int rank, corank, codim;
1192
1193   type = gfc_get_int_type (gfc_default_integer_kind);
1194   corank = gfc_get_corank (expr->value.function.actual->expr);
1195   rank = expr->value.function.actual->expr->rank;
1196
1197   /* Obtain the descriptor of the COARRAY.  */
1198   gfc_init_se (&argse, NULL);
1199   ss = walk_coarray (expr->value.function.actual->expr);
1200   gcc_assert (ss != gfc_ss_terminator);
1201   argse.want_coarray = 1;
1202   gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss);
1203   gfc_add_block_to_block (&se->pre, &argse.pre);
1204   gfc_add_block_to_block (&se->post, &argse.post);
1205   desc = argse.expr;
1206
1207   /* Obtain a handle to the SUB argument.  */
1208   gfc_init_se (&subse, NULL);
1209   subss = gfc_walk_expr (expr->value.function.actual->next->expr);
1210   gcc_assert (subss != gfc_ss_terminator);
1211   gfc_conv_expr_descriptor (&subse, expr->value.function.actual->next->expr,
1212                             subss);
1213   gfc_add_block_to_block (&se->pre, &subse.pre);
1214   gfc_add_block_to_block (&se->post, &subse.post);
1215   subdesc = build_fold_indirect_ref_loc (input_location,
1216                         gfc_conv_descriptor_data_get (subse.expr));
1217
1218   /* Fortran 2008 does not require that the values remain in the cobounds,
1219      thus we need explicitly check this - and return 0 if they are exceeded.  */
1220
1221   lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[rank+corank-1]);
1222   tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[corank-1], NULL);
1223   invalid_bound = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1224                                  fold_convert (gfc_array_index_type, tmp),
1225                                  lbound);
1226
1227   for (codim = corank + rank - 2; codim >= rank; codim--)
1228     {
1229       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]);
1230       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[codim]);
1231       tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[codim-rank], NULL);
1232       cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1233                               fold_convert (gfc_array_index_type, tmp),
1234                               lbound);
1235       invalid_bound = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1236                                        boolean_type_node, invalid_bound, cond);
1237       cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1238                               fold_convert (gfc_array_index_type, tmp),
1239                               ubound);
1240       invalid_bound = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1241                                        boolean_type_node, invalid_bound, cond);
1242     }
1243
1244   invalid_bound = gfc_unlikely (invalid_bound);
1245
1246
1247   /* See Fortran 2008, C.10 for the following algorithm.  */
1248
1249   /* coindex = sub(corank) - lcobound(n).  */
1250   coindex = fold_convert (gfc_array_index_type,
1251                           gfc_build_array_ref (subdesc, gfc_rank_cst[corank-1],
1252                                                NULL));
1253   lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[rank+corank-1]);
1254   coindex = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
1255                              fold_convert (gfc_array_index_type, coindex),
1256                              lbound);
1257
1258   for (codim = corank + rank - 2; codim >= rank; codim--)
1259     {
1260       tree extent, ubound;
1261
1262       /* coindex = coindex*extent(codim) + sub(codim) - lcobound(codim).  */
1263       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]);
1264       ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[codim]);
1265       extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
1266
1267       /* coindex *= extent.  */
1268       coindex = fold_build2_loc (input_location, MULT_EXPR,
1269                                  gfc_array_index_type, coindex, extent);
1270
1271       /* coindex += sub(codim).  */
1272       tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[codim-rank], NULL);
1273       coindex = fold_build2_loc (input_location, PLUS_EXPR,
1274                                  gfc_array_index_type, coindex,
1275                                  fold_convert (gfc_array_index_type, tmp));
1276
1277       /* coindex -= lbound(codim).  */
1278       lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]);
1279       coindex = fold_build2_loc (input_location, MINUS_EXPR,
1280                                  gfc_array_index_type, coindex, lbound);
1281     }
1282
1283   coindex = fold_build2_loc (input_location, PLUS_EXPR, type,
1284                              fold_convert(type, coindex),
1285                              build_int_cst (type, 1));
1286
1287   /* Return 0 if "coindex" exceeds num_images().  */
1288
1289   if (gfc_option.coarray == GFC_FCOARRAY_SINGLE)
1290     num_images = build_int_cst (type, 1);
1291   else
1292     {
1293       gfc_init_coarray_decl (false);
1294       num_images = fold_convert (type, gfort_gvar_caf_num_images);
1295     }
1296
1297   tmp = gfc_create_var (type, NULL);
1298   gfc_add_modify (&se->pre, tmp, coindex);
1299
1300   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, tmp,
1301                           num_images);
1302   cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, boolean_type_node,
1303                           cond,
1304                           fold_convert (boolean_type_node, invalid_bound));
1305   se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
1306                               build_int_cst (type, 0), tmp);
1307 }
1308
1309
1310 static void
1311 trans_num_images (gfc_se * se)
1312 {
1313   gfc_init_coarray_decl (false);
1314   se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind),
1315                            gfort_gvar_caf_num_images);
1316 }
1317
1318
1319 /* Evaluate a single upper or lower bound.  */
1320 /* TODO: bound intrinsic generates way too much unnecessary code.  */
1321
1322 static void
1323 gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
1324 {
1325   gfc_actual_arglist *arg;
1326   gfc_actual_arglist *arg2;
1327   tree desc;
1328   tree type;
1329   tree bound;
1330   tree tmp;
1331   tree cond, cond1, cond3, cond4, size;
1332   tree ubound;
1333   tree lbound;
1334   gfc_se argse;
1335   gfc_ss *ss;
1336   gfc_array_spec * as;
1337
1338   arg = expr->value.function.actual;
1339   arg2 = arg->next;
1340
1341   if (se->ss)
1342     {
1343       /* Create an implicit second parameter from the loop variable.  */
1344       gcc_assert (!arg2->expr);
1345       gcc_assert (se->loop->dimen == 1);
1346       gcc_assert (se->ss->info->expr == expr);
1347       gfc_advance_se_ss_chain (se);
1348       bound = se->loop->loopvar[0];
1349       bound = fold_build2_loc (input_location, MINUS_EXPR,
1350                                gfc_array_index_type, bound,
1351                                se->loop->from[0]);
1352     }
1353   else
1354     {
1355       /* use the passed argument.  */
1356       gcc_assert (arg2->expr);
1357       gfc_init_se (&argse, NULL);
1358       gfc_conv_expr_type (&argse, arg2->expr, gfc_array_index_type);
1359       gfc_add_block_to_block (&se->pre, &argse.pre);
1360       bound = argse.expr;
1361       /* Convert from one based to zero based.  */
1362       bound = fold_build2_loc (input_location, MINUS_EXPR,
1363                                gfc_array_index_type, bound,
1364                                gfc_index_one_node);
1365     }
1366
1367   /* TODO: don't re-evaluate the descriptor on each iteration.  */
1368   /* Get a descriptor for the first parameter.  */
1369   ss = gfc_walk_expr (arg->expr);
1370   gcc_assert (ss != gfc_ss_terminator);
1371   gfc_init_se (&argse, NULL);
1372   gfc_conv_expr_descriptor (&argse, arg->expr, ss);
1373   gfc_add_block_to_block (&se->pre, &argse.pre);
1374   gfc_add_block_to_block (&se->post, &argse.post);
1375
1376   desc = argse.expr;
1377
1378   if (INTEGER_CST_P (bound))
1379     {
1380       int hi, low;
1381
1382       hi = TREE_INT_CST_HIGH (bound);
1383       low = TREE_INT_CST_LOW (bound);
1384       if (hi || low < 0 || low >= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc)))
1385         gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
1386                    "dimension index", upper ? "UBOUND" : "LBOUND",
1387                    &expr->where);
1388     }
1389   else
1390     {
1391       if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1392         {
1393           bound = gfc_evaluate_now (bound, &se->pre);
1394           cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1395                                   bound, build_int_cst (TREE_TYPE (bound), 0));
1396           tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
1397           tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
1398                                  bound, tmp);
1399           cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
1400                                   boolean_type_node, cond, tmp);
1401           gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
1402                                    gfc_msg_fault);
1403         }
1404     }
1405
1406   ubound = gfc_conv_descriptor_ubound_get (desc, bound);
1407   lbound = gfc_conv_descriptor_lbound_get (desc, bound);
1408   
1409   as = gfc_get_full_arrayspec_from_expr (arg->expr);
1410
1411   /* 13.14.53: Result value for LBOUND
1412
1413      Case (i): For an array section or for an array expression other than a
1414                whole array or array structure component, LBOUND(ARRAY, DIM)
1415                has the value 1.  For a whole array or array structure
1416                component, LBOUND(ARRAY, DIM) has the value:
1417                  (a) equal to the lower bound for subscript DIM of ARRAY if
1418                      dimension DIM of ARRAY does not have extent zero
1419                      or if ARRAY is an assumed-size array of rank DIM,
1420               or (b) 1 otherwise.
1421
1422      13.14.113: Result value for UBOUND
1423
1424      Case (i): For an array section or for an array expression other than a
1425                whole array or array structure component, UBOUND(ARRAY, DIM)
1426                has the value equal to the number of elements in the given
1427                dimension; otherwise, it has a value equal to the upper bound
1428                for subscript DIM of ARRAY if dimension DIM of ARRAY does
1429                not have size zero and has value zero if dimension DIM has
1430                size zero.  */
1431
1432   if (as)
1433     {
1434       tree stride = gfc_conv_descriptor_stride_get (desc, bound);
1435
1436       cond1 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
1437                                ubound, lbound);
1438       cond3 = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
1439                                stride, gfc_index_zero_node);
1440       cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1441                                boolean_type_node, cond3, cond1);
1442       cond4 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1443                                stride, gfc_index_zero_node);
1444
1445       if (upper)
1446         {
1447           tree cond5;
1448           cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1449                                   boolean_type_node, cond3, cond4);
1450           cond5 = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1451                                    gfc_index_one_node, lbound);
1452           cond5 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1453                                    boolean_type_node, cond4, cond5);
1454
1455           cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1456                                   boolean_type_node, cond, cond5);
1457
1458           se->expr = fold_build3_loc (input_location, COND_EXPR,
1459                                       gfc_array_index_type, cond,
1460                                       ubound, gfc_index_zero_node);
1461         }
1462       else
1463         {
1464           if (as->type == AS_ASSUMED_SIZE)
1465             cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1466                                     bound, build_int_cst (TREE_TYPE (bound),
1467                                                           arg->expr->rank - 1));
1468           else
1469             cond = boolean_false_node;
1470
1471           cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1472                                    boolean_type_node, cond3, cond4);
1473           cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
1474                                   boolean_type_node, cond, cond1);
1475
1476           se->expr = fold_build3_loc (input_location, COND_EXPR,
1477                                       gfc_array_index_type, cond,
1478                                       lbound, gfc_index_one_node);
1479         }
1480     }
1481   else
1482     {
1483       if (upper)
1484         {
1485           size = fold_build2_loc (input_location, MINUS_EXPR,
1486                                   gfc_array_index_type, ubound, lbound);
1487           se->expr = fold_build2_loc (input_location, PLUS_EXPR,
1488                                       gfc_array_index_type, size,
1489                                   gfc_index_one_node);
1490           se->expr = fold_build2_loc (input_location, MAX_EXPR,
1491                                       gfc_array_index_type, se->expr,
1492                                       gfc_index_zero_node);
1493         }
1494       else
1495         se->expr = gfc_index_one_node;
1496     }
1497
1498   type = gfc_typenode_for_spec (&expr->ts);
1499   se->expr = convert (type, se->expr);
1500 }
1501
1502
1503 static void
1504 conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
1505 {
1506   gfc_actual_arglist *arg;
1507   gfc_actual_arglist *arg2;
1508   gfc_se argse;
1509   gfc_ss *ss;
1510   tree bound, resbound, resbound2, desc, cond, tmp;
1511   tree type;
1512   int corank;
1513
1514   gcc_assert (expr->value.function.isym->id == GFC_ISYM_LCOBOUND
1515               || expr->value.function.isym->id == GFC_ISYM_UCOBOUND
1516               || expr->value.function.isym->id == GFC_ISYM_THIS_IMAGE);
1517
1518   arg = expr->value.function.actual;
1519   arg2 = arg->next;
1520
1521   gcc_assert (arg->expr->expr_type == EXPR_VARIABLE);
1522   corank = gfc_get_corank (arg->expr);
1523
1524   ss = walk_coarray (arg->expr);
1525   gcc_assert (ss != gfc_ss_terminator);
1526   gfc_init_se (&argse, NULL);
1527   argse.want_coarray = 1;
1528
1529   gfc_conv_expr_descriptor (&argse, arg->expr, ss);
1530   gfc_add_block_to_block (&se->pre, &argse.pre);
1531   gfc_add_block_to_block (&se->post, &argse.post);
1532   desc = argse.expr;
1533
1534   if (se->ss)
1535     {
1536       /* Create an implicit second parameter from the loop variable.  */
1537       gcc_assert (!arg2->expr);
1538       gcc_assert (corank > 0);
1539       gcc_assert (se->loop->dimen == 1);
1540       gcc_assert (se->ss->info->expr == expr);
1541
1542       bound = se->loop->loopvar[0];
1543       bound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
1544                                bound, gfc_rank_cst[arg->expr->rank]);
1545       gfc_advance_se_ss_chain (se);
1546     }
1547   else
1548     {
1549       /* use the passed argument.  */
1550       gcc_assert (arg2->expr);
1551       gfc_init_se (&argse, NULL);
1552       gfc_conv_expr_type (&argse, arg2->expr, gfc_array_index_type);
1553       gfc_add_block_to_block (&se->pre, &argse.pre);
1554       bound = argse.expr;
1555
1556       if (INTEGER_CST_P (bound))
1557         {
1558           int hi, low;
1559
1560           hi = TREE_INT_CST_HIGH (bound);
1561           low = TREE_INT_CST_LOW (bound);
1562           if (hi || low < 1 || low > GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc)))
1563             gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
1564                        "dimension index", expr->value.function.isym->name,
1565                        &expr->where);
1566         }
1567       else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
1568         {
1569           bound = gfc_evaluate_now (bound, &se->pre);
1570           cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1571                                   bound, build_int_cst (TREE_TYPE (bound), 1));
1572           tmp = gfc_rank_cst[GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))];
1573           tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
1574                                  bound, tmp);
1575           cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
1576                                   boolean_type_node, cond, tmp);
1577           gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
1578                                    gfc_msg_fault);
1579         }
1580
1581
1582       /* Substract 1 to get to zero based and add dimensions.  */
1583       switch (arg->expr->rank)
1584         {
1585         case 0:
1586           bound = fold_build2_loc (input_location, MINUS_EXPR,
1587                                    gfc_array_index_type, bound,
1588                                    gfc_index_one_node);
1589         case 1:
1590           break;
1591         default:
1592           bound = fold_build2_loc (input_location, PLUS_EXPR,
1593                                    gfc_array_index_type, bound,
1594                                    gfc_rank_cst[arg->expr->rank - 1]);
1595         }
1596     }
1597
1598   resbound = gfc_conv_descriptor_lbound_get (desc, bound);
1599
1600   /* Handle UCOBOUND with special handling of the last codimension.  */
1601   if (expr->value.function.isym->id == GFC_ISYM_UCOBOUND)
1602     {
1603       /* Last codimension: For -fcoarray=single just return
1604          the lcobound - otherwise add
1605            ceiling (real (num_images ()) / real (size)) - 1
1606          = (num_images () + size - 1) / size - 1
1607          = (num_images - 1) / size(),
1608          where size is the product of the extent of all but the last
1609          codimension.  */
1610
1611       if (gfc_option.coarray != GFC_FCOARRAY_SINGLE && corank > 1)
1612         {
1613           tree cosize;
1614
1615           gfc_init_coarray_decl (false);
1616           cosize = gfc_conv_descriptor_cosize (desc, arg->expr->rank, corank);
1617
1618           tmp = fold_build2_loc (input_location, MINUS_EXPR,
1619                                  gfc_array_index_type,
1620                                  fold_convert (gfc_array_index_type,
1621                                                gfort_gvar_caf_num_images),
1622                                  build_int_cst (gfc_array_index_type, 1));
1623           tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
1624                                  gfc_array_index_type, tmp,
1625                                  fold_convert (gfc_array_index_type, cosize));
1626           resbound = fold_build2_loc (input_location, PLUS_EXPR,
1627                                       gfc_array_index_type, resbound, tmp);
1628         }
1629       else if (gfc_option.coarray != GFC_FCOARRAY_SINGLE)
1630         {
1631           /* ubound = lbound + num_images() - 1.  */
1632           gfc_init_coarray_decl (false);
1633           tmp = fold_build2_loc (input_location, MINUS_EXPR,
1634                                  gfc_array_index_type,
1635                                  fold_convert (gfc_array_index_type,
1636                                                gfort_gvar_caf_num_images),
1637                                  build_int_cst (gfc_array_index_type, 1));
1638           resbound = fold_build2_loc (input_location, PLUS_EXPR,
1639                                       gfc_array_index_type, resbound, tmp);
1640         }
1641
1642       if (corank > 1)
1643         {
1644           cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1645                                   bound,
1646                                   build_int_cst (TREE_TYPE (bound),
1647                                                  arg->expr->rank + corank - 1));
1648
1649           resbound2 = gfc_conv_descriptor_ubound_get (desc, bound);
1650           se->expr = fold_build3_loc (input_location, COND_EXPR,
1651                                       gfc_array_index_type, cond,
1652                                       resbound, resbound2);
1653         }
1654       else
1655         se->expr = resbound;
1656     }
1657   else
1658     se->expr = resbound;
1659
1660   type = gfc_typenode_for_spec (&expr->ts);
1661   se->expr = convert (type, se->expr);
1662 }
1663
1664
1665 static void
1666 gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
1667 {
1668   tree arg, cabs;
1669
1670   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
1671
1672   switch (expr->value.function.actual->expr->ts.type)
1673     {
1674     case BT_INTEGER:
1675     case BT_REAL:
1676       se->expr = fold_build1_loc (input_location, ABS_EXPR, TREE_TYPE (arg),
1677                                   arg);
1678       break;
1679
1680     case BT_COMPLEX:
1681       cabs = gfc_builtin_decl_for_float_kind (BUILT_IN_CABS, expr->ts.kind);
1682       se->expr = build_call_expr_loc (input_location, cabs, 1, arg);
1683       break;
1684
1685     default:
1686       gcc_unreachable ();
1687     }
1688 }
1689
1690
1691 /* Create a complex value from one or two real components.  */
1692
1693 static void
1694 gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
1695 {
1696   tree real;
1697   tree imag;
1698   tree type;
1699   tree *args;
1700   unsigned int num_args;
1701
1702   num_args = gfc_intrinsic_argument_list_length (expr);
1703   args = XALLOCAVEC (tree, num_args);
1704
1705   type = gfc_typenode_for_spec (&expr->ts);
1706   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
1707   real = convert (TREE_TYPE (type), args[0]);
1708   if (both)
1709     imag = convert (TREE_TYPE (type), args[1]);
1710   else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
1711     {
1712       imag = fold_build1_loc (input_location, IMAGPART_EXPR,
1713                               TREE_TYPE (TREE_TYPE (args[0])), args[0]);
1714       imag = convert (TREE_TYPE (type), imag);
1715     }
1716   else
1717     imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
1718
1719   se->expr = fold_build2_loc (input_location, COMPLEX_EXPR, type, real, imag);
1720 }
1721
1722 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1723                       MODULO(A, P) = A - FLOOR (A / P) * P  */
1724 /* TODO: MOD(x, 0)  */
1725
1726 static void
1727 gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
1728 {
1729   tree type;
1730   tree itype;
1731   tree tmp;
1732   tree test;
1733   tree test2;
1734   tree fmod;
1735   mpfr_t huge;
1736   int n, ikind;
1737   tree args[2];
1738
1739   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1740
1741   switch (expr->ts.type)
1742     {
1743     case BT_INTEGER:
1744       /* Integer case is easy, we've got a builtin op.  */
1745       type = TREE_TYPE (args[0]);
1746
1747       if (modulo)
1748        se->expr = fold_build2_loc (input_location, FLOOR_MOD_EXPR, type,
1749                                    args[0], args[1]);
1750       else
1751        se->expr = fold_build2_loc (input_location, TRUNC_MOD_EXPR, type,
1752                                    args[0], args[1]);
1753       break;
1754
1755     case BT_REAL:
1756       fmod = NULL_TREE;
1757       /* Check if we have a builtin fmod.  */
1758       fmod = gfc_builtin_decl_for_float_kind (BUILT_IN_FMOD, expr->ts.kind);
1759
1760       /* Use it if it exists.  */
1761       if (fmod != NULL_TREE)
1762         {
1763           tmp = build_addr (fmod, current_function_decl);
1764           se->expr = build_call_array_loc (input_location,
1765                                        TREE_TYPE (TREE_TYPE (fmod)),
1766                                        tmp, 2, args);
1767           if (modulo == 0)
1768             return;
1769         }
1770
1771       type = TREE_TYPE (args[0]);
1772
1773       args[0] = gfc_evaluate_now (args[0], &se->pre);
1774       args[1] = gfc_evaluate_now (args[1], &se->pre);
1775
1776       /* Definition:
1777          modulo = arg - floor (arg/arg2) * arg2, so
1778                 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2, 
1779          where
1780           test  = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1781          thereby avoiding another division and retaining the accuracy
1782          of the builtin function.  */
1783       if (fmod != NULL_TREE && modulo)
1784         {
1785           tree zero = gfc_build_const (type, integer_zero_node);
1786           tmp = gfc_evaluate_now (se->expr, &se->pre);
1787           test = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1788                                   args[0], zero);
1789           test2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1790                                    args[1], zero);
1791           test2 = fold_build2_loc (input_location, TRUTH_XOR_EXPR,
1792                                    boolean_type_node, test, test2);
1793           test = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
1794                                   tmp, zero);
1795           test = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1796                                   boolean_type_node, test, test2);
1797           test = gfc_evaluate_now (test, &se->pre);
1798           se->expr = fold_build3_loc (input_location, COND_EXPR, type, test,
1799                                   fold_build2_loc (input_location, PLUS_EXPR,
1800                                                    type, tmp, args[1]), tmp);
1801           return;
1802         }
1803
1804       /* If we do not have a built_in fmod, the calculation is going to
1805          have to be done longhand.  */
1806       tmp = fold_build2_loc (input_location, RDIV_EXPR, type, args[0], args[1]);
1807
1808       /* Test if the value is too large to handle sensibly.  */
1809       gfc_set_model_kind (expr->ts.kind);
1810       mpfr_init (huge);
1811       n = gfc_validate_kind (BT_INTEGER, expr->ts.kind, true);
1812       ikind = expr->ts.kind;
1813       if (n < 0)
1814         {
1815           n = gfc_validate_kind (BT_INTEGER, gfc_max_integer_kind, false);
1816           ikind = gfc_max_integer_kind;
1817         }
1818       mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
1819       test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1820       test2 = fold_build2_loc (input_location, LT_EXPR, boolean_type_node,
1821                                tmp, test);
1822
1823       mpfr_neg (huge, huge, GFC_RND_MODE);
1824       test = gfc_conv_mpfr_to_tree (huge, expr->ts.kind, 0);
1825       test = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, tmp,
1826                               test);
1827       test2 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
1828                                boolean_type_node, test, test2);
1829
1830       itype = gfc_get_int_type (ikind);
1831       if (modulo)
1832        tmp = build_fix_expr (&se->pre, tmp, itype, RND_FLOOR);
1833       else
1834        tmp = build_fix_expr (&se->pre, tmp, itype, RND_TRUNC);
1835       tmp = convert (type, tmp);
1836       tmp = fold_build3_loc (input_location, COND_EXPR, type, test2, tmp,
1837                              args[0]);
1838       tmp = fold_build2_loc (input_location, MULT_EXPR, type, tmp, args[1]);
1839       se->expr = fold_build2_loc (input_location, MINUS_EXPR, type, args[0],
1840                                   tmp);
1841       mpfr_clear (huge);
1842       break;
1843
1844     default:
1845       gcc_unreachable ();
1846     }
1847 }
1848
1849 /* DSHIFTL(I,J,S) = (I << S) | (J >> (BITSIZE(J) - S))
1850    DSHIFTR(I,J,S) = (I << (BITSIZE(I) - S)) | (J >> S)
1851    where the right shifts are logical (i.e. 0's are shifted in).
1852    Because SHIFT_EXPR's want shifts strictly smaller than the integral
1853    type width, we have to special-case both S == 0 and S == BITSIZE(J):
1854      DSHIFTL(I,J,0) = I
1855      DSHIFTL(I,J,BITSIZE) = J
1856      DSHIFTR(I,J,0) = J
1857      DSHIFTR(I,J,BITSIZE) = I.  */
1858
1859 static void
1860 gfc_conv_intrinsic_dshift (gfc_se * se, gfc_expr * expr, bool dshiftl)
1861 {
1862   tree type, utype, stype, arg1, arg2, shift, res, left, right;
1863   tree args[3], cond, tmp;
1864   int bitsize;
1865
1866   gfc_conv_intrinsic_function_args (se, expr, args, 3);
1867
1868   gcc_assert (TREE_TYPE (args[0]) == TREE_TYPE (args[1]));
1869   type = TREE_TYPE (args[0]);
1870   bitsize = TYPE_PRECISION (type);
1871   utype = unsigned_type_for (type);
1872   stype = TREE_TYPE (args[2]);
1873
1874   arg1 = gfc_evaluate_now (args[0], &se->pre);
1875   arg2 = gfc_evaluate_now (args[1], &se->pre);
1876   shift = gfc_evaluate_now (args[2], &se->pre);
1877
1878   /* The generic case.  */
1879   tmp = fold_build2_loc (input_location, MINUS_EXPR, stype,
1880                          build_int_cst (stype, bitsize), shift);
1881   left = fold_build2_loc (input_location, LSHIFT_EXPR, type,
1882                           arg1, dshiftl ? shift : tmp);
1883
1884   right = fold_build2_loc (input_location, RSHIFT_EXPR, utype,
1885                            fold_convert (utype, arg2), dshiftl ? tmp : shift);
1886   right = fold_convert (type, right);
1887
1888   res = fold_build2_loc (input_location, BIT_IOR_EXPR, type, left, right);
1889
1890   /* Special cases.  */
1891   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, shift,
1892                           build_int_cst (stype, 0));
1893   res = fold_build3_loc (input_location, COND_EXPR, type, cond,
1894                          dshiftl ? arg1 : arg2, res);
1895
1896   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, shift,
1897                           build_int_cst (stype, bitsize));
1898   res = fold_build3_loc (input_location, COND_EXPR, type, cond,
1899                          dshiftl ? arg2 : arg1, res);
1900
1901   se->expr = res;
1902 }
1903
1904
1905 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y.  */
1906
1907 static void
1908 gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
1909 {
1910   tree val;
1911   tree tmp;
1912   tree type;
1913   tree zero;
1914   tree args[2];
1915
1916   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1917   type = TREE_TYPE (args[0]);
1918
1919   val = fold_build2_loc (input_location, MINUS_EXPR, type, args[0], args[1]);
1920   val = gfc_evaluate_now (val, &se->pre);
1921
1922   zero = gfc_build_const (type, integer_zero_node);
1923   tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node, val, zero);
1924   se->expr = fold_build3_loc (input_location, COND_EXPR, type, tmp, zero, val);
1925 }
1926
1927
1928 /* SIGN(A, B) is absolute value of A times sign of B.
1929    The real value versions use library functions to ensure the correct
1930    handling of negative zero.  Integer case implemented as:
1931    SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1932   */
1933
1934 static void
1935 gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
1936 {
1937   tree tmp;
1938   tree type;
1939   tree args[2];
1940
1941   gfc_conv_intrinsic_function_args (se, expr, args, 2);
1942   if (expr->ts.type == BT_REAL)
1943     {
1944       tree abs;
1945
1946       tmp = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
1947       abs = gfc_builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
1948
1949       /* We explicitly have to ignore the minus sign. We do so by using
1950          result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1).  */
1951       if (!gfc_option.flag_sign_zero
1952           && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
1953         {
1954           tree cond, zero;
1955           zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
1956           cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
1957                                   args[1], zero);
1958           se->expr = fold_build3_loc (input_location, COND_EXPR,
1959                                   TREE_TYPE (args[0]), cond,
1960                                   build_call_expr_loc (input_location, abs, 1,
1961                                                        args[0]),
1962                                   build_call_expr_loc (input_location, tmp, 2,
1963                                                        args[0], args[1]));
1964         }
1965       else
1966         se->expr = build_call_expr_loc (input_location, tmp, 2,
1967                                         args[0], args[1]);
1968       return;
1969     }
1970
1971   /* Having excluded floating point types, we know we are now dealing
1972      with signed integer types.  */
1973   type = TREE_TYPE (args[0]);
1974
1975   /* Args[0] is used multiple times below.  */
1976   args[0] = gfc_evaluate_now (args[0], &se->pre);
1977
1978   /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1979      the signs of A and B are the same, and of all ones if they differ.  */
1980   tmp = fold_build2_loc (input_location, BIT_XOR_EXPR, type, args[0], args[1]);
1981   tmp = fold_build2_loc (input_location, RSHIFT_EXPR, type, tmp,
1982                          build_int_cst (type, TYPE_PRECISION (type) - 1));
1983   tmp = gfc_evaluate_now (tmp, &se->pre);
1984
1985   /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1986      is all ones (i.e. -1).  */
1987   se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, type,
1988                               fold_build2_loc (input_location, PLUS_EXPR,
1989                                                type, args[0], tmp), tmp);
1990 }
1991
1992
1993 /* Test for the presence of an optional argument.  */
1994
1995 static void
1996 gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
1997 {
1998   gfc_expr *arg;
1999
2000   arg = expr->value.function.actual->expr;
2001   gcc_assert (arg->expr_type == EXPR_VARIABLE);
2002   se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
2003   se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
2004 }
2005
2006
2007 /* Calculate the double precision product of two single precision values.  */
2008
2009 static void
2010 gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
2011 {
2012   tree type;
2013   tree args[2];
2014
2015   gfc_conv_intrinsic_function_args (se, expr, args, 2);
2016
2017   /* Convert the args to double precision before multiplying.  */
2018   type = gfc_typenode_for_spec (&expr->ts);
2019   args[0] = convert (type, args[0]);
2020   args[1] = convert (type, args[1]);
2021   se->expr = fold_build2_loc (input_location, MULT_EXPR, type, args[0],
2022                               args[1]);
2023 }
2024
2025
2026 /* Return a length one character string containing an ascii character.  */
2027
2028 static void
2029 gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
2030 {
2031   tree arg[2];
2032   tree var;
2033   tree type;
2034   unsigned int num_args;
2035
2036   num_args = gfc_intrinsic_argument_list_length (expr);
2037   gfc_conv_intrinsic_function_args (se, expr, arg, num_args);
2038
2039   type = gfc_get_char_type (expr->ts.kind);
2040   var = gfc_create_var (type, "char");
2041
2042   arg[0] = fold_build1_loc (input_location, NOP_EXPR, type, arg[0]);
2043   gfc_add_modify (&se->pre, var, arg[0]);
2044   se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
2045   se->string_length = build_int_cst (gfc_charlen_type_node, 1);
2046 }
2047
2048
2049 static void
2050 gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
2051 {
2052   tree var;
2053   tree len;
2054   tree tmp;
2055   tree cond;
2056   tree fndecl;
2057   tree *args;
2058   unsigned int num_args;
2059
2060   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
2061   args = XALLOCAVEC (tree, num_args);
2062
2063   var = gfc_create_var (pchar_type_node, "pstr");
2064   len = gfc_create_var (gfc_charlen_type_node, "len");
2065
2066   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
2067   args[0] = gfc_build_addr_expr (NULL_TREE, var);
2068   args[1] = gfc_build_addr_expr (NULL_TREE, len);
2069
2070   fndecl = build_addr (gfor_fndecl_ctime, current_function_decl);
2071   tmp = build_call_array_loc (input_location,
2072                           TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
2073                           fndecl, num_args, args);
2074   gfc_add_expr_to_block (&se->pre, tmp);
2075
2076   /* Free the temporary afterwards, if necessary.  */
2077   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2078                           len, build_int_cst (TREE_TYPE (len), 0));
2079   tmp = gfc_call_free (var);
2080   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2081   gfc_add_expr_to_block (&se->post, tmp);
2082
2083   se->expr = var;
2084   se->string_length = len;
2085 }
2086
2087
2088 static void
2089 gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
2090 {
2091   tree var;
2092   tree len;
2093   tree tmp;
2094   tree cond;
2095   tree fndecl;
2096   tree *args;
2097   unsigned int num_args;
2098
2099   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
2100   args = XALLOCAVEC (tree, num_args);
2101
2102   var = gfc_create_var (pchar_type_node, "pstr");
2103   len = gfc_create_var (gfc_charlen_type_node, "len");
2104
2105   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
2106   args[0] = gfc_build_addr_expr (NULL_TREE, var);
2107   args[1] = gfc_build_addr_expr (NULL_TREE, len);
2108
2109   fndecl = build_addr (gfor_fndecl_fdate, current_function_decl);
2110   tmp = build_call_array_loc (input_location,
2111                           TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
2112                           fndecl, num_args, args);
2113   gfc_add_expr_to_block (&se->pre, tmp);
2114
2115   /* Free the temporary afterwards, if necessary.  */
2116   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2117                           len, build_int_cst (TREE_TYPE (len), 0));
2118   tmp = gfc_call_free (var);
2119   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2120   gfc_add_expr_to_block (&se->post, tmp);
2121
2122   se->expr = var;
2123   se->string_length = len;
2124 }
2125
2126
2127 /* Return a character string containing the tty name.  */
2128
2129 static void
2130 gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
2131 {
2132   tree var;
2133   tree len;
2134   tree tmp;
2135   tree cond;
2136   tree fndecl;
2137   tree *args;
2138   unsigned int num_args;
2139
2140   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
2141   args = XALLOCAVEC (tree, num_args);
2142
2143   var = gfc_create_var (pchar_type_node, "pstr");
2144   len = gfc_create_var (gfc_charlen_type_node, "len");
2145
2146   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
2147   args[0] = gfc_build_addr_expr (NULL_TREE, var);
2148   args[1] = gfc_build_addr_expr (NULL_TREE, len);
2149
2150   fndecl = build_addr (gfor_fndecl_ttynam, current_function_decl);
2151   tmp = build_call_array_loc (input_location,
2152                           TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
2153                           fndecl, num_args, args);
2154   gfc_add_expr_to_block (&se->pre, tmp);
2155
2156   /* Free the temporary afterwards, if necessary.  */
2157   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2158                           len, build_int_cst (TREE_TYPE (len), 0));
2159   tmp = gfc_call_free (var);
2160   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2161   gfc_add_expr_to_block (&se->post, tmp);
2162
2163   se->expr = var;
2164   se->string_length = len;
2165 }
2166
2167
2168 /* Get the minimum/maximum value of all the parameters.
2169     minmax (a1, a2, a3, ...)
2170     {
2171       mvar = a1;
2172       if (a2 .op. mvar || isnan(mvar))
2173         mvar = a2;
2174       if (a3 .op. mvar || isnan(mvar))
2175         mvar = a3;
2176       ...
2177       return mvar
2178     }
2179  */
2180
2181 /* TODO: Mismatching types can occur when specific names are used.
2182    These should be handled during resolution.  */
2183 static void
2184 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
2185 {
2186   tree tmp;
2187   tree mvar;
2188   tree val;
2189   tree thencase;
2190   tree *args;
2191   tree type;
2192   gfc_actual_arglist *argexpr;
2193   unsigned int i, nargs;
2194
2195   nargs = gfc_intrinsic_argument_list_length (expr);
2196   args = XALLOCAVEC (tree, nargs);
2197
2198   gfc_conv_intrinsic_function_args (se, expr, args, nargs);
2199   type = gfc_typenode_for_spec (&expr->ts);
2200
2201   argexpr = expr->value.function.actual;
2202   if (TREE_TYPE (args[0]) != type)
2203     args[0] = convert (type, args[0]);
2204   /* Only evaluate the argument once.  */
2205   if (TREE_CODE (args[0]) != VAR_DECL && !TREE_CONSTANT (args[0]))
2206     args[0] = gfc_evaluate_now (args[0], &se->pre);
2207
2208   mvar = gfc_create_var (type, "M");
2209   gfc_add_modify (&se->pre, mvar, args[0]);
2210   for (i = 1, argexpr = argexpr->next; i < nargs; i++)
2211     {
2212       tree cond, isnan;
2213
2214       val = args[i]; 
2215
2216       /* Handle absent optional arguments by ignoring the comparison.  */
2217       if (argexpr->expr->expr_type == EXPR_VARIABLE
2218           && argexpr->expr->symtree->n.sym->attr.optional
2219           && TREE_CODE (val) == INDIRECT_REF)
2220         cond = fold_build2_loc (input_location,
2221                                 NE_EXPR, boolean_type_node,
2222                                 TREE_OPERAND (val, 0), 
2223                         build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
2224       else
2225       {
2226         cond = NULL_TREE;
2227
2228         /* Only evaluate the argument once.  */
2229         if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
2230           val = gfc_evaluate_now (val, &se->pre);
2231       }
2232
2233       thencase = build2_v (MODIFY_EXPR, mvar, convert (type, val));
2234
2235       tmp = fold_build2_loc (input_location, op, boolean_type_node,
2236                              convert (type, val), mvar);
2237
2238       /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
2239          __builtin_isnan might be made dependent on that module being loaded,
2240          to help performance of programs that don't rely on IEEE semantics.  */
2241       if (FLOAT_TYPE_P (TREE_TYPE (mvar)))
2242         {
2243           isnan = build_call_expr_loc (input_location,
2244                                        builtin_decl_explicit (BUILT_IN_ISNAN),
2245                                        1, mvar);
2246           tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
2247                                  boolean_type_node, tmp,
2248                                  fold_convert (boolean_type_node, isnan));
2249         }
2250       tmp = build3_v (COND_EXPR, tmp, thencase,
2251                       build_empty_stmt (input_location));
2252
2253       if (cond != NULL_TREE)
2254         tmp = build3_v (COND_EXPR, cond, tmp,
2255                         build_empty_stmt (input_location));
2256
2257       gfc_add_expr_to_block (&se->pre, tmp);
2258       argexpr = argexpr->next;
2259     }
2260   se->expr = mvar;
2261 }
2262
2263
2264 /* Generate library calls for MIN and MAX intrinsics for character
2265    variables.  */
2266 static void
2267 gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
2268 {
2269   tree *args;
2270   tree var, len, fndecl, tmp, cond, function;
2271   unsigned int nargs;
2272
2273   nargs = gfc_intrinsic_argument_list_length (expr);
2274   args = XALLOCAVEC (tree, nargs + 4);
2275   gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);
2276
2277   /* Create the result variables.  */
2278   len = gfc_create_var (gfc_charlen_type_node, "len");
2279   args[0] = gfc_build_addr_expr (NULL_TREE, len);
2280   var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
2281   args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
2282   args[2] = build_int_cst (integer_type_node, op);
2283   args[3] = build_int_cst (integer_type_node, nargs / 2);
2284
2285   if (expr->ts.kind == 1)
2286     function = gfor_fndecl_string_minmax;
2287   else if (expr->ts.kind == 4)
2288     function = gfor_fndecl_string_minmax_char4;
2289   else
2290     gcc_unreachable ();
2291
2292   /* Make the function call.  */
2293   fndecl = build_addr (function, current_function_decl);
2294   tmp = build_call_array_loc (input_location,
2295                           TREE_TYPE (TREE_TYPE (function)), fndecl,
2296                           nargs + 4, args);
2297   gfc_add_expr_to_block (&se->pre, tmp);
2298
2299   /* Free the temporary afterwards, if necessary.  */
2300   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2301                           len, build_int_cst (TREE_TYPE (len), 0));
2302   tmp = gfc_call_free (var);
2303   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2304   gfc_add_expr_to_block (&se->post, tmp);
2305
2306   se->expr = var;
2307   se->string_length = len;
2308 }
2309
2310
2311 /* Create a symbol node for this intrinsic.  The symbol from the frontend
2312    has the generic name.  */
2313
2314 static gfc_symbol *
2315 gfc_get_symbol_for_expr (gfc_expr * expr)
2316 {
2317   gfc_symbol *sym;
2318
2319   /* TODO: Add symbols for intrinsic function to the global namespace.  */
2320   gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
2321   sym = gfc_new_symbol (expr->value.function.name, NULL);
2322
2323   sym->ts = expr->ts;
2324   sym->attr.external = 1;
2325   sym->attr.function = 1;
2326   sym->attr.always_explicit = 1;
2327   sym->attr.proc = PROC_INTRINSIC;
2328   sym->attr.flavor = FL_PROCEDURE;
2329   sym->result = sym;
2330   if (expr->rank > 0)
2331     {
2332       sym->attr.dimension = 1;
2333       sym->as = gfc_get_array_spec ();
2334       sym->as->type = AS_ASSUMED_SHAPE;
2335       sym->as->rank = expr->rank;
2336     }
2337
2338   gfc_copy_formal_args_intr (sym, expr->value.function.isym);
2339
2340   return sym;
2341 }
2342
2343 /* Generate a call to an external intrinsic function.  */
2344 static void
2345 gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
2346 {
2347   gfc_symbol *sym;
2348   VEC(tree,gc) *append_args;
2349
2350   gcc_assert (!se->ss || se->ss->info->expr == expr);
2351
2352   if (se->ss)
2353     gcc_assert (expr->rank > 0);
2354   else
2355     gcc_assert (expr->rank == 0);
2356
2357   sym = gfc_get_symbol_for_expr (expr);
2358
2359   /* Calls to libgfortran_matmul need to be appended special arguments,
2360      to be able to call the BLAS ?gemm functions if required and possible.  */
2361   append_args = NULL;
2362   if (expr->value.function.isym->id == GFC_ISYM_MATMUL
2363       && sym->ts.type != BT_LOGICAL)
2364     {
2365       tree cint = gfc_get_int_type (gfc_c_int_kind);
2366
2367       if (gfc_option.flag_external_blas
2368           && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
2369           && (sym->ts.kind == gfc_default_real_kind
2370               || sym->ts.kind == gfc_default_double_kind))
2371         {
2372           tree gemm_fndecl;
2373
2374           if (sym->ts.type == BT_REAL)
2375             {
2376               if (sym->ts.kind == gfc_default_real_kind)
2377                 gemm_fndecl = gfor_fndecl_sgemm;
2378               else
2379                 gemm_fndecl = gfor_fndecl_dgemm;
2380             }
2381           else
2382             {
2383               if (sym->ts.kind == gfc_default_real_kind)
2384                 gemm_fndecl = gfor_fndecl_cgemm;
2385               else
2386                 gemm_fndecl = gfor_fndecl_zgemm;
2387             }
2388
2389           append_args = VEC_alloc (tree, gc, 3);
2390           VEC_quick_push (tree, append_args, build_int_cst (cint, 1));
2391           VEC_quick_push (tree, append_args,
2392                           build_int_cst (cint, gfc_option.blas_matmul_limit));
2393           VEC_quick_push (tree, append_args,
2394                           gfc_build_addr_expr (NULL_TREE, gemm_fndecl));
2395         }
2396       else
2397         {
2398           append_args = VEC_alloc (tree, gc, 3);
2399           VEC_quick_push (tree, append_args, build_int_cst (cint, 0));
2400           VEC_quick_push (tree, append_args, build_int_cst (cint, 0));
2401           VEC_quick_push (tree, append_args, null_pointer_node);
2402         }
2403     }
2404
2405   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
2406                           append_args);
2407   gfc_free_symbol (sym);
2408 }
2409
2410 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
2411    Implemented as
2412     any(a)
2413     {
2414       forall (i=...)
2415         if (a[i] != 0)
2416           return 1
2417       end forall
2418       return 0
2419     }
2420     all(a)
2421     {
2422       forall (i=...)
2423         if (a[i] == 0)
2424           return 0
2425       end forall
2426       return 1
2427     }
2428  */
2429 static void
2430 gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
2431 {
2432   tree resvar;
2433   stmtblock_t block;
2434   stmtblock_t body;
2435   tree type;
2436   tree tmp;
2437   tree found;
2438   gfc_loopinfo loop;
2439   gfc_actual_arglist *actual;
2440   gfc_ss *arrayss;
2441   gfc_se arrayse;
2442   tree exit_label;
2443
2444   if (se->ss)
2445     {
2446       gfc_conv_intrinsic_funcall (se, expr);
2447       return;
2448     }
2449
2450   actual = expr->value.function.actual;
2451   type = gfc_typenode_for_spec (&expr->ts);
2452   /* Initialize the result.  */
2453   resvar = gfc_create_var (type, "test");
2454   if (op == EQ_EXPR)
2455     tmp = convert (type, boolean_true_node);
2456   else
2457     tmp = convert (type, boolean_false_node);
2458   gfc_add_modify (&se->pre, resvar, tmp);
2459
2460   /* Walk the arguments.  */
2461   arrayss = gfc_walk_expr (actual->expr);
2462   gcc_assert (arrayss != gfc_ss_terminator);
2463
2464   /* Initialize the scalarizer.  */
2465   gfc_init_loopinfo (&loop);
2466   exit_label = gfc_build_label_decl (NULL_TREE);
2467   TREE_USED (exit_label) = 1;
2468   gfc_add_ss_to_loop (&loop, arrayss);
2469
2470   /* Initialize the loop.  */
2471   gfc_conv_ss_startstride (&loop);
2472   gfc_conv_loop_setup (&loop, &expr->where);
2473
2474   gfc_mark_ss_chain_used (arrayss, 1);
2475   /* Generate the loop body.  */
2476   gfc_start_scalarized_body (&loop, &body);
2477
2478   /* If the condition matches then set the return value.  */
2479   gfc_start_block (&block);
2480   if (op == EQ_EXPR)
2481     tmp = convert (type, boolean_false_node);
2482   else
2483     tmp = convert (type, boolean_true_node);
2484   gfc_add_modify (&block, resvar, tmp);
2485
2486   /* And break out of the loop.  */
2487   tmp = build1_v (GOTO_EXPR, exit_label);
2488   gfc_add_expr_to_block (&block, tmp);
2489
2490   found = gfc_finish_block (&block);
2491
2492   /* Check this element.  */
2493   gfc_init_se (&arrayse, NULL);
2494   gfc_copy_loopinfo_to_se (&arrayse, &loop);
2495   arrayse.ss = arrayss;
2496   gfc_conv_expr_val (&arrayse, actual->expr);
2497
2498   gfc_add_block_to_block (&body, &arrayse.pre);
2499   tmp = fold_build2_loc (input_location, op, boolean_type_node, arrayse.expr,
2500                          build_int_cst (TREE_TYPE (arrayse.expr), 0));
2501   tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
2502   gfc_add_expr_to_block (&body, tmp);
2503   gfc_add_block_to_block (&body, &arrayse.post);
2504
2505   gfc_trans_scalarizing_loops (&loop, &body);
2506
2507   /* Add the exit label.  */
2508   tmp = build1_v (LABEL_EXPR, exit_label);
2509   gfc_add_expr_to_block (&loop.pre, tmp);
2510
2511   gfc_add_block_to_block (&se->pre, &loop.pre);
2512   gfc_add_block_to_block (&se->pre, &loop.post);
2513   gfc_cleanup_loop (&loop);
2514
2515   se->expr = resvar;
2516 }
2517
2518 /* COUNT(A) = Number of true elements in A.  */
2519 static void
2520 gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
2521 {
2522   tree resvar;
2523   tree type;
2524   stmtblock_t body;
2525   tree tmp;
2526   gfc_loopinfo loop;
2527   gfc_actual_arglist *actual;
2528   gfc_ss *arrayss;
2529   gfc_se arrayse;
2530
2531   if (se->ss)
2532     {
2533       gfc_conv_intrinsic_funcall (se, expr);
2534       return;
2535     }
2536
2537   actual = expr->value.function.actual;
2538
2539   type = gfc_typenode_for_spec (&expr->ts);
2540   /* Initialize the result.  */
2541   resvar = gfc_create_var (type, "count");
2542   gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));
2543
2544   /* Walk the arguments.  */
2545   arrayss = gfc_walk_expr (actual->expr);
2546   gcc_assert (arrayss != gfc_ss_terminator);
2547
2548   /* Initialize the scalarizer.  */
2549   gfc_init_loopinfo (&loop);
2550   gfc_add_ss_to_loop (&loop, arrayss);
2551
2552   /* Initialize the loop.  */
2553   gfc_conv_ss_startstride (&loop);
2554   gfc_conv_loop_setup (&loop, &expr->where);
2555
2556   gfc_mark_ss_chain_used (arrayss, 1);
2557   /* Generate the loop body.  */
2558   gfc_start_scalarized_body (&loop, &body);
2559
2560   tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (resvar),
2561                          resvar, build_int_cst (TREE_TYPE (resvar), 1));
2562   tmp = build2_v (MODIFY_EXPR, resvar, tmp);
2563
2564   gfc_init_se (&arrayse, NULL);
2565   gfc_copy_loopinfo_to_se (&arrayse, &loop);
2566   arrayse.ss = arrayss;
2567   gfc_conv_expr_val (&arrayse, actual->expr);
2568   tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
2569                   build_empty_stmt (input_location));
2570
2571   gfc_add_block_to_block (&body, &arrayse.pre);
2572   gfc_add_expr_to_block (&body, tmp);
2573   gfc_add_block_to_block (&body, &arrayse.post);
2574
2575   gfc_trans_scalarizing_loops (&loop, &body);
2576
2577   gfc_add_block_to_block (&se->pre, &loop.pre);
2578   gfc_add_block_to_block (&se->pre, &loop.post);
2579   gfc_cleanup_loop (&loop);
2580
2581   se->expr = resvar;
2582 }
2583
2584
2585 /* Update given gfc_se to have ss component pointing to the nested gfc_ss
2586    struct and return the corresponding loopinfo.  */
2587
2588 static gfc_loopinfo *
2589 enter_nested_loop (gfc_se *se)
2590 {
2591   se->ss = se->ss->nested_ss;
2592   gcc_assert (se->ss == se->ss->loop->ss);
2593
2594   return se->ss->loop;
2595 }
2596
2597
2598 /* Inline implementation of the sum and product intrinsics.  */
2599 static void
2600 gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op,
2601                           bool norm2)
2602 {
2603   tree resvar;
2604   tree scale = NULL_TREE;
2605   tree type;
2606   stmtblock_t body;
2607   stmtblock_t block;
2608   tree tmp;
2609   gfc_loopinfo loop, *ploop;
2610   gfc_actual_arglist *arg_array, *arg_mask;
2611   gfc_ss *arrayss = NULL;
2612   gfc_ss *maskss = NULL;
2613   gfc_se arrayse;
2614   gfc_se maskse;
2615   gfc_se *parent_se;
2616   gfc_expr *arrayexpr;
2617   gfc_expr *maskexpr;
2618
2619   if (expr->rank > 0)
2620     {
2621       gcc_assert (gfc_inline_intrinsic_function_p (expr));
2622       parent_se = se;
2623     }
2624   else
2625     parent_se = NULL;
2626
2627   type = gfc_typenode_for_spec (&expr->ts);
2628   /* Initialize the result.  */
2629   resvar = gfc_create_var (type, "val");
2630   if (norm2)
2631     {
2632       /* result = 0.0;
2633          scale = 1.0.  */
2634       scale = gfc_create_var (type, "scale");
2635       gfc_add_modify (&se->pre, scale,
2636                       gfc_build_const (type, integer_one_node));
2637       tmp = gfc_build_const (type, integer_zero_node);
2638     }
2639   else if (op == PLUS_EXPR || op == BIT_IOR_EXPR || op == BIT_XOR_EXPR)
2640     tmp = gfc_build_const (type, integer_zero_node);
2641   else if (op == NE_EXPR)
2642     /* PARITY.  */
2643     tmp = convert (type, boolean_false_node);
2644   else if (op == BIT_AND_EXPR)
2645     tmp = gfc_build_const (type, fold_build1_loc (input_location, NEGATE_EXPR,
2646                                                   type, integer_one_node));
2647   else
2648     tmp = gfc_build_const (type, integer_one_node);
2649
2650   gfc_add_modify (&se->pre, resvar, tmp);
2651
2652   arg_array = expr->value.function.actual;
2653
2654   arrayexpr = arg_array->expr;
2655
2656   if (op == NE_EXPR || norm2)
2657     /* PARITY and NORM2.  */
2658     maskexpr = NULL;
2659   else
2660     {
2661       arg_mask  = arg_array->next->next;
2662       gcc_assert (arg_mask != NULL);
2663       maskexpr = arg_mask->expr;
2664     }
2665
2666   if (expr->rank == 0)
2667     {
2668       /* Walk the arguments.  */
2669       arrayss = gfc_walk_expr (arrayexpr);
2670       gcc_assert (arrayss != gfc_ss_terminator);
2671
2672       if (maskexpr && maskexpr->rank > 0)
2673         {
2674           maskss = gfc_walk_expr (maskexpr);
2675           gcc_assert (maskss != gfc_ss_terminator);
2676         }
2677       else
2678         maskss = NULL;
2679
2680       /* Initialize the scalarizer.  */
2681       gfc_init_loopinfo (&loop);
2682       gfc_add_ss_to_loop (&loop, arrayss);
2683       if (maskexpr && maskexpr->rank > 0)
2684         gfc_add_ss_to_loop (&loop, maskss);
2685
2686       /* Initialize the loop.  */
2687       gfc_conv_ss_startstride (&loop);
2688       gfc_conv_loop_setup (&loop, &expr->where);
2689
2690       gfc_mark_ss_chain_used (arrayss, 1);
2691       if (maskexpr && maskexpr->rank > 0)
2692         gfc_mark_ss_chain_used (maskss, 1);
2693
2694       ploop = &loop;
2695     }
2696   else
2697     /* All the work has been done in the parent loops.  */
2698     ploop = enter_nested_loop (se);
2699
2700   gcc_assert (ploop);
2701
2702   /* Generate the loop body.  */
2703   gfc_start_scalarized_body (ploop, &body);
2704
2705   /* If we have a mask, only add this element if the mask is set.  */
2706   if (maskexpr && maskexpr->rank > 0)
2707     {
2708       gfc_init_se (&maskse, parent_se);
2709       gfc_copy_loopinfo_to_se (&maskse, ploop);
2710       if (expr->rank == 0)
2711         maskse.ss = maskss;
2712       gfc_conv_expr_val (&maskse, maskexpr);
2713       gfc_add_block_to_block (&body, &maskse.pre);
2714
2715       gfc_start_block (&block);
2716     }
2717   else
2718     gfc_init_block (&block);
2719
2720   /* Do the actual summation/product.  */
2721   gfc_init_se (&arrayse, parent_se);
2722   gfc_copy_loopinfo_to_se (&arrayse, ploop);
2723   if (expr->rank == 0)
2724     arrayse.ss = arrayss;
2725   gfc_conv_expr_val (&arrayse, arrayexpr);
2726   gfc_add_block_to_block (&block, &arrayse.pre);
2727
2728   if (norm2)
2729     {
2730       /* if (x(i) != 0.0)
2731            {
2732              absX = abs(x(i))
2733              if (absX > scale)
2734                {
2735                  val = scale/absX;
2736                  result = 1.0 + result * val * val;
2737                  scale = absX;
2738                }
2739              else
2740                {
2741                  val = absX/scale;
2742                  result += val * val;
2743                }
2744            }  */
2745       tree res1, res2, cond, absX, val;
2746       stmtblock_t ifblock1, ifblock2, ifblock3;
2747
2748       gfc_init_block (&ifblock1);
2749
2750       absX = gfc_create_var (type, "absX");
2751       gfc_add_modify (&ifblock1, absX,
2752                       fold_build1_loc (input_location, ABS_EXPR, type,
2753                                        arrayse.expr));
2754       val = gfc_create_var (type, "val");
2755       gfc_add_expr_to_block (&ifblock1, val);
2756
2757       gfc_init_block (&ifblock2);
2758       gfc_add_modify (&ifblock2, val,
2759                       fold_build2_loc (input_location, RDIV_EXPR, type, scale,
2760                                        absX));
2761       res1 = fold_build2_loc (input_location, MULT_EXPR, type, val, val); 
2762       res1 = fold_build2_loc (input_location, MULT_EXPR, type, resvar, res1);
2763       res1 = fold_build2_loc (input_location, PLUS_EXPR, type, res1,
2764                               gfc_build_const (type, integer_one_node));
2765       gfc_add_modify (&ifblock2, resvar, res1);
2766       gfc_add_modify (&ifblock2, scale, absX);
2767       res1 = gfc_finish_block (&ifblock2); 
2768
2769       gfc_init_block (&ifblock3);
2770       gfc_add_modify (&ifblock3, val,
2771                       fold_build2_loc (input_location, RDIV_EXPR, type, absX,
2772                                        scale));
2773       res2 = fold_build2_loc (input_location, MULT_EXPR, type, val, val); 
2774       res2 = fold_build2_loc (input_location, PLUS_EXPR, type, resvar, res2);
2775       gfc_add_modify (&ifblock3, resvar, res2);
2776       res2 = gfc_finish_block (&ifblock3);
2777
2778       cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
2779                               absX, scale);
2780       tmp = build3_v (COND_EXPR, cond, res1, res2);
2781       gfc_add_expr_to_block (&ifblock1, tmp);  
2782       tmp = gfc_finish_block (&ifblock1);
2783
2784       cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
2785                               arrayse.expr,
2786                               gfc_build_const (type, integer_zero_node));
2787
2788       tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
2789       gfc_add_expr_to_block (&block, tmp);  
2790     }
2791   else
2792     {
2793       tmp = fold_build2_loc (input_location, op, type, resvar, arrayse.expr);
2794       gfc_add_modify (&block, resvar, tmp);
2795     }
2796
2797   gfc_add_block_to_block (&block, &arrayse.post);
2798
2799   if (maskexpr && maskexpr->rank > 0)
2800     {
2801       /* We enclose the above in if (mask) {...} .  */
2802
2803       tmp = gfc_finish_block (&block);
2804       tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2805                       build_empty_stmt (input_location));
2806     }
2807   else
2808     tmp = gfc_finish_block (&block);
2809   gfc_add_expr_to_block (&body, tmp);
2810
2811   gfc_trans_scalarizing_loops (ploop, &body);
2812
2813   /* For a scalar mask, enclose the loop in an if statement.  */
2814   if (maskexpr && maskexpr->rank == 0)
2815     {
2816       gfc_init_block (&block);
2817       gfc_add_block_to_block (&block, &ploop->pre);
2818       gfc_add_block_to_block (&block, &ploop->post);
2819       tmp = gfc_finish_block (&block);
2820
2821       if (expr->rank > 0)
2822         {
2823           tmp = build3_v (COND_EXPR, se->ss->info->data.scalar.value, tmp,
2824                           build_empty_stmt (input_location));
2825           gfc_advance_se_ss_chain (se);
2826         }
2827       else
2828         {
2829           gcc_assert (expr->rank == 0);
2830           gfc_init_se (&maskse, NULL);
2831           gfc_conv_expr_val (&maskse, maskexpr);
2832           tmp = build3_v (COND_EXPR, maskse.expr, tmp,
2833                           build_empty_stmt (input_location));
2834         }
2835
2836       gfc_add_expr_to_block (&block, tmp);
2837       gfc_add_block_to_block (&se->pre, &block);
2838       gcc_assert (se->post.head == NULL);
2839     }
2840   else
2841     {
2842       gfc_add_block_to_block (&se->pre, &ploop->pre);
2843       gfc_add_block_to_block (&se->pre, &ploop->post);
2844     }
2845
2846   if (expr->rank == 0)
2847     gfc_cleanup_loop (ploop);
2848
2849   if (norm2)
2850     {
2851       /* result = scale * sqrt(result).  */
2852       tree sqrt;
2853       sqrt = gfc_builtin_decl_for_float_kind (BUILT_IN_SQRT, expr->ts.kind);
2854       resvar = build_call_expr_loc (input_location,
2855                                     sqrt, 1, resvar);
2856       resvar = fold_build2_loc (input_location, MULT_EXPR, type, scale, resvar);
2857     }
2858
2859   se->expr = resvar;
2860 }
2861
2862
2863 /* Inline implementation of the dot_product intrinsic. This function
2864    is based on gfc_conv_intrinsic_arith (the previous function).  */
2865 static void
2866 gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
2867 {
2868   tree resvar;
2869   tree type;
2870   stmtblock_t body;
2871   stmtblock_t block;
2872   tree tmp;
2873   gfc_loopinfo loop;
2874   gfc_actual_arglist *actual;
2875   gfc_ss *arrayss1, *arrayss2;
2876   gfc_se arrayse1, arrayse2;
2877   gfc_expr *arrayexpr1, *arrayexpr2;
2878
2879   type = gfc_typenode_for_spec (&expr->ts);
2880
2881   /* Initialize the result.  */
2882   resvar = gfc_create_var (type, "val");
2883   if (expr->ts.type == BT_LOGICAL)
2884     tmp = build_int_cst (type, 0);
2885   else
2886     tmp = gfc_build_const (type, integer_zero_node);
2887
2888   gfc_add_modify (&se->pre, resvar, tmp);
2889
2890   /* Walk argument #1.  */
2891   actual = expr->value.function.actual;
2892   arrayexpr1 = actual->expr;
2893   arrayss1 = gfc_walk_expr (arrayexpr1);
2894   gcc_assert (arrayss1 != gfc_ss_terminator);
2895
2896   /* Walk argument #2.  */
2897   actual = actual->next;
2898   arrayexpr2 = actual->expr;
2899   arrayss2 = gfc_walk_expr (arrayexpr2);
2900   gcc_assert (arrayss2 != gfc_ss_terminator);
2901
2902   /* Initialize the scalarizer.  */
2903   gfc_init_loopinfo (&loop);
2904   gfc_add_ss_to_loop (&loop, arrayss1);
2905   gfc_add_ss_to_loop (&loop, arrayss2);
2906
2907   /* Initialize the loop.  */
2908   gfc_conv_ss_startstride (&loop);
2909   gfc_conv_loop_setup (&loop, &expr->where);
2910
2911   gfc_mark_ss_chain_used (arrayss1, 1);
2912   gfc_mark_ss_chain_used (arrayss2, 1);
2913
2914   /* Generate the loop body.  */
2915   gfc_start_scalarized_body (&loop, &body);
2916   gfc_init_block (&block);
2917
2918   /* Make the tree expression for [conjg(]array1[)].  */
2919   gfc_init_se (&arrayse1, NULL);
2920   gfc_copy_loopinfo_to_se (&arrayse1, &loop);
2921   arrayse1.ss = arrayss1;
2922   gfc_conv_expr_val (&arrayse1, arrayexpr1);
2923   if (expr->ts.type == BT_COMPLEX)
2924     arrayse1.expr = fold_build1_loc (input_location, CONJ_EXPR, type,
2925                                      arrayse1.expr);
2926   gfc_add_block_to_block (&block, &arrayse1.pre);
2927
2928   /* Make the tree expression for array2.  */
2929   gfc_init_se (&arrayse2, NULL);
2930   gfc_copy_loopinfo_to_se (&arrayse2, &loop);
2931   arrayse2.ss = arrayss2;
2932   gfc_conv_expr_val (&arrayse2, arrayexpr2);
2933   gfc_add_block_to_block (&block, &arrayse2.pre);
2934
2935   /* Do the actual product and sum.  */
2936   if (expr->ts.type == BT_LOGICAL)
2937     {
2938       tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, type,
2939                              arrayse1.expr, arrayse2.expr);
2940       tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, type, resvar, tmp);
2941     }
2942   else
2943     {
2944       tmp = fold_build2_loc (input_location, MULT_EXPR, type, arrayse1.expr,
2945                              arrayse2.expr);
2946       tmp = fold_build2_loc (input_location, PLUS_EXPR, type, resvar, tmp);
2947     }
2948   gfc_add_modify (&block, resvar, tmp);
2949
2950   /* Finish up the loop block and the loop.  */
2951   tmp = gfc_finish_block (&block);
2952   gfc_add_expr_to_block (&body, tmp);
2953
2954   gfc_trans_scalarizing_loops (&loop, &body);
2955   gfc_add_block_to_block (&se->pre, &loop.pre);
2956   gfc_add_block_to_block (&se->pre, &loop.post);
2957   gfc_cleanup_loop (&loop);
2958
2959   se->expr = resvar;
2960 }
2961
2962
2963 /* Emit code for minloc or maxloc intrinsic.  There are many different cases
2964    we need to handle.  For performance reasons we sometimes create two
2965    loops instead of one, where the second one is much simpler.
2966    Examples for minloc intrinsic:
2967    1) Result is an array, a call is generated
2968    2) Array mask is used and NaNs need to be supported:
2969       limit = Infinity;
2970       pos = 0;
2971       S = from;
2972       while (S <= to) {
2973         if (mask[S]) {
2974           if (pos == 0) pos = S + (1 - from);
2975           if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2976         }
2977         S++;
2978       }
2979       goto lab2;
2980       lab1:;
2981       while (S <= to) {
2982         if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2983         S++;
2984       }
2985       lab2:;
2986    3) NaNs need to be supported, but it is known at compile time or cheaply
2987       at runtime whether array is nonempty or not:
2988       limit = Infinity;
2989       pos = 0;
2990       S = from;
2991       while (S <= to) {
2992         if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2993         S++;
2994       }
2995       if (from <= to) pos = 1;
2996       goto lab2;
2997       lab1:;
2998       while (S <= to) {
2999         if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
3000         S++;
3001       }
3002       lab2:;
3003    4) NaNs aren't supported, array mask is used:
3004       limit = infinities_supported ? Infinity : huge (limit);
3005       pos = 0;
3006       S = from;
3007       while (S <= to) {
3008         if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
3009         S++;
3010       }
3011       goto lab2;
3012       lab1:;
3013       while (S <= to) {
3014         if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
3015         S++;
3016       }
3017       lab2:;
3018    5) Same without array mask:
3019       limit = infinities_supported ? Infinity : huge (limit);
3020       pos = (from <= to) ? 1 : 0;
3021       S = from;
3022       while (S <= to) {
3023         if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
3024         S++;
3025       }
3026    For 3) and 5), if mask is scalar, this all goes into a conditional,
3027    setting pos = 0; in the else branch.  */
3028
3029 static void
3030 gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
3031 {
3032   stmtblock_t body;
3033   stmtblock_t block;
3034   stmtblock_t ifblock;
3035   stmtblock_t elseblock;
3036   tree limit;
3037   tree type;
3038   tree tmp;
3039   tree cond;
3040   tree elsetmp;
3041   tree ifbody;
3042   tree offset;
3043   tree nonempty;
3044   tree lab1, lab2;
3045   gfc_loopinfo loop;
3046   gfc_actual_arglist *actual;
3047   gfc_ss *arrayss;
3048   gfc_ss *maskss;
3049   gfc_se arrayse;
3050   gfc_se maskse;
3051   gfc_expr *arrayexpr;
3052   gfc_expr *maskexpr;
3053   tree pos;
3054   int n;
3055
3056   if (se->ss)
3057     {
3058       gfc_conv_intrinsic_funcall (se, expr);
3059       return;
3060     }
3061
3062   /* Initialize the result.  */
3063   pos = gfc_create_var (gfc_array_index_type, "pos");
3064   offset = gfc_create_var (gfc_array_index_type, "offset");
3065   type = gfc_typenode_for_spec (&expr->ts);
3066
3067   /* Walk the arguments.  */
3068   actual = expr->value.function.actual;
3069   arrayexpr = actual->expr;
3070   arrayss = gfc_walk_expr (arrayexpr);
3071   gcc_assert (arrayss != gfc_ss_terminator);
3072
3073   actual = actual->next->next;
3074   gcc_assert (actual);
3075   maskexpr = actual->expr;
3076   nonempty = NULL;
3077   if (maskexpr && maskexpr->rank != 0)
3078     {
3079       maskss = gfc_walk_expr (maskexpr);
3080       gcc_assert (maskss != gfc_ss_terminator);
3081     }
3082   else
3083     {
3084       mpz_t asize;
3085       if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
3086         {
3087           nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
3088           mpz_clear (asize);
3089           nonempty = fold_build2_loc (input_location, GT_EXPR,
3090                                       boolean_type_node, nonempty,
3091                                       gfc_index_zero_node);
3092         }
3093       maskss = NULL;
3094     }
3095
3096   limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
3097   switch (arrayexpr->ts.type)
3098     {
3099     case BT_REAL:
3100       tmp = gfc_build_inf_or_huge (TREE_TYPE (limit), arrayexpr->ts.kind);
3101       break;
3102
3103     case BT_INTEGER:
3104       n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
3105       tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
3106                                   arrayexpr->ts.kind);
3107       break;
3108
3109     default:
3110       gcc_unreachable ();
3111     }
3112
3113   /* We start with the most negative possible value for MAXLOC, and the most
3114      positive possible value for MINLOC. The most negative possible value is
3115      -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
3116      possible value is HUGE in both cases.  */
3117   if (op == GT_EXPR)
3118     tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
3119   if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
3120     tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp), tmp,
3121                            build_int_cst (type, 1));
3122
3123   gfc_add_modify (&se->pre, limit, tmp);
3124
3125   /* Initialize the scalarizer.  */
3126   gfc_init_loopinfo (&loop);
3127   gfc_add_ss_to_loop (&loop, arrayss);
3128   if (maskss)
3129     gfc_add_ss_to_loop (&loop, maskss);
3130
3131   /* Initialize the loop.  */
3132   gfc_conv_ss_startstride (&loop);
3133
3134   /* The code generated can have more than one loop in sequence (see the
3135      comment at the function header).  This doesn't work well with the
3136      scalarizer, which changes arrays' offset when the scalarization loops
3137      are generated (see gfc_trans_preloop_setup).  Fortunately, {min,max}loc
3138      are  currently inlined in the scalar case only (for which loop is of rank
3139      one).  As there is no dependency to care about in that case, there is no
3140      temporary, so that we can use the scalarizer temporary code to handle
3141      multiple loops.  Thus, we set temp_dim here, we call gfc_mark_ss_chain_used
3142      with flag=3 later, and we use gfc_trans_scalarized_loop_boundary even later
3143      to restore offset.
3144      TODO: this prevents inlining of rank > 0 minmaxloc calls, so this
3145      should eventually go away.  We could either create two loops properly,
3146      or find another way to save/restore the array offsets between the two
3147      loops (without conflicting with temporary management), or use a single
3148      loop minmaxloc implementation.  See PR 31067.  */
3149   loop.temp_dim = loop.dimen;
3150   gfc_conv_loop_setup (&loop, &expr->where);
3151
3152   gcc_assert (loop.dimen == 1);
3153   if (nonempty == NULL && maskss == NULL && loop.from[0] && loop.to[0])
3154     nonempty = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3155                                 loop.from[0], loop.to[0]);
3156
3157   lab1 = NULL;
3158   lab2 = NULL;
3159   /* Initialize the position to zero, following Fortran 2003.  We are free
3160      to do this because Fortran 95 allows the result of an entirely false
3161      mask to be processor dependent.  If we know at compile time the array
3162      is non-empty and no MASK is used, we can initialize to 1 to simplify
3163      the inner loop.  */
3164   if (nonempty != NULL && !HONOR_NANS (DECL_MODE (limit)))
3165     gfc_add_modify (&loop.pre, pos,
3166                     fold_build3_loc (input_location, COND_EXPR,
3167                                      gfc_array_index_type,
3168                                      nonempty, gfc_index_one_node,
3169                                      gfc_index_zero_node));
3170   else
3171     {
3172       gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
3173       lab1 = gfc_build_label_decl (NULL_TREE);
3174       TREE_USED (lab1) = 1;
3175       lab2 = gfc_build_label_decl (NULL_TREE);
3176       TREE_USED (lab2) = 1;
3177     }
3178
3179   /* An offset must be added to the loop
3180      counter to obtain the required position.  */
3181   gcc_assert (loop.from[0]);
3182
3183   tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
3184                          gfc_index_one_node, loop.from[0]);
3185   gfc_add_modify (&loop.pre, offset, tmp);
3186
3187   gfc_mark_ss_chain_used (arrayss, lab1 ? 3 : 1);
3188   if (maskss)
3189     gfc_mark_ss_chain_used (maskss, lab1 ? 3 : 1);
3190   /* Generate the loop body.  */
3191   gfc_start_scalarized_body (&loop, &body);
3192
3193   /* If we have a mask, only check this element if the mask is set.  */
3194   if (maskss)
3195     {
3196       gfc_init_se (&maskse, NULL);
3197       gfc_copy_loopinfo_to_se (&maskse, &loop);
3198       maskse.ss = maskss;
3199       gfc_conv_expr_val (&maskse, maskexpr);
3200       gfc_add_block_to_block (&body, &maskse.pre);
3201
3202       gfc_start_block (&block);
3203     }
3204   else
3205     gfc_init_block (&block);
3206
3207   /* Compare with the current limit.  */
3208   gfc_init_se (&arrayse, NULL);
3209   gfc_copy_loopinfo_to_se (&arrayse, &loop);
3210   arrayse.ss = arrayss;
3211   gfc_conv_expr_val (&arrayse, arrayexpr);
3212   gfc_add_block_to_block (&block, &arrayse.pre);
3213
3214   /* We do the following if this is a more extreme value.  */
3215   gfc_start_block (&ifblock);
3216
3217   /* Assign the value to the limit...  */
3218   gfc_add_modify (&ifblock, limit, arrayse.expr);
3219
3220   if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
3221     {
3222       stmtblock_t ifblock2;
3223       tree ifbody2;
3224
3225       gfc_start_block (&ifblock2);
3226       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
3227                              loop.loopvar[0], offset);
3228       gfc_add_modify (&ifblock2, pos, tmp);
3229       ifbody2 = gfc_finish_block (&ifblock2);
3230       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, pos,
3231                               gfc_index_zero_node);
3232       tmp = build3_v (COND_EXPR, cond, ifbody2,
3233                       build_empty_stmt (input_location));
3234       gfc_add_expr_to_block (&block, tmp);
3235     }
3236
3237   tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
3238                          loop.loopvar[0], offset);
3239   gfc_add_modify (&ifblock, pos, tmp);
3240
3241   if (lab1)
3242     gfc_add_expr_to_block (&ifblock, build1_v (GOTO_EXPR, lab1));
3243
3244   ifbody = gfc_finish_block (&ifblock);
3245
3246   if (!lab1 || HONOR_NANS (DECL_MODE (limit)))
3247     {
3248       if (lab1)
3249         cond = fold_build2_loc (input_location,
3250                                 op == GT_EXPR ? GE_EXPR : LE_EXPR,
3251                                 boolean_type_node, arrayse.expr, limit);
3252       else
3253         cond = fold_build2_loc (input_location, op, boolean_type_node,
3254                                 arrayse.expr, limit);
3255
3256       ifbody = build3_v (COND_EXPR, cond, ifbody,
3257                          build_empty_stmt (input_location));
3258     }
3259   gfc_add_expr_to_block (&block, ifbody);
3260
3261   if (maskss)
3262     {
3263       /* We enclose the above in if (mask) {...}.  */
3264       tmp = gfc_finish_block (&block);
3265
3266       tmp = build3_v (COND_EXPR, maskse.expr, tmp,
3267                       build_empty_stmt (input_location));
3268     }
3269   else
3270     tmp = gfc_finish_block (&block);
3271   gfc_add_expr_to_block (&body, tmp);
3272
3273   if (lab1)
3274     {
3275       gfc_trans_scalarized_loop_boundary (&loop, &body);
3276
3277       if (HONOR_NANS (DECL_MODE (limit)))
3278         {
3279           if (nonempty != NULL)
3280             {
3281               ifbody = build2_v (MODIFY_EXPR, pos, gfc_index_one_node);
3282               tmp = build3_v (COND_EXPR, nonempty, ifbody,
3283                               build_empty_stmt (input_location));
3284               gfc_add_expr_to_block (&loop.code[0], tmp);
3285             }
3286         }
3287
3288       gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
3289       gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));
3290
3291       /* If we have a mask, only check this element if the mask is set.  */
3292       if (maskss)
3293         {
3294           gfc_init_se (&maskse, NULL);
3295           gfc_copy_loopinfo_to_se (&maskse, &loop);
3296           maskse.ss = maskss;
3297           gfc_conv_expr_val (&maskse, maskexpr);
3298           gfc_add_block_to_block (&body, &maskse.pre);
3299
3300           gfc_start_block (&block);
3301         }
3302       else
3303         gfc_init_block (&block);
3304
3305       /* Compare with the current limit.  */
3306       gfc_init_se (&arrayse, NULL);
3307       gfc_copy_loopinfo_to_se (&arrayse, &loop);
3308       arrayse.ss = arrayss;
3309       gfc_conv_expr_val (&arrayse, arrayexpr);
3310       gfc_add_block_to_block (&block, &arrayse.pre);
3311
3312       /* We do the following if this is a more extreme value.  */
3313       gfc_start_block (&ifblock);
3314
3315       /* Assign the value to the limit...  */
3316       gfc_add_modify (&ifblock, limit, arrayse.expr);
3317
3318       tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
3319                              loop.loopvar[0], offset);
3320       gfc_add_modify (&ifblock, pos, tmp);
3321
3322       ifbody = gfc_finish_block (&ifblock);
3323
3324       cond = fold_build2_loc (input_location, op, boolean_type_node,
3325                               arrayse.expr, limit);
3326
3327       tmp = build3_v (COND_EXPR, cond, ifbody,
3328                       build_empty_stmt (input_location));
3329       gfc_add_expr_to_block (&block, tmp);
3330
3331       if (maskss)
3332         {
3333           /* We enclose the above in if (mask) {...}.  */
3334           tmp = gfc_finish_block (&block);
3335
3336           tmp = build3_v (COND_EXPR, maskse.expr, tmp,
3337                           build_empty_stmt (input_location));
3338         }
3339       else
3340         tmp = gfc_finish_block (&block);
3341       gfc_add_expr_to_block (&body, tmp);
3342       /* Avoid initializing loopvar[0] again, it should be left where
3343          it finished by the first loop.  */
3344       loop.from[0] = loop.loopvar[0];
3345     }
3346
3347   gfc_trans_scalarizing_loops (&loop, &body);
3348
3349   if (lab2)
3350     gfc_add_expr_to_block (&loop.pre, build1_v (LABEL_EXPR, lab2));
3351
3352   /* For a scalar mask, enclose the loop in an if statement.  */
3353   if (maskexpr && maskss == NULL)
3354     {
3355       gfc_init_se (&maskse, NULL);
3356       gfc_conv_expr_val (&maskse, maskexpr);
3357       gfc_init_block (&block);
3358       gfc_add_block_to_block (&block, &loop.pre);
3359       gfc_add_block_to_block (&block, &loop.post);
3360       tmp = gfc_finish_block (&block);
3361
3362       /* For the else part of the scalar mask, just initialize
3363          the pos variable the same way as above.  */
3364
3365       gfc_init_block (&elseblock);
3366       gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
3367       elsetmp = gfc_finish_block (&elseblock);
3368
3369       tmp = build3_v (COND_EXPR, maskse.expr, tmp, elsetmp);
3370       gfc_add_expr_to_block (&block, tmp);
3371       gfc_add_block_to_block (&se->pre, &block);
3372     }
3373   else
3374     {
3375       gfc_add_block_to_block (&se->pre, &loop.pre);
3376       gfc_add_block_to_block (&se->pre, &loop.post);
3377     }
3378   gfc_cleanup_loop (&loop);
3379
3380   se->expr = convert (type, pos);
3381 }
3382
3383 /* Emit code for minval or maxval intrinsic.  There are many different cases
3384    we need to handle.  For performance reasons we sometimes create two
3385    loops instead of one, where the second one is much simpler.
3386    Examples for minval intrinsic:
3387    1) Result is an array, a call is generated
3388    2) Array mask is used and NaNs need to be supported, rank 1:
3389       limit = Infinity;
3390       nonempty = false;
3391       S = from;
3392       while (S <= to) {
3393         if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
3394         S++;
3395       }
3396       limit = nonempty ? NaN : huge (limit);
3397       lab:
3398       while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
3399    3) NaNs need to be supported, but it is known at compile time or cheaply
3400       at runtime whether array is nonempty or not, rank 1:
3401       limit = Infinity;
3402       S = from;
3403       while (S <= to) { if (a[S] <= limit) goto lab; S++; }
3404       limit = (from <= to) ? NaN : huge (limit);
3405       lab:
3406       while (S <= to) { limit = min (a[S], limit); S++; }
3407    4) Array mask is used and NaNs need to be supported, rank > 1:
3408       limit = Infinity;
3409       nonempty = false;
3410       fast = false;
3411       S1 = from1;
3412       while (S1 <= to1) {
3413         S2 = from2;
3414         while (S2 <= to2) {
3415           if (mask[S1][S2]) {
3416             if (fast) limit = min (a[S1][S2], limit);
3417             else {
3418               nonempty = true;
3419               if (a[S1][S2] <= limit) {
3420                 limit = a[S1][S2];
3421                 fast = true;
3422               }
3423             }
3424           }
3425           S2++;
3426         }
3427         S1++;
3428       }
3429       if (!fast)
3430         limit = nonempty ? NaN : huge (limit);
3431    5) NaNs need to be supported, but it is known at compile time or cheaply
3432       at runtime whether array is nonempty or not, rank > 1:
3433       limit = Infinity;
3434       fast = false;
3435       S1 = from1;
3436       while (S1 <= to1) {
3437         S2 = from2;
3438         while (S2 <= to2) {
3439           if (fast) limit = min (a[S1][S2], limit);
3440           else {
3441             if (a[S1][S2] <= limit) {
3442               limit = a[S1][S2];
3443               fast = true;
3444             }
3445           }
3446           S2++;
3447         }
3448         S1++;
3449       }
3450       if (!fast)
3451         limit = (nonempty_array) ? NaN : huge (limit);
3452    6) NaNs aren't supported, but infinities are.  Array mask is used:
3453       limit = Infinity;
3454       nonempty = false;
3455       S = from;
3456       while (S <= to) {
3457         if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
3458         S++;
3459       }
3460       limit = nonempty ? limit : huge (limit);
3461    7) Same without array mask:
3462       limit = Infinity;
3463       S = from;
3464       while (S <= to) { limit = min (a[S], limit); S++; }
3465       limit = (from <= to) ? limit : huge (limit);
3466    8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
3467       limit = huge (limit);
3468       S = from;
3469       while (S <= to) { limit = min (a[S], limit); S++); }
3470       (or
3471       while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
3472       with array mask instead).
3473    For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
3474    setting limit = huge (limit); in the else branch.  */
3475
3476 static void
3477 gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
3478 {
3479   tree limit;
3480   tree type;
3481   tree tmp;
3482   tree ifbody;
3483   tree nonempty;
3484   tree nonempty_var;
3485   tree lab;
3486   tree fast;
3487   tree huge_cst = NULL, nan_cst = NULL;
3488   stmtblock_t body;
3489   stmtblock_t block, block2;
3490   gfc_loopinfo loop;
3491   gfc_actual_arglist *actual;
3492   gfc_ss *arrayss;
3493   gfc_ss *maskss;
3494   gfc_se arrayse;
3495   gfc_se maskse;
3496   gfc_expr *arrayexpr;
3497   gfc_expr *maskexpr;
3498   int n;
3499
3500   if (se->ss)
3501     {
3502       gfc_conv_intrinsic_funcall (se, expr);
3503       return;
3504     }
3505
3506   type = gfc_typenode_for_spec (&expr->ts);
3507   /* Initialize the result.  */
3508   limit = gfc_create_var (type, "limit");
3509   n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
3510   switch (expr->ts.type)
3511     {
3512     case BT_REAL:
3513       huge_cst = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
3514                                         expr->ts.kind, 0);
3515       if (HONOR_INFINITIES (DECL_MODE (limit)))
3516         {
3517           REAL_VALUE_TYPE real;
3518           real_inf (&real);
3519           tmp = build_real (type, real);
3520         }
3521       else
3522         tmp = huge_cst;
3523       if (HONOR_NANS (DECL_MODE (limit)))
3524         {
3525           REAL_VALUE_TYPE real;
3526           real_nan (&real, "", 1, DECL_MODE (limit));
3527           nan_cst = build_real (type, real);
3528         }
3529       break;
3530
3531     case BT_INTEGER:
3532       tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
3533       break;
3534
3535     default:
3536       gcc_unreachable ();
3537     }
3538
3539   /* We start with the most negative possible value for MAXVAL, and the most
3540      positive possible value for MINVAL. The most negative possible value is
3541      -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
3542      possible value is HUGE in both cases.  */
3543   if (op == GT_EXPR)
3544     {
3545       tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
3546       if (huge_cst)
3547         huge_cst = fold_build1_loc (input_location, NEGATE_EXPR,
3548                                     TREE_TYPE (huge_cst), huge_cst);
3549     }
3550
3551   if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
3552     tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
3553                            tmp, build_int_cst (type, 1));
3554
3555   gfc_add_modify (&se->pre, limit, tmp);
3556
3557   /* Walk the arguments.  */
3558   actual = expr->value.function.actual;
3559   arrayexpr = actual->expr;
3560   arrayss = gfc_walk_expr (arrayexpr);
3561   gcc_assert (arrayss != gfc_ss_terminator);
3562
3563   actual = actual->next->next;
3564   gcc_assert (actual);
3565   maskexpr = actual->expr;
3566   nonempty = NULL;
3567   if (maskexpr && maskexpr->rank != 0)
3568     {
3569       maskss = gfc_walk_expr (maskexpr);
3570       gcc_assert (maskss != gfc_ss_terminator);
3571     }
3572   else
3573     {
3574       mpz_t asize;
3575       if (gfc_array_size (arrayexpr, &asize) == SUCCESS)
3576         {
3577           nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
3578           mpz_clear (asize);
3579           nonempty = fold_build2_loc (input_location, GT_EXPR,
3580                                       boolean_type_node, nonempty,
3581                                       gfc_index_zero_node);
3582         }
3583       maskss = NULL;
3584     }
3585
3586   /* Initialize the scalarizer.  */
3587   gfc_init_loopinfo (&loop);
3588   gfc_add_ss_to_loop (&loop, arrayss);
3589   if (maskss)
3590     gfc_add_ss_to_loop (&loop, maskss);
3591
3592   /* Initialize the loop.  */
3593   gfc_conv_ss_startstride (&loop);
3594
3595   /* The code generated can have more than one loop in sequence (see the
3596      comment at the function header).  This doesn't work well with the
3597      scalarizer, which changes arrays' offset when the scalarization loops
3598      are generated (see gfc_trans_preloop_setup).  Fortunately, {min,max}val
3599      are  currently inlined in the scalar case only.  As there is no dependency
3600      to care about in that case, there is no temporary, so that we can use the
3601      scalarizer temporary code to handle multiple loops.  Thus, we set temp_dim
3602      here, we call gfc_mark_ss_chain_used with flag=3 later, and we use
3603      gfc_trans_scalarized_loop_boundary even later to restore offset.
3604      TODO: this prevents inlining of rank > 0 minmaxval calls, so this
3605      should eventually go away.  We could either create two loops properly,
3606      or find another way to save/restore the array offsets between the two
3607      loops (without conflicting with temporary management), or use a single
3608      loop minmaxval implementation.  See PR 31067.  */
3609   loop.temp_dim = loop.dimen;
3610   gfc_conv_loop_setup (&loop, &expr->where);
3611
3612   if (nonempty == NULL && maskss == NULL
3613       && loop.dimen == 1 && loop.from[0] && loop.to[0])
3614     nonempty = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
3615                                 loop.from[0], loop.to[0]);
3616   nonempty_var = NULL;
3617   if (nonempty == NULL
3618       && (HONOR_INFINITIES (DECL_MODE (limit))
3619           || HONOR_NANS (DECL_MODE (limit))))
3620     {
3621       nonempty_var = gfc_create_var (boolean_type_node, "nonempty");
3622       gfc_add_modify (&se->pre, nonempty_var, boolean_false_node);
3623       nonempty = nonempty_var;
3624     }
3625   lab = NULL;
3626   fast = NULL;
3627   if (HONOR_NANS (DECL_MODE (limit)))
3628     {
3629       if (loop.dimen == 1)
3630         {
3631           lab = gfc_build_label_decl (NULL_TREE);
3632           TREE_USED (lab) = 1;
3633         }
3634       else
3635         {
3636           fast = gfc_create_var (boolean_type_node, "fast");
3637           gfc_add_modify (&se->pre, fast, boolean_false_node);
3638         }
3639     }
3640
3641   gfc_mark_ss_chain_used (arrayss, lab ? 3 : 1);
3642   if (maskss)
3643     gfc_mark_ss_chain_used (maskss, lab ? 3 : 1);
3644   /* Generate the loop body.  */
3645   gfc_start_scalarized_body (&loop, &body);
3646
3647   /* If we have a mask, only add this element if the mask is set.  */
3648   if (maskss)
3649     {
3650       gfc_init_se (&maskse, NULL);
3651       gfc_copy_loopinfo_to_se (&maskse, &loop);
3652       maskse.ss = maskss;
3653       gfc_conv_expr_val (&maskse, maskexpr);
3654       gfc_add_block_to_block (&body, &maskse.pre);
3655
3656       gfc_start_block (&block);
3657     }
3658   else
3659     gfc_init_block (&block);
3660
3661   /* Compare with the current limit.  */
3662   gfc_init_se (&arrayse, NULL);
3663   gfc_copy_loopinfo_to_se (&arrayse, &loop);
3664   arrayse.ss = arrayss;
3665   gfc_conv_expr_val (&arrayse, arrayexpr);
3666   gfc_add_block_to_block (&block, &arrayse.pre);
3667
3668   gfc_init_block (&block2);
3669
3670   if (nonempty_var)
3671     gfc_add_modify (&block2, nonempty_var, boolean_true_node);
3672
3673   if (HONOR_NANS (DECL_MODE (limit)))
3674     {
3675       tmp = fold_build2_loc (input_location, op == GT_EXPR ? GE_EXPR : LE_EXPR,
3676                              boolean_type_node, arrayse.expr, limit);
3677       if (lab)
3678         ifbody = build1_v (GOTO_EXPR, lab);
3679       else
3680         {
3681           stmtblock_t ifblock;
3682
3683           gfc_init_block (&ifblock);
3684           gfc_add_modify (&ifblock, limit, arrayse.expr);
3685           gfc_add_modify (&ifblock, fast, boolean_true_node);
3686           ifbody = gfc_finish_block (&ifblock);
3687         }
3688       tmp = build3_v (COND_EXPR, tmp, ifbody,
3689                       build_empty_stmt (input_location));
3690       gfc_add_expr_to_block (&block2, tmp);
3691     }
3692   else
3693     {
3694       /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3695          signed zeros.  */
3696       if (HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
3697         {
3698           tmp = fold_build2_loc (input_location, op, boolean_type_node,
3699                                  arrayse.expr, limit);
3700           ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
3701           tmp = build3_v (COND_EXPR, tmp, ifbody,
3702                           build_empty_stmt (input_location));
3703           gfc_add_expr_to_block (&block2, tmp);
3704         }
3705       else
3706         {
3707           tmp = fold_build2_loc (input_location,
3708                                  op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
3709                                  type, arrayse.expr, limit);
3710           gfc_add_modify (&block2, limit, tmp);
3711         }
3712     }
3713
3714   if (fast)
3715     {
3716       tree elsebody = gfc_finish_block (&block2);
3717
3718       /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3719          signed zeros.  */
3720       if (HONOR_NANS (DECL_MODE (limit))
3721           || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
3722         {
3723           tmp = fold_build2_loc (input_location, op, boolean_type_node,
3724                                  arrayse.expr, limit);
3725           ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
3726           ifbody = build3_v (COND_EXPR, tmp, ifbody,
3727                              build_empty_stmt (input_location));
3728         }
3729       else
3730         {
3731           tmp = fold_build2_loc (input_location,
3732                                  op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
3733                                  type, arrayse.expr, limit);
3734           ifbody = build2_v (MODIFY_EXPR, limit, tmp);
3735         }
3736       tmp = build3_v (COND_EXPR, fast, ifbody, elsebody);
3737       gfc_add_expr_to_block (&block, tmp);
3738     }
3739   else
3740     gfc_add_block_to_block (&block, &block2);
3741
3742   gfc_add_block_to_block (&block, &arrayse.post);
3743
3744   tmp = gfc_finish_block (&block);
3745   if (maskss)
3746     /* We enclose the above in if (mask) {...}.  */
3747     tmp = build3_v (COND_EXPR, maskse.expr, tmp,
3748                     build_empty_stmt (input_location));
3749   gfc_add_expr_to_block (&body, tmp);
3750
3751   if (lab)
3752     {
3753       gfc_trans_scalarized_loop_boundary (&loop, &body);
3754
3755       tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
3756                              nan_cst, huge_cst);
3757       gfc_add_modify (&loop.code[0], limit, tmp);
3758       gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));
3759
3760       /* If we have a mask, only add this element if the mask is set.  */
3761       if (maskss)
3762         {
3763           gfc_init_se (&maskse, NULL);
3764           gfc_copy_loopinfo_to_se (&maskse, &loop);
3765           maskse.ss = maskss;
3766           gfc_conv_expr_val (&maskse, maskexpr);
3767           gfc_add_block_to_block (&body, &maskse.pre);
3768
3769           gfc_start_block (&block);
3770         }
3771       else
3772         gfc_init_block (&block);
3773
3774       /* Compare with the current limit.  */
3775       gfc_init_se (&arrayse, NULL);
3776       gfc_copy_loopinfo_to_se (&arrayse, &loop);
3777       arrayse.ss = arrayss;
3778       gfc_conv_expr_val (&arrayse, arrayexpr);
3779       gfc_add_block_to_block (&block, &arrayse.pre);
3780
3781       /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3782          signed zeros.  */
3783       if (HONOR_NANS (DECL_MODE (limit))
3784           || HONOR_SIGNED_ZEROS (DECL_MODE (limit)))
3785         {
3786           tmp = fold_build2_loc (input_location, op, boolean_type_node,
3787                                  arrayse.expr, limit);
3788           ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
3789           tmp = build3_v (COND_EXPR, tmp, ifbody,
3790                           build_empty_stmt (input_location));
3791           gfc_add_expr_to_block (&block, tmp);
3792         }
3793       else
3794         {
3795           tmp = fold_build2_loc (input_location,
3796                                  op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
3797                                  type, arrayse.expr, limit);
3798           gfc_add_modify (&block, limit, tmp);
3799         }
3800
3801       gfc_add_block_to_block (&block, &arrayse.post);
3802
3803       tmp = gfc_finish_block (&block);
3804       if (maskss)
3805         /* We enclose the above in if (mask) {...}.  */
3806         tmp = build3_v (COND_EXPR, maskse.expr, tmp,
3807                         build_empty_stmt (input_location));
3808       gfc_add_expr_to_block (&body, tmp);
3809       /* Avoid initializing loopvar[0] again, it should be left where
3810          it finished by the first loop.  */
3811       loop.from[0] = loop.loopvar[0];
3812     }
3813   gfc_trans_scalarizing_loops (&loop, &body);
3814
3815   if (fast)
3816     {
3817       tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
3818                              nan_cst, huge_cst);
3819       ifbody = build2_v (MODIFY_EXPR, limit, tmp);
3820       tmp = build3_v (COND_EXPR, fast, build_empty_stmt (input_location),
3821                       ifbody);
3822       gfc_add_expr_to_block (&loop.pre, tmp);
3823     }
3824   else if (HONOR_INFINITIES (DECL_MODE (limit)) && !lab)
3825     {
3826       tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty, limit,
3827                              huge_cst);
3828       gfc_add_modify (&loop.pre, limit, tmp);
3829     }
3830
3831   /* For a scalar mask, enclose the loop in an if statement.  */
3832   if (maskexpr && maskss == NULL)
3833     {
3834       tree else_stmt;
3835
3836       gfc_init_se (&maskse, NULL);
3837       gfc_conv_expr_val (&maskse, maskexpr);
3838       gfc_init_block (&block);
3839       gfc_add_block_to_block (&block, &loop.pre);
3840       gfc_add_block_to_block (&block, &loop.post);
3841       tmp = gfc_finish_block (&block);
3842
3843       if (HONOR_INFINITIES (DECL_MODE (limit)))
3844         else_stmt = build2_v (MODIFY_EXPR, limit, huge_cst);
3845       else
3846         else_stmt = build_empty_stmt (input_location);
3847       tmp = build3_v (COND_EXPR, maskse.expr, tmp, else_stmt);
3848       gfc_add_expr_to_block (&block, tmp);
3849       gfc_add_block_to_block (&se->pre, &block);
3850     }
3851   else
3852     {
3853       gfc_add_block_to_block (&se->pre, &loop.pre);
3854       gfc_add_block_to_block (&se->pre, &loop.post);
3855     }
3856
3857   gfc_cleanup_loop (&loop);
3858
3859   se->expr = limit;
3860 }
3861
3862 /* BTEST (i, pos) = (i & (1 << pos)) != 0.  */
3863 static void
3864 gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
3865 {
3866   tree args[2];
3867   tree type;
3868   tree tmp;
3869
3870   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3871   type = TREE_TYPE (args[0]);
3872
3873   tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3874                          build_int_cst (type, 1), args[1]);
3875   tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], tmp);
3876   tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
3877                          build_int_cst (type, 0));
3878   type = gfc_typenode_for_spec (&expr->ts);
3879   se->expr = convert (type, tmp);
3880 }
3881
3882
3883 /* Generate code for BGE, BGT, BLE and BLT intrinsics.  */
3884 static void
3885 gfc_conv_intrinsic_bitcomp (gfc_se * se, gfc_expr * expr, enum tree_code op)
3886 {
3887   tree args[2];
3888
3889   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3890
3891   /* Convert both arguments to the unsigned type of the same size.  */
3892   args[0] = fold_convert (unsigned_type_for (TREE_TYPE (args[0])), args[0]);
3893   args[1] = fold_convert (unsigned_type_for (TREE_TYPE (args[1])), args[1]);
3894
3895   /* If they have unequal type size, convert to the larger one.  */
3896   if (TYPE_PRECISION (TREE_TYPE (args[0]))
3897       > TYPE_PRECISION (TREE_TYPE (args[1])))
3898     args[1] = fold_convert (TREE_TYPE (args[0]), args[1]);
3899   else if (TYPE_PRECISION (TREE_TYPE (args[1]))
3900            > TYPE_PRECISION (TREE_TYPE (args[0])))
3901     args[0] = fold_convert (TREE_TYPE (args[1]), args[0]);
3902
3903   /* Now, we compare them.  */
3904   se->expr = fold_build2_loc (input_location, op, boolean_type_node,
3905                               args[0], args[1]);
3906 }
3907
3908
3909 /* Generate code to perform the specified operation.  */
3910 static void
3911 gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
3912 {
3913   tree args[2];
3914
3915   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3916   se->expr = fold_build2_loc (input_location, op, TREE_TYPE (args[0]),
3917                               args[0], args[1]);
3918 }
3919
3920 /* Bitwise not.  */
3921 static void
3922 gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
3923 {
3924   tree arg;
3925
3926   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
3927   se->expr = fold_build1_loc (input_location, BIT_NOT_EXPR,
3928                               TREE_TYPE (arg), arg);
3929 }
3930
3931 /* Set or clear a single bit.  */
3932 static void
3933 gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
3934 {
3935   tree args[2];
3936   tree type;
3937   tree tmp;
3938   enum tree_code op;
3939
3940   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3941   type = TREE_TYPE (args[0]);
3942
3943   tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
3944                          build_int_cst (type, 1), args[1]);
3945   if (set)
3946     op = BIT_IOR_EXPR;
3947   else
3948     {
3949       op = BIT_AND_EXPR;
3950       tmp = fold_build1_loc (input_location, BIT_NOT_EXPR, type, tmp);
3951     }
3952   se->expr = fold_build2_loc (input_location, op, type, args[0], tmp);
3953 }
3954
3955 /* Extract a sequence of bits.
3956     IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN).  */
3957 static void
3958 gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
3959 {
3960   tree args[3];
3961   tree type;
3962   tree tmp;
3963   tree mask;
3964
3965   gfc_conv_intrinsic_function_args (se, expr, args, 3);
3966   type = TREE_TYPE (args[0]);
3967
3968   mask = build_int_cst (type, -1);
3969   mask = fold_build2_loc (input_location, LSHIFT_EXPR, type, mask, args[2]);
3970   mask = fold_build1_loc (input_location, BIT_NOT_EXPR, type, mask);
3971
3972   tmp = fold_build2_loc (input_location, RSHIFT_EXPR, type, args[0], args[1]);
3973
3974   se->expr = fold_build2_loc (input_location, BIT_AND_EXPR, type, tmp, mask);
3975 }
3976
3977 static void
3978 gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
3979                           bool arithmetic)
3980 {
3981   tree args[2], type, num_bits, cond;
3982
3983   gfc_conv_intrinsic_function_args (se, expr, args, 2);
3984
3985   args[0] = gfc_evaluate_now (args[0], &se->pre);
3986   args[1] = gfc_evaluate_now (args[1], &se->pre);
3987   type = TREE_TYPE (args[0]);
3988
3989   if (!arithmetic)
3990     args[0] = fold_convert (unsigned_type_for (type), args[0]);
3991   else
3992     gcc_assert (right_shift);
3993
3994   se->expr = fold_build2_loc (input_location,
3995                               right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
3996                               TREE_TYPE (args[0]), args[0], args[1]);
3997
3998   if (!arithmetic)
3999     se->expr = fold_convert (type, se->expr);
4000
4001   /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
4002      gcc requires a shift width < BIT_SIZE(I), so we have to catch this
4003      special case.  */
4004   num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
4005   cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node,
4006                           args[1], num_bits);
4007
4008   se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
4009                               build_int_cst (type, 0), se->expr);
4010 }
4011
4012 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
4013                         ? 0
4014                         : ((shift >= 0) ? i << shift : i >> -shift)
4015    where all shifts are logical shifts.  */
4016 static void
4017 gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
4018 {
4019   tree args[2];
4020   tree type;
4021   tree utype;
4022   tree tmp;
4023   tree width;
4024   tree num_bits;
4025   tree cond;
4026   tree lshift;
4027   tree rshift;
4028
4029   gfc_conv_intrinsic_function_args (se, expr, args, 2);
4030
4031   args[0] = gfc_evaluate_now (args[0], &se->pre);
4032   args[1] = gfc_evaluate_now (args[1], &se->pre);
4033
4034   type = TREE_TYPE (args[0]);
4035   utype = unsigned_type_for (type);
4036
4037   width = fold_build1_loc (input_location, ABS_EXPR, TREE_TYPE (args[1]),
4038                            args[1]);
4039
4040   /* Left shift if positive.  */
4041   lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type, args[0], width);
4042
4043   /* Right shift if negative.
4044      We convert to an unsigned type because we want a logical shift.
4045      The standard doesn't define the case of shifting negative
4046      numbers, and we try to be compatible with other compilers, most
4047      notably g77, here.  */
4048   rshift = fold_convert (type, fold_build2_loc (input_location, RSHIFT_EXPR,
4049                                     utype, convert (utype, args[0]), width));
4050
4051   tmp = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, args[1],
4052                          build_int_cst (TREE_TYPE (args[1]), 0));
4053   tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp, lshift, rshift);
4054
4055   /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
4056      gcc requires a shift width < BIT_SIZE(I), so we have to catch this
4057      special case.  */
4058   num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
4059   cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, width,
4060                           num_bits);
4061   se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
4062                               build_int_cst (type, 0), tmp);
4063 }
4064
4065
4066 /* Circular shift.  AKA rotate or barrel shift.  */
4067
4068 static void
4069 gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
4070 {
4071   tree *args;
4072   tree type;
4073   tree tmp;
4074   tree lrot;
4075   tree rrot;
4076   tree zero;
4077   unsigned int num_args;
4078
4079   num_args = gfc_intrinsic_argument_list_length (expr);
4080   args = XALLOCAVEC (tree, num_args);
4081
4082   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
4083
4084   if (num_args == 3)
4085     {
4086       /* Use a library function for the 3 parameter version.  */
4087       tree int4type = gfc_get_int_type (4);
4088
4089       type = TREE_TYPE (args[0]);
4090       /* We convert the first argument to at least 4 bytes, and
4091          convert back afterwards.  This removes the need for library
4092          functions for all argument sizes, and function will be
4093          aligned to at least 32 bits, so there's no loss.  */
4094       if (expr->ts.kind < 4)
4095         args[0] = convert (int4type, args[0]);
4096
4097       /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
4098          need loads of library  functions.  They cannot have values >
4099          BIT_SIZE (I) so the conversion is safe.  */
4100       args[1] = convert (int4type, args[1]);
4101       args[2] = convert (int4type, args[2]);
4102
4103       switch (expr->ts.kind)
4104         {
4105         case 1:
4106         case 2:
4107         case 4:
4108           tmp = gfor_fndecl_math_ishftc4;
4109           break;
4110         case 8:
4111           tmp = gfor_fndecl_math_ishftc8;
4112           break;
4113         case 16:
4114           tmp = gfor_fndecl_math_ishftc16;
4115           break;
4116         default:
4117           gcc_unreachable ();
4118         }
4119       se->expr = build_call_expr_loc (input_location,
4120                                       tmp, 3, args[0], args[1], args[2]);
4121       /* Convert the result back to the original type, if we extended
4122          the first argument's width above.  */
4123       if (expr->ts.kind < 4)
4124         se->expr = convert (type, se->expr);
4125
4126       return;
4127     }
4128   type = TREE_TYPE (args[0]);
4129
4130   /* Evaluate arguments only once.  */
4131   args[0] = gfc_evaluate_now (args[0], &se->pre);
4132   args[1] = gfc_evaluate_now (args[1], &se->pre);
4133
4134   /* Rotate left if positive.  */
4135   lrot = fold_build2_loc (input_location, LROTATE_EXPR, type, args[0], args[1]);
4136
4137   /* Rotate right if negative.  */
4138   tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (args[1]),
4139                          args[1]);
4140   rrot = fold_build2_loc (input_location,RROTATE_EXPR, type, args[0], tmp);
4141
4142   zero = build_int_cst (TREE_TYPE (args[1]), 0);
4143   tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node, args[1],
4144                          zero);
4145   rrot = fold_build3_loc (input_location, COND_EXPR, type, tmp, lrot, rrot);
4146
4147   /* Do nothing if shift == 0.  */
4148   tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, args[1],
4149                          zero);
4150   se->expr = fold_build3_loc (input_location, COND_EXPR, type, tmp, args[0],
4151                               rrot);
4152 }
4153
4154
4155 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
4156                         : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
4157
4158    The conditional expression is necessary because the result of LEADZ(0)
4159    is defined, but the result of __builtin_clz(0) is undefined for most
4160    targets.
4161
4162    For INTEGER kinds smaller than the C 'int' type, we have to subtract the
4163    difference in bit size between the argument of LEADZ and the C int.  */
4164  
4165 static void
4166 gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
4167 {
4168   tree arg;
4169   tree arg_type;
4170   tree cond;
4171   tree result_type;
4172   tree leadz;
4173   tree bit_size;
4174   tree tmp;
4175   tree func;
4176   int s, argsize;
4177
4178   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4179   argsize = TYPE_PRECISION (TREE_TYPE (arg));
4180
4181   /* Which variant of __builtin_clz* should we call?  */
4182   if (argsize <= INT_TYPE_SIZE)
4183     {
4184       arg_type = unsigned_type_node;
4185       func = builtin_decl_explicit (BUILT_IN_CLZ);
4186     }
4187   else if (argsize <= LONG_TYPE_SIZE)
4188     {
4189       arg_type = long_unsigned_type_node;
4190       func = builtin_decl_explicit (BUILT_IN_CLZL);
4191     }
4192   else if (argsize <= LONG_LONG_TYPE_SIZE)
4193     {
4194       arg_type = long_long_unsigned_type_node;
4195       func = builtin_decl_explicit (BUILT_IN_CLZLL);
4196     }
4197   else
4198     {
4199       gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
4200       arg_type = gfc_build_uint_type (argsize);
4201       func = NULL_TREE;
4202     }
4203
4204   /* Convert the actual argument twice: first, to the unsigned type of the
4205      same size; then, to the proper argument type for the built-in
4206      function.  But the return type is of the default INTEGER kind.  */
4207   arg = fold_convert (gfc_build_uint_type (argsize), arg);
4208   arg = fold_convert (arg_type, arg);
4209   arg = gfc_evaluate_now (arg, &se->pre);
4210   result_type = gfc_get_int_type (gfc_default_integer_kind);
4211
4212   /* Compute LEADZ for the case i .ne. 0.  */
4213   if (func)
4214     {
4215       s = TYPE_PRECISION (arg_type) - argsize;
4216       tmp = fold_convert (result_type,
4217                           build_call_expr_loc (input_location, func,
4218                                                1, arg));
4219       leadz = fold_build2_loc (input_location, MINUS_EXPR, result_type,
4220                                tmp, build_int_cst (result_type, s));
4221     }
4222   else
4223     {
4224       /* We end up here if the argument type is larger than 'long long'.
4225          We generate this code:
4226   
4227             if (x & (ULL_MAX << ULL_SIZE) != 0)
4228               return clzll ((unsigned long long) (x >> ULLSIZE));
4229             else
4230               return ULL_SIZE + clzll ((unsigned long long) x);
4231          where ULL_MAX is the largest value that a ULL_MAX can hold
4232          (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
4233          is the bit-size of the long long type (64 in this example).  */
4234       tree ullsize, ullmax, tmp1, tmp2, btmp;
4235
4236       ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
4237       ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
4238                                 long_long_unsigned_type_node,
4239                                 build_int_cst (long_long_unsigned_type_node,
4240                                                0));
4241
4242       cond = fold_build2_loc (input_location, LSHIFT_EXPR, arg_type,
4243                               fold_convert (arg_type, ullmax), ullsize);
4244       cond = fold_build2_loc (input_location, BIT_AND_EXPR, arg_type,
4245                               arg, cond);
4246       cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
4247                               cond, build_int_cst (arg_type, 0));
4248
4249       tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
4250                               arg, ullsize);
4251       tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
4252       btmp = builtin_decl_explicit (BUILT_IN_CLZLL);
4253       tmp1 = fold_convert (result_type,
4254                            build_call_expr_loc (input_location, btmp, 1, tmp1));
4255
4256       tmp2 = fold_convert (long_long_unsigned_type_node, arg);
4257       btmp = builtin_decl_explicit (BUILT_IN_CLZLL);
4258       tmp2 = fold_convert (result_type,
4259                            build_call_expr_loc (input_location, btmp, 1, tmp2));
4260       tmp2 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
4261                               tmp2, ullsize);
4262
4263       leadz = fold_build3_loc (input_location, COND_EXPR, result_type,
4264                                cond, tmp1, tmp2);
4265     }
4266
4267   /* Build BIT_SIZE.  */
4268   bit_size = build_int_cst (result_type, argsize);
4269
4270   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4271                           arg, build_int_cst (arg_type, 0));
4272   se->expr = fold_build3_loc (input_location, COND_EXPR, result_type, cond,
4273                               bit_size, leadz);
4274 }
4275
4276
4277 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
4278
4279    The conditional expression is necessary because the result of TRAILZ(0)
4280    is defined, but the result of __builtin_ctz(0) is undefined for most
4281    targets.  */
4282  
4283 static void
4284 gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
4285 {
4286   tree arg;
4287   tree arg_type;
4288   tree cond;
4289   tree result_type;
4290   tree trailz;
4291   tree bit_size;
4292   tree func;
4293   int argsize;
4294
4295   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4296   argsize = TYPE_PRECISION (TREE_TYPE (arg));
4297
4298   /* Which variant of __builtin_ctz* should we call?  */
4299   if (argsize <= INT_TYPE_SIZE)
4300     {
4301       arg_type = unsigned_type_node;
4302       func = builtin_decl_explicit (BUILT_IN_CTZ);
4303     }
4304   else if (argsize <= LONG_TYPE_SIZE)
4305     {
4306       arg_type = long_unsigned_type_node;
4307       func = builtin_decl_explicit (BUILT_IN_CTZL);
4308     }
4309   else if (argsize <= LONG_LONG_TYPE_SIZE)
4310     {
4311       arg_type = long_long_unsigned_type_node;
4312       func = builtin_decl_explicit (BUILT_IN_CTZLL);
4313     }
4314   else
4315     {
4316       gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
4317       arg_type = gfc_build_uint_type (argsize);
4318       func = NULL_TREE;
4319     }
4320
4321   /* Convert the actual argument twice: first, to the unsigned type of the
4322      same size; then, to the proper argument type for the built-in
4323      function.  But the return type is of the default INTEGER kind.  */
4324   arg = fold_convert (gfc_build_uint_type (argsize), arg);
4325   arg = fold_convert (arg_type, arg);
4326   arg = gfc_evaluate_now (arg, &se->pre);
4327   result_type = gfc_get_int_type (gfc_default_integer_kind);
4328
4329   /* Compute TRAILZ for the case i .ne. 0.  */
4330   if (func)
4331     trailz = fold_convert (result_type, build_call_expr_loc (input_location,
4332                                                              func, 1, arg));
4333   else
4334     {
4335       /* We end up here if the argument type is larger than 'long long'.
4336          We generate this code:
4337   
4338             if ((x & ULL_MAX) == 0)
4339               return ULL_SIZE + ctzll ((unsigned long long) (x >> ULLSIZE));
4340             else
4341               return ctzll ((unsigned long long) x);
4342
4343          where ULL_MAX is the largest value that a ULL_MAX can hold
4344          (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
4345          is the bit-size of the long long type (64 in this example).  */
4346       tree ullsize, ullmax, tmp1, tmp2, btmp;
4347
4348       ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
4349       ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
4350                                 long_long_unsigned_type_node,
4351                                 build_int_cst (long_long_unsigned_type_node, 0));
4352
4353       cond = fold_build2_loc (input_location, BIT_AND_EXPR, arg_type, arg,
4354                               fold_convert (arg_type, ullmax));
4355       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, cond,
4356                               build_int_cst (arg_type, 0));
4357
4358       tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
4359                               arg, ullsize);
4360       tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
4361       btmp = builtin_decl_explicit (BUILT_IN_CTZLL);
4362       tmp1 = fold_convert (result_type,
4363                            build_call_expr_loc (input_location, btmp, 1, tmp1));
4364       tmp1 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
4365                               tmp1, ullsize);
4366
4367       tmp2 = fold_convert (long_long_unsigned_type_node, arg);
4368       btmp = builtin_decl_explicit (BUILT_IN_CTZLL);
4369       tmp2 = fold_convert (result_type,
4370                            build_call_expr_loc (input_location, btmp, 1, tmp2));
4371
4372       trailz = fold_build3_loc (input_location, COND_EXPR, result_type,
4373                                 cond, tmp1, tmp2);
4374     }
4375
4376   /* Build BIT_SIZE.  */
4377   bit_size = build_int_cst (result_type, argsize);
4378
4379   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4380                           arg, build_int_cst (arg_type, 0));
4381   se->expr = fold_build3_loc (input_location, COND_EXPR, result_type, cond,
4382                               bit_size, trailz);
4383 }
4384
4385 /* Using __builtin_popcount for POPCNT and __builtin_parity for POPPAR;
4386    for types larger than "long long", we call the long long built-in for
4387    the lower and higher bits and combine the result.  */
4388  
4389 static void
4390 gfc_conv_intrinsic_popcnt_poppar (gfc_se * se, gfc_expr *expr, int parity)
4391 {
4392   tree arg;
4393   tree arg_type;
4394   tree result_type;
4395   tree func;
4396   int argsize;
4397
4398   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4399   argsize = TYPE_PRECISION (TREE_TYPE (arg));
4400   result_type = gfc_get_int_type (gfc_default_integer_kind);
4401
4402   /* Which variant of the builtin should we call?  */
4403   if (argsize <= INT_TYPE_SIZE)
4404     {
4405       arg_type = unsigned_type_node;
4406       func = builtin_decl_explicit (parity
4407                                     ? BUILT_IN_PARITY
4408                                     : BUILT_IN_POPCOUNT);
4409     }
4410   else if (argsize <= LONG_TYPE_SIZE)
4411     {
4412       arg_type = long_unsigned_type_node;
4413       func = builtin_decl_explicit (parity
4414                                     ? BUILT_IN_PARITYL
4415                                     : BUILT_IN_POPCOUNTL);
4416     }
4417   else if (argsize <= LONG_LONG_TYPE_SIZE)
4418     {
4419       arg_type = long_long_unsigned_type_node;
4420       func = builtin_decl_explicit (parity
4421                                     ? BUILT_IN_PARITYLL
4422                                     : BUILT_IN_POPCOUNTLL);
4423     }
4424   else
4425     {
4426       /* Our argument type is larger than 'long long', which mean none
4427          of the POPCOUNT builtins covers it.  We thus call the 'long long'
4428          variant multiple times, and add the results.  */
4429       tree utype, arg2, call1, call2;
4430
4431       /* For now, we only cover the case where argsize is twice as large
4432          as 'long long'.  */
4433       gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
4434
4435       func = builtin_decl_explicit (parity
4436                                     ? BUILT_IN_PARITYLL
4437                                     : BUILT_IN_POPCOUNTLL);
4438
4439       /* Convert it to an integer, and store into a variable.  */
4440       utype = gfc_build_uint_type (argsize);
4441       arg = fold_convert (utype, arg);
4442       arg = gfc_evaluate_now (arg, &se->pre);
4443
4444       /* Call the builtin twice.  */
4445       call1 = build_call_expr_loc (input_location, func, 1,
4446                                    fold_convert (long_long_unsigned_type_node,
4447                                                  arg));
4448
4449       arg2 = fold_build2_loc (input_location, RSHIFT_EXPR, utype, arg,
4450                               build_int_cst (utype, LONG_LONG_TYPE_SIZE));
4451       call2 = build_call_expr_loc (input_location, func, 1,
4452                                    fold_convert (long_long_unsigned_type_node,
4453                                                  arg2));
4454                           
4455       /* Combine the results.  */
4456       if (parity)
4457         se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, result_type,
4458                                     call1, call2);
4459       else
4460         se->expr = fold_build2_loc (input_location, PLUS_EXPR, result_type,
4461                                     call1, call2);
4462
4463       return;
4464     }
4465
4466   /* Convert the actual argument twice: first, to the unsigned type of the
4467      same size; then, to the proper argument type for the built-in
4468      function.  */
4469   arg = fold_convert (gfc_build_uint_type (argsize), arg);
4470   arg = fold_convert (arg_type, arg);
4471
4472   se->expr = fold_convert (result_type,
4473                            build_call_expr_loc (input_location, func, 1, arg));
4474 }
4475
4476
4477 /* Process an intrinsic with unspecified argument-types that has an optional
4478    argument (which could be of type character), e.g. EOSHIFT.  For those, we
4479    need to append the string length of the optional argument if it is not
4480    present and the type is really character.
4481    primary specifies the position (starting at 1) of the non-optional argument
4482    specifying the type and optional gives the position of the optional
4483    argument in the arglist.  */
4484
4485 static void
4486 conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
4487                                      unsigned primary, unsigned optional)
4488 {
4489   gfc_actual_arglist* prim_arg;
4490   gfc_actual_arglist* opt_arg;
4491   unsigned cur_pos;
4492   gfc_actual_arglist* arg;
4493   gfc_symbol* sym;
4494   VEC(tree,gc) *append_args;
4495
4496   /* Find the two arguments given as position.  */
4497   cur_pos = 0;
4498   prim_arg = NULL;
4499   opt_arg = NULL;
4500   for (arg = expr->value.function.actual; arg; arg = arg->next)
4501     {
4502       ++cur_pos;
4503
4504       if (cur_pos == primary)
4505         prim_arg = arg;
4506       if (cur_pos == optional)
4507         opt_arg = arg;
4508
4509       if (cur_pos >= primary && cur_pos >= optional)
4510         break;
4511     }
4512   gcc_assert (prim_arg);
4513   gcc_assert (prim_arg->expr);
4514   gcc_assert (opt_arg);
4515
4516   /* If we do have type CHARACTER and the optional argument is really absent,
4517      append a dummy 0 as string length.  */
4518   append_args = NULL;
4519   if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
4520     {
4521       tree dummy;
4522
4523       dummy = build_int_cst (gfc_charlen_type_node, 0);
4524       append_args = VEC_alloc (tree, gc, 1);
4525       VEC_quick_push (tree, append_args, dummy);
4526     }
4527
4528   /* Build the call itself.  */
4529   sym = gfc_get_symbol_for_expr (expr);
4530   gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
4531                           append_args);
4532   free (sym);
4533 }
4534
4535
4536 /* The length of a character string.  */
4537 static void
4538 gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
4539 {
4540   tree len;
4541   tree type;
4542   tree decl;
4543   gfc_symbol *sym;
4544   gfc_se argse;
4545   gfc_expr *arg;
4546   gfc_ss *ss;
4547
4548   gcc_assert (!se->ss);
4549
4550   arg = expr->value.function.actual->expr;
4551
4552   type = gfc_typenode_for_spec (&expr->ts);
4553   switch (arg->expr_type)
4554     {
4555     case EXPR_CONSTANT:
4556       len = build_int_cst (gfc_charlen_type_node, arg->value.character.length);
4557       break;
4558
4559     case EXPR_ARRAY:
4560       /* Obtain the string length from the function used by
4561          trans-array.c(gfc_trans_array_constructor).  */
4562       len = NULL_TREE;
4563       get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
4564       break;
4565
4566     case EXPR_VARIABLE:
4567       if (arg->ref == NULL
4568             || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
4569         {
4570           /* This doesn't catch all cases.
4571              See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
4572              and the surrounding thread.  */
4573           sym = arg->symtree->n.sym;
4574           decl = gfc_get_symbol_decl (sym);
4575           if (decl == current_function_decl && sym->attr.function
4576                 && (sym->result == sym))
4577             decl = gfc_get_fake_result_decl (sym, 0);
4578
4579           len = sym->ts.u.cl->backend_decl;
4580           gcc_assert (len);
4581           break;
4582         }
4583
4584       /* Otherwise fall through.  */
4585
4586     default:
4587       /* Anybody stupid enough to do this deserves inefficient code.  */
4588       ss = gfc_walk_expr (arg);
4589       gfc_init_se (&argse, se);
4590       if (ss == gfc_ss_terminator)
4591         gfc_conv_expr (&argse, arg);
4592       else
4593         gfc_conv_expr_descriptor (&argse, arg, ss);
4594       gfc_add_block_to_block (&se->pre, &argse.pre);
4595       gfc_add_block_to_block (&se->post, &argse.post);
4596       len = argse.string_length;
4597       break;
4598     }
4599   se->expr = convert (type, len);
4600 }
4601
4602 /* The length of a character string not including trailing blanks.  */
4603 static void
4604 gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
4605 {
4606   int kind = expr->value.function.actual->expr->ts.kind;
4607   tree args[2], type, fndecl;
4608
4609   gfc_conv_intrinsic_function_args (se, expr, args, 2);
4610   type = gfc_typenode_for_spec (&expr->ts);
4611
4612   if (kind == 1)
4613     fndecl = gfor_fndecl_string_len_trim;
4614   else if (kind == 4)
4615     fndecl = gfor_fndecl_string_len_trim_char4;
4616   else
4617     gcc_unreachable ();
4618
4619   se->expr = build_call_expr_loc (input_location,
4620                               fndecl, 2, args[0], args[1]);
4621   se->expr = convert (type, se->expr);
4622 }
4623
4624
4625 /* Returns the starting position of a substring within a string.  */
4626
4627 static void
4628 gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
4629                                       tree function)
4630 {
4631   tree logical4_type_node = gfc_get_logical_type (4);
4632   tree type;
4633   tree fndecl;
4634   tree *args;
4635   unsigned int num_args;
4636
4637   args = XALLOCAVEC (tree, 5);
4638
4639   /* Get number of arguments; characters count double due to the
4640      string length argument. Kind= is not passed to the library
4641      and thus ignored.  */
4642   if (expr->value.function.actual->next->next->expr == NULL)
4643     num_args = 4;
4644   else
4645     num_args = 5;
4646
4647   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
4648   type = gfc_typenode_for_spec (&expr->ts);
4649
4650   if (num_args == 4)
4651     args[4] = build_int_cst (logical4_type_node, 0);
4652   else
4653     args[4] = convert (logical4_type_node, args[4]);
4654
4655   fndecl = build_addr (function, current_function_decl);
4656   se->expr = build_call_array_loc (input_location,
4657                                TREE_TYPE (TREE_TYPE (function)), fndecl,
4658                                5, args);
4659   se->expr = convert (type, se->expr);
4660
4661 }
4662
4663 /* The ascii value for a single character.  */
4664 static void
4665 gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
4666 {
4667   tree args[2], type, pchartype;
4668
4669   gfc_conv_intrinsic_function_args (se, expr, args, 2);
4670   gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
4671   pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
4672   args[1] = fold_build1_loc (input_location, NOP_EXPR, pchartype, args[1]);
4673   type = gfc_typenode_for_spec (&expr->ts);
4674
4675   se->expr = build_fold_indirect_ref_loc (input_location,
4676                                       args[1]);
4677   se->expr = convert (type, se->expr);
4678 }
4679
4680
4681 /* Intrinsic ISNAN calls __builtin_isnan.  */
4682
4683 static void
4684 gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
4685 {
4686   tree arg;
4687
4688   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4689   se->expr = build_call_expr_loc (input_location,
4690                                   builtin_decl_explicit (BUILT_IN_ISNAN),
4691                                   1, arg);
4692   STRIP_TYPE_NOPS (se->expr);
4693   se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
4694 }
4695
4696
4697 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
4698    their argument against a constant integer value.  */
4699
4700 static void
4701 gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
4702 {
4703   tree arg;
4704
4705   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4706   se->expr = fold_build2_loc (input_location, EQ_EXPR,
4707                               gfc_typenode_for_spec (&expr->ts),
4708                               arg, build_int_cst (TREE_TYPE (arg), value));
4709 }
4710
4711
4712
4713 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource.  */
4714
4715 static void
4716 gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
4717 {
4718   tree tsource;
4719   tree fsource;
4720   tree mask;
4721   tree type;
4722   tree len, len2;
4723   tree *args;
4724   unsigned int num_args;
4725
4726   num_args = gfc_intrinsic_argument_list_length (expr);
4727   args = XALLOCAVEC (tree, num_args);
4728
4729   gfc_conv_intrinsic_function_args (se, expr, args, num_args);
4730   if (expr->ts.type != BT_CHARACTER)
4731     {
4732       tsource = args[0];
4733       fsource = args[1];
4734       mask = args[2];
4735     }
4736   else
4737     {
4738       /* We do the same as in the non-character case, but the argument
4739          list is different because of the string length arguments. We
4740          also have to set the string length for the result.  */
4741       len = args[0];
4742       tsource = args[1];
4743       len2 = args[2];
4744       fsource = args[3];
4745       mask = args[4];
4746
4747       gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
4748                                    &se->pre);
4749       se->string_length = len;
4750     }
4751   type = TREE_TYPE (tsource);
4752   se->expr = fold_build3_loc (input_location, COND_EXPR, type, mask, tsource,
4753                               fold_convert (type, fsource));
4754 }
4755
4756
4757 /* MERGE_BITS (I, J, MASK) = (I & MASK) | (I & (~MASK)).  */
4758
4759 static void
4760 gfc_conv_intrinsic_merge_bits (gfc_se * se, gfc_expr * expr)
4761 {
4762   tree args[3], mask, type;
4763
4764   gfc_conv_intrinsic_function_args (se, expr, args, 3);
4765   mask = gfc_evaluate_now (args[2], &se->pre);
4766
4767   type = TREE_TYPE (args[0]);
4768   gcc_assert (TREE_TYPE (args[1]) == type);
4769   gcc_assert (TREE_TYPE (mask) == type);
4770
4771   args[0] = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], mask);
4772   args[1] = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[1],
4773                              fold_build1_loc (input_location, BIT_NOT_EXPR,
4774                                               type, mask));
4775   se->expr = fold_build2_loc (input_location, BIT_IOR_EXPR, type,
4776                               args[0], args[1]);
4777 }
4778
4779
4780 /* MASKL(n)  =  n == 0 ? 0 : (~0) << (BIT_SIZE - n)
4781    MASKR(n)  =  n == BIT_SIZE ? ~0 : ~((~0) << n)  */
4782
4783 static void
4784 gfc_conv_intrinsic_mask (gfc_se * se, gfc_expr * expr, int left)
4785 {
4786   tree arg, allones, type, utype, res, cond, bitsize;
4787   int i;
4788  
4789   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4790   arg = gfc_evaluate_now (arg, &se->pre);
4791
4792   type = gfc_get_int_type (expr->ts.kind);
4793   utype = unsigned_type_for (type);
4794
4795   i = gfc_validate_kind (BT_INTEGER, expr->ts.kind, false);
4796   bitsize = build_int_cst (TREE_TYPE (arg), gfc_integer_kinds[i].bit_size);
4797
4798   allones = fold_build1_loc (input_location, BIT_NOT_EXPR, utype,
4799                              build_int_cst (utype, 0));
4800
4801   if (left)
4802     {
4803       /* Left-justified mask.  */
4804       res = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (arg),
4805                              bitsize, arg);
4806       res = fold_build2_loc (input_location, LSHIFT_EXPR, utype, allones,
4807                              fold_convert (utype, res));
4808
4809       /* Special case arg == 0, because SHIFT_EXPR wants a shift strictly
4810          smaller than type width.  */
4811       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, arg,
4812                               build_int_cst (TREE_TYPE (arg), 0));
4813       res = fold_build3_loc (input_location, COND_EXPR, utype, cond,
4814                              build_int_cst (utype, 0), res);
4815     }
4816   else
4817     {
4818       /* Right-justified mask.  */
4819       res = fold_build2_loc (input_location, LSHIFT_EXPR, utype, allones,
4820                              fold_convert (utype, arg));
4821       res = fold_build1_loc (input_location, BIT_NOT_EXPR, utype, res);
4822
4823       /* Special case agr == bit_size, because SHIFT_EXPR wants a shift
4824          strictly smaller than type width.  */
4825       cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
4826                               arg, bitsize);
4827       res = fold_build3_loc (input_location, COND_EXPR, utype,
4828                              cond, allones, res);
4829     }
4830
4831   se->expr = fold_convert (type, res);
4832 }
4833
4834
4835 /* FRACTION (s) is translated into frexp (s, &dummy_int).  */
4836 static void
4837 gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
4838 {
4839   tree arg, type, tmp, frexp;
4840
4841   frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4842
4843   type = gfc_typenode_for_spec (&expr->ts);
4844   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4845   tmp = gfc_create_var (integer_type_node, NULL);
4846   se->expr = build_call_expr_loc (input_location, frexp, 2,
4847                                   fold_convert (type, arg),
4848                                   gfc_build_addr_expr (NULL_TREE, tmp));
4849   se->expr = fold_convert (type, se->expr);
4850 }
4851
4852
4853 /* NEAREST (s, dir) is translated into
4854      tmp = copysign (HUGE_VAL, dir);
4855      return nextafter (s, tmp);
4856  */
4857 static void
4858 gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
4859 {
4860   tree args[2], type, tmp, nextafter, copysign, huge_val;
4861
4862   nextafter = gfc_builtin_decl_for_float_kind (BUILT_IN_NEXTAFTER, expr->ts.kind);
4863   copysign = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
4864
4865   type = gfc_typenode_for_spec (&expr->ts);
4866   gfc_conv_intrinsic_function_args (se, expr, args, 2);
4867
4868   huge_val = gfc_build_inf_or_huge (type, expr->ts.kind);
4869   tmp = build_call_expr_loc (input_location, copysign, 2, huge_val,
4870                              fold_convert (type, args[1]));
4871   se->expr = build_call_expr_loc (input_location, nextafter, 2,
4872                                   fold_convert (type, args[0]), tmp);
4873   se->expr = fold_convert (type, se->expr);
4874 }
4875
4876
4877 /* SPACING (s) is translated into
4878     int e;
4879     if (s == 0)
4880       res = tiny;
4881     else
4882     {
4883       frexp (s, &e);
4884       e = e - prec;
4885       e = MAX_EXPR (e, emin);
4886       res = scalbn (1., e);
4887     }
4888     return res;
4889
4890  where prec is the precision of s, gfc_real_kinds[k].digits,
4891        emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
4892    and tiny is tiny(s), gfc_real_kinds[k].tiny.  */
4893
4894 static void
4895 gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
4896 {
4897   tree arg, type, prec, emin, tiny, res, e;
4898   tree cond, tmp, frexp, scalbn;
4899   int k;
4900   stmtblock_t block;
4901
4902   k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
4903   prec = build_int_cst (integer_type_node, gfc_real_kinds[k].digits);
4904   emin = build_int_cst (integer_type_node, gfc_real_kinds[k].min_exponent - 1);
4905   tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);
4906
4907   frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4908   scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
4909
4910   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4911   arg = gfc_evaluate_now (arg, &se->pre);
4912
4913   type = gfc_typenode_for_spec (&expr->ts);
4914   e = gfc_create_var (integer_type_node, NULL);
4915   res = gfc_create_var (type, NULL);
4916
4917
4918   /* Build the block for s /= 0.  */
4919   gfc_start_block (&block);
4920   tmp = build_call_expr_loc (input_location, frexp, 2, arg,
4921                              gfc_build_addr_expr (NULL_TREE, e));
4922   gfc_add_expr_to_block (&block, tmp);
4923
4924   tmp = fold_build2_loc (input_location, MINUS_EXPR, integer_type_node, e,
4925                          prec);
4926   gfc_add_modify (&block, e, fold_build2_loc (input_location, MAX_EXPR,
4927                                               integer_type_node, tmp, emin));
4928
4929   tmp = build_call_expr_loc (input_location, scalbn, 2,
4930                          build_real_from_int_cst (type, integer_one_node), e);
4931   gfc_add_modify (&block, res, tmp);
4932
4933   /* Finish by building the IF statement.  */
4934   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, arg,
4935                           build_real_from_int_cst (type, integer_zero_node));
4936   tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
4937                   gfc_finish_block (&block));
4938
4939   gfc_add_expr_to_block (&se->pre, tmp);
4940   se->expr = res;
4941 }
4942
4943
4944 /* RRSPACING (s) is translated into
4945       int e;
4946       real x;
4947       x = fabs (s);
4948       if (x != 0)
4949       {
4950         frexp (s, &e);
4951         x = scalbn (x, precision - e);
4952       }
4953       return x;
4954
4955  where precision is gfc_real_kinds[k].digits.  */
4956
4957 static void
4958 gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
4959 {
4960   tree arg, type, e, x, cond, stmt, tmp, frexp, scalbn, fabs;
4961   int prec, k;
4962   stmtblock_t block;
4963
4964   k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
4965   prec = gfc_real_kinds[k].digits;
4966
4967   frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
4968   scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
4969   fabs = gfc_builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);
4970
4971   type = gfc_typenode_for_spec (&expr->ts);
4972   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
4973   arg = gfc_evaluate_now (arg, &se->pre);
4974
4975   e = gfc_create_var (integer_type_node, NULL);
4976   x = gfc_create_var (type, NULL);
4977   gfc_add_modify (&se->pre, x,
4978                   build_call_expr_loc (input_location, fabs, 1, arg));
4979
4980
4981   gfc_start_block (&block);
4982   tmp = build_call_expr_loc (input_location, frexp, 2, arg,
4983                              gfc_build_addr_expr (NULL_TREE, e));
4984   gfc_add_expr_to_block (&block, tmp);
4985
4986   tmp = fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
4987                          build_int_cst (integer_type_node, prec), e);
4988   tmp = build_call_expr_loc (input_location, scalbn, 2, x, tmp);
4989   gfc_add_modify (&block, x, tmp);
4990   stmt = gfc_finish_block (&block);
4991
4992   cond = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, x,
4993                           build_real_from_int_cst (type, integer_zero_node));
4994   tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));
4995   gfc_add_expr_to_block (&se->pre, tmp);
4996
4997   se->expr = fold_convert (type, x);
4998 }
4999
5000
5001 /* SCALE (s, i) is translated into scalbn (s, i).  */
5002 static void
5003 gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
5004 {
5005   tree args[2], type, scalbn;
5006
5007   scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
5008
5009   type = gfc_typenode_for_spec (&expr->ts);
5010   gfc_conv_intrinsic_function_args (se, expr, args, 2);
5011   se->expr = build_call_expr_loc (input_location, scalbn, 2,
5012                                   fold_convert (type, args[0]),
5013                                   fold_convert (integer_type_node, args[1]));
5014   se->expr = fold_convert (type, se->expr);
5015 }
5016
5017
5018 /* SET_EXPONENT (s, i) is translated into
5019    scalbn (frexp (s, &dummy_int), i).  */
5020 static void
5021 gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
5022 {
5023   tree args[2], type, tmp, frexp, scalbn;
5024
5025   frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
5026   scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
5027
5028   type = gfc_typenode_for_spec (&expr->ts);
5029   gfc_conv_intrinsic_function_args (se, expr, args, 2);
5030
5031   tmp = gfc_create_var (integer_type_node, NULL);
5032   tmp = build_call_expr_loc (input_location, frexp, 2,
5033                              fold_convert (type, args[0]),
5034                              gfc_build_addr_expr (NULL_TREE, tmp));
5035   se->expr = build_call_expr_loc (input_location, scalbn, 2, tmp,
5036                                   fold_convert (integer_type_node, args[1]));
5037   se->expr = fold_convert (type, se->expr);
5038 }
5039
5040
5041 static void
5042 gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
5043 {
5044   gfc_actual_arglist *actual;
5045   tree arg1;
5046   tree type;
5047   tree fncall0;
5048   tree fncall1;
5049   gfc_se argse;
5050   gfc_ss *ss;
5051
5052   gfc_init_se (&argse, NULL);
5053   actual = expr->value.function.actual;
5054
5055   if (actual->expr->ts.type == BT_CLASS)
5056     gfc_add_class_array_ref (actual->expr);
5057
5058   ss = gfc_walk_expr (actual->expr);
5059   gcc_assert (ss != gfc_ss_terminator);
5060   argse.want_pointer = 1;
5061   argse.data_not_needed = 1;
5062   gfc_conv_expr_descriptor (&argse, actual->expr, ss);
5063   gfc_add_block_to_block (&se->pre, &argse.pre);
5064   gfc_add_block_to_block (&se->post, &argse.post);
5065   arg1 = gfc_evaluate_now (argse.expr, &se->pre);
5066
5067   /* Build the call to size0.  */
5068   fncall0 = build_call_expr_loc (input_location,
5069                              gfor_fndecl_size0, 1, arg1);
5070
5071   actual = actual->next;
5072
5073   if (actual->expr)
5074     {
5075       gfc_init_se (&argse, NULL);
5076       gfc_conv_expr_type (&argse, actual->expr,
5077                           gfc_array_index_type);
5078       gfc_add_block_to_block (&se->pre, &argse.pre);
5079
5080       /* Unusually, for an intrinsic, size does not exclude
5081          an optional arg2, so we must test for it.  */  
5082       if (actual->expr->expr_type == EXPR_VARIABLE
5083             && actual->expr->symtree->n.sym->attr.dummy
5084             && actual->expr->symtree->n.sym->attr.optional)
5085         {
5086           tree tmp;
5087           /* Build the call to size1.  */
5088           fncall1 = build_call_expr_loc (input_location,
5089                                      gfor_fndecl_size1, 2,
5090                                      arg1, argse.expr);
5091
5092           gfc_init_se (&argse, NULL);
5093           argse.want_pointer = 1;
5094           argse.data_not_needed = 1;
5095           gfc_conv_expr (&argse, actual->expr);
5096           gfc_add_block_to_block (&se->pre, &argse.pre);
5097           tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5098                                  argse.expr, null_pointer_node);
5099           tmp = gfc_evaluate_now (tmp, &se->pre);
5100           se->expr = fold_build3_loc (input_location, COND_EXPR,
5101                                       pvoid_type_node, tmp, fncall1, fncall0);
5102         }
5103       else
5104         {
5105           se->expr = NULL_TREE;
5106           argse.expr = fold_build2_loc (input_location, MINUS_EXPR,
5107                                         gfc_array_index_type,
5108                                         argse.expr, gfc_index_one_node);
5109         }
5110     }
5111   else if (expr->value.function.actual->expr->rank == 1)
5112     {
5113       argse.expr = gfc_index_zero_node;
5114       se->expr = NULL_TREE;
5115     }
5116   else
5117     se->expr = fncall0;
5118
5119   if (se->expr == NULL_TREE)
5120     {
5121       tree ubound, lbound;
5122
5123       arg1 = build_fold_indirect_ref_loc (input_location,
5124                                       arg1);
5125       ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
5126       lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
5127       se->expr = fold_build2_loc (input_location, MINUS_EXPR,
5128                                   gfc_array_index_type, ubound, lbound);
5129       se->expr = fold_build2_loc (input_location, PLUS_EXPR,
5130                                   gfc_array_index_type,
5131                                   se->expr, gfc_index_one_node);
5132       se->expr = fold_build2_loc (input_location, MAX_EXPR,
5133                                   gfc_array_index_type, se->expr,
5134                                   gfc_index_zero_node);
5135     }
5136
5137   type = gfc_typenode_for_spec (&expr->ts);
5138   se->expr = convert (type, se->expr);
5139 }
5140
5141
5142 /* Helper function to compute the size of a character variable,
5143    excluding the terminating null characters.  The result has
5144    gfc_array_index_type type.  */
5145
5146 static tree
5147 size_of_string_in_bytes (int kind, tree string_length)
5148 {
5149   tree bytesize;
5150   int i = gfc_validate_kind (BT_CHARACTER, kind, false);
5151  
5152   bytesize = build_int_cst (gfc_array_index_type,
5153                             gfc_character_kinds[i].bit_size / 8);
5154
5155   return fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5156                           bytesize,
5157                           fold_convert (gfc_array_index_type, string_length));
5158 }
5159
5160
5161 static void
5162 gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
5163 {
5164   gfc_expr *arg;
5165   gfc_ss *ss;
5166   gfc_se argse;
5167   tree source_bytes;
5168   tree type;
5169   tree tmp;
5170   tree lower;
5171   tree upper;
5172   int n;
5173
5174   arg = expr->value.function.actual->expr;
5175
5176   gfc_init_se (&argse, NULL);
5177   ss = gfc_walk_expr (arg);
5178
5179   if (ss == gfc_ss_terminator)
5180     {
5181       if (arg->ts.type == BT_CLASS)
5182         gfc_add_data_component (arg);
5183
5184       gfc_conv_expr_reference (&argse, arg);
5185
5186       type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
5187                                                  argse.expr));
5188
5189       /* Obtain the source word length.  */
5190       if (arg->ts.type == BT_CHARACTER)
5191         se->expr = size_of_string_in_bytes (arg->ts.kind,
5192                                             argse.string_length);
5193       else
5194         se->expr = fold_convert (gfc_array_index_type, size_in_bytes (type)); 
5195     }
5196   else
5197     {
5198       source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
5199       argse.want_pointer = 0;
5200       gfc_conv_expr_descriptor (&argse, arg, ss);
5201       type = gfc_get_element_type (TREE_TYPE (argse.expr));
5202
5203       /* Obtain the argument's word length.  */
5204       if (arg->ts.type == BT_CHARACTER)
5205         tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
5206       else
5207         tmp = fold_convert (gfc_array_index_type,
5208                             size_in_bytes (type)); 
5209       gfc_add_modify (&argse.pre, source_bytes, tmp);
5210
5211       /* Obtain the size of the array in bytes.  */
5212       for (n = 0; n < arg->rank; n++)
5213         {
5214           tree idx;
5215           idx = gfc_rank_cst[n];
5216           lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
5217           upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
5218           tmp = fold_build2_loc (input_location, MINUS_EXPR,
5219                                  gfc_array_index_type, upper, lower);
5220           tmp = fold_build2_loc (input_location, PLUS_EXPR,
5221                                  gfc_array_index_type, tmp, gfc_index_one_node);
5222           tmp = fold_build2_loc (input_location, MULT_EXPR,
5223                                  gfc_array_index_type, tmp, source_bytes);
5224           gfc_add_modify (&argse.pre, source_bytes, tmp);
5225         }
5226       se->expr = source_bytes;
5227     }
5228
5229   gfc_add_block_to_block (&se->pre, &argse.pre);
5230 }
5231
5232
5233 static void
5234 gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
5235 {
5236   gfc_expr *arg;
5237   gfc_ss *ss;
5238   gfc_se argse,eight;
5239   tree type, result_type, tmp;
5240
5241   arg = expr->value.function.actual->expr;
5242   gfc_init_se (&eight, NULL);
5243   gfc_conv_expr (&eight, gfc_get_int_expr (expr->ts.kind, NULL, 8));
5244   
5245   gfc_init_se (&argse, NULL);
5246   ss = gfc_walk_expr (arg);
5247   result_type = gfc_get_int_type (expr->ts.kind);
5248
5249   if (ss == gfc_ss_terminator)
5250     {
5251       if (arg->ts.type == BT_CLASS)
5252       {
5253         gfc_add_vptr_component (arg);
5254         gfc_add_size_component (arg);
5255         gfc_conv_expr (&argse, arg);
5256         tmp = fold_convert (result_type, argse.expr);
5257         goto done;
5258       }
5259
5260       gfc_conv_expr_reference (&argse, arg);
5261       type = TREE_TYPE (build_fold_indirect_ref_loc (input_location, 
5262                                                      argse.expr));
5263     }
5264   else
5265     {
5266       argse.want_pointer = 0;
5267       gfc_conv_expr_descriptor (&argse, arg, ss);
5268       type = gfc_get_element_type (TREE_TYPE (argse.expr));
5269     }
5270     
5271   /* Obtain the argument's word length.  */
5272   if (arg->ts.type == BT_CHARACTER)
5273     tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
5274   else
5275     tmp = fold_convert (result_type, size_in_bytes (type)); 
5276
5277 done:
5278   se->expr = fold_build2_loc (input_location, MULT_EXPR, result_type, tmp,
5279                               eight.expr);
5280   gfc_add_block_to_block (&se->pre, &argse.pre);
5281 }
5282
5283
5284 /* Intrinsic string comparison functions.  */
5285
5286 static void
5287 gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
5288 {
5289   tree args[4];
5290
5291   gfc_conv_intrinsic_function_args (se, expr, args, 4);
5292
5293   se->expr
5294     = gfc_build_compare_string (args[0], args[1], args[2], args[3],
5295                                 expr->value.function.actual->expr->ts.kind,
5296                                 op);
5297   se->expr = fold_build2_loc (input_location, op,
5298                               gfc_typenode_for_spec (&expr->ts), se->expr,
5299                               build_int_cst (TREE_TYPE (se->expr), 0));
5300 }
5301
5302 /* Generate a call to the adjustl/adjustr library function.  */
5303 static void
5304 gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
5305 {
5306   tree args[3];
5307   tree len;
5308   tree type;
5309   tree var;
5310   tree tmp;
5311
5312   gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
5313   len = args[1];
5314
5315   type = TREE_TYPE (args[2]);
5316   var = gfc_conv_string_tmp (se, type, len);
5317   args[0] = var;
5318
5319   tmp = build_call_expr_loc (input_location,
5320                          fndecl, 3, args[0], args[1], args[2]);
5321   gfc_add_expr_to_block (&se->pre, tmp);
5322   se->expr = var;
5323   se->string_length = len;
5324 }
5325
5326
5327 /* Generate code for the TRANSFER intrinsic:
5328         For scalar results:
5329           DEST = TRANSFER (SOURCE, MOLD)
5330         where:
5331           typeof<DEST> = typeof<MOLD>
5332         and:
5333           MOLD is scalar.
5334
5335         For array results:
5336           DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
5337         where:
5338           typeof<DEST> = typeof<MOLD>
5339         and:
5340           N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
5341               sizeof (DEST(0) * SIZE).  */
5342 static void
5343 gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
5344 {
5345   tree tmp;
5346   tree tmpdecl;
5347   tree ptr;
5348   tree extent;
5349   tree source;
5350   tree source_type;
5351   tree source_bytes;
5352   tree mold_type;
5353   tree dest_word_len;
5354   tree size_words;
5355   tree size_bytes;
5356   tree upper;
5357   tree lower;
5358   tree stmt;
5359   gfc_actual_arglist *arg;
5360   gfc_se argse;
5361   gfc_ss *ss;
5362   gfc_array_info *info;
5363   stmtblock_t block;
5364   int n;
5365   bool scalar_mold;
5366
5367   info = NULL;
5368   if (se->loop)
5369     info = &se->ss->info->data.array;
5370
5371   /* Convert SOURCE.  The output from this stage is:-
5372         source_bytes = length of the source in bytes
5373         source = pointer to the source data.  */
5374   arg = expr->value.function.actual;
5375
5376   /* Ensure double transfer through LOGICAL preserves all
5377      the needed bits.  */
5378   if (arg->expr->expr_type == EXPR_FUNCTION
5379         && arg->expr->value.function.esym == NULL
5380         && arg->expr->value.function.isym != NULL
5381         && arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
5382         && arg->expr->ts.type == BT_LOGICAL
5383         && expr->ts.type != arg->expr->ts.type)
5384     arg->expr->value.function.name = "__transfer_in_transfer";
5385
5386   gfc_init_se (&argse, NULL);
5387   ss = gfc_walk_expr (arg->expr);
5388
5389   source_bytes = gfc_create_var (gfc_array_index_type, NULL);
5390
5391   /* Obtain the pointer to source and the length of source in bytes.  */
5392   if (ss == gfc_ss_terminator)
5393     {
5394       gfc_conv_expr_reference (&argse, arg->expr);
5395       source = argse.expr;
5396
5397       source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
5398                                                         argse.expr));
5399
5400       /* Obtain the source word length.  */
5401       if (arg->expr->ts.type == BT_CHARACTER)
5402         tmp = size_of_string_in_bytes (arg->expr->ts.kind,
5403                                        argse.string_length);
5404       else
5405         tmp = fold_convert (gfc_array_index_type,
5406                             size_in_bytes (source_type)); 
5407     }
5408   else
5409     {
5410       argse.want_pointer = 0;
5411       gfc_conv_expr_descriptor (&argse, arg->expr, ss);
5412       source = gfc_conv_descriptor_data_get (argse.expr);
5413       source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
5414
5415       /* Repack the source if not a full variable array.  */
5416       if (arg->expr->expr_type == EXPR_VARIABLE
5417               && arg->expr->ref->u.ar.type != AR_FULL)
5418         {
5419           tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
5420
5421           if (gfc_option.warn_array_temp)
5422             gfc_warning ("Creating array temporary at %L", &expr->where);
5423
5424           source = build_call_expr_loc (input_location,
5425                                     gfor_fndecl_in_pack, 1, tmp);
5426           source = gfc_evaluate_now (source, &argse.pre);
5427
5428           /* Free the temporary.  */
5429           gfc_start_block (&block);
5430           tmp = gfc_call_free (convert (pvoid_type_node, source));
5431           gfc_add_expr_to_block (&block, tmp);
5432           stmt = gfc_finish_block (&block);
5433
5434           /* Clean up if it was repacked.  */
5435           gfc_init_block (&block);
5436           tmp = gfc_conv_array_data (argse.expr);
5437           tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5438                                  source, tmp);
5439           tmp = build3_v (COND_EXPR, tmp, stmt,
5440                           build_empty_stmt (input_location));
5441           gfc_add_expr_to_block (&block, tmp);
5442           gfc_add_block_to_block (&block, &se->post);
5443           gfc_init_block (&se->post);
5444           gfc_add_block_to_block (&se->post, &block);
5445         }
5446
5447       /* Obtain the source word length.  */
5448       if (arg->expr->ts.type == BT_CHARACTER)
5449         tmp = size_of_string_in_bytes (arg->expr->ts.kind,
5450                                        argse.string_length);
5451       else
5452         tmp = fold_convert (gfc_array_index_type,
5453                             size_in_bytes (source_type)); 
5454
5455       /* Obtain the size of the array in bytes.  */
5456       extent = gfc_create_var (gfc_array_index_type, NULL);
5457       for (n = 0; n < arg->expr->rank; n++)
5458         {
5459           tree idx;
5460           idx = gfc_rank_cst[n];
5461           gfc_add_modify (&argse.pre, source_bytes, tmp);
5462           lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
5463           upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
5464           tmp = fold_build2_loc (input_location, MINUS_EXPR,
5465                                  gfc_array_index_type, upper, lower);
5466           gfc_add_modify (&argse.pre, extent, tmp);
5467           tmp = fold_build2_loc (input_location, PLUS_EXPR,
5468                                  gfc_array_index_type, extent,
5469                                  gfc_index_one_node);
5470           tmp = fold_build2_loc (input_location, MULT_EXPR,
5471                                  gfc_array_index_type, tmp, source_bytes);
5472         }
5473     }
5474
5475   gfc_add_modify (&argse.pre, source_bytes, tmp);
5476   gfc_add_block_to_block (&se->pre, &argse.pre);
5477   gfc_add_block_to_block (&se->post, &argse.post);
5478
5479   /* Now convert MOLD.  The outputs are:
5480         mold_type = the TREE type of MOLD
5481         dest_word_len = destination word length in bytes.  */
5482   arg = arg->next;
5483
5484   gfc_init_se (&argse, NULL);
5485   ss = gfc_walk_expr (arg->expr);
5486
5487   scalar_mold = arg->expr->rank == 0;
5488
5489   if (ss == gfc_ss_terminator)
5490     {
5491       gfc_conv_expr_reference (&argse, arg->expr);
5492       mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
5493                                                       argse.expr));
5494     }
5495   else
5496     {
5497       gfc_init_se (&argse, NULL);
5498       argse.want_pointer = 0;
5499       gfc_conv_expr_descriptor (&argse, arg->expr, ss);
5500       mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
5501     }
5502
5503   gfc_add_block_to_block (&se->pre, &argse.pre);
5504   gfc_add_block_to_block (&se->post, &argse.post);
5505
5506   if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
5507     {
5508       /* If this TRANSFER is nested in another TRANSFER, use a type
5509          that preserves all bits.  */
5510       if (arg->expr->ts.type == BT_LOGICAL)
5511         mold_type = gfc_get_int_type (arg->expr->ts.kind);
5512     }
5513
5514   if (arg->expr->ts.type == BT_CHARACTER)
5515     {
5516       tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
5517       mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
5518     }
5519   else
5520     tmp = fold_convert (gfc_array_index_type,
5521                         size_in_bytes (mold_type)); 
5522  
5523   dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
5524   gfc_add_modify (&se->pre, dest_word_len, tmp);
5525
5526   /* Finally convert SIZE, if it is present.  */
5527   arg = arg->next;
5528   size_words = gfc_create_var (gfc_array_index_type, NULL);
5529
5530   if (arg->expr)
5531     {
5532       gfc_init_se (&argse, NULL);
5533       gfc_conv_expr_reference (&argse, arg->expr);
5534       tmp = convert (gfc_array_index_type,
5535                      build_fold_indirect_ref_loc (input_location,
5536                                               argse.expr));
5537       gfc_add_block_to_block (&se->pre, &argse.pre);
5538       gfc_add_block_to_block (&se->post, &argse.post);
5539     }
5540   else
5541     tmp = NULL_TREE;
5542
5543   /* Separate array and scalar results.  */
5544   if (scalar_mold && tmp == NULL_TREE)
5545     goto scalar_transfer;
5546
5547   size_bytes = gfc_create_var (gfc_array_index_type, NULL);
5548   if (tmp != NULL_TREE)
5549     tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
5550                            tmp, dest_word_len);
5551   else
5552     tmp = source_bytes;
5553
5554   gfc_add_modify (&se->pre, size_bytes, tmp);
5555   gfc_add_modify (&se->pre, size_words,
5556                        fold_build2_loc (input_location, CEIL_DIV_EXPR,
5557                                         gfc_array_index_type,
5558                                         size_bytes, dest_word_len));
5559
5560   /* Evaluate the bounds of the result.  If the loop range exists, we have
5561      to check if it is too large.  If so, we modify loop->to be consistent
5562      with min(size, size(source)).  Otherwise, size is made consistent with
5563      the loop range, so that the right number of bytes is transferred.*/
5564   n = se->loop->order[0];
5565   if (se->loop->to[n] != NULL_TREE)
5566     {
5567       tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5568                              se->loop->to[n], se->loop->from[n]);
5569       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5570                              tmp, gfc_index_one_node);
5571       tmp = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
5572                          tmp, size_words);
5573       gfc_add_modify (&se->pre, size_words, tmp);
5574       gfc_add_modify (&se->pre, size_bytes,
5575                            fold_build2_loc (input_location, MULT_EXPR,
5576                                             gfc_array_index_type,
5577                                             size_words, dest_word_len));
5578       upper = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
5579                                size_words, se->loop->from[n]);
5580       upper = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5581                                upper, gfc_index_one_node);
5582     }
5583   else
5584     {
5585       upper = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
5586                                size_words, gfc_index_one_node);
5587       se->loop->from[n] = gfc_index_zero_node;
5588     }
5589
5590   se->loop->to[n] = upper;
5591
5592   /* Build a destination descriptor, using the pointer, source, as the
5593      data field.  */
5594   gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, mold_type,
5595                                NULL_TREE, false, true, false, &expr->where);
5596
5597   /* Cast the pointer to the result.  */
5598   tmp = gfc_conv_descriptor_data_get (info->descriptor);
5599   tmp = fold_convert (pvoid_type_node, tmp);
5600
5601   /* Use memcpy to do the transfer.  */
5602   tmp = build_call_expr_loc (input_location,
5603                          builtin_decl_explicit (BUILT_IN_MEMCPY),
5604                          3,
5605                          tmp,
5606                          fold_convert (pvoid_type_node, source),
5607                          fold_build2_loc (input_location, MIN_EXPR,
5608                                           gfc_array_index_type,
5609                                           size_bytes, source_bytes));
5610   gfc_add_expr_to_block (&se->pre, tmp);
5611
5612   se->expr = info->descriptor;
5613   if (expr->ts.type == BT_CHARACTER)
5614     se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len);
5615
5616   return;
5617
5618 /* Deal with scalar results.  */
5619 scalar_transfer:
5620   extent = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
5621                             dest_word_len, source_bytes);
5622   extent = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
5623                             extent, gfc_index_zero_node);
5624
5625   if (expr->ts.type == BT_CHARACTER)
5626     {
5627       tree direct;
5628       tree indirect;
5629
5630       ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
5631       tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
5632                                 "transfer");
5633
5634       /* If source is longer than the destination, use a pointer to
5635          the source directly.  */
5636       gfc_init_block (&block);
5637       gfc_add_modify (&block, tmpdecl, ptr);
5638       direct = gfc_finish_block (&block);
5639
5640       /* Otherwise, allocate a string with the length of the destination
5641          and copy the source into it.  */
5642       gfc_init_block (&block);
5643       tmp = gfc_get_pchar_type (expr->ts.kind);
5644       tmp = gfc_call_malloc (&block, tmp, dest_word_len);
5645       gfc_add_modify (&block, tmpdecl,
5646                       fold_convert (TREE_TYPE (ptr), tmp));
5647       tmp = build_call_expr_loc (input_location,
5648                              builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
5649                              fold_convert (pvoid_type_node, tmpdecl),
5650                              fold_convert (pvoid_type_node, ptr),
5651                              extent);
5652       gfc_add_expr_to_block (&block, tmp);
5653       indirect = gfc_finish_block (&block);
5654
5655       /* Wrap it up with the condition.  */
5656       tmp = fold_build2_loc (input_location, LE_EXPR, boolean_type_node,
5657                              dest_word_len, source_bytes);
5658       tmp = build3_v (COND_EXPR, tmp, direct, indirect);
5659       gfc_add_expr_to_block (&se->pre, tmp);
5660
5661       se->expr = tmpdecl;
5662       se->string_length = dest_word_len;
5663     }
5664   else
5665     {
5666       tmpdecl = gfc_create_var (mold_type, "transfer");
5667
5668       ptr = convert (build_pointer_type (mold_type), source);
5669
5670       /* Use memcpy to do the transfer.  */
5671       tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);
5672       tmp = build_call_expr_loc (input_location,
5673                              builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
5674                              fold_convert (pvoid_type_node, tmp),
5675                              fold_convert (pvoid_type_node, ptr),
5676                              extent);
5677       gfc_add_expr_to_block (&se->pre, tmp);
5678
5679       se->expr = tmpdecl;
5680     }
5681 }
5682
5683
5684 /* Generate code for the ALLOCATED intrinsic.
5685    Generate inline code that directly check the address of the argument.  */
5686
5687 static void
5688 gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
5689 {
5690   gfc_actual_arglist *arg1;
5691   gfc_se arg1se;
5692   gfc_ss *ss1;
5693   tree tmp;
5694
5695   gfc_init_se (&arg1se, NULL);
5696   arg1 = expr->value.function.actual;
5697
5698   if (arg1->expr->ts.type == BT_CLASS)
5699     {
5700       /* Make sure that class array expressions have both a _data
5701          component reference and an array reference....  */
5702       if (CLASS_DATA (arg1->expr)->attr.dimension)
5703         gfc_add_class_array_ref (arg1->expr);
5704       /* .... whilst scalars only need the _data component.  */
5705       else
5706         gfc_add_data_component (arg1->expr);
5707     }
5708
5709   ss1 = gfc_walk_expr (arg1->expr);
5710
5711   if (ss1 == gfc_ss_terminator)
5712     {
5713       /* Allocatable scalar.  */
5714       arg1se.want_pointer = 1;
5715       gfc_conv_expr (&arg1se, arg1->expr);
5716       tmp = arg1se.expr;
5717     }
5718   else
5719     {
5720       /* Allocatable array.  */
5721       arg1se.descriptor_only = 1;
5722       gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
5723       tmp = gfc_conv_descriptor_data_get (arg1se.expr);
5724     }
5725
5726   tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp,
5727                          fold_convert (TREE_TYPE (tmp), null_pointer_node));
5728   se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
5729 }
5730
5731
5732 /* Generate code for the ASSOCIATED intrinsic.
5733    If both POINTER and TARGET are arrays, generate a call to library function
5734    _gfor_associated, and pass descriptors of POINTER and TARGET to it.
5735    In other cases, generate inline code that directly compare the address of
5736    POINTER with the address of TARGET.  */
5737
5738 static void
5739 gfc_conv_associated (gfc_se *se, gfc_expr *expr)
5740 {
5741   gfc_actual_arglist *arg1;
5742   gfc_actual_arglist *arg2;
5743   gfc_se arg1se;
5744   gfc_se arg2se;
5745   tree tmp2;
5746   tree tmp;
5747   tree nonzero_charlen;
5748   tree nonzero_arraylen;
5749   gfc_ss *ss1, *ss2;
5750
5751   gfc_init_se (&arg1se, NULL);
5752   gfc_init_se (&arg2se, NULL);
5753   arg1 = expr->value.function.actual;
5754   if (arg1->expr->ts.type == BT_CLASS)
5755     gfc_add_data_component (arg1->expr);
5756   arg2 = arg1->next;
5757   ss1 = gfc_walk_expr (arg1->expr);
5758
5759   if (!arg2->expr)
5760     {
5761       /* No optional target.  */
5762       if (ss1 == gfc_ss_terminator)
5763         {
5764           /* A pointer to a scalar.  */
5765           arg1se.want_pointer = 1;
5766           gfc_conv_expr (&arg1se, arg1->expr);
5767           tmp2 = arg1se.expr;
5768         }
5769       else
5770         {
5771           /* A pointer to an array.  */
5772           gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
5773           tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
5774         }
5775       gfc_add_block_to_block (&se->pre, &arg1se.pre);
5776       gfc_add_block_to_block (&se->post, &arg1se.post);
5777       tmp = fold_build2_loc (input_location, NE_EXPR, boolean_type_node, tmp2,
5778                              fold_convert (TREE_TYPE (tmp2), null_pointer_node));
5779       se->expr = tmp;
5780     }
5781   else
5782     {
5783       /* An optional target.  */
5784       if (arg2->expr->ts.type == BT_CLASS)
5785         gfc_add_data_component (arg2->expr);
5786       ss2 = gfc_walk_expr (arg2->expr);
5787
5788       nonzero_charlen = NULL_TREE;
5789       if (arg1->expr->ts.type == BT_CHARACTER)
5790         nonzero_charlen = fold_build2_loc (input_location, NE_EXPR,
5791                                            boolean_type_node,
5792                                            arg1->expr->ts.u.cl->backend_decl,
5793                                            integer_zero_node);
5794
5795       if (ss1 == gfc_ss_terminator)
5796         {
5797           /* A pointer to a scalar.  */
5798           gcc_assert (ss2 == gfc_ss_terminator);
5799           arg1se.want_pointer = 1;
5800           gfc_conv_expr (&arg1se, arg1->expr);
5801           arg2se.want_pointer = 1;
5802           gfc_conv_expr (&arg2se, arg2->expr);
5803           gfc_add_block_to_block (&se->pre, &arg1se.pre);
5804           gfc_add_block_to_block (&se->post, &arg1se.post);
5805           tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5806                                  arg1se.expr, arg2se.expr);
5807           tmp2 = fold_build2_loc (input_location, NE_EXPR, boolean_type_node,
5808                                   arg1se.expr, null_pointer_node);
5809           se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5810                                       boolean_type_node, tmp, tmp2);
5811         }
5812       else
5813         {
5814           /* An array pointer of zero length is not associated if target is
5815              present.  */
5816           arg1se.descriptor_only = 1;
5817           gfc_conv_expr_lhs (&arg1se, arg1->expr);
5818           tmp = gfc_conv_descriptor_stride_get (arg1se.expr,
5819                                             gfc_rank_cst[arg1->expr->rank - 1]);
5820           nonzero_arraylen = fold_build2_loc (input_location, NE_EXPR,
5821                                               boolean_type_node, tmp,
5822                                               build_int_cst (TREE_TYPE (tmp), 0));
5823
5824           /* A pointer to an array, call library function _gfor_associated.  */
5825           gcc_assert (ss2 != gfc_ss_terminator);
5826           arg1se.want_pointer = 1;
5827           gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
5828
5829           arg2se.want_pointer = 1;
5830           gfc_conv_expr_descriptor (&arg2se, arg2->expr, ss2);
5831           gfc_add_block_to_block (&se->pre, &arg2se.pre);
5832           gfc_add_block_to_block (&se->post, &arg2se.post);
5833           se->expr = build_call_expr_loc (input_location,
5834                                       gfor_fndecl_associated, 2,
5835                                       arg1se.expr, arg2se.expr);
5836           se->expr = convert (boolean_type_node, se->expr);
5837           se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5838                                       boolean_type_node, se->expr,
5839                                       nonzero_arraylen);
5840         }
5841
5842       /* If target is present zero character length pointers cannot
5843          be associated.  */
5844       if (nonzero_charlen != NULL_TREE)
5845         se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
5846                                     boolean_type_node,
5847                                     se->expr, nonzero_charlen);
5848     }
5849
5850   se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
5851 }
5852
5853
5854 /* Generate code for the SAME_TYPE_AS intrinsic.
5855    Generate inline code that directly checks the vindices.  */
5856
5857 static void
5858 gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
5859 {
5860   gfc_expr *a, *b;
5861   gfc_se se1, se2;
5862   tree tmp;
5863
5864   gfc_init_se (&se1, NULL);
5865   gfc_init_se (&se2, NULL);
5866
5867   a = expr->value.function.actual->expr;
5868   b = expr->value.function.actual->next->expr;
5869
5870   if (a->ts.type == BT_CLASS)
5871     {
5872       gfc_add_vptr_component (a);
5873       gfc_add_hash_component (a);
5874     }
5875   else if (a->ts.type == BT_DERIVED)
5876     a = gfc_get_int_expr (gfc_default_integer_kind, NULL,
5877                           a->ts.u.derived->hash_value);
5878
5879   if (b->ts.type == BT_CLASS)
5880     {
5881       gfc_add_vptr_component (b);
5882       gfc_add_hash_component (b);
5883     }
5884   else if (b->ts.type == BT_DERIVED)
5885     b = gfc_get_int_expr (gfc_default_integer_kind, NULL,
5886                           b->ts.u.derived->hash_value);
5887
5888   gfc_conv_expr (&se1, a);
5889   gfc_conv_expr (&se2, b);
5890
5891   tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
5892                          se1.expr, fold_convert (TREE_TYPE (se1.expr), se2.expr));
5893   se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
5894 }
5895
5896
5897 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function.  */
5898
5899 static void
5900 gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
5901 {
5902   tree args[2];
5903
5904   gfc_conv_intrinsic_function_args (se, expr, args, 2);
5905   se->expr = build_call_expr_loc (input_location,
5906                               gfor_fndecl_sc_kind, 2, args[0], args[1]);
5907   se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
5908 }
5909
5910
5911 /* Generate code for SELECTED_INT_KIND (R) intrinsic function.  */
5912
5913 static void
5914 gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
5915 {
5916   tree arg, type;
5917
5918   gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
5919
5920   /* The argument to SELECTED_INT_KIND is INTEGER(4).  */
5921   type = gfc_get_int_type (4); 
5922   arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));
5923
5924   /* Convert it to the required type.  */
5925   type = gfc_typenode_for_spec (&expr->ts);
5926   se->expr = build_call_expr_loc (input_location,
5927                               gfor_fndecl_si_kind, 1, arg);
5928   se->expr = fold_convert (type, se->expr);
5929 }
5930
5931
5932 /* Generate code for SELECTED_REAL_KIND (P, R, RADIX) intrinsic function.  */
5933
5934 static void
5935 gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
5936 {
5937   gfc_actual_arglist *actual;
5938   tree type;
5939   gfc_se argse;
5940   VEC(tree,gc) *args = NULL;
5941
5942   for (actual = expr->value.function.actual; actual; actual = actual->next)
5943     {
5944       gfc_init_se (&argse, se);
5945
5946       /* Pass a NULL pointer for an absent arg.  */
5947       if (actual->expr == NULL)
5948         argse.expr = null_pointer_node;
5949       else
5950         {
5951           gfc_typespec ts;
5952           gfc_clear_ts (&ts);
5953
5954           if (actual->expr->ts.kind != gfc_c_int_kind)
5955             {
5956               /* The arguments to SELECTED_REAL_KIND are INTEGER(4).  */
5957               ts.type = BT_INTEGER;
5958               ts.kind = gfc_c_int_kind;
5959               gfc_convert_type (actual->expr, &ts, 2);
5960             }
5961           gfc_conv_expr_reference (&argse, actual->expr);
5962         } 
5963
5964       gfc_add_block_to_block (&se->pre, &argse.pre);
5965       gfc_add_block_to_block (&se->post, &argse.post);
5966       VEC_safe_push (tree, gc, args, argse.expr);
5967     }
5968
5969   /* Convert it to the required type.  */
5970   type = gfc_typenode_for_spec (&expr->ts);
5971   se->expr = build_call_expr_loc_vec (input_location,
5972                                       gfor_fndecl_sr_kind, args);
5973   se->expr = fold_convert (type, se->expr);
5974 }
5975
5976
5977 /* Generate code for TRIM (A) intrinsic function.  */
5978
5979 static void
5980 gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
5981 {
5982   tree var;
5983   tree len;
5984   tree addr;
5985   tree tmp;
5986   tree cond;
5987   tree fndecl;
5988   tree function;
5989   tree *args;
5990   unsigned int num_args;
5991
5992   num_args = gfc_intrinsic_argument_list_length (expr) + 2;
5993   args = XALLOCAVEC (tree, num_args);
5994
5995   var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
5996   addr = gfc_build_addr_expr (ppvoid_type_node, var);
5997   len = gfc_create_var (gfc_charlen_type_node, "len");
5998
5999   gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
6000   args[0] = gfc_build_addr_expr (NULL_TREE, len);
6001   args[1] = addr;
6002
6003   if (expr->ts.kind == 1)
6004     function = gfor_fndecl_string_trim;
6005   else if (expr->ts.kind == 4)
6006     function = gfor_fndecl_string_trim_char4;
6007   else
6008     gcc_unreachable ();
6009
6010   fndecl = build_addr (function, current_function_decl);
6011   tmp = build_call_array_loc (input_location,
6012                           TREE_TYPE (TREE_TYPE (function)), fndecl,
6013                           num_args, args);
6014   gfc_add_expr_to_block (&se->pre, tmp);
6015
6016   /* Free the temporary afterwards, if necessary.  */
6017   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
6018                           len, build_int_cst (TREE_TYPE (len), 0));
6019   tmp = gfc_call_free (var);
6020   tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
6021   gfc_add_expr_to_block (&se->post, tmp);
6022
6023   se->expr = var;
6024   se->string_length = len;
6025 }
6026
6027
6028 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function.  */
6029
6030 static void
6031 gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
6032 {
6033   tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
6034   tree type, cond, tmp, count, exit_label, n, max, largest;
6035   tree size;
6036   stmtblock_t block, body;
6037   int i;
6038
6039   /* We store in charsize the size of a character.  */
6040   i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
6041   size = build_int_cst (size_type_node, gfc_character_kinds[i].bit_size / 8);
6042
6043   /* Get the arguments.  */
6044   gfc_conv_intrinsic_function_args (se, expr, args, 3);
6045   slen = fold_convert (size_type_node, gfc_evaluate_now (args[0], &se->pre));
6046   src = args[1];
6047   ncopies = gfc_evaluate_now (args[2], &se->pre);
6048   ncopies_type = TREE_TYPE (ncopies);
6049
6050   /* Check that NCOPIES is not negative.  */
6051   cond = fold_build2_loc (input_location, LT_EXPR, boolean_type_node, ncopies,
6052                           build_int_cst (ncopies_type, 0));
6053   gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
6054                            "Argument NCOPIES of REPEAT intrinsic is negative "
6055                            "(its value is %ld)",
6056                            fold_convert (long_integer_type_node, ncopies));
6057
6058   /* If the source length is zero, any non negative value of NCOPIES
6059      is valid, and nothing happens.  */
6060   n = gfc_create_var (ncopies_type, "ncopies");
6061   cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, slen,
6062                           build_int_cst (size_type_node, 0));
6063   tmp = fold_build3_loc (input_location, COND_EXPR, ncopies_type, cond,
6064                          build_int_cst (ncopies_type, 0), ncopies);
6065   gfc_add_modify (&se->pre, n, tmp);
6066   ncopies = n;
6067
6068   /* Check that ncopies is not too large: ncopies should be less than
6069      (or equal to) MAX / slen, where MAX is the maximal integer of
6070      the gfc_charlen_type_node type.  If slen == 0, we need a special
6071      case to avoid the division by zero.  */
6072   i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
6073   max = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_charlen_int_kind);
6074   max = fold_build2_loc (input_location, TRUNC_DIV_EXPR, size_type_node,
6075                           fold_convert (size_type_node, max), slen);
6076   largest = TYPE_PRECISION (size_type_node) > TYPE_PRECISION (ncopies_type)
6077               ? size_type_node : ncopies_type;
6078   cond = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
6079                           fold_convert (largest, ncopies),
6080                           fold_convert (largest, max));
6081   tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, slen,
6082                          build_int_cst (size_type_node, 0));
6083   cond = fold_build3_loc (input_location, COND_EXPR, boolean_type_node, tmp,
6084                           boolean_false_node, cond);
6085   gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
6086                            "Argument NCOPIES of REPEAT intrinsic is too large");
6087
6088   /* Compute the destination length.  */
6089   dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
6090                           fold_convert (gfc_charlen_type_node, slen),
6091                           fold_convert (gfc_charlen_type_node, ncopies));
6092   type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
6093   dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);
6094
6095   /* Generate the code to do the repeat operation:
6096        for (i = 0; i < ncopies; i++)
6097          memmove (dest + (i * slen * size), src, slen*size);  */
6098   gfc_start_block (&block);
6099   count = gfc_create_var (ncopies_type, "count");
6100   gfc_add_modify (&block, count, build_int_cst (ncopies_type, 0));
6101   exit_label = gfc_build_label_decl (NULL_TREE);
6102
6103   /* Start the loop body.  */
6104   gfc_start_block (&body);
6105
6106   /* Exit the loop if count >= ncopies.  */
6107   cond = fold_build2_loc (input_location, GE_EXPR, boolean_type_node, count,
6108                           ncopies);
6109   tmp = build1_v (GOTO_EXPR, exit_label);
6110   TREE_USED (exit_label) = 1;
6111   tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
6112                          build_empty_stmt (input_location));
6113   gfc_add_expr_to_block (&body, tmp);
6114
6115   /* Call memmove (dest + (i*slen*size), src, slen*size).  */
6116   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
6117                          fold_convert (gfc_charlen_type_node, slen),
6118                          fold_convert (gfc_charlen_type_node, count));
6119   tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
6120                          tmp, fold_convert (gfc_charlen_type_node, size));
6121   tmp = fold_build_pointer_plus_loc (input_location,
6122                                      fold_convert (pvoid_type_node, dest), tmp);
6123   tmp = build_call_expr_loc (input_location,
6124                              builtin_decl_explicit (BUILT_IN_MEMMOVE),
6125                              3, tmp, src,
6126                              fold_build2_loc (input_location, MULT_EXPR,
6127                                               size_type_node, slen,
6128                                               fold_convert (size_type_node,
6129                                                             size)));
6130   gfc_add_expr_to_block (&body, tmp);
6131
6132   /* Increment count.  */
6133   tmp = fold_build2_loc (input_location, PLUS_EXPR, ncopies_type,
6134                          count, build_int_cst (TREE_TYPE (count), 1));
6135   gfc_add_modify (&body, count, tmp);
6136
6137   /* Build the loop.  */
6138   tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
6139   gfc_add_expr_to_block (&block, tmp);
6140
6141   /* Add the exit label.  */
6142   tmp = build1_v (LABEL_EXPR, exit_label);
6143   gfc_add_expr_to_block (&block, tmp);
6144
6145   /* Finish the block.  */
6146   tmp = gfc_finish_block (&block);
6147   gfc_add_expr_to_block (&se->pre, tmp);
6148
6149   /* Set the result value.  */
6150   se->expr = dest;
6151   se->string_length = dlen;
6152 }
6153
6154
6155 /* Generate code for the IARGC intrinsic.  */
6156
6157 static void
6158 gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
6159 {
6160   tree tmp;
6161   tree fndecl;
6162   tree type;
6163
6164   /* Call the library function.  This always returns an INTEGER(4).  */
6165   fndecl = gfor_fndecl_iargc;
6166   tmp = build_call_expr_loc (input_location,
6167                          fndecl, 0);
6168
6169   /* Convert it to the required type.  */
6170   type = gfc_typenode_for_spec (&expr->ts);
6171   tmp = fold_convert (type, tmp);
6172
6173   se->expr = tmp;
6174 }
6175
6176
6177 /* The loc intrinsic returns the address of its argument as
6178    gfc_index_integer_kind integer.  */
6179
6180 static void
6181 gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
6182 {
6183   tree temp_var;
6184   gfc_expr *arg_expr;
6185   gfc_ss *ss;
6186
6187   gcc_assert (!se->ss);
6188
6189   arg_expr = expr->value.function.actual->expr;
6190   ss = gfc_walk_expr (arg_expr);
6191   if (ss == gfc_ss_terminator)
6192     gfc_conv_expr_reference (se, arg_expr);
6193   else
6194     gfc_conv_array_parameter (se, arg_expr, ss, true, NULL, NULL, NULL);
6195   se->expr= convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);
6196    
6197   /* Create a temporary variable for loc return value.  Without this, 
6198      we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1).  */
6199   temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
6200   gfc_add_modify (&se->pre, temp_var, se->expr);
6201   se->expr = temp_var;
6202 }
6203
6204 /* Generate code for an intrinsic function.  Some map directly to library
6205    calls, others get special handling.  In some cases the name of the function
6206    used depends on the type specifiers.  */
6207
6208 void
6209 gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
6210 {
6211   const char *name;
6212   int lib, kind;
6213   tree fndecl;
6214
6215   name = &expr->value.function.name[2];
6216
6217   if (expr->rank > 0)
6218     {
6219       lib = gfc_is_intrinsic_libcall (expr);
6220       if (lib != 0)
6221         {
6222           if (lib == 1)
6223             se->ignore_optional = 1;
6224
6225           switch (expr->value.function.isym->id)
6226             {
6227             case GFC_ISYM_EOSHIFT:
6228             case GFC_ISYM_PACK:
6229             case GFC_ISYM_RESHAPE:
6230               /* For all of those the first argument specifies the type and the
6231                  third is optional.  */
6232               conv_generic_with_optional_char_arg (se, expr, 1, 3);
6233               break;
6234
6235             default:
6236               gfc_conv_intrinsic_funcall (se, expr);
6237               break;
6238             }
6239
6240           return;
6241         }
6242     }
6243
6244   switch (expr->value.function.isym->id)
6245     {
6246     case GFC_ISYM_NONE:
6247       gcc_unreachable ();
6248
6249     case GFC_ISYM_REPEAT:
6250       gfc_conv_intrinsic_repeat (se, expr);
6251       break;
6252
6253     case GFC_ISYM_TRIM:
6254       gfc_conv_intrinsic_trim (se, expr);
6255       break;
6256
6257     case GFC_ISYM_SC_KIND:
6258       gfc_conv_intrinsic_sc_kind (se, expr);
6259       break;
6260
6261     case GFC_ISYM_SI_KIND:
6262       gfc_conv_intrinsic_si_kind (se, expr);
6263       break;
6264
6265     case GFC_ISYM_SR_KIND:
6266       gfc_conv_intrinsic_sr_kind (se, expr);
6267       break;
6268
6269     case GFC_ISYM_EXPONENT:
6270       gfc_conv_intrinsic_exponent (se, expr);
6271       break;
6272
6273     case GFC_ISYM_SCAN:
6274       kind = expr->value.function.actual->expr->ts.kind;
6275       if (kind == 1)
6276        fndecl = gfor_fndecl_string_scan;
6277       else if (kind == 4)
6278        fndecl = gfor_fndecl_string_scan_char4;
6279       else
6280        gcc_unreachable ();
6281
6282       gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
6283       break;
6284
6285     case GFC_ISYM_VERIFY:
6286       kind = expr->value.function.actual->expr->ts.kind;
6287       if (kind == 1)
6288        fndecl = gfor_fndecl_string_verify;
6289       else if (kind == 4)
6290        fndecl = gfor_fndecl_string_verify_char4;
6291       else
6292        gcc_unreachable ();
6293
6294       gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
6295       break;
6296
6297     case GFC_ISYM_ALLOCATED:
6298       gfc_conv_allocated (se, expr);
6299       break;
6300
6301     case GFC_ISYM_ASSOCIATED:
6302       gfc_conv_associated(se, expr);
6303       break;
6304
6305     case GFC_ISYM_SAME_TYPE_AS:
6306       gfc_conv_same_type_as (se, expr);
6307       break;
6308
6309     case GFC_ISYM_ABS:
6310       gfc_conv_intrinsic_abs (se, expr);
6311       break;
6312
6313     case GFC_ISYM_ADJUSTL:
6314       if (expr->ts.kind == 1)
6315        fndecl = gfor_fndecl_adjustl;
6316       else if (expr->ts.kind == 4)
6317        fndecl = gfor_fndecl_adjustl_char4;
6318       else
6319        gcc_unreachable ();
6320
6321       gfc_conv_intrinsic_adjust (se, expr, fndecl);
6322       break;
6323
6324     case GFC_ISYM_ADJUSTR:
6325       if (expr->ts.kind == 1)
6326        fndecl = gfor_fndecl_adjustr;
6327       else if (expr->ts.kind == 4)
6328        fndecl = gfor_fndecl_adjustr_char4;
6329       else
6330        gcc_unreachable ();
6331
6332       gfc_conv_intrinsic_adjust (se, expr, fndecl);
6333       break;
6334
6335     case GFC_ISYM_AIMAG:
6336       gfc_conv_intrinsic_imagpart (se, expr);
6337       break;
6338
6339     case GFC_ISYM_AINT:
6340       gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
6341       break;
6342
6343     case GFC_ISYM_ALL:
6344       gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
6345       break;
6346
6347     case GFC_ISYM_ANINT:
6348       gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
6349       break;
6350
6351     case GFC_ISYM_AND:
6352       gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
6353       break;
6354
6355     case GFC_ISYM_ANY:
6356       gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
6357       break;
6358
6359     case GFC_ISYM_BTEST:
6360       gfc_conv_intrinsic_btest (se, expr);
6361       break;
6362
6363     case GFC_ISYM_BGE:
6364       gfc_conv_intrinsic_bitcomp (se, expr, GE_EXPR);
6365       break;
6366
6367     case GFC_ISYM_BGT:
6368       gfc_conv_intrinsic_bitcomp (se, expr, GT_EXPR);
6369       break;
6370
6371     case GFC_ISYM_BLE:
6372       gfc_conv_intrinsic_bitcomp (se, expr, LE_EXPR);
6373       break;
6374
6375     case GFC_ISYM_BLT:
6376       gfc_conv_intrinsic_bitcomp (se, expr, LT_EXPR);
6377       break;
6378
6379     case GFC_ISYM_ACHAR:
6380     case GFC_ISYM_CHAR:
6381       gfc_conv_intrinsic_char (se, expr);
6382       break;
6383
6384     case GFC_ISYM_CONVERSION:
6385     case GFC_ISYM_REAL:
6386     case GFC_ISYM_LOGICAL:
6387     case GFC_ISYM_DBLE:
6388       gfc_conv_intrinsic_conversion (se, expr);
6389       break;
6390
6391       /* Integer conversions are handled separately to make sure we get the
6392          correct rounding mode.  */
6393     case GFC_ISYM_INT:
6394     case GFC_ISYM_INT2:
6395     case GFC_ISYM_INT8:
6396     case GFC_ISYM_LONG:
6397       gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
6398       break;
6399
6400     case GFC_ISYM_NINT:
6401       gfc_conv_intrinsic_int (se, expr, RND_ROUND);
6402       break;
6403
6404     case GFC_ISYM_CEILING:
6405       gfc_conv_intrinsic_int (se, expr, RND_CEIL);
6406       break;
6407
6408     case GFC_ISYM_FLOOR:
6409       gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
6410       break;
6411
6412     case GFC_ISYM_MOD:
6413       gfc_conv_intrinsic_mod (se, expr, 0);
6414       break;
6415
6416     case GFC_ISYM_MODULO:
6417       gfc_conv_intrinsic_mod (se, expr, 1);
6418       break;
6419
6420     case GFC_ISYM_CMPLX:
6421       gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
6422       break;
6423
6424     case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
6425       gfc_conv_intrinsic_iargc (se, expr);
6426       break;
6427
6428     case GFC_ISYM_COMPLEX:
6429       gfc_conv_intrinsic_cmplx (se, expr, 1);
6430       break;
6431
6432     case GFC_ISYM_CONJG:
6433       gfc_conv_intrinsic_conjg (se, expr);
6434       break;
6435
6436     case GFC_ISYM_COUNT:
6437       gfc_conv_intrinsic_count (se, expr);
6438       break;
6439
6440     case GFC_ISYM_CTIME:
6441       gfc_conv_intrinsic_ctime (se, expr);
6442       break;
6443
6444     case GFC_ISYM_DIM:
6445       gfc_conv_intrinsic_dim (se, expr);
6446       break;
6447
6448     case GFC_ISYM_DOT_PRODUCT:
6449       gfc_conv_intrinsic_dot_product (se, expr);
6450       break;
6451
6452     case GFC_ISYM_DPROD:
6453       gfc_conv_intrinsic_dprod (se, expr);
6454       break;
6455
6456     case GFC_ISYM_DSHIFTL:
6457       gfc_conv_intrinsic_dshift (se, expr, true);
6458       break;
6459
6460     case GFC_ISYM_DSHIFTR:
6461       gfc_conv_intrinsic_dshift (se, expr, false);
6462       break;
6463
6464     case GFC_ISYM_FDATE:
6465       gfc_conv_intrinsic_fdate (se, expr);
6466       break;
6467
6468     case GFC_ISYM_FRACTION:
6469       gfc_conv_intrinsic_fraction (se, expr);
6470       break;
6471
6472     case GFC_ISYM_IALL:
6473       gfc_conv_intrinsic_arith (se, expr, BIT_AND_EXPR, false);
6474       break;
6475
6476     case GFC_ISYM_IAND:
6477       gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
6478       break;
6479
6480     case GFC_ISYM_IANY:
6481       gfc_conv_intrinsic_arith (se, expr, BIT_IOR_EXPR, false);
6482       break;
6483
6484     case GFC_ISYM_IBCLR:
6485       gfc_conv_intrinsic_singlebitop (se, expr, 0);
6486       break;
6487
6488     case GFC_ISYM_IBITS:
6489       gfc_conv_intrinsic_ibits (se, expr);
6490       break;
6491
6492     case GFC_ISYM_IBSET:
6493       gfc_conv_intrinsic_singlebitop (se, expr, 1);
6494       break;
6495
6496     case GFC_ISYM_IACHAR:
6497     case GFC_ISYM_ICHAR:
6498       /* We assume ASCII character sequence.  */
6499       gfc_conv_intrinsic_ichar (se, expr);
6500       break;
6501
6502     case GFC_ISYM_IARGC:
6503       gfc_conv_intrinsic_iargc (se, expr);
6504       break;
6505
6506     case GFC_ISYM_IEOR:
6507       gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
6508       break;
6509
6510     case GFC_ISYM_INDEX:
6511       kind = expr->value.function.actual->expr->ts.kind;
6512       if (kind == 1)
6513        fndecl = gfor_fndecl_string_index;
6514       else if (kind == 4)
6515        fndecl = gfor_fndecl_string_index_char4;
6516       else
6517        gcc_unreachable ();
6518
6519       gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
6520       break;
6521
6522     case GFC_ISYM_IOR:
6523       gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
6524       break;
6525
6526     case GFC_ISYM_IPARITY:
6527       gfc_conv_intrinsic_arith (se, expr, BIT_XOR_EXPR, false);
6528       break;
6529
6530     case GFC_ISYM_IS_IOSTAT_END:
6531       gfc_conv_has_intvalue (se, expr, LIBERROR_END);
6532       break;
6533
6534     case GFC_ISYM_IS_IOSTAT_EOR:
6535       gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
6536       break;
6537
6538     case GFC_ISYM_ISNAN:
6539       gfc_conv_intrinsic_isnan (se, expr);
6540       break;
6541
6542     case GFC_ISYM_LSHIFT:
6543       gfc_conv_intrinsic_shift (se, expr, false, false);
6544       break;
6545
6546     case GFC_ISYM_RSHIFT:
6547       gfc_conv_intrinsic_shift (se, expr, true, true);
6548       break;
6549
6550     case GFC_ISYM_SHIFTA:
6551       gfc_conv_intrinsic_shift (se, expr, true, true);
6552       break;
6553
6554     case GFC_ISYM_SHIFTL:
6555       gfc_conv_intrinsic_shift (se, expr, false, false);
6556       break;
6557
6558     case GFC_ISYM_SHIFTR:
6559       gfc_conv_intrinsic_shift (se, expr, true, false);
6560       break;
6561
6562     case GFC_ISYM_ISHFT:
6563       gfc_conv_intrinsic_ishft (se, expr);
6564       break;
6565
6566     case GFC_ISYM_ISHFTC:
6567       gfc_conv_intrinsic_ishftc (se, expr);
6568       break;
6569
6570     case GFC_ISYM_LEADZ:
6571       gfc_conv_intrinsic_leadz (se, expr);
6572       break;
6573
6574     case GFC_ISYM_TRAILZ:
6575       gfc_conv_intrinsic_trailz (se, expr);
6576       break;
6577
6578     case GFC_ISYM_POPCNT:
6579       gfc_conv_intrinsic_popcnt_poppar (se, expr, 0);
6580       break;
6581
6582     case GFC_ISYM_POPPAR:
6583       gfc_conv_intrinsic_popcnt_poppar (se, expr, 1);
6584       break;
6585
6586     case GFC_ISYM_LBOUND:
6587       gfc_conv_intrinsic_bound (se, expr, 0);
6588       break;
6589
6590     case GFC_ISYM_LCOBOUND:
6591       conv_intrinsic_cobound (se, expr);
6592       break;
6593
6594     case GFC_ISYM_TRANSPOSE:
6595       /* The scalarizer has already been set up for reversed dimension access
6596          order ; now we just get the argument value normally.  */
6597       gfc_conv_expr (se, expr->value.function.actual->expr);
6598       break;
6599
6600     case GFC_ISYM_LEN:
6601       gfc_conv_intrinsic_len (se, expr);
6602       break;
6603
6604     case GFC_ISYM_LEN_TRIM:
6605       gfc_conv_intrinsic_len_trim (se, expr);
6606       break;
6607
6608     case GFC_ISYM_LGE:
6609       gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
6610       break;
6611
6612     case GFC_ISYM_LGT:
6613       gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
6614       break;
6615
6616     case GFC_ISYM_LLE:
6617       gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
6618       break;
6619
6620     case GFC_ISYM_LLT:
6621       gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
6622       break;
6623
6624     case GFC_ISYM_MASKL:
6625       gfc_conv_intrinsic_mask (se, expr, 1);
6626       break;
6627
6628     case GFC_ISYM_MASKR:
6629       gfc_conv_intrinsic_mask (se, expr, 0);
6630       break;
6631
6632     case GFC_ISYM_MAX:
6633       if (expr->ts.type == BT_CHARACTER)
6634         gfc_conv_intrinsic_minmax_char (se, expr, 1);
6635       else
6636         gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
6637       break;
6638
6639     case GFC_ISYM_MAXLOC:
6640       gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
6641       break;
6642
6643     case GFC_ISYM_MAXVAL:
6644       gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
6645       break;
6646
6647     case GFC_ISYM_MERGE:
6648       gfc_conv_intrinsic_merge (se, expr);
6649       break;
6650
6651     case GFC_ISYM_MERGE_BITS:
6652       gfc_conv_intrinsic_merge_bits (se, expr);
6653       break;
6654
6655     case GFC_ISYM_MIN:
6656       if (expr->ts.type == BT_CHARACTER)
6657         gfc_conv_intrinsic_minmax_char (se, expr, -1);
6658       else
6659         gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
6660       break;
6661
6662     case GFC_ISYM_MINLOC:
6663       gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
6664       break;
6665
6666     case GFC_ISYM_MINVAL:
6667       gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
6668       break;
6669
6670     case GFC_ISYM_NEAREST:
6671       gfc_conv_intrinsic_nearest (se, expr);
6672       break;
6673
6674     case GFC_ISYM_NORM2:
6675       gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, true);
6676       break;
6677
6678     case GFC_ISYM_NOT:
6679       gfc_conv_intrinsic_not (se, expr);
6680       break;
6681
6682     case GFC_ISYM_OR:
6683       gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
6684       break;
6685
6686     case GFC_ISYM_PARITY:
6687       gfc_conv_intrinsic_arith (se, expr, NE_EXPR, false);
6688       break;
6689
6690     case GFC_ISYM_PRESENT:
6691       gfc_conv_intrinsic_present (se, expr);
6692       break;
6693
6694     case GFC_ISYM_PRODUCT:
6695       gfc_conv_intrinsic_arith (se, expr, MULT_EXPR, false);
6696       break;
6697
6698     case GFC_ISYM_RRSPACING:
6699       gfc_conv_intrinsic_rrspacing (se, expr);
6700       break;
6701
6702     case GFC_ISYM_SET_EXPONENT:
6703       gfc_conv_intrinsic_set_exponent (se, expr);
6704       break;
6705
6706     case GFC_ISYM_SCALE:
6707       gfc_conv_intrinsic_scale (se, expr);
6708       break;
6709
6710     case GFC_ISYM_SIGN:
6711       gfc_conv_intrinsic_sign (se, expr);
6712       break;
6713
6714     case GFC_ISYM_SIZE:
6715       gfc_conv_intrinsic_size (se, expr);
6716       break;
6717
6718     case GFC_ISYM_SIZEOF:
6719     case GFC_ISYM_C_SIZEOF:
6720       gfc_conv_intrinsic_sizeof (se, expr);
6721       break;
6722
6723     case GFC_ISYM_STORAGE_SIZE:
6724       gfc_conv_intrinsic_storage_size (se, expr);
6725       break;
6726
6727     case GFC_ISYM_SPACING:
6728       gfc_conv_intrinsic_spacing (se, expr);
6729       break;
6730
6731     case GFC_ISYM_SUM:
6732       gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false);
6733       break;
6734
6735     case GFC_ISYM_TRANSFER:
6736       if (se->ss && se->ss->info->useflags)
6737         /* Access the previously obtained result.  */
6738         gfc_conv_tmp_array_ref (se);
6739       else
6740         gfc_conv_intrinsic_transfer (se, expr);
6741       break;
6742
6743     case GFC_ISYM_TTYNAM:
6744       gfc_conv_intrinsic_ttynam (se, expr);
6745       break;
6746
6747     case GFC_ISYM_UBOUND:
6748       gfc_conv_intrinsic_bound (se, expr, 1);
6749       break;
6750
6751     case GFC_ISYM_UCOBOUND:
6752       conv_intrinsic_cobound (se, expr);
6753       break;
6754
6755     case GFC_ISYM_XOR:
6756       gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
6757       break;
6758
6759     case GFC_ISYM_LOC:
6760       gfc_conv_intrinsic_loc (se, expr);
6761       break;
6762
6763     case GFC_ISYM_THIS_IMAGE:
6764       /* For num_images() == 1, handle as LCOBOUND.  */
6765       if (expr->value.function.actual->expr
6766           && gfc_option.coarray == GFC_FCOARRAY_SINGLE)
6767         conv_intrinsic_cobound (se, expr);
6768       else
6769         trans_this_image (se, expr);
6770       break;
6771
6772     case GFC_ISYM_IMAGE_INDEX:
6773       trans_image_index (se, expr);
6774       break;
6775
6776     case GFC_ISYM_NUM_IMAGES:
6777       trans_num_images (se);
6778       break;
6779
6780     case GFC_ISYM_ACCESS:
6781     case GFC_ISYM_CHDIR:
6782     case GFC_ISYM_CHMOD:
6783     case GFC_ISYM_DTIME:
6784     case GFC_ISYM_ETIME:
6785     case GFC_ISYM_EXTENDS_TYPE_OF:
6786     case GFC_ISYM_FGET:
6787     case GFC_ISYM_FGETC:
6788     case GFC_ISYM_FNUM:
6789     case GFC_ISYM_FPUT:
6790     case GFC_ISYM_FPUTC:
6791     case GFC_ISYM_FSTAT:
6792     case GFC_ISYM_FTELL:
6793     case GFC_ISYM_GETCWD:
6794     case GFC_ISYM_GETGID:
6795     case GFC_ISYM_GETPID:
6796     case GFC_ISYM_GETUID:
6797     case GFC_ISYM_HOSTNM:
6798     case GFC_ISYM_KILL:
6799     case GFC_ISYM_IERRNO:
6800     case GFC_ISYM_IRAND:
6801     case GFC_ISYM_ISATTY:
6802     case GFC_ISYM_JN2:
6803     case GFC_ISYM_LINK:
6804     case GFC_ISYM_LSTAT:
6805     case GFC_ISYM_MALLOC:
6806     case GFC_ISYM_MATMUL:
6807     case GFC_ISYM_MCLOCK:
6808     case GFC_ISYM_MCLOCK8:
6809     case GFC_ISYM_RAND:
6810     case GFC_ISYM_RENAME:
6811     case GFC_ISYM_SECOND:
6812     case GFC_ISYM_SECNDS:
6813     case GFC_ISYM_SIGNAL:
6814     case GFC_ISYM_STAT:
6815     case GFC_ISYM_SYMLNK:
6816     case GFC_ISYM_SYSTEM:
6817     case GFC_ISYM_TIME:
6818     case GFC_ISYM_TIME8:
6819     case GFC_ISYM_UMASK:
6820     case GFC_ISYM_UNLINK:
6821     case GFC_ISYM_YN2:
6822       gfc_conv_intrinsic_funcall (se, expr);
6823       break;
6824
6825     case GFC_ISYM_EOSHIFT:
6826     case GFC_ISYM_PACK:
6827     case GFC_ISYM_RESHAPE:
6828       /* For those, expr->rank should always be >0 and thus the if above the
6829          switch should have matched.  */
6830       gcc_unreachable ();
6831       break;
6832
6833     default:
6834       gfc_conv_intrinsic_lib_function (se, expr);
6835       break;
6836     }
6837 }
6838
6839
6840 static gfc_ss *
6841 walk_inline_intrinsic_transpose (gfc_ss *ss, gfc_expr *expr)
6842 {
6843   gfc_ss *arg_ss, *tmp_ss;
6844   gfc_actual_arglist *arg;
6845
6846   arg = expr->value.function.actual;
6847
6848   gcc_assert (arg->expr);
6849
6850   arg_ss = gfc_walk_subexpr (gfc_ss_terminator, arg->expr);
6851   gcc_assert (arg_ss != gfc_ss_terminator);
6852
6853   for (tmp_ss = arg_ss; ; tmp_ss = tmp_ss->next)
6854     {
6855       if (tmp_ss->info->type != GFC_SS_SCALAR
6856           && tmp_ss->info->type != GFC_SS_REFERENCE)
6857         {
6858           int tmp_dim;
6859
6860           gcc_assert (tmp_ss->dimen == 2);
6861
6862           /* We just invert dimensions.  */
6863           tmp_dim = tmp_ss->dim[0];
6864           tmp_ss->dim[0] = tmp_ss->dim[1];
6865           tmp_ss->dim[1] = tmp_dim;
6866         }
6867
6868       /* Stop when tmp_ss points to the last valid element of the chain...  */
6869       if (tmp_ss->next == gfc_ss_terminator)
6870         break;
6871     }
6872
6873   /* ... so that we can attach the rest of the chain to it.  */
6874   tmp_ss->next = ss;
6875
6876   return arg_ss;
6877 }
6878
6879
6880 /* Move the given dimension of the given gfc_ss list to a nested gfc_ss list.
6881    This has the side effect of reversing the nested list, so there is no
6882    need to call gfc_reverse_ss on it (the given list is assumed not to be
6883    reversed yet).   */
6884
6885 static gfc_ss *
6886 nest_loop_dimension (gfc_ss *ss, int dim)
6887 {
6888   int ss_dim, i;
6889   gfc_ss *new_ss, *prev_ss = gfc_ss_terminator;
6890   gfc_loopinfo *new_loop;
6891
6892   gcc_assert (ss != gfc_ss_terminator);
6893
6894   for (; ss != gfc_ss_terminator; ss = ss->next)
6895     {
6896       new_ss = gfc_get_ss ();
6897       new_ss->next = prev_ss;
6898       new_ss->parent = ss;
6899       new_ss->info = ss->info;
6900       new_ss->info->refcount++;
6901       if (ss->dimen != 0)
6902         {
6903           gcc_assert (ss->info->type != GFC_SS_SCALAR
6904                       && ss->info->type != GFC_SS_REFERENCE);
6905
6906           new_ss->dimen = 1;
6907           new_ss->dim[0] = ss->dim[dim];
6908
6909           gcc_assert (dim < ss->dimen);
6910
6911           ss_dim = --ss->dimen;
6912           for (i = dim; i < ss_dim; i++)
6913             ss->dim[i] = ss->dim[i + 1];
6914
6915           ss->dim[ss_dim] = 0;
6916         }
6917       prev_ss = new_ss;
6918
6919       if (ss->nested_ss)
6920         {
6921           ss->nested_ss->parent = new_ss;
6922           new_ss->nested_ss = ss->nested_ss;
6923         }
6924       ss->nested_ss = new_ss;
6925     }
6926
6927   new_loop = gfc_get_loopinfo ();
6928   gfc_init_loopinfo (new_loop);
6929
6930   gcc_assert (prev_ss != NULL);
6931   gcc_assert (prev_ss != gfc_ss_terminator);
6932   gfc_add_ss_to_loop (new_loop, prev_ss);
6933   return new_ss->parent;
6934 }
6935
6936
6937 /* Create the gfc_ss list for the SUM/PRODUCT arguments when the function
6938    is to be inlined.  */
6939
6940 static gfc_ss *
6941 walk_inline_intrinsic_arith (gfc_ss *ss, gfc_expr *expr)
6942 {
6943   gfc_ss *tmp_ss, *tail, *array_ss;
6944   gfc_actual_arglist *arg1, *arg2, *arg3;
6945   int sum_dim;
6946   bool scalar_mask = false;
6947
6948   /* The rank of the result will be determined later.  */
6949   arg1 = expr->value.function.actual;
6950   arg2 = arg1->next;
6951   arg3 = arg2->next;
6952   gcc_assert (arg3 != NULL);
6953
6954   if (expr->rank == 0)
6955     return ss;
6956
6957   tmp_ss = gfc_ss_terminator;
6958
6959   if (arg3->expr)
6960     {
6961       gfc_ss *mask_ss;
6962
6963       mask_ss = gfc_walk_subexpr (tmp_ss, arg3->expr);
6964       if (mask_ss == tmp_ss)
6965         scalar_mask = 1;
6966
6967       tmp_ss = mask_ss;
6968     }
6969
6970   array_ss = gfc_walk_subexpr (tmp_ss, arg1->expr);
6971   gcc_assert (array_ss != tmp_ss);
6972
6973   /* Odd thing: If the mask is scalar, it is used by the frontend after
6974      the array (to make an if around the nested loop). Thus it shall
6975      be after array_ss once the gfc_ss list is reversed.  */
6976   if (scalar_mask)
6977     tmp_ss = gfc_get_scalar_ss (array_ss, arg3->expr);
6978   else
6979     tmp_ss = array_ss;
6980
6981   /* "Hide" the dimension on which we will sum in the first arg's scalarization
6982      chain.  */
6983   sum_dim = mpz_get_si (arg2->expr->value.integer) - 1;
6984   tail = nest_loop_dimension (tmp_ss, sum_dim);
6985   tail->next = ss;
6986
6987   return tmp_ss;
6988 }
6989
6990
6991 static gfc_ss *
6992 walk_inline_intrinsic_function (gfc_ss * ss, gfc_expr * expr)
6993 {
6994
6995   switch (expr->value.function.isym->id)
6996     {
6997       case GFC_ISYM_PRODUCT:
6998       case GFC_ISYM_SUM:
6999         return walk_inline_intrinsic_arith (ss, expr);
7000
7001       case GFC_ISYM_TRANSPOSE:
7002         return walk_inline_intrinsic_transpose (ss, expr);
7003
7004       default:
7005         gcc_unreachable ();
7006     }
7007   gcc_unreachable ();
7008 }
7009
7010
7011 /* This generates code to execute before entering the scalarization loop.
7012    Currently does nothing.  */
7013
7014 void
7015 gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
7016 {
7017   switch (ss->info->expr->value.function.isym->id)
7018     {
7019     case GFC_ISYM_UBOUND:
7020     case GFC_ISYM_LBOUND:
7021     case GFC_ISYM_UCOBOUND:
7022     case GFC_ISYM_LCOBOUND:
7023     case GFC_ISYM_THIS_IMAGE:
7024       break;
7025
7026     default:
7027       gcc_unreachable ();
7028     }
7029 }
7030
7031
7032 /* The LBOUND, LCOBOUND, UBOUND and UCOBOUND intrinsics with one parameter
7033    are expanded into code inside the scalarization loop.  */
7034
7035 static gfc_ss *
7036 gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
7037 {
7038   if (expr->value.function.actual->expr->ts.type == BT_CLASS)
7039     gfc_add_class_array_ref (expr->value.function.actual->expr);
7040
7041   /* The two argument version returns a scalar.  */
7042   if (expr->value.function.actual->next->expr)
7043     return ss;
7044
7045   return gfc_get_array_ss (ss, expr, 1, GFC_SS_INTRINSIC);
7046 }
7047
7048
7049 /* Walk an intrinsic array libcall.  */
7050
7051 static gfc_ss *
7052 gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
7053 {
7054   gcc_assert (expr->rank > 0);
7055   return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_FUNCTION);
7056 }
7057
7058
7059 /* Return whether the function call expression EXPR will be expanded
7060    inline by gfc_conv_intrinsic_function.  */
7061
7062 bool
7063 gfc_inline_intrinsic_function_p (gfc_expr *expr)
7064 {
7065   gfc_actual_arglist *args;
7066
7067   if (!expr->value.function.isym)
7068     return false;
7069
7070   switch (expr->value.function.isym->id)
7071     {
7072     case GFC_ISYM_PRODUCT:
7073     case GFC_ISYM_SUM:
7074       /* Disable inline expansion if code size matters.  */
7075       if (optimize_size)
7076         return false;
7077
7078       args = expr->value.function.actual;
7079       /* We need to be able to subset the SUM argument at compile-time.  */
7080       if (args->next->expr && args->next->expr->expr_type != EXPR_CONSTANT)
7081         return false;
7082
7083       return true;
7084
7085     case GFC_ISYM_TRANSPOSE:
7086       return true;
7087
7088     default:
7089       return false;
7090     }
7091 }
7092
7093
7094 /* Returns nonzero if the specified intrinsic function call maps directly to
7095    an external library call.  Should only be used for functions that return
7096    arrays.  */
7097
7098 int
7099 gfc_is_intrinsic_libcall (gfc_expr * expr)
7100 {
7101   gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
7102   gcc_assert (expr->rank > 0);
7103
7104   if (gfc_inline_intrinsic_function_p (expr))
7105     return 0;
7106
7107   switch (expr->value.function.isym->id)
7108     {
7109     case GFC_ISYM_ALL:
7110     case GFC_ISYM_ANY:
7111     case GFC_ISYM_COUNT:
7112     case GFC_ISYM_JN2:
7113     case GFC_ISYM_IANY:
7114     case GFC_ISYM_IALL:
7115     case GFC_ISYM_IPARITY:
7116     case GFC_ISYM_MATMUL:
7117     case GFC_ISYM_MAXLOC:
7118     case GFC_ISYM_MAXVAL:
7119     case GFC_ISYM_MINLOC:
7120     case GFC_ISYM_MINVAL:
7121     case GFC_ISYM_NORM2:
7122     case GFC_ISYM_PARITY:
7123     case GFC_ISYM_PRODUCT:
7124     case GFC_ISYM_SUM:
7125     case GFC_ISYM_SHAPE:
7126     case GFC_ISYM_SPREAD:
7127     case GFC_ISYM_YN2:
7128       /* Ignore absent optional parameters.  */
7129       return 1;
7130
7131     case GFC_ISYM_RESHAPE:
7132     case GFC_ISYM_CSHIFT:
7133     case GFC_ISYM_EOSHIFT:
7134     case GFC_ISYM_PACK:
7135     case GFC_ISYM_UNPACK:
7136       /* Pass absent optional parameters.  */
7137       return 2;
7138
7139     default:
7140       return 0;
7141     }
7142 }
7143
7144 /* Walk an intrinsic function.  */
7145 gfc_ss *
7146 gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
7147                              gfc_intrinsic_sym * isym)
7148 {
7149   gcc_assert (isym);
7150
7151   if (isym->elemental)
7152     return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
7153                                              NULL, GFC_SS_SCALAR);
7154
7155   if (expr->rank == 0)
7156     return ss;
7157
7158   if (gfc_inline_intrinsic_function_p (expr))
7159     return walk_inline_intrinsic_function (ss, expr);
7160
7161   if (gfc_is_intrinsic_libcall (expr))
7162     return gfc_walk_intrinsic_libfunc (ss, expr);
7163
7164   /* Special cases.  */
7165   switch (isym->id)
7166     {
7167     case GFC_ISYM_LBOUND:
7168     case GFC_ISYM_LCOBOUND:
7169     case GFC_ISYM_UBOUND:
7170     case GFC_ISYM_UCOBOUND:
7171     case GFC_ISYM_THIS_IMAGE:
7172       return gfc_walk_intrinsic_bound (ss, expr);
7173
7174     case GFC_ISYM_TRANSFER:
7175       return gfc_walk_intrinsic_libfunc (ss, expr);
7176
7177     default:
7178       /* This probably meant someone forgot to add an intrinsic to the above
7179          list(s) when they implemented it, or something's gone horribly
7180          wrong.  */
7181       gcc_unreachable ();
7182     }
7183 }
7184
7185
7186 static tree
7187 conv_intrinsic_atomic_def (gfc_code *code)
7188 {
7189   gfc_se atom, value;
7190   stmtblock_t block;
7191
7192   gfc_init_se (&atom, NULL);
7193   gfc_init_se (&value, NULL);
7194   gfc_conv_expr (&atom, code->ext.actual->expr);
7195   gfc_conv_expr (&value, code->ext.actual->next->expr);
7196
7197   gfc_init_block (&block);
7198   gfc_add_modify (&block, atom.expr,
7199                   fold_convert (TREE_TYPE (atom.expr), value.expr));
7200   return gfc_finish_block (&block);
7201 }
7202
7203
7204 static tree
7205 conv_intrinsic_atomic_ref (gfc_code *code)
7206 {
7207   gfc_se atom, value;
7208   stmtblock_t block;
7209
7210   gfc_init_se (&atom, NULL);
7211   gfc_init_se (&value, NULL);
7212   gfc_conv_expr (&value, code->ext.actual->expr);
7213   gfc_conv_expr (&atom, code->ext.actual->next->expr);
7214
7215   gfc_init_block (&block);
7216   gfc_add_modify (&block, value.expr,
7217                   fold_convert (TREE_TYPE (value.expr), atom.expr));
7218   return gfc_finish_block (&block);
7219 }
7220
7221
7222 static tree
7223 conv_intrinsic_move_alloc (gfc_code *code)
7224 {
7225   stmtblock_t block;
7226   gfc_expr *from_expr, *to_expr;
7227   gfc_expr *to_expr2, *from_expr2 = NULL;
7228   gfc_se from_se, to_se;
7229   gfc_ss *from_ss, *to_ss;
7230   tree tmp;
7231
7232   gfc_start_block (&block);
7233
7234   from_expr = code->ext.actual->expr;
7235   to_expr = code->ext.actual->next->expr;
7236
7237   gfc_init_se (&from_se, NULL);
7238   gfc_init_se (&to_se, NULL);
7239
7240   if (from_expr->rank == 0)
7241     {
7242       gcc_assert (from_expr->ts.type != BT_CLASS
7243                   || to_expr->ts.type == BT_CLASS);
7244       if (from_expr->ts.type != BT_CLASS)
7245         from_expr2 = from_expr;
7246       else
7247         {
7248           from_expr2 = gfc_copy_expr (from_expr);
7249           gfc_add_data_component (from_expr2);
7250         }
7251
7252       if (to_expr->ts.type != BT_CLASS)
7253         to_expr2 = to_expr;
7254       else
7255         {
7256           to_expr2 = gfc_copy_expr (to_expr);
7257           gfc_add_data_component (to_expr2);
7258         }
7259
7260       from_se.want_pointer = 1;
7261       to_se.want_pointer = 1;
7262       gfc_conv_expr (&from_se, from_expr2);
7263       gfc_conv_expr (&to_se, to_expr2);
7264       gfc_add_block_to_block (&block, &from_se.pre);
7265       gfc_add_block_to_block (&block, &to_se.pre);
7266
7267       /* Deallocate "to".  */
7268       tmp = gfc_deallocate_scalar_with_status (to_se.expr, NULL_TREE, true,
7269                                                to_expr2, to_expr->ts);
7270       gfc_add_expr_to_block (&block, tmp);
7271
7272       /* Assign (_data) pointers.  */
7273       gfc_add_modify_loc (input_location, &block, to_se.expr,
7274                           fold_convert (TREE_TYPE (to_se.expr), from_se.expr));
7275
7276       /* Set "from" to NULL.  */
7277       gfc_add_modify_loc (input_location, &block, from_se.expr,
7278                           fold_convert (TREE_TYPE (from_se.expr), null_pointer_node));
7279
7280       gfc_add_block_to_block (&block, &from_se.post);
7281       gfc_add_block_to_block (&block, &to_se.post);
7282
7283       /* Set _vptr.  */
7284       if (to_expr->ts.type == BT_CLASS)
7285         {
7286           gfc_free_expr (to_expr2);
7287           gfc_init_se (&to_se, NULL);
7288           to_se.want_pointer = 1;
7289           gfc_add_vptr_component (to_expr);
7290           gfc_conv_expr (&to_se, to_expr);
7291
7292           if (from_expr->ts.type == BT_CLASS)
7293             {
7294               gfc_free_expr (from_expr2);
7295               gfc_init_se (&from_se, NULL);
7296               from_se.want_pointer = 1;
7297               gfc_add_vptr_component (from_expr);
7298               gfc_conv_expr (&from_se, from_expr);
7299               tmp = from_se.expr;
7300             }
7301           else
7302             {
7303               gfc_symbol *vtab;
7304               vtab = gfc_find_derived_vtab (from_expr->ts.u.derived);
7305               gcc_assert (vtab);
7306               tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
7307             }
7308
7309           gfc_add_modify_loc (input_location, &block, to_se.expr,
7310                               fold_convert (TREE_TYPE (to_se.expr), tmp));
7311         }
7312
7313       return gfc_finish_block (&block);
7314     }
7315
7316   /* Update _vptr component.  */
7317   if (to_expr->ts.type == BT_CLASS)
7318     {
7319       to_se.want_pointer = 1;
7320       to_expr2 = gfc_copy_expr (to_expr);
7321       gfc_add_vptr_component (to_expr2);
7322       gfc_conv_expr (&to_se, to_expr2);
7323
7324       if (from_expr->ts.type == BT_CLASS)
7325         {
7326           from_se.want_pointer = 1;
7327           from_expr2 = gfc_copy_expr (from_expr);
7328           gfc_add_vptr_component (from_expr2);
7329           gfc_conv_expr (&from_se, from_expr2);
7330           tmp = from_se.expr;
7331         }
7332       else
7333         {
7334           gfc_symbol *vtab;
7335           vtab = gfc_find_derived_vtab (from_expr->ts.u.derived);
7336           gcc_assert (vtab);
7337           tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
7338         }
7339
7340       gfc_add_modify_loc (input_location, &block, to_se.expr,
7341                           fold_convert (TREE_TYPE (to_se.expr), tmp));
7342       gfc_free_expr (to_expr2);
7343       gfc_init_se (&to_se, NULL);
7344
7345       if (from_expr->ts.type == BT_CLASS)
7346         {
7347           gfc_free_expr (from_expr2);
7348           gfc_init_se (&from_se, NULL);
7349         }
7350     }
7351
7352   /* Deallocate "to".  */
7353   to_ss = gfc_walk_expr (to_expr);
7354   from_ss = gfc_walk_expr (from_expr);
7355   gfc_conv_expr_descriptor (&to_se, to_expr, to_ss);
7356   gfc_conv_expr_descriptor (&from_se, from_expr, from_ss);
7357
7358   tmp = gfc_conv_descriptor_data_get (to_se.expr);
7359   tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE, NULL_TREE,
7360                                     NULL_TREE, true, to_expr, false);
7361   gfc_add_expr_to_block (&block, tmp);
7362
7363   /* Move the pointer and update the array descriptor data.  */
7364   gfc_add_modify_loc (input_location, &block, to_se.expr, from_se.expr);
7365
7366   /* Set "to" to NULL.  */
7367   tmp = gfc_conv_descriptor_data_get (from_se.expr);
7368   gfc_add_modify_loc (input_location, &block, tmp,
7369                       fold_convert (TREE_TYPE (tmp), null_pointer_node));
7370
7371   return gfc_finish_block (&block);
7372 }
7373
7374
7375 tree
7376 gfc_conv_intrinsic_subroutine (gfc_code *code)
7377 {
7378   tree res;
7379
7380   gcc_assert (code->resolved_isym);
7381
7382   switch (code->resolved_isym->id)
7383     {
7384     case GFC_ISYM_MOVE_ALLOC:
7385       res = conv_intrinsic_move_alloc (code);
7386       break;
7387
7388     case GFC_ISYM_ATOMIC_DEF:
7389       res = conv_intrinsic_atomic_def (code);
7390       break;
7391
7392     case GFC_ISYM_ATOMIC_REF:
7393       res = conv_intrinsic_atomic_ref (code);
7394       break;
7395
7396     default:
7397       res = NULL_TREE;
7398       break;
7399     }
7400
7401   return res;
7402 }
7403
7404 #include "gt-fortran-trans-intrinsic.h"