OSDN Git Service

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