OSDN Git Service

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