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>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
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
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics. */
27 #include "coretypes.h"
28 #include "tm.h" /* For UNITS_PER_WORD. */
31 #include "diagnostic-core.h" /* For internal_error. */
32 #include "toplev.h" /* For rest_of_decl_compilation. */
36 #include "intrinsic.h"
38 #include "trans-const.h"
39 #include "trans-types.h"
40 #include "trans-array.h"
42 /* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
43 #include "trans-stmt.h"
45 /* This maps fortran intrinsic math functions to external library or GCC
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. */
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
;
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)". */
66 /* True if a complex version of the function exists. */
67 bool complex_available
;
69 /* True if the function should be marked const. */
72 /* The base library name of this function. */
75 /* Cache decls created for the various operand types. */
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
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},
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},
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 }
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},
114 static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map
[] =
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"
121 /* Functions in libgfortran. */
122 LIB_FUNCTION (ERFC_SCALED
, "erfc_scaled", false),
125 LIB_FUNCTION (NONE
, NULL
, false)
130 #undef DEFINE_MATH_BUILTIN
131 #undef DEFINE_MATH_BUILTIN_C
134 enum rounding_mode
{ RND_ROUND
, RND_TRUNC
, RND_CEIL
, RND_FLOOR
};
137 /* Find the correct variant of a given builtin from its argument. */
139 builtin_decl_for_precision (enum built_in_function base_built_in
,
142 int i
= END_BUILTINS
;
144 gfc_intrinsic_map_t
*m
;
145 for (m
= gfc_intrinsic_map
; m
->double_built_in
!= base_built_in
; m
++)
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
))
156 /* Special treatment, because it is not exactly a built-in, but
157 a library function. */
158 return m
->real16_decl
;
161 return (i
== END_BUILTINS
? NULL_TREE
: built_in_decls
[i
]);
166 gfc_builtin_decl_for_float_kind (enum built_in_function double_built_in
,
169 int i
= gfc_validate_kind (BT_REAL
, kind
, false);
171 if (gfc_real_kinds
[i
].c_float128
)
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
++)
179 return m
->real16_decl
;
182 return builtin_decl_for_precision (double_built_in
,
183 gfc_real_kinds
[i
].mode_precision
);
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. */
193 gfc_conv_intrinsic_function_args (gfc_se
*se
, gfc_expr
*expr
,
194 tree
*argarray
, int nargs
)
196 gfc_actual_arglist
*actual
;
198 gfc_intrinsic_arg
*formal
;
202 formal
= expr
->value
.function
.isym
->formal
;
203 actual
= expr
->value
.function
.actual
;
205 for (curr_arg
= 0; curr_arg
< nargs
; curr_arg
++,
206 actual
= actual
->next
,
207 formal
= formal
? formal
->next
: NULL
)
211 /* Skip omitted optional arguments. */
218 /* Evaluate the parameter. This will substitute scalarized
219 references automatically. */
220 gfc_init_se (&argse
, se
);
222 if (e
->ts
.type
== BT_CHARACTER
)
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
);
230 gfc_conv_expr_val (&argse
, e
);
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
238 gfc_conv_missing_dummy (&argse
, e
, formal
->ts
, 0);
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
;
246 /* Count the number of actual arguments to the intrinsic function EXPR
247 including any "hidden" string length arguments. */
250 gfc_intrinsic_argument_list_length (gfc_expr
*expr
)
253 gfc_actual_arglist
*actual
;
255 for (actual
= expr
->value
.function
.actual
; actual
; actual
= actual
->next
)
260 if (actual
->expr
->ts
.type
== BT_CHARACTER
)
270 /* Conversions between different types are output by the frontend as
271 intrinsic functions. We implement these directly with inline code. */
274 gfc_conv_intrinsic_conversion (gfc_se
* se
, gfc_expr
* expr
)
280 nargs
= gfc_intrinsic_argument_list_length (expr
);
281 args
= XALLOCAVEC (tree
, nargs
);
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
);
290 /* Conversion between character kinds involves a call to a library
292 if (expr
->ts
.type
== BT_CHARACTER
)
294 tree fndecl
, var
, addr
, tmp
;
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
;
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
);
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
);
316 /* Free the temporary afterwards. */
317 tmp
= gfc_call_free (var
);
318 gfc_add_expr_to_block (&se
->post
, tmp
);
321 se
->string_length
= args
[0];
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
)
333 artype
= TREE_TYPE (TREE_TYPE (args
[0]));
334 args
[0] = fold_build1_loc (input_location
, REALPART_EXPR
, artype
,
338 se
->expr
= convert (type
, args
[0]);
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. */
347 build_fixbound_expr (stmtblock_t
* pblock
, tree arg
, tree type
, int up
)
354 argtype
= TREE_TYPE (arg
);
355 arg
= gfc_evaluate_now (arg
, pblock
);
357 intval
= convert (type
, arg
);
358 intval
= gfc_evaluate_now (intval
, pblock
);
360 tmp
= convert (argtype
, intval
);
361 cond
= fold_build2_loc (input_location
, up
? GE_EXPR
: LE_EXPR
,
362 boolean_type_node
, tmp
, arg
);
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
);
371 /* Round to nearest integer, away from zero. */
374 build_round_expr (tree arg
, tree restype
)
379 int argprec
, resprec
;
381 argtype
= TREE_TYPE (arg
);
382 argprec
= TYPE_PRECISION (argtype
);
383 resprec
= TYPE_PRECISION (restype
);
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
)
390 else if (resprec
<= LONG_LONG_TYPE_SIZE
)
395 /* Now, depending on the argument type, we choose between intrinsics. */
397 fn
= builtin_decl_for_precision (BUILT_IN_LLROUND
, argprec
);
399 fn
= builtin_decl_for_precision (BUILT_IN_LROUND
, argprec
);
401 return fold_convert (restype
, build_call_expr_loc (input_location
,
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. */
411 build_fix_expr (stmtblock_t
* pblock
, tree arg
, tree type
,
412 enum rounding_mode op
)
417 return build_fixbound_expr (pblock
, arg
, type
, 0);
421 return build_fixbound_expr (pblock
, arg
, type
, 1);
425 return build_round_expr (arg
, type
);
429 return fold_build1_loc (input_location
, FIX_TRUNC_EXPR
, type
, arg
);
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
443 huge = HUGE (KIND (a))
444 aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
448 gfc_conv_intrinsic_aint (gfc_se
* se
, gfc_expr
* expr
, enum rounding_mode op
)
460 kind
= expr
->ts
.kind
;
461 nargs
= gfc_intrinsic_argument_list_length (expr
);
464 /* We have builtin functions for some cases. */
468 decl
= gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND
, kind
);
472 decl
= gfc_builtin_decl_for_float_kind (BUILT_IN_TRUNC
, kind
);
479 /* Evaluate the argument. */
480 gcc_assert (expr
->value
.function
.actual
->expr
);
481 gfc_conv_intrinsic_function_args (se
, expr
, arg
, nargs
);
483 /* Use a builtin function if one exists. */
484 if (decl
!= NULL_TREE
)
486 se
->expr
= build_call_expr_loc (input_location
, decl
, 1, arg
[0]);
490 /* This code is probably redundant, but we'll keep it lying around just
492 type
= gfc_typenode_for_spec (&expr
->ts
);
493 arg
[0] = gfc_evaluate_now (arg
[0], &se
->pre
);
495 /* Test if the value is too large to handle sensibly. */
496 gfc_set_model_kind (kind
);
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],
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],
508 cond
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
, boolean_type_node
,
510 itype
= gfc_get_int_type (kind
);
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
,
520 /* Convert to an integer using the specified rounding mode. */
523 gfc_conv_intrinsic_int (gfc_se
* se
, gfc_expr
* expr
, enum rounding_mode op
)
529 nargs
= gfc_intrinsic_argument_list_length (expr
);
530 args
= XALLOCAVEC (tree
, nargs
);
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
);
538 if (TREE_CODE (TREE_TYPE (args
[0])) == INTEGER_TYPE
)
540 /* Conversion to a different integer kind. */
541 se
->expr
= convert (type
, args
[0]);
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
)
552 artype
= TREE_TYPE (TREE_TYPE (args
[0]));
553 args
[0] = fold_build1_loc (input_location
, REALPART_EXPR
, artype
,
557 se
->expr
= build_fix_expr (&se
->pre
, args
[0], type
, op
);
562 /* Get the imaginary component of a value. */
565 gfc_conv_intrinsic_imagpart (gfc_se
* se
, gfc_expr
* expr
)
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
);
575 /* Get the complex conjugate of a value. */
578 gfc_conv_intrinsic_conjg (gfc_se
* se
, gfc_expr
* expr
)
582 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
583 se
->expr
= fold_build1_loc (input_location
, CONJ_EXPR
, TREE_TYPE (arg
), arg
);
589 define_quad_builtin (const char *name
, tree type
, bool is_const
)
592 fndecl
= build_decl (input_location
, FUNCTION_DECL
, get_identifier (name
),
595 /* Mark the decl as external. */
596 DECL_EXTERNAL (fndecl
) = 1;
597 TREE_PUBLIC (fndecl
) = 1;
599 /* Mark it __attribute__((const)). */
600 TREE_READONLY (fndecl
) = is_const
;
602 rest_of_decl_compilation (fndecl
, 1, 0);
609 /* Initialize function decls for library functions. The external functions
610 are created as required. Builtin functions are added here. */
613 gfc_build_intrinsic_lib_fndecls (void)
615 gfc_intrinsic_map_t
*m
;
616 tree quad_decls
[END_BUILTINS
+ 1];
618 if (gfc_real16_is_float128
)
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. */
624 tree tmp
, func_1
, func_2
, func_cabs
, func_frexp
;
625 tree func_lround
, func_llround
, func_scalbn
, func_cpow
;
627 memset (quad_decls
, 0, sizeof(tree
) * (END_BUILTINS
+ 1));
629 /* type (*) (type) */
630 tmp
= tree_cons (NULL_TREE
, float128_type_node
, void_list_node
);
631 func_1
= build_function_type (float128_type_node
, tmp
);
632 /* long (*) (type) */
633 func_lround
= build_function_type (long_integer_type_node
, tmp
);
634 /* long long (*) (type) */
635 func_llround
= build_function_type (long_long_integer_type_node
, tmp
);
636 /* type (*) (type, type) */
637 tmp
= tree_cons (NULL_TREE
, float128_type_node
, tmp
);
638 func_2
= build_function_type (float128_type_node
, tmp
);
639 /* type (*) (type, &int) */
640 tmp
= tree_cons (NULL_TREE
, float128_type_node
, void_list_node
);
641 tmp
= tree_cons (NULL_TREE
, build_pointer_type (integer_type_node
), tmp
);
642 func_frexp
= build_function_type (float128_type_node
, tmp
);
643 /* type (*) (type, int) */
644 tmp
= tree_cons (NULL_TREE
, float128_type_node
, void_list_node
);
645 tmp
= tree_cons (NULL_TREE
, integer_type_node
, tmp
);
646 func_scalbn
= build_function_type (float128_type_node
, tmp
);
647 /* type (*) (complex type) */
648 tmp
= tree_cons (NULL_TREE
, complex_float128_type_node
, void_list_node
);
649 func_cabs
= build_function_type (float128_type_node
, tmp
);
650 /* complex type (*) (complex type, complex type) */
651 tmp
= tree_cons (NULL_TREE
, complex_float128_type_node
, tmp
);
652 func_cpow
= build_function_type (complex_float128_type_node
, tmp
);
654 #define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE)
655 #define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE)
656 #define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX)
658 /* Only these built-ins are actually needed here. These are used directly
659 from the code, when calling builtin_decl_for_precision() or
660 builtin_decl_for_float_type(). The others are all constructed by
661 gfc_get_intrinsic_lib_fndecl(). */
662 #define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
663 quad_decls[BUILT_IN_ ## ID] = define_quad_builtin (NAME "q", func_ ## TYPE, CONST);
665 #include "mathbuiltins.def"
669 #undef DEFINE_MATH_BUILTIN
670 #undef DEFINE_MATH_BUILTIN_C
674 /* Add GCC builtin functions. */
675 for (m
= gfc_intrinsic_map
;
676 m
->id
!= GFC_ISYM_NONE
|| m
->double_built_in
!= END_BUILTINS
; m
++)
678 if (m
->float_built_in
!= END_BUILTINS
)
679 m
->real4_decl
= built_in_decls
[m
->float_built_in
];
680 if (m
->complex_float_built_in
!= END_BUILTINS
)
681 m
->complex4_decl
= built_in_decls
[m
->complex_float_built_in
];
682 if (m
->double_built_in
!= END_BUILTINS
)
683 m
->real8_decl
= built_in_decls
[m
->double_built_in
];
684 if (m
->complex_double_built_in
!= END_BUILTINS
)
685 m
->complex8_decl
= built_in_decls
[m
->complex_double_built_in
];
687 /* If real(kind=10) exists, it is always long double. */
688 if (m
->long_double_built_in
!= END_BUILTINS
)
689 m
->real10_decl
= built_in_decls
[m
->long_double_built_in
];
690 if (m
->complex_long_double_built_in
!= END_BUILTINS
)
691 m
->complex10_decl
= built_in_decls
[m
->complex_long_double_built_in
];
693 if (!gfc_real16_is_float128
)
695 if (m
->long_double_built_in
!= END_BUILTINS
)
696 m
->real16_decl
= built_in_decls
[m
->long_double_built_in
];
697 if (m
->complex_long_double_built_in
!= END_BUILTINS
)
698 m
->complex16_decl
= built_in_decls
[m
->complex_long_double_built_in
];
700 else if (quad_decls
[m
->double_built_in
] != NULL_TREE
)
702 /* Quad-precision function calls are constructed when first
703 needed by builtin_decl_for_precision(), except for those
704 that will be used directly (define by OTHER_BUILTIN). */
705 m
->real16_decl
= quad_decls
[m
->double_built_in
];
707 else if (quad_decls
[m
->complex_double_built_in
] != NULL_TREE
)
709 /* Same thing for the complex ones. */
710 m
->complex16_decl
= quad_decls
[m
->double_built_in
];
716 /* Create a fndecl for a simple intrinsic library function. */
719 gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t
* m
, gfc_expr
* expr
)
724 gfc_actual_arglist
*actual
;
727 char name
[GFC_MAX_SYMBOL_LEN
+ 3];
730 if (ts
->type
== BT_REAL
)
735 pdecl
= &m
->real4_decl
;
738 pdecl
= &m
->real8_decl
;
741 pdecl
= &m
->real10_decl
;
744 pdecl
= &m
->real16_decl
;
750 else if (ts
->type
== BT_COMPLEX
)
752 gcc_assert (m
->complex_available
);
757 pdecl
= &m
->complex4_decl
;
760 pdecl
= &m
->complex8_decl
;
763 pdecl
= &m
->complex10_decl
;
766 pdecl
= &m
->complex16_decl
;
780 int n
= gfc_validate_kind (BT_REAL
, ts
->kind
, false);
781 if (gfc_real_kinds
[n
].c_float
)
782 snprintf (name
, sizeof (name
), "%s%s%s",
783 ts
->type
== BT_COMPLEX
? "c" : "", m
->name
, "f");
784 else if (gfc_real_kinds
[n
].c_double
)
785 snprintf (name
, sizeof (name
), "%s%s",
786 ts
->type
== BT_COMPLEX
? "c" : "", m
->name
);
787 else if (gfc_real_kinds
[n
].c_long_double
)
788 snprintf (name
, sizeof (name
), "%s%s%s",
789 ts
->type
== BT_COMPLEX
? "c" : "", m
->name
, "l");
790 else if (gfc_real_kinds
[n
].c_float128
)
791 snprintf (name
, sizeof (name
), "%s%s%s",
792 ts
->type
== BT_COMPLEX
? "c" : "", m
->name
, "q");
798 snprintf (name
, sizeof (name
), PREFIX ("%s_%c%d"), m
->name
,
799 ts
->type
== BT_COMPLEX
? 'c' : 'r',
803 argtypes
= NULL_TREE
;
804 for (actual
= expr
->value
.function
.actual
; actual
; actual
= actual
->next
)
806 type
= gfc_typenode_for_spec (&actual
->expr
->ts
);
807 argtypes
= gfc_chainon_list (argtypes
, type
);
809 argtypes
= chainon (argtypes
, void_list_node
);
810 type
= build_function_type (gfc_typenode_for_spec (ts
), argtypes
);
811 fndecl
= build_decl (input_location
,
812 FUNCTION_DECL
, get_identifier (name
), type
);
814 /* Mark the decl as external. */
815 DECL_EXTERNAL (fndecl
) = 1;
816 TREE_PUBLIC (fndecl
) = 1;
818 /* Mark it __attribute__((const)), if possible. */
819 TREE_READONLY (fndecl
) = m
->is_constant
;
821 rest_of_decl_compilation (fndecl
, 1, 0);
828 /* Convert an intrinsic function into an external or builtin call. */
831 gfc_conv_intrinsic_lib_function (gfc_se
* se
, gfc_expr
* expr
)
833 gfc_intrinsic_map_t
*m
;
837 unsigned int num_args
;
840 id
= expr
->value
.function
.isym
->id
;
841 /* Find the entry for this function. */
842 for (m
= gfc_intrinsic_map
;
843 m
->id
!= GFC_ISYM_NONE
|| m
->double_built_in
!= END_BUILTINS
; m
++)
849 if (m
->id
== GFC_ISYM_NONE
)
851 internal_error ("Intrinsic function %s(%d) not recognized",
852 expr
->value
.function
.name
, id
);
855 /* Get the decl and generate the call. */
856 num_args
= gfc_intrinsic_argument_list_length (expr
);
857 args
= XALLOCAVEC (tree
, num_args
);
859 gfc_conv_intrinsic_function_args (se
, expr
, args
, num_args
);
860 fndecl
= gfc_get_intrinsic_lib_fndecl (m
, expr
);
861 rettype
= TREE_TYPE (TREE_TYPE (fndecl
));
863 fndecl
= build_addr (fndecl
, current_function_decl
);
864 se
->expr
= build_call_array_loc (input_location
, rettype
, fndecl
, num_args
, args
);
868 /* If bounds-checking is enabled, create code to verify at runtime that the
869 string lengths for both expressions are the same (needed for e.g. MERGE).
870 If bounds-checking is not enabled, does nothing. */
873 gfc_trans_same_strlen_check (const char* intr_name
, locus
* where
,
874 tree a
, tree b
, stmtblock_t
* target
)
879 /* If bounds-checking is disabled, do nothing. */
880 if (!(gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
))
883 /* Compare the two string lengths. */
884 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, a
, b
);
886 /* Output the runtime-check. */
887 name
= gfc_build_cstring_const (intr_name
);
888 name
= gfc_build_addr_expr (pchar_type_node
, name
);
889 gfc_trans_runtime_check (true, false, cond
, target
, where
,
890 "Unequal character lengths (%ld/%ld) in %s",
891 fold_convert (long_integer_type_node
, a
),
892 fold_convert (long_integer_type_node
, b
), name
);
896 /* The EXPONENT(s) intrinsic function is translated into
903 gfc_conv_intrinsic_exponent (gfc_se
*se
, gfc_expr
*expr
)
905 tree arg
, type
, res
, tmp
, frexp
;
907 frexp
= gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP
,
908 expr
->value
.function
.actual
->expr
->ts
.kind
);
910 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
912 res
= gfc_create_var (integer_type_node
, NULL
);
913 tmp
= build_call_expr_loc (input_location
, frexp
, 2, arg
,
914 gfc_build_addr_expr (NULL_TREE
, res
));
915 gfc_add_expr_to_block (&se
->pre
, tmp
);
917 type
= gfc_typenode_for_spec (&expr
->ts
);
918 se
->expr
= fold_convert (type
, res
);
922 trans_this_image (gfc_se
* se
, gfc_expr
*expr ATTRIBUTE_UNUSED
)
924 gfc_init_coarray_decl ();
925 se
->expr
= gfort_gvar_caf_this_image
;
929 trans_num_images (gfc_se
* se
)
931 gfc_init_coarray_decl ();
932 se
->expr
= gfort_gvar_caf_num_images
;
935 /* Evaluate a single upper or lower bound. */
936 /* TODO: bound intrinsic generates way too much unnecessary code. */
939 gfc_conv_intrinsic_bound (gfc_se
* se
, gfc_expr
* expr
, int upper
)
941 gfc_actual_arglist
*arg
;
942 gfc_actual_arglist
*arg2
;
947 tree cond
, cond1
, cond3
, cond4
, size
;
954 arg
= expr
->value
.function
.actual
;
959 /* Create an implicit second parameter from the loop variable. */
960 gcc_assert (!arg2
->expr
);
961 gcc_assert (se
->loop
->dimen
== 1);
962 gcc_assert (se
->ss
->expr
== expr
);
963 gfc_advance_se_ss_chain (se
);
964 bound
= se
->loop
->loopvar
[0];
965 bound
= fold_build2_loc (input_location
, MINUS_EXPR
,
966 gfc_array_index_type
, bound
,
971 /* use the passed argument. */
972 gcc_assert (arg
->next
->expr
);
973 gfc_init_se (&argse
, NULL
);
974 gfc_conv_expr_type (&argse
, arg
->next
->expr
, gfc_array_index_type
);
975 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
977 /* Convert from one based to zero based. */
978 bound
= fold_build2_loc (input_location
, MINUS_EXPR
,
979 gfc_array_index_type
, bound
,
983 /* TODO: don't re-evaluate the descriptor on each iteration. */
984 /* Get a descriptor for the first parameter. */
985 ss
= gfc_walk_expr (arg
->expr
);
986 gcc_assert (ss
!= gfc_ss_terminator
);
987 gfc_init_se (&argse
, NULL
);
988 gfc_conv_expr_descriptor (&argse
, arg
->expr
, ss
);
989 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
990 gfc_add_block_to_block (&se
->post
, &argse
.post
);
994 if (INTEGER_CST_P (bound
))
998 hi
= TREE_INT_CST_HIGH (bound
);
999 low
= TREE_INT_CST_LOW (bound
);
1000 if (hi
|| low
< 0 || low
>= GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc
)))
1001 gfc_error ("'dim' argument of %s intrinsic at %L is not a valid "
1002 "dimension index", upper
? "UBOUND" : "LBOUND",
1007 if (gfc_option
.rtcheck
& GFC_RTCHECK_BOUNDS
)
1009 bound
= gfc_evaluate_now (bound
, &se
->pre
);
1010 cond
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
1011 bound
, build_int_cst (TREE_TYPE (bound
), 0));
1012 tmp
= gfc_rank_cst
[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc
))];
1013 tmp
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
1015 cond
= fold_build2_loc (input_location
, TRUTH_ORIF_EXPR
,
1016 boolean_type_node
, cond
, tmp
);
1017 gfc_trans_runtime_check (true, false, cond
, &se
->pre
, &expr
->where
,
1022 ubound
= gfc_conv_descriptor_ubound_get (desc
, bound
);
1023 lbound
= gfc_conv_descriptor_lbound_get (desc
, bound
);
1025 as
= gfc_get_full_arrayspec_from_expr (arg
->expr
);
1027 /* 13.14.53: Result value for LBOUND
1029 Case (i): For an array section or for an array expression other than a
1030 whole array or array structure component, LBOUND(ARRAY, DIM)
1031 has the value 1. For a whole array or array structure
1032 component, LBOUND(ARRAY, DIM) has the value:
1033 (a) equal to the lower bound for subscript DIM of ARRAY if
1034 dimension DIM of ARRAY does not have extent zero
1035 or if ARRAY is an assumed-size array of rank DIM,
1038 13.14.113: Result value for UBOUND
1040 Case (i): For an array section or for an array expression other than a
1041 whole array or array structure component, UBOUND(ARRAY, DIM)
1042 has the value equal to the number of elements in the given
1043 dimension; otherwise, it has a value equal to the upper bound
1044 for subscript DIM of ARRAY if dimension DIM of ARRAY does
1045 not have size zero and has value zero if dimension DIM has
1050 tree stride
= gfc_conv_descriptor_stride_get (desc
, bound
);
1052 cond1
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
1054 cond3
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
1055 stride
, gfc_index_zero_node
);
1056 cond3
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
1057 boolean_type_node
, cond3
, cond1
);
1058 cond4
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
1059 stride
, gfc_index_zero_node
);
1064 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
1065 boolean_type_node
, cond3
, cond4
);
1066 cond5
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
1067 gfc_index_one_node
, lbound
);
1068 cond5
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
1069 boolean_type_node
, cond4
, cond5
);
1071 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
1072 boolean_type_node
, cond
, cond5
);
1074 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
,
1075 gfc_array_index_type
, cond
,
1076 ubound
, gfc_index_zero_node
);
1080 if (as
->type
== AS_ASSUMED_SIZE
)
1081 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
1082 bound
, build_int_cst (TREE_TYPE (bound
),
1083 arg
->expr
->rank
- 1));
1085 cond
= boolean_false_node
;
1087 cond1
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
1088 boolean_type_node
, cond3
, cond4
);
1089 cond
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
1090 boolean_type_node
, cond
, cond1
);
1092 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
,
1093 gfc_array_index_type
, cond
,
1094 lbound
, gfc_index_one_node
);
1101 size
= fold_build2_loc (input_location
, MINUS_EXPR
,
1102 gfc_array_index_type
, ubound
, lbound
);
1103 se
->expr
= fold_build2_loc (input_location
, PLUS_EXPR
,
1104 gfc_array_index_type
, size
,
1105 gfc_index_one_node
);
1106 se
->expr
= fold_build2_loc (input_location
, MAX_EXPR
,
1107 gfc_array_index_type
, se
->expr
,
1108 gfc_index_zero_node
);
1111 se
->expr
= gfc_index_one_node
;
1114 type
= gfc_typenode_for_spec (&expr
->ts
);
1115 se
->expr
= convert (type
, se
->expr
);
1120 gfc_conv_intrinsic_abs (gfc_se
* se
, gfc_expr
* expr
)
1124 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
1126 switch (expr
->value
.function
.actual
->expr
->ts
.type
)
1130 se
->expr
= fold_build1_loc (input_location
, ABS_EXPR
, TREE_TYPE (arg
),
1135 cabs
= gfc_builtin_decl_for_float_kind (BUILT_IN_CABS
, expr
->ts
.kind
);
1136 se
->expr
= build_call_expr_loc (input_location
, cabs
, 1, arg
);
1145 /* Create a complex value from one or two real components. */
1148 gfc_conv_intrinsic_cmplx (gfc_se
* se
, gfc_expr
* expr
, int both
)
1154 unsigned int num_args
;
1156 num_args
= gfc_intrinsic_argument_list_length (expr
);
1157 args
= XALLOCAVEC (tree
, num_args
);
1159 type
= gfc_typenode_for_spec (&expr
->ts
);
1160 gfc_conv_intrinsic_function_args (se
, expr
, args
, num_args
);
1161 real
= convert (TREE_TYPE (type
), args
[0]);
1163 imag
= convert (TREE_TYPE (type
), args
[1]);
1164 else if (TREE_CODE (TREE_TYPE (args
[0])) == COMPLEX_TYPE
)
1166 imag
= fold_build1_loc (input_location
, IMAGPART_EXPR
,
1167 TREE_TYPE (TREE_TYPE (args
[0])), args
[0]);
1168 imag
= convert (TREE_TYPE (type
), imag
);
1171 imag
= build_real_from_int_cst (TREE_TYPE (type
), integer_zero_node
);
1173 se
->expr
= fold_build2_loc (input_location
, COMPLEX_EXPR
, type
, real
, imag
);
1176 /* Remainder function MOD(A, P) = A - INT(A / P) * P
1177 MODULO(A, P) = A - FLOOR (A / P) * P */
1178 /* TODO: MOD(x, 0) */
1181 gfc_conv_intrinsic_mod (gfc_se
* se
, gfc_expr
* expr
, int modulo
)
1193 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
1195 switch (expr
->ts
.type
)
1198 /* Integer case is easy, we've got a builtin op. */
1199 type
= TREE_TYPE (args
[0]);
1202 se
->expr
= fold_build2_loc (input_location
, FLOOR_MOD_EXPR
, type
,
1205 se
->expr
= fold_build2_loc (input_location
, TRUNC_MOD_EXPR
, type
,
1211 /* Check if we have a builtin fmod. */
1212 fmod
= gfc_builtin_decl_for_float_kind (BUILT_IN_FMOD
, expr
->ts
.kind
);
1214 /* Use it if it exists. */
1215 if (fmod
!= NULL_TREE
)
1217 tmp
= build_addr (fmod
, current_function_decl
);
1218 se
->expr
= build_call_array_loc (input_location
,
1219 TREE_TYPE (TREE_TYPE (fmod
)),
1225 type
= TREE_TYPE (args
[0]);
1227 args
[0] = gfc_evaluate_now (args
[0], &se
->pre
);
1228 args
[1] = gfc_evaluate_now (args
[1], &se
->pre
);
1231 modulo = arg - floor (arg/arg2) * arg2, so
1232 = test ? fmod (arg, arg2) : fmod (arg, arg2) + arg2,
1234 test = (fmod (arg, arg2) != 0) && ((arg < 0) xor (arg2 < 0))
1235 thereby avoiding another division and retaining the accuracy
1236 of the builtin function. */
1237 if (fmod
!= NULL_TREE
&& modulo
)
1239 tree zero
= gfc_build_const (type
, integer_zero_node
);
1240 tmp
= gfc_evaluate_now (se
->expr
, &se
->pre
);
1241 test
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
1243 test2
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
1245 test2
= fold_build2_loc (input_location
, TRUTH_XOR_EXPR
,
1246 boolean_type_node
, test
, test2
);
1247 test
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
1249 test
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
1250 boolean_type_node
, test
, test2
);
1251 test
= gfc_evaluate_now (test
, &se
->pre
);
1252 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
, test
,
1253 fold_build2_loc (input_location
, PLUS_EXPR
,
1254 type
, tmp
, args
[1]), tmp
);
1258 /* If we do not have a built_in fmod, the calculation is going to
1259 have to be done longhand. */
1260 tmp
= fold_build2_loc (input_location
, RDIV_EXPR
, type
, args
[0], args
[1]);
1262 /* Test if the value is too large to handle sensibly. */
1263 gfc_set_model_kind (expr
->ts
.kind
);
1265 n
= gfc_validate_kind (BT_INTEGER
, expr
->ts
.kind
, true);
1266 ikind
= expr
->ts
.kind
;
1269 n
= gfc_validate_kind (BT_INTEGER
, gfc_max_integer_kind
, false);
1270 ikind
= gfc_max_integer_kind
;
1272 mpfr_set_z (huge
, gfc_integer_kinds
[n
].huge
, GFC_RND_MODE
);
1273 test
= gfc_conv_mpfr_to_tree (huge
, expr
->ts
.kind
, 0);
1274 test2
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
,
1277 mpfr_neg (huge
, huge
, GFC_RND_MODE
);
1278 test
= gfc_conv_mpfr_to_tree (huge
, expr
->ts
.kind
, 0);
1279 test
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
, tmp
,
1281 test2
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
1282 boolean_type_node
, test
, test2
);
1284 itype
= gfc_get_int_type (ikind
);
1286 tmp
= build_fix_expr (&se
->pre
, tmp
, itype
, RND_FLOOR
);
1288 tmp
= build_fix_expr (&se
->pre
, tmp
, itype
, RND_TRUNC
);
1289 tmp
= convert (type
, tmp
);
1290 tmp
= fold_build3_loc (input_location
, COND_EXPR
, type
, test2
, tmp
,
1292 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, type
, tmp
, args
[1]);
1293 se
->expr
= fold_build2_loc (input_location
, MINUS_EXPR
, type
, args
[0],
1303 /* DSHIFTL(I,J,S) = (I << S) | (J >> (BITSIZE(J) - S))
1304 DSHIFTR(I,J,S) = (I << (BITSIZE(I) - S)) | (J >> S)
1305 where the right shifts are logical (i.e. 0's are shifted in).
1306 Because SHIFT_EXPR's want shifts strictly smaller than the integral
1307 type width, we have to special-case both S == 0 and S == BITSIZE(J):
1309 DSHIFTL(I,J,BITSIZE) = J
1311 DSHIFTR(I,J,BITSIZE) = I. */
1314 gfc_conv_intrinsic_dshift (gfc_se
* se
, gfc_expr
* expr
, bool dshiftl
)
1316 tree type
, utype
, stype
, arg1
, arg2
, shift
, res
, left
, right
;
1317 tree args
[3], cond
, tmp
;
1320 gfc_conv_intrinsic_function_args (se
, expr
, args
, 3);
1322 gcc_assert (TREE_TYPE (args
[0]) == TREE_TYPE (args
[1]));
1323 type
= TREE_TYPE (args
[0]);
1324 bitsize
= TYPE_PRECISION (type
);
1325 utype
= unsigned_type_for (type
);
1326 stype
= TREE_TYPE (args
[2]);
1328 arg1
= gfc_evaluate_now (args
[0], &se
->pre
);
1329 arg2
= gfc_evaluate_now (args
[1], &se
->pre
);
1330 shift
= gfc_evaluate_now (args
[2], &se
->pre
);
1332 /* The generic case. */
1333 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, stype
,
1334 build_int_cst (stype
, bitsize
), shift
);
1335 left
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
,
1336 arg1
, dshiftl
? shift
: tmp
);
1338 right
= fold_build2_loc (input_location
, RSHIFT_EXPR
, utype
,
1339 fold_convert (utype
, arg2
), dshiftl
? tmp
: shift
);
1340 right
= fold_convert (type
, right
);
1342 res
= fold_build2_loc (input_location
, BIT_IOR_EXPR
, type
, left
, right
);
1344 /* Special cases. */
1345 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, shift
,
1346 build_int_cst (stype
, 0));
1347 res
= fold_build3_loc (input_location
, COND_EXPR
, type
, cond
,
1348 dshiftl
? arg1
: arg2
, res
);
1350 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, shift
,
1351 build_int_cst (stype
, bitsize
));
1352 res
= fold_build3_loc (input_location
, COND_EXPR
, type
, cond
,
1353 dshiftl
? arg2
: arg1
, res
);
1359 /* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y. */
1362 gfc_conv_intrinsic_dim (gfc_se
* se
, gfc_expr
* expr
)
1370 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
1371 type
= TREE_TYPE (args
[0]);
1373 val
= fold_build2_loc (input_location
, MINUS_EXPR
, type
, args
[0], args
[1]);
1374 val
= gfc_evaluate_now (val
, &se
->pre
);
1376 zero
= gfc_build_const (type
, integer_zero_node
);
1377 tmp
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
, val
, zero
);
1378 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
, tmp
, zero
, val
);
1382 /* SIGN(A, B) is absolute value of A times sign of B.
1383 The real value versions use library functions to ensure the correct
1384 handling of negative zero. Integer case implemented as:
1385 SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
1389 gfc_conv_intrinsic_sign (gfc_se
* se
, gfc_expr
* expr
)
1395 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
1396 if (expr
->ts
.type
== BT_REAL
)
1400 tmp
= gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN
, expr
->ts
.kind
);
1401 abs
= gfc_builtin_decl_for_float_kind (BUILT_IN_FABS
, expr
->ts
.kind
);
1403 /* We explicitly have to ignore the minus sign. We do so by using
1404 result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1). */
1405 if (!gfc_option
.flag_sign_zero
1406 && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args
[1]))))
1409 zero
= build_real_from_int_cst (TREE_TYPE (args
[1]), integer_zero_node
);
1410 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
1412 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
,
1413 TREE_TYPE (args
[0]), cond
,
1414 build_call_expr_loc (input_location
, abs
, 1,
1416 build_call_expr_loc (input_location
, tmp
, 2,
1420 se
->expr
= build_call_expr_loc (input_location
, tmp
, 2,
1425 /* Having excluded floating point types, we know we are now dealing
1426 with signed integer types. */
1427 type
= TREE_TYPE (args
[0]);
1429 /* Args[0] is used multiple times below. */
1430 args
[0] = gfc_evaluate_now (args
[0], &se
->pre
);
1432 /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
1433 the signs of A and B are the same, and of all ones if they differ. */
1434 tmp
= fold_build2_loc (input_location
, BIT_XOR_EXPR
, type
, args
[0], args
[1]);
1435 tmp
= fold_build2_loc (input_location
, RSHIFT_EXPR
, type
, tmp
,
1436 build_int_cst (type
, TYPE_PRECISION (type
) - 1));
1437 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
1439 /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
1440 is all ones (i.e. -1). */
1441 se
->expr
= fold_build2_loc (input_location
, BIT_XOR_EXPR
, type
,
1442 fold_build2_loc (input_location
, PLUS_EXPR
,
1443 type
, args
[0], tmp
), tmp
);
1447 /* Test for the presence of an optional argument. */
1450 gfc_conv_intrinsic_present (gfc_se
* se
, gfc_expr
* expr
)
1454 arg
= expr
->value
.function
.actual
->expr
;
1455 gcc_assert (arg
->expr_type
== EXPR_VARIABLE
);
1456 se
->expr
= gfc_conv_expr_present (arg
->symtree
->n
.sym
);
1457 se
->expr
= convert (gfc_typenode_for_spec (&expr
->ts
), se
->expr
);
1461 /* Calculate the double precision product of two single precision values. */
1464 gfc_conv_intrinsic_dprod (gfc_se
* se
, gfc_expr
* expr
)
1469 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
1471 /* Convert the args to double precision before multiplying. */
1472 type
= gfc_typenode_for_spec (&expr
->ts
);
1473 args
[0] = convert (type
, args
[0]);
1474 args
[1] = convert (type
, args
[1]);
1475 se
->expr
= fold_build2_loc (input_location
, MULT_EXPR
, type
, args
[0],
1480 /* Return a length one character string containing an ascii character. */
1483 gfc_conv_intrinsic_char (gfc_se
* se
, gfc_expr
* expr
)
1488 unsigned int num_args
;
1490 num_args
= gfc_intrinsic_argument_list_length (expr
);
1491 gfc_conv_intrinsic_function_args (se
, expr
, arg
, num_args
);
1493 type
= gfc_get_char_type (expr
->ts
.kind
);
1494 var
= gfc_create_var (type
, "char");
1496 arg
[0] = fold_build1_loc (input_location
, NOP_EXPR
, type
, arg
[0]);
1497 gfc_add_modify (&se
->pre
, var
, arg
[0]);
1498 se
->expr
= gfc_build_addr_expr (build_pointer_type (type
), var
);
1499 se
->string_length
= build_int_cst (gfc_charlen_type_node
, 1);
1504 gfc_conv_intrinsic_ctime (gfc_se
* se
, gfc_expr
* expr
)
1512 unsigned int num_args
;
1514 num_args
= gfc_intrinsic_argument_list_length (expr
) + 2;
1515 args
= XALLOCAVEC (tree
, num_args
);
1517 var
= gfc_create_var (pchar_type_node
, "pstr");
1518 len
= gfc_create_var (gfc_charlen_type_node
, "len");
1520 gfc_conv_intrinsic_function_args (se
, expr
, &args
[2], num_args
- 2);
1521 args
[0] = gfc_build_addr_expr (NULL_TREE
, var
);
1522 args
[1] = gfc_build_addr_expr (NULL_TREE
, len
);
1524 fndecl
= build_addr (gfor_fndecl_ctime
, current_function_decl
);
1525 tmp
= build_call_array_loc (input_location
,
1526 TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime
)),
1527 fndecl
, num_args
, args
);
1528 gfc_add_expr_to_block (&se
->pre
, tmp
);
1530 /* Free the temporary afterwards, if necessary. */
1531 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
1532 len
, build_int_cst (TREE_TYPE (len
), 0));
1533 tmp
= gfc_call_free (var
);
1534 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
1535 gfc_add_expr_to_block (&se
->post
, tmp
);
1538 se
->string_length
= len
;
1543 gfc_conv_intrinsic_fdate (gfc_se
* se
, gfc_expr
* expr
)
1551 unsigned int num_args
;
1553 num_args
= gfc_intrinsic_argument_list_length (expr
) + 2;
1554 args
= XALLOCAVEC (tree
, num_args
);
1556 var
= gfc_create_var (pchar_type_node
, "pstr");
1557 len
= gfc_create_var (gfc_charlen_type_node
, "len");
1559 gfc_conv_intrinsic_function_args (se
, expr
, &args
[2], num_args
- 2);
1560 args
[0] = gfc_build_addr_expr (NULL_TREE
, var
);
1561 args
[1] = gfc_build_addr_expr (NULL_TREE
, len
);
1563 fndecl
= build_addr (gfor_fndecl_fdate
, current_function_decl
);
1564 tmp
= build_call_array_loc (input_location
,
1565 TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate
)),
1566 fndecl
, num_args
, args
);
1567 gfc_add_expr_to_block (&se
->pre
, tmp
);
1569 /* Free the temporary afterwards, if necessary. */
1570 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
1571 len
, build_int_cst (TREE_TYPE (len
), 0));
1572 tmp
= gfc_call_free (var
);
1573 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
1574 gfc_add_expr_to_block (&se
->post
, tmp
);
1577 se
->string_length
= len
;
1581 /* Return a character string containing the tty name. */
1584 gfc_conv_intrinsic_ttynam (gfc_se
* se
, gfc_expr
* expr
)
1592 unsigned int num_args
;
1594 num_args
= gfc_intrinsic_argument_list_length (expr
) + 2;
1595 args
= XALLOCAVEC (tree
, num_args
);
1597 var
= gfc_create_var (pchar_type_node
, "pstr");
1598 len
= gfc_create_var (gfc_charlen_type_node
, "len");
1600 gfc_conv_intrinsic_function_args (se
, expr
, &args
[2], num_args
- 2);
1601 args
[0] = gfc_build_addr_expr (NULL_TREE
, var
);
1602 args
[1] = gfc_build_addr_expr (NULL_TREE
, len
);
1604 fndecl
= build_addr (gfor_fndecl_ttynam
, current_function_decl
);
1605 tmp
= build_call_array_loc (input_location
,
1606 TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam
)),
1607 fndecl
, num_args
, args
);
1608 gfc_add_expr_to_block (&se
->pre
, tmp
);
1610 /* Free the temporary afterwards, if necessary. */
1611 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
1612 len
, build_int_cst (TREE_TYPE (len
), 0));
1613 tmp
= gfc_call_free (var
);
1614 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
1615 gfc_add_expr_to_block (&se
->post
, tmp
);
1618 se
->string_length
= len
;
1622 /* Get the minimum/maximum value of all the parameters.
1623 minmax (a1, a2, a3, ...)
1626 if (a2 .op. mvar || isnan(mvar))
1628 if (a3 .op. mvar || isnan(mvar))
1635 /* TODO: Mismatching types can occur when specific names are used.
1636 These should be handled during resolution. */
1638 gfc_conv_intrinsic_minmax (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
1646 gfc_actual_arglist
*argexpr
;
1647 unsigned int i
, nargs
;
1649 nargs
= gfc_intrinsic_argument_list_length (expr
);
1650 args
= XALLOCAVEC (tree
, nargs
);
1652 gfc_conv_intrinsic_function_args (se
, expr
, args
, nargs
);
1653 type
= gfc_typenode_for_spec (&expr
->ts
);
1655 argexpr
= expr
->value
.function
.actual
;
1656 if (TREE_TYPE (args
[0]) != type
)
1657 args
[0] = convert (type
, args
[0]);
1658 /* Only evaluate the argument once. */
1659 if (TREE_CODE (args
[0]) != VAR_DECL
&& !TREE_CONSTANT (args
[0]))
1660 args
[0] = gfc_evaluate_now (args
[0], &se
->pre
);
1662 mvar
= gfc_create_var (type
, "M");
1663 gfc_add_modify (&se
->pre
, mvar
, args
[0]);
1664 for (i
= 1, argexpr
= argexpr
->next
; i
< nargs
; i
++)
1670 /* Handle absent optional arguments by ignoring the comparison. */
1671 if (argexpr
->expr
->expr_type
== EXPR_VARIABLE
1672 && argexpr
->expr
->symtree
->n
.sym
->attr
.optional
1673 && TREE_CODE (val
) == INDIRECT_REF
)
1674 cond
= fold_build2_loc (input_location
,
1675 NE_EXPR
, boolean_type_node
,
1676 TREE_OPERAND (val
, 0),
1677 build_int_cst (TREE_TYPE (TREE_OPERAND (val
, 0)), 0));
1682 /* Only evaluate the argument once. */
1683 if (TREE_CODE (val
) != VAR_DECL
&& !TREE_CONSTANT (val
))
1684 val
= gfc_evaluate_now (val
, &se
->pre
);
1687 thencase
= build2_v (MODIFY_EXPR
, mvar
, convert (type
, val
));
1689 tmp
= fold_build2_loc (input_location
, op
, boolean_type_node
,
1690 convert (type
, val
), mvar
);
1692 /* FIXME: When the IEEE_ARITHMETIC module is implemented, the call to
1693 __builtin_isnan might be made dependent on that module being loaded,
1694 to help performance of programs that don't rely on IEEE semantics. */
1695 if (FLOAT_TYPE_P (TREE_TYPE (mvar
)))
1697 isnan
= build_call_expr_loc (input_location
,
1698 built_in_decls
[BUILT_IN_ISNAN
], 1, mvar
);
1699 tmp
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
,
1700 boolean_type_node
, tmp
,
1701 fold_convert (boolean_type_node
, isnan
));
1703 tmp
= build3_v (COND_EXPR
, tmp
, thencase
,
1704 build_empty_stmt (input_location
));
1706 if (cond
!= NULL_TREE
)
1707 tmp
= build3_v (COND_EXPR
, cond
, tmp
,
1708 build_empty_stmt (input_location
));
1710 gfc_add_expr_to_block (&se
->pre
, tmp
);
1711 argexpr
= argexpr
->next
;
1717 /* Generate library calls for MIN and MAX intrinsics for character
1720 gfc_conv_intrinsic_minmax_char (gfc_se
* se
, gfc_expr
* expr
, int op
)
1723 tree var
, len
, fndecl
, tmp
, cond
, function
;
1726 nargs
= gfc_intrinsic_argument_list_length (expr
);
1727 args
= XALLOCAVEC (tree
, nargs
+ 4);
1728 gfc_conv_intrinsic_function_args (se
, expr
, &args
[4], nargs
);
1730 /* Create the result variables. */
1731 len
= gfc_create_var (gfc_charlen_type_node
, "len");
1732 args
[0] = gfc_build_addr_expr (NULL_TREE
, len
);
1733 var
= gfc_create_var (gfc_get_pchar_type (expr
->ts
.kind
), "pstr");
1734 args
[1] = gfc_build_addr_expr (ppvoid_type_node
, var
);
1735 args
[2] = build_int_cst (NULL_TREE
, op
);
1736 args
[3] = build_int_cst (NULL_TREE
, nargs
/ 2);
1738 if (expr
->ts
.kind
== 1)
1739 function
= gfor_fndecl_string_minmax
;
1740 else if (expr
->ts
.kind
== 4)
1741 function
= gfor_fndecl_string_minmax_char4
;
1745 /* Make the function call. */
1746 fndecl
= build_addr (function
, current_function_decl
);
1747 tmp
= build_call_array_loc (input_location
,
1748 TREE_TYPE (TREE_TYPE (function
)), fndecl
,
1750 gfc_add_expr_to_block (&se
->pre
, tmp
);
1752 /* Free the temporary afterwards, if necessary. */
1753 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
1754 len
, build_int_cst (TREE_TYPE (len
), 0));
1755 tmp
= gfc_call_free (var
);
1756 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
1757 gfc_add_expr_to_block (&se
->post
, tmp
);
1760 se
->string_length
= len
;
1764 /* Create a symbol node for this intrinsic. The symbol from the frontend
1765 has the generic name. */
1768 gfc_get_symbol_for_expr (gfc_expr
* expr
)
1772 /* TODO: Add symbols for intrinsic function to the global namespace. */
1773 gcc_assert (strlen (expr
->value
.function
.name
) <= GFC_MAX_SYMBOL_LEN
- 5);
1774 sym
= gfc_new_symbol (expr
->value
.function
.name
, NULL
);
1777 sym
->attr
.external
= 1;
1778 sym
->attr
.function
= 1;
1779 sym
->attr
.always_explicit
= 1;
1780 sym
->attr
.proc
= PROC_INTRINSIC
;
1781 sym
->attr
.flavor
= FL_PROCEDURE
;
1785 sym
->attr
.dimension
= 1;
1786 sym
->as
= gfc_get_array_spec ();
1787 sym
->as
->type
= AS_ASSUMED_SHAPE
;
1788 sym
->as
->rank
= expr
->rank
;
1791 gfc_copy_formal_args_intr (sym
, expr
->value
.function
.isym
);
1796 /* Generate a call to an external intrinsic function. */
1798 gfc_conv_intrinsic_funcall (gfc_se
* se
, gfc_expr
* expr
)
1801 VEC(tree
,gc
) *append_args
;
1803 gcc_assert (!se
->ss
|| se
->ss
->expr
== expr
);
1806 gcc_assert (expr
->rank
> 0);
1808 gcc_assert (expr
->rank
== 0);
1810 sym
= gfc_get_symbol_for_expr (expr
);
1812 /* Calls to libgfortran_matmul need to be appended special arguments,
1813 to be able to call the BLAS ?gemm functions if required and possible. */
1815 if (expr
->value
.function
.isym
->id
== GFC_ISYM_MATMUL
1816 && sym
->ts
.type
!= BT_LOGICAL
)
1818 tree cint
= gfc_get_int_type (gfc_c_int_kind
);
1820 if (gfc_option
.flag_external_blas
1821 && (sym
->ts
.type
== BT_REAL
|| sym
->ts
.type
== BT_COMPLEX
)
1822 && (sym
->ts
.kind
== gfc_default_real_kind
1823 || sym
->ts
.kind
== gfc_default_double_kind
))
1827 if (sym
->ts
.type
== BT_REAL
)
1829 if (sym
->ts
.kind
== gfc_default_real_kind
)
1830 gemm_fndecl
= gfor_fndecl_sgemm
;
1832 gemm_fndecl
= gfor_fndecl_dgemm
;
1836 if (sym
->ts
.kind
== gfc_default_real_kind
)
1837 gemm_fndecl
= gfor_fndecl_cgemm
;
1839 gemm_fndecl
= gfor_fndecl_zgemm
;
1842 append_args
= VEC_alloc (tree
, gc
, 3);
1843 VEC_quick_push (tree
, append_args
, build_int_cst (cint
, 1));
1844 VEC_quick_push (tree
, append_args
,
1845 build_int_cst (cint
, gfc_option
.blas_matmul_limit
));
1846 VEC_quick_push (tree
, append_args
,
1847 gfc_build_addr_expr (NULL_TREE
, gemm_fndecl
));
1851 append_args
= VEC_alloc (tree
, gc
, 3);
1852 VEC_quick_push (tree
, append_args
, build_int_cst (cint
, 0));
1853 VEC_quick_push (tree
, append_args
, build_int_cst (cint
, 0));
1854 VEC_quick_push (tree
, append_args
, null_pointer_node
);
1858 gfc_conv_procedure_call (se
, sym
, expr
->value
.function
.actual
, expr
,
1860 gfc_free_symbol (sym
);
1863 /* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
1883 gfc_conv_intrinsic_anyall (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
1892 gfc_actual_arglist
*actual
;
1899 gfc_conv_intrinsic_funcall (se
, expr
);
1903 actual
= expr
->value
.function
.actual
;
1904 type
= gfc_typenode_for_spec (&expr
->ts
);
1905 /* Initialize the result. */
1906 resvar
= gfc_create_var (type
, "test");
1908 tmp
= convert (type
, boolean_true_node
);
1910 tmp
= convert (type
, boolean_false_node
);
1911 gfc_add_modify (&se
->pre
, resvar
, tmp
);
1913 /* Walk the arguments. */
1914 arrayss
= gfc_walk_expr (actual
->expr
);
1915 gcc_assert (arrayss
!= gfc_ss_terminator
);
1917 /* Initialize the scalarizer. */
1918 gfc_init_loopinfo (&loop
);
1919 exit_label
= gfc_build_label_decl (NULL_TREE
);
1920 TREE_USED (exit_label
) = 1;
1921 gfc_add_ss_to_loop (&loop
, arrayss
);
1923 /* Initialize the loop. */
1924 gfc_conv_ss_startstride (&loop
);
1925 gfc_conv_loop_setup (&loop
, &expr
->where
);
1927 gfc_mark_ss_chain_used (arrayss
, 1);
1928 /* Generate the loop body. */
1929 gfc_start_scalarized_body (&loop
, &body
);
1931 /* If the condition matches then set the return value. */
1932 gfc_start_block (&block
);
1934 tmp
= convert (type
, boolean_false_node
);
1936 tmp
= convert (type
, boolean_true_node
);
1937 gfc_add_modify (&block
, resvar
, tmp
);
1939 /* And break out of the loop. */
1940 tmp
= build1_v (GOTO_EXPR
, exit_label
);
1941 gfc_add_expr_to_block (&block
, tmp
);
1943 found
= gfc_finish_block (&block
);
1945 /* Check this element. */
1946 gfc_init_se (&arrayse
, NULL
);
1947 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
1948 arrayse
.ss
= arrayss
;
1949 gfc_conv_expr_val (&arrayse
, actual
->expr
);
1951 gfc_add_block_to_block (&body
, &arrayse
.pre
);
1952 tmp
= fold_build2_loc (input_location
, op
, boolean_type_node
, arrayse
.expr
,
1953 build_int_cst (TREE_TYPE (arrayse
.expr
), 0));
1954 tmp
= build3_v (COND_EXPR
, tmp
, found
, build_empty_stmt (input_location
));
1955 gfc_add_expr_to_block (&body
, tmp
);
1956 gfc_add_block_to_block (&body
, &arrayse
.post
);
1958 gfc_trans_scalarizing_loops (&loop
, &body
);
1960 /* Add the exit label. */
1961 tmp
= build1_v (LABEL_EXPR
, exit_label
);
1962 gfc_add_expr_to_block (&loop
.pre
, tmp
);
1964 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
1965 gfc_add_block_to_block (&se
->pre
, &loop
.post
);
1966 gfc_cleanup_loop (&loop
);
1971 /* COUNT(A) = Number of true elements in A. */
1973 gfc_conv_intrinsic_count (gfc_se
* se
, gfc_expr
* expr
)
1980 gfc_actual_arglist
*actual
;
1986 gfc_conv_intrinsic_funcall (se
, expr
);
1990 actual
= expr
->value
.function
.actual
;
1992 type
= gfc_typenode_for_spec (&expr
->ts
);
1993 /* Initialize the result. */
1994 resvar
= gfc_create_var (type
, "count");
1995 gfc_add_modify (&se
->pre
, resvar
, build_int_cst (type
, 0));
1997 /* Walk the arguments. */
1998 arrayss
= gfc_walk_expr (actual
->expr
);
1999 gcc_assert (arrayss
!= gfc_ss_terminator
);
2001 /* Initialize the scalarizer. */
2002 gfc_init_loopinfo (&loop
);
2003 gfc_add_ss_to_loop (&loop
, arrayss
);
2005 /* Initialize the loop. */
2006 gfc_conv_ss_startstride (&loop
);
2007 gfc_conv_loop_setup (&loop
, &expr
->where
);
2009 gfc_mark_ss_chain_used (arrayss
, 1);
2010 /* Generate the loop body. */
2011 gfc_start_scalarized_body (&loop
, &body
);
2013 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (resvar
),
2014 resvar
, build_int_cst (TREE_TYPE (resvar
), 1));
2015 tmp
= build2_v (MODIFY_EXPR
, resvar
, tmp
);
2017 gfc_init_se (&arrayse
, NULL
);
2018 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
2019 arrayse
.ss
= arrayss
;
2020 gfc_conv_expr_val (&arrayse
, actual
->expr
);
2021 tmp
= build3_v (COND_EXPR
, arrayse
.expr
, tmp
,
2022 build_empty_stmt (input_location
));
2024 gfc_add_block_to_block (&body
, &arrayse
.pre
);
2025 gfc_add_expr_to_block (&body
, tmp
);
2026 gfc_add_block_to_block (&body
, &arrayse
.post
);
2028 gfc_trans_scalarizing_loops (&loop
, &body
);
2030 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
2031 gfc_add_block_to_block (&se
->pre
, &loop
.post
);
2032 gfc_cleanup_loop (&loop
);
2037 /* Inline implementation of the sum and product intrinsics. */
2039 gfc_conv_intrinsic_arith (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
,
2043 tree scale
= NULL_TREE
;
2049 gfc_actual_arglist
*actual
;
2054 gfc_expr
*arrayexpr
;
2059 gfc_conv_intrinsic_funcall (se
, expr
);
2063 type
= gfc_typenode_for_spec (&expr
->ts
);
2064 /* Initialize the result. */
2065 resvar
= gfc_create_var (type
, "val");
2070 scale
= gfc_create_var (type
, "scale");
2071 gfc_add_modify (&se
->pre
, scale
,
2072 gfc_build_const (type
, integer_one_node
));
2073 tmp
= gfc_build_const (type
, integer_zero_node
);
2075 else if (op
== PLUS_EXPR
|| op
== BIT_IOR_EXPR
|| op
== BIT_XOR_EXPR
)
2076 tmp
= gfc_build_const (type
, integer_zero_node
);
2077 else if (op
== NE_EXPR
)
2079 tmp
= convert (type
, boolean_false_node
);
2080 else if (op
== BIT_AND_EXPR
)
2081 tmp
= gfc_build_const (type
, fold_build1_loc (input_location
, NEGATE_EXPR
,
2082 type
, integer_one_node
));
2084 tmp
= gfc_build_const (type
, integer_one_node
);
2086 gfc_add_modify (&se
->pre
, resvar
, tmp
);
2088 /* Walk the arguments. */
2089 actual
= expr
->value
.function
.actual
;
2090 arrayexpr
= actual
->expr
;
2091 arrayss
= gfc_walk_expr (arrayexpr
);
2092 gcc_assert (arrayss
!= gfc_ss_terminator
);
2094 if (op
== NE_EXPR
|| norm2
)
2095 /* PARITY and NORM2. */
2099 actual
= actual
->next
->next
;
2100 gcc_assert (actual
);
2101 maskexpr
= actual
->expr
;
2104 if (maskexpr
&& maskexpr
->rank
!= 0)
2106 maskss
= gfc_walk_expr (maskexpr
);
2107 gcc_assert (maskss
!= gfc_ss_terminator
);
2112 /* Initialize the scalarizer. */
2113 gfc_init_loopinfo (&loop
);
2114 gfc_add_ss_to_loop (&loop
, arrayss
);
2116 gfc_add_ss_to_loop (&loop
, maskss
);
2118 /* Initialize the loop. */
2119 gfc_conv_ss_startstride (&loop
);
2120 gfc_conv_loop_setup (&loop
, &expr
->where
);
2122 gfc_mark_ss_chain_used (arrayss
, 1);
2124 gfc_mark_ss_chain_used (maskss
, 1);
2125 /* Generate the loop body. */
2126 gfc_start_scalarized_body (&loop
, &body
);
2128 /* If we have a mask, only add this element if the mask is set. */
2131 gfc_init_se (&maskse
, NULL
);
2132 gfc_copy_loopinfo_to_se (&maskse
, &loop
);
2134 gfc_conv_expr_val (&maskse
, maskexpr
);
2135 gfc_add_block_to_block (&body
, &maskse
.pre
);
2137 gfc_start_block (&block
);
2140 gfc_init_block (&block
);
2142 /* Do the actual summation/product. */
2143 gfc_init_se (&arrayse
, NULL
);
2144 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
2145 arrayse
.ss
= arrayss
;
2146 gfc_conv_expr_val (&arrayse
, arrayexpr
);
2147 gfc_add_block_to_block (&block
, &arrayse
.pre
);
2157 result = 1.0 + result * val * val;
2163 result += val * val;
2166 tree res1
, res2
, cond
, absX
, val
;
2167 stmtblock_t ifblock1
, ifblock2
, ifblock3
;
2169 gfc_init_block (&ifblock1
);
2171 absX
= gfc_create_var (type
, "absX");
2172 gfc_add_modify (&ifblock1
, absX
,
2173 fold_build1_loc (input_location
, ABS_EXPR
, type
,
2175 val
= gfc_create_var (type
, "val");
2176 gfc_add_expr_to_block (&ifblock1
, val
);
2178 gfc_init_block (&ifblock2
);
2179 gfc_add_modify (&ifblock2
, val
,
2180 fold_build2_loc (input_location
, RDIV_EXPR
, type
, scale
,
2182 res1
= fold_build2_loc (input_location
, MULT_EXPR
, type
, val
, val
);
2183 res1
= fold_build2_loc (input_location
, MULT_EXPR
, type
, resvar
, res1
);
2184 res1
= fold_build2_loc (input_location
, PLUS_EXPR
, type
, res1
,
2185 gfc_build_const (type
, integer_one_node
));
2186 gfc_add_modify (&ifblock2
, resvar
, res1
);
2187 gfc_add_modify (&ifblock2
, scale
, absX
);
2188 res1
= gfc_finish_block (&ifblock2
);
2190 gfc_init_block (&ifblock3
);
2191 gfc_add_modify (&ifblock3
, val
,
2192 fold_build2_loc (input_location
, RDIV_EXPR
, type
, absX
,
2194 res2
= fold_build2_loc (input_location
, MULT_EXPR
, type
, val
, val
);
2195 res2
= fold_build2_loc (input_location
, PLUS_EXPR
, type
, resvar
, res2
);
2196 gfc_add_modify (&ifblock3
, resvar
, res2
);
2197 res2
= gfc_finish_block (&ifblock3
);
2199 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
2201 tmp
= build3_v (COND_EXPR
, cond
, res1
, res2
);
2202 gfc_add_expr_to_block (&ifblock1
, tmp
);
2203 tmp
= gfc_finish_block (&ifblock1
);
2205 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
2207 gfc_build_const (type
, integer_zero_node
));
2209 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
2210 gfc_add_expr_to_block (&block
, tmp
);
2214 tmp
= fold_build2_loc (input_location
, op
, type
, resvar
, arrayse
.expr
);
2215 gfc_add_modify (&block
, resvar
, tmp
);
2218 gfc_add_block_to_block (&block
, &arrayse
.post
);
2222 /* We enclose the above in if (mask) {...} . */
2224 tmp
= gfc_finish_block (&block
);
2225 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
,
2226 build_empty_stmt (input_location
));
2229 tmp
= gfc_finish_block (&block
);
2230 gfc_add_expr_to_block (&body
, tmp
);
2232 gfc_trans_scalarizing_loops (&loop
, &body
);
2234 /* For a scalar mask, enclose the loop in an if statement. */
2235 if (maskexpr
&& maskss
== NULL
)
2237 gfc_init_se (&maskse
, NULL
);
2238 gfc_conv_expr_val (&maskse
, maskexpr
);
2239 gfc_init_block (&block
);
2240 gfc_add_block_to_block (&block
, &loop
.pre
);
2241 gfc_add_block_to_block (&block
, &loop
.post
);
2242 tmp
= gfc_finish_block (&block
);
2244 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
,
2245 build_empty_stmt (input_location
));
2246 gfc_add_expr_to_block (&block
, tmp
);
2247 gfc_add_block_to_block (&se
->pre
, &block
);
2251 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
2252 gfc_add_block_to_block (&se
->pre
, &loop
.post
);
2255 gfc_cleanup_loop (&loop
);
2259 /* result = scale * sqrt(result). */
2261 sqrt
= gfc_builtin_decl_for_float_kind (BUILT_IN_SQRT
, expr
->ts
.kind
);
2262 resvar
= build_call_expr_loc (input_location
,
2264 resvar
= fold_build2_loc (input_location
, MULT_EXPR
, type
, scale
, resvar
);
2271 /* Inline implementation of the dot_product intrinsic. This function
2272 is based on gfc_conv_intrinsic_arith (the previous function). */
2274 gfc_conv_intrinsic_dot_product (gfc_se
* se
, gfc_expr
* expr
)
2282 gfc_actual_arglist
*actual
;
2283 gfc_ss
*arrayss1
, *arrayss2
;
2284 gfc_se arrayse1
, arrayse2
;
2285 gfc_expr
*arrayexpr1
, *arrayexpr2
;
2287 type
= gfc_typenode_for_spec (&expr
->ts
);
2289 /* Initialize the result. */
2290 resvar
= gfc_create_var (type
, "val");
2291 if (expr
->ts
.type
== BT_LOGICAL
)
2292 tmp
= build_int_cst (type
, 0);
2294 tmp
= gfc_build_const (type
, integer_zero_node
);
2296 gfc_add_modify (&se
->pre
, resvar
, tmp
);
2298 /* Walk argument #1. */
2299 actual
= expr
->value
.function
.actual
;
2300 arrayexpr1
= actual
->expr
;
2301 arrayss1
= gfc_walk_expr (arrayexpr1
);
2302 gcc_assert (arrayss1
!= gfc_ss_terminator
);
2304 /* Walk argument #2. */
2305 actual
= actual
->next
;
2306 arrayexpr2
= actual
->expr
;
2307 arrayss2
= gfc_walk_expr (arrayexpr2
);
2308 gcc_assert (arrayss2
!= gfc_ss_terminator
);
2310 /* Initialize the scalarizer. */
2311 gfc_init_loopinfo (&loop
);
2312 gfc_add_ss_to_loop (&loop
, arrayss1
);
2313 gfc_add_ss_to_loop (&loop
, arrayss2
);
2315 /* Initialize the loop. */
2316 gfc_conv_ss_startstride (&loop
);
2317 gfc_conv_loop_setup (&loop
, &expr
->where
);
2319 gfc_mark_ss_chain_used (arrayss1
, 1);
2320 gfc_mark_ss_chain_used (arrayss2
, 1);
2322 /* Generate the loop body. */
2323 gfc_start_scalarized_body (&loop
, &body
);
2324 gfc_init_block (&block
);
2326 /* Make the tree expression for [conjg(]array1[)]. */
2327 gfc_init_se (&arrayse1
, NULL
);
2328 gfc_copy_loopinfo_to_se (&arrayse1
, &loop
);
2329 arrayse1
.ss
= arrayss1
;
2330 gfc_conv_expr_val (&arrayse1
, arrayexpr1
);
2331 if (expr
->ts
.type
== BT_COMPLEX
)
2332 arrayse1
.expr
= fold_build1_loc (input_location
, CONJ_EXPR
, type
,
2334 gfc_add_block_to_block (&block
, &arrayse1
.pre
);
2336 /* Make the tree expression for array2. */
2337 gfc_init_se (&arrayse2
, NULL
);
2338 gfc_copy_loopinfo_to_se (&arrayse2
, &loop
);
2339 arrayse2
.ss
= arrayss2
;
2340 gfc_conv_expr_val (&arrayse2
, arrayexpr2
);
2341 gfc_add_block_to_block (&block
, &arrayse2
.pre
);
2343 /* Do the actual product and sum. */
2344 if (expr
->ts
.type
== BT_LOGICAL
)
2346 tmp
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
, type
,
2347 arrayse1
.expr
, arrayse2
.expr
);
2348 tmp
= fold_build2_loc (input_location
, TRUTH_OR_EXPR
, type
, resvar
, tmp
);
2352 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, type
, arrayse1
.expr
,
2354 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, type
, resvar
, tmp
);
2356 gfc_add_modify (&block
, resvar
, tmp
);
2358 /* Finish up the loop block and the loop. */
2359 tmp
= gfc_finish_block (&block
);
2360 gfc_add_expr_to_block (&body
, tmp
);
2362 gfc_trans_scalarizing_loops (&loop
, &body
);
2363 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
2364 gfc_add_block_to_block (&se
->pre
, &loop
.post
);
2365 gfc_cleanup_loop (&loop
);
2371 /* Emit code for minloc or maxloc intrinsic. There are many different cases
2372 we need to handle. For performance reasons we sometimes create two
2373 loops instead of one, where the second one is much simpler.
2374 Examples for minloc intrinsic:
2375 1) Result is an array, a call is generated
2376 2) Array mask is used and NaNs need to be supported:
2382 if (pos == 0) pos = S + (1 - from);
2383 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2390 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2394 3) NaNs need to be supported, but it is known at compile time or cheaply
2395 at runtime whether array is nonempty or not:
2400 if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2403 if (from <= to) pos = 1;
2407 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2411 4) NaNs aren't supported, array mask is used:
2412 limit = infinities_supported ? Infinity : huge (limit);
2416 if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
2422 if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2426 5) Same without array mask:
2427 limit = infinities_supported ? Infinity : huge (limit);
2428 pos = (from <= to) ? 1 : 0;
2431 if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
2434 For 3) and 5), if mask is scalar, this all goes into a conditional,
2435 setting pos = 0; in the else branch. */
2438 gfc_conv_intrinsic_minmaxloc (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
2442 stmtblock_t ifblock
;
2443 stmtblock_t elseblock
;
2454 gfc_actual_arglist
*actual
;
2459 gfc_expr
*arrayexpr
;
2466 gfc_conv_intrinsic_funcall (se
, expr
);
2470 /* Initialize the result. */
2471 pos
= gfc_create_var (gfc_array_index_type
, "pos");
2472 offset
= gfc_create_var (gfc_array_index_type
, "offset");
2473 type
= gfc_typenode_for_spec (&expr
->ts
);
2475 /* Walk the arguments. */
2476 actual
= expr
->value
.function
.actual
;
2477 arrayexpr
= actual
->expr
;
2478 arrayss
= gfc_walk_expr (arrayexpr
);
2479 gcc_assert (arrayss
!= gfc_ss_terminator
);
2481 actual
= actual
->next
->next
;
2482 gcc_assert (actual
);
2483 maskexpr
= actual
->expr
;
2485 if (maskexpr
&& maskexpr
->rank
!= 0)
2487 maskss
= gfc_walk_expr (maskexpr
);
2488 gcc_assert (maskss
!= gfc_ss_terminator
);
2493 if (gfc_array_size (arrayexpr
, &asize
) == SUCCESS
)
2495 nonempty
= gfc_conv_mpz_to_tree (asize
, gfc_index_integer_kind
);
2497 nonempty
= fold_build2_loc (input_location
, GT_EXPR
,
2498 boolean_type_node
, nonempty
,
2499 gfc_index_zero_node
);
2504 limit
= gfc_create_var (gfc_typenode_for_spec (&arrayexpr
->ts
), "limit");
2505 switch (arrayexpr
->ts
.type
)
2508 tmp
= gfc_build_inf_or_huge (TREE_TYPE (limit
), arrayexpr
->ts
.kind
);
2512 n
= gfc_validate_kind (arrayexpr
->ts
.type
, arrayexpr
->ts
.kind
, false);
2513 tmp
= gfc_conv_mpz_to_tree (gfc_integer_kinds
[n
].huge
,
2514 arrayexpr
->ts
.kind
);
2521 /* We start with the most negative possible value for MAXLOC, and the most
2522 positive possible value for MINLOC. The most negative possible value is
2523 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2524 possible value is HUGE in both cases. */
2526 tmp
= fold_build1_loc (input_location
, NEGATE_EXPR
, TREE_TYPE (tmp
), tmp
);
2527 if (op
== GT_EXPR
&& expr
->ts
.type
== BT_INTEGER
)
2528 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (tmp
), tmp
,
2529 build_int_cst (type
, 1));
2531 gfc_add_modify (&se
->pre
, limit
, tmp
);
2533 /* Initialize the scalarizer. */
2534 gfc_init_loopinfo (&loop
);
2535 gfc_add_ss_to_loop (&loop
, arrayss
);
2537 gfc_add_ss_to_loop (&loop
, maskss
);
2539 /* Initialize the loop. */
2540 gfc_conv_ss_startstride (&loop
);
2541 gfc_conv_loop_setup (&loop
, &expr
->where
);
2543 gcc_assert (loop
.dimen
== 1);
2544 if (nonempty
== NULL
&& maskss
== NULL
&& loop
.from
[0] && loop
.to
[0])
2545 nonempty
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
2546 loop
.from
[0], loop
.to
[0]);
2550 /* Initialize the position to zero, following Fortran 2003. We are free
2551 to do this because Fortran 95 allows the result of an entirely false
2552 mask to be processor dependent. If we know at compile time the array
2553 is non-empty and no MASK is used, we can initialize to 1 to simplify
2555 if (nonempty
!= NULL
&& !HONOR_NANS (DECL_MODE (limit
)))
2556 gfc_add_modify (&loop
.pre
, pos
,
2557 fold_build3_loc (input_location
, COND_EXPR
,
2558 gfc_array_index_type
,
2559 nonempty
, gfc_index_one_node
,
2560 gfc_index_zero_node
));
2563 gfc_add_modify (&loop
.pre
, pos
, gfc_index_zero_node
);
2564 lab1
= gfc_build_label_decl (NULL_TREE
);
2565 TREE_USED (lab1
) = 1;
2566 lab2
= gfc_build_label_decl (NULL_TREE
);
2567 TREE_USED (lab2
) = 1;
2570 gfc_mark_ss_chain_used (arrayss
, 1);
2572 gfc_mark_ss_chain_used (maskss
, 1);
2573 /* Generate the loop body. */
2574 gfc_start_scalarized_body (&loop
, &body
);
2576 /* If we have a mask, only check this element if the mask is set. */
2579 gfc_init_se (&maskse
, NULL
);
2580 gfc_copy_loopinfo_to_se (&maskse
, &loop
);
2582 gfc_conv_expr_val (&maskse
, maskexpr
);
2583 gfc_add_block_to_block (&body
, &maskse
.pre
);
2585 gfc_start_block (&block
);
2588 gfc_init_block (&block
);
2590 /* Compare with the current limit. */
2591 gfc_init_se (&arrayse
, NULL
);
2592 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
2593 arrayse
.ss
= arrayss
;
2594 gfc_conv_expr_val (&arrayse
, arrayexpr
);
2595 gfc_add_block_to_block (&block
, &arrayse
.pre
);
2597 /* We do the following if this is a more extreme value. */
2598 gfc_start_block (&ifblock
);
2600 /* Assign the value to the limit... */
2601 gfc_add_modify (&ifblock
, limit
, arrayse
.expr
);
2603 /* Remember where we are. An offset must be added to the loop
2604 counter to obtain the required position. */
2606 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
2607 gfc_index_one_node
, loop
.from
[0]);
2609 tmp
= gfc_index_one_node
;
2611 gfc_add_modify (&block
, offset
, tmp
);
2613 if (nonempty
== NULL
&& HONOR_NANS (DECL_MODE (limit
)))
2615 stmtblock_t ifblock2
;
2618 gfc_start_block (&ifblock2
);
2619 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (pos
),
2620 loop
.loopvar
[0], offset
);
2621 gfc_add_modify (&ifblock2
, pos
, tmp
);
2622 ifbody2
= gfc_finish_block (&ifblock2
);
2623 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, pos
,
2624 gfc_index_zero_node
);
2625 tmp
= build3_v (COND_EXPR
, cond
, ifbody2
,
2626 build_empty_stmt (input_location
));
2627 gfc_add_expr_to_block (&block
, tmp
);
2630 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (pos
),
2631 loop
.loopvar
[0], offset
);
2632 gfc_add_modify (&ifblock
, pos
, tmp
);
2635 gfc_add_expr_to_block (&ifblock
, build1_v (GOTO_EXPR
, lab1
));
2637 ifbody
= gfc_finish_block (&ifblock
);
2639 if (!lab1
|| HONOR_NANS (DECL_MODE (limit
)))
2642 cond
= fold_build2_loc (input_location
,
2643 op
== GT_EXPR
? GE_EXPR
: LE_EXPR
,
2644 boolean_type_node
, arrayse
.expr
, limit
);
2646 cond
= fold_build2_loc (input_location
, op
, boolean_type_node
,
2647 arrayse
.expr
, limit
);
2649 ifbody
= build3_v (COND_EXPR
, cond
, ifbody
,
2650 build_empty_stmt (input_location
));
2652 gfc_add_expr_to_block (&block
, ifbody
);
2656 /* We enclose the above in if (mask) {...}. */
2657 tmp
= gfc_finish_block (&block
);
2659 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
,
2660 build_empty_stmt (input_location
));
2663 tmp
= gfc_finish_block (&block
);
2664 gfc_add_expr_to_block (&body
, tmp
);
2668 gfc_trans_scalarized_loop_end (&loop
, 0, &body
);
2670 if (HONOR_NANS (DECL_MODE (limit
)))
2672 if (nonempty
!= NULL
)
2674 ifbody
= build2_v (MODIFY_EXPR
, pos
, gfc_index_one_node
);
2675 tmp
= build3_v (COND_EXPR
, nonempty
, ifbody
,
2676 build_empty_stmt (input_location
));
2677 gfc_add_expr_to_block (&loop
.code
[0], tmp
);
2681 gfc_add_expr_to_block (&loop
.code
[0], build1_v (GOTO_EXPR
, lab2
));
2682 gfc_add_expr_to_block (&loop
.code
[0], build1_v (LABEL_EXPR
, lab1
));
2683 gfc_start_block (&body
);
2685 /* If we have a mask, only check this element if the mask is set. */
2688 gfc_init_se (&maskse
, NULL
);
2689 gfc_copy_loopinfo_to_se (&maskse
, &loop
);
2691 gfc_conv_expr_val (&maskse
, maskexpr
);
2692 gfc_add_block_to_block (&body
, &maskse
.pre
);
2694 gfc_start_block (&block
);
2697 gfc_init_block (&block
);
2699 /* Compare with the current limit. */
2700 gfc_init_se (&arrayse
, NULL
);
2701 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
2702 arrayse
.ss
= arrayss
;
2703 gfc_conv_expr_val (&arrayse
, arrayexpr
);
2704 gfc_add_block_to_block (&block
, &arrayse
.pre
);
2706 /* We do the following if this is a more extreme value. */
2707 gfc_start_block (&ifblock
);
2709 /* Assign the value to the limit... */
2710 gfc_add_modify (&ifblock
, limit
, arrayse
.expr
);
2712 /* Remember where we are. An offset must be added to the loop
2713 counter to obtain the required position. */
2715 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
2716 gfc_index_one_node
, loop
.from
[0]);
2718 tmp
= gfc_index_one_node
;
2720 gfc_add_modify (&block
, offset
, tmp
);
2722 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, TREE_TYPE (pos
),
2723 loop
.loopvar
[0], offset
);
2724 gfc_add_modify (&ifblock
, pos
, tmp
);
2726 ifbody
= gfc_finish_block (&ifblock
);
2728 cond
= fold_build2_loc (input_location
, op
, boolean_type_node
,
2729 arrayse
.expr
, limit
);
2731 tmp
= build3_v (COND_EXPR
, cond
, ifbody
,
2732 build_empty_stmt (input_location
));
2733 gfc_add_expr_to_block (&block
, tmp
);
2737 /* We enclose the above in if (mask) {...}. */
2738 tmp
= gfc_finish_block (&block
);
2740 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
,
2741 build_empty_stmt (input_location
));
2744 tmp
= gfc_finish_block (&block
);
2745 gfc_add_expr_to_block (&body
, tmp
);
2746 /* Avoid initializing loopvar[0] again, it should be left where
2747 it finished by the first loop. */
2748 loop
.from
[0] = loop
.loopvar
[0];
2751 gfc_trans_scalarizing_loops (&loop
, &body
);
2754 gfc_add_expr_to_block (&loop
.pre
, build1_v (LABEL_EXPR
, lab2
));
2756 /* For a scalar mask, enclose the loop in an if statement. */
2757 if (maskexpr
&& maskss
== NULL
)
2759 gfc_init_se (&maskse
, NULL
);
2760 gfc_conv_expr_val (&maskse
, maskexpr
);
2761 gfc_init_block (&block
);
2762 gfc_add_block_to_block (&block
, &loop
.pre
);
2763 gfc_add_block_to_block (&block
, &loop
.post
);
2764 tmp
= gfc_finish_block (&block
);
2766 /* For the else part of the scalar mask, just initialize
2767 the pos variable the same way as above. */
2769 gfc_init_block (&elseblock
);
2770 gfc_add_modify (&elseblock
, pos
, gfc_index_zero_node
);
2771 elsetmp
= gfc_finish_block (&elseblock
);
2773 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
, elsetmp
);
2774 gfc_add_expr_to_block (&block
, tmp
);
2775 gfc_add_block_to_block (&se
->pre
, &block
);
2779 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
2780 gfc_add_block_to_block (&se
->pre
, &loop
.post
);
2782 gfc_cleanup_loop (&loop
);
2784 se
->expr
= convert (type
, pos
);
2787 /* Emit code for minval or maxval intrinsic. There are many different cases
2788 we need to handle. For performance reasons we sometimes create two
2789 loops instead of one, where the second one is much simpler.
2790 Examples for minval intrinsic:
2791 1) Result is an array, a call is generated
2792 2) Array mask is used and NaNs need to be supported, rank 1:
2797 if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
2800 limit = nonempty ? NaN : huge (limit);
2802 while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
2803 3) NaNs need to be supported, but it is known at compile time or cheaply
2804 at runtime whether array is nonempty or not, rank 1:
2807 while (S <= to) { if (a[S] <= limit) goto lab; S++; }
2808 limit = (from <= to) ? NaN : huge (limit);
2810 while (S <= to) { limit = min (a[S], limit); S++; }
2811 4) Array mask is used and NaNs need to be supported, rank > 1:
2820 if (fast) limit = min (a[S1][S2], limit);
2823 if (a[S1][S2] <= limit) {
2834 limit = nonempty ? NaN : huge (limit);
2835 5) NaNs need to be supported, but it is known at compile time or cheaply
2836 at runtime whether array is nonempty or not, rank > 1:
2843 if (fast) limit = min (a[S1][S2], limit);
2845 if (a[S1][S2] <= limit) {
2855 limit = (nonempty_array) ? NaN : huge (limit);
2856 6) NaNs aren't supported, but infinities are. Array mask is used:
2861 if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
2864 limit = nonempty ? limit : huge (limit);
2865 7) Same without array mask:
2868 while (S <= to) { limit = min (a[S], limit); S++; }
2869 limit = (from <= to) ? limit : huge (limit);
2870 8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
2871 limit = huge (limit);
2873 while (S <= to) { limit = min (a[S], limit); S++); }
2875 while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
2876 with array mask instead).
2877 For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
2878 setting limit = huge (limit); in the else branch. */
2881 gfc_conv_intrinsic_minmaxval (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
2891 tree huge_cst
= NULL
, nan_cst
= NULL
;
2893 stmtblock_t block
, block2
;
2895 gfc_actual_arglist
*actual
;
2900 gfc_expr
*arrayexpr
;
2906 gfc_conv_intrinsic_funcall (se
, expr
);
2910 type
= gfc_typenode_for_spec (&expr
->ts
);
2911 /* Initialize the result. */
2912 limit
= gfc_create_var (type
, "limit");
2913 n
= gfc_validate_kind (expr
->ts
.type
, expr
->ts
.kind
, false);
2914 switch (expr
->ts
.type
)
2917 huge_cst
= gfc_conv_mpfr_to_tree (gfc_real_kinds
[n
].huge
,
2919 if (HONOR_INFINITIES (DECL_MODE (limit
)))
2921 REAL_VALUE_TYPE real
;
2923 tmp
= build_real (type
, real
);
2927 if (HONOR_NANS (DECL_MODE (limit
)))
2929 REAL_VALUE_TYPE real
;
2930 real_nan (&real
, "", 1, DECL_MODE (limit
));
2931 nan_cst
= build_real (type
, real
);
2936 tmp
= gfc_conv_mpz_to_tree (gfc_integer_kinds
[n
].huge
, expr
->ts
.kind
);
2943 /* We start with the most negative possible value for MAXVAL, and the most
2944 positive possible value for MINVAL. The most negative possible value is
2945 -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
2946 possible value is HUGE in both cases. */
2949 tmp
= fold_build1_loc (input_location
, NEGATE_EXPR
, TREE_TYPE (tmp
), tmp
);
2951 huge_cst
= fold_build1_loc (input_location
, NEGATE_EXPR
,
2952 TREE_TYPE (huge_cst
), huge_cst
);
2955 if (op
== GT_EXPR
&& expr
->ts
.type
== BT_INTEGER
)
2956 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (tmp
),
2957 tmp
, build_int_cst (type
, 1));
2959 gfc_add_modify (&se
->pre
, limit
, tmp
);
2961 /* Walk the arguments. */
2962 actual
= expr
->value
.function
.actual
;
2963 arrayexpr
= actual
->expr
;
2964 arrayss
= gfc_walk_expr (arrayexpr
);
2965 gcc_assert (arrayss
!= gfc_ss_terminator
);
2967 actual
= actual
->next
->next
;
2968 gcc_assert (actual
);
2969 maskexpr
= actual
->expr
;
2971 if (maskexpr
&& maskexpr
->rank
!= 0)
2973 maskss
= gfc_walk_expr (maskexpr
);
2974 gcc_assert (maskss
!= gfc_ss_terminator
);
2979 if (gfc_array_size (arrayexpr
, &asize
) == SUCCESS
)
2981 nonempty
= gfc_conv_mpz_to_tree (asize
, gfc_index_integer_kind
);
2983 nonempty
= fold_build2_loc (input_location
, GT_EXPR
,
2984 boolean_type_node
, nonempty
,
2985 gfc_index_zero_node
);
2990 /* Initialize the scalarizer. */
2991 gfc_init_loopinfo (&loop
);
2992 gfc_add_ss_to_loop (&loop
, arrayss
);
2994 gfc_add_ss_to_loop (&loop
, maskss
);
2996 /* Initialize the loop. */
2997 gfc_conv_ss_startstride (&loop
);
2998 gfc_conv_loop_setup (&loop
, &expr
->where
);
3000 if (nonempty
== NULL
&& maskss
== NULL
3001 && loop
.dimen
== 1 && loop
.from
[0] && loop
.to
[0])
3002 nonempty
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
3003 loop
.from
[0], loop
.to
[0]);
3004 nonempty_var
= NULL
;
3005 if (nonempty
== NULL
3006 && (HONOR_INFINITIES (DECL_MODE (limit
))
3007 || HONOR_NANS (DECL_MODE (limit
))))
3009 nonempty_var
= gfc_create_var (boolean_type_node
, "nonempty");
3010 gfc_add_modify (&se
->pre
, nonempty_var
, boolean_false_node
);
3011 nonempty
= nonempty_var
;
3015 if (HONOR_NANS (DECL_MODE (limit
)))
3017 if (loop
.dimen
== 1)
3019 lab
= gfc_build_label_decl (NULL_TREE
);
3020 TREE_USED (lab
) = 1;
3024 fast
= gfc_create_var (boolean_type_node
, "fast");
3025 gfc_add_modify (&se
->pre
, fast
, boolean_false_node
);
3029 gfc_mark_ss_chain_used (arrayss
, 1);
3031 gfc_mark_ss_chain_used (maskss
, 1);
3032 /* Generate the loop body. */
3033 gfc_start_scalarized_body (&loop
, &body
);
3035 /* If we have a mask, only add this element if the mask is set. */
3038 gfc_init_se (&maskse
, NULL
);
3039 gfc_copy_loopinfo_to_se (&maskse
, &loop
);
3041 gfc_conv_expr_val (&maskse
, maskexpr
);
3042 gfc_add_block_to_block (&body
, &maskse
.pre
);
3044 gfc_start_block (&block
);
3047 gfc_init_block (&block
);
3049 /* Compare with the current limit. */
3050 gfc_init_se (&arrayse
, NULL
);
3051 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
3052 arrayse
.ss
= arrayss
;
3053 gfc_conv_expr_val (&arrayse
, arrayexpr
);
3054 gfc_add_block_to_block (&block
, &arrayse
.pre
);
3056 gfc_init_block (&block2
);
3059 gfc_add_modify (&block2
, nonempty_var
, boolean_true_node
);
3061 if (HONOR_NANS (DECL_MODE (limit
)))
3063 tmp
= fold_build2_loc (input_location
, op
== GT_EXPR
? GE_EXPR
: LE_EXPR
,
3064 boolean_type_node
, arrayse
.expr
, limit
);
3066 ifbody
= build1_v (GOTO_EXPR
, lab
);
3069 stmtblock_t ifblock
;
3071 gfc_init_block (&ifblock
);
3072 gfc_add_modify (&ifblock
, limit
, arrayse
.expr
);
3073 gfc_add_modify (&ifblock
, fast
, boolean_true_node
);
3074 ifbody
= gfc_finish_block (&ifblock
);
3076 tmp
= build3_v (COND_EXPR
, tmp
, ifbody
,
3077 build_empty_stmt (input_location
));
3078 gfc_add_expr_to_block (&block2
, tmp
);
3082 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3084 if (HONOR_SIGNED_ZEROS (DECL_MODE (limit
)))
3086 tmp
= fold_build2_loc (input_location
, op
, boolean_type_node
,
3087 arrayse
.expr
, limit
);
3088 ifbody
= build2_v (MODIFY_EXPR
, limit
, arrayse
.expr
);
3089 tmp
= build3_v (COND_EXPR
, tmp
, ifbody
,
3090 build_empty_stmt (input_location
));
3091 gfc_add_expr_to_block (&block2
, tmp
);
3095 tmp
= fold_build2_loc (input_location
,
3096 op
== GT_EXPR
? MAX_EXPR
: MIN_EXPR
,
3097 type
, arrayse
.expr
, limit
);
3098 gfc_add_modify (&block2
, limit
, tmp
);
3104 tree elsebody
= gfc_finish_block (&block2
);
3106 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3108 if (HONOR_NANS (DECL_MODE (limit
))
3109 || HONOR_SIGNED_ZEROS (DECL_MODE (limit
)))
3111 tmp
= fold_build2_loc (input_location
, op
, boolean_type_node
,
3112 arrayse
.expr
, limit
);
3113 ifbody
= build2_v (MODIFY_EXPR
, limit
, arrayse
.expr
);
3114 ifbody
= build3_v (COND_EXPR
, tmp
, ifbody
,
3115 build_empty_stmt (input_location
));
3119 tmp
= fold_build2_loc (input_location
,
3120 op
== GT_EXPR
? MAX_EXPR
: MIN_EXPR
,
3121 type
, arrayse
.expr
, limit
);
3122 ifbody
= build2_v (MODIFY_EXPR
, limit
, tmp
);
3124 tmp
= build3_v (COND_EXPR
, fast
, ifbody
, elsebody
);
3125 gfc_add_expr_to_block (&block
, tmp
);
3128 gfc_add_block_to_block (&block
, &block2
);
3130 gfc_add_block_to_block (&block
, &arrayse
.post
);
3132 tmp
= gfc_finish_block (&block
);
3134 /* We enclose the above in if (mask) {...}. */
3135 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
,
3136 build_empty_stmt (input_location
));
3137 gfc_add_expr_to_block (&body
, tmp
);
3141 gfc_trans_scalarized_loop_end (&loop
, 0, &body
);
3143 tmp
= fold_build3_loc (input_location
, COND_EXPR
, type
, nonempty
,
3145 gfc_add_modify (&loop
.code
[0], limit
, tmp
);
3146 gfc_add_expr_to_block (&loop
.code
[0], build1_v (LABEL_EXPR
, lab
));
3148 gfc_start_block (&body
);
3150 /* If we have a mask, only add this element if the mask is set. */
3153 gfc_init_se (&maskse
, NULL
);
3154 gfc_copy_loopinfo_to_se (&maskse
, &loop
);
3156 gfc_conv_expr_val (&maskse
, maskexpr
);
3157 gfc_add_block_to_block (&body
, &maskse
.pre
);
3159 gfc_start_block (&block
);
3162 gfc_init_block (&block
);
3164 /* Compare with the current limit. */
3165 gfc_init_se (&arrayse
, NULL
);
3166 gfc_copy_loopinfo_to_se (&arrayse
, &loop
);
3167 arrayse
.ss
= arrayss
;
3168 gfc_conv_expr_val (&arrayse
, arrayexpr
);
3169 gfc_add_block_to_block (&block
, &arrayse
.pre
);
3171 /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
3173 if (HONOR_NANS (DECL_MODE (limit
))
3174 || HONOR_SIGNED_ZEROS (DECL_MODE (limit
)))
3176 tmp
= fold_build2_loc (input_location
, op
, boolean_type_node
,
3177 arrayse
.expr
, limit
);
3178 ifbody
= build2_v (MODIFY_EXPR
, limit
, arrayse
.expr
);
3179 tmp
= build3_v (COND_EXPR
, tmp
, ifbody
,
3180 build_empty_stmt (input_location
));
3181 gfc_add_expr_to_block (&block
, tmp
);
3185 tmp
= fold_build2_loc (input_location
,
3186 op
== GT_EXPR
? MAX_EXPR
: MIN_EXPR
,
3187 type
, arrayse
.expr
, limit
);
3188 gfc_add_modify (&block
, limit
, tmp
);
3191 gfc_add_block_to_block (&block
, &arrayse
.post
);
3193 tmp
= gfc_finish_block (&block
);
3195 /* We enclose the above in if (mask) {...}. */
3196 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
,
3197 build_empty_stmt (input_location
));
3198 gfc_add_expr_to_block (&body
, tmp
);
3199 /* Avoid initializing loopvar[0] again, it should be left where
3200 it finished by the first loop. */
3201 loop
.from
[0] = loop
.loopvar
[0];
3203 gfc_trans_scalarizing_loops (&loop
, &body
);
3207 tmp
= fold_build3_loc (input_location
, COND_EXPR
, type
, nonempty
,
3209 ifbody
= build2_v (MODIFY_EXPR
, limit
, tmp
);
3210 tmp
= build3_v (COND_EXPR
, fast
, build_empty_stmt (input_location
),
3212 gfc_add_expr_to_block (&loop
.pre
, tmp
);
3214 else if (HONOR_INFINITIES (DECL_MODE (limit
)) && !lab
)
3216 tmp
= fold_build3_loc (input_location
, COND_EXPR
, type
, nonempty
, limit
,
3218 gfc_add_modify (&loop
.pre
, limit
, tmp
);
3221 /* For a scalar mask, enclose the loop in an if statement. */
3222 if (maskexpr
&& maskss
== NULL
)
3226 gfc_init_se (&maskse
, NULL
);
3227 gfc_conv_expr_val (&maskse
, maskexpr
);
3228 gfc_init_block (&block
);
3229 gfc_add_block_to_block (&block
, &loop
.pre
);
3230 gfc_add_block_to_block (&block
, &loop
.post
);
3231 tmp
= gfc_finish_block (&block
);
3233 if (HONOR_INFINITIES (DECL_MODE (limit
)))
3234 else_stmt
= build2_v (MODIFY_EXPR
, limit
, huge_cst
);
3236 else_stmt
= build_empty_stmt (input_location
);
3237 tmp
= build3_v (COND_EXPR
, maskse
.expr
, tmp
, else_stmt
);
3238 gfc_add_expr_to_block (&block
, tmp
);
3239 gfc_add_block_to_block (&se
->pre
, &block
);
3243 gfc_add_block_to_block (&se
->pre
, &loop
.pre
);
3244 gfc_add_block_to_block (&se
->pre
, &loop
.post
);
3247 gfc_cleanup_loop (&loop
);
3252 /* BTEST (i, pos) = (i & (1 << pos)) != 0. */
3254 gfc_conv_intrinsic_btest (gfc_se
* se
, gfc_expr
* expr
)
3260 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3261 type
= TREE_TYPE (args
[0]);
3263 tmp
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
,
3264 build_int_cst (type
, 1), args
[1]);
3265 tmp
= fold_build2_loc (input_location
, BIT_AND_EXPR
, type
, args
[0], tmp
);
3266 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, tmp
,
3267 build_int_cst (type
, 0));
3268 type
= gfc_typenode_for_spec (&expr
->ts
);
3269 se
->expr
= convert (type
, tmp
);
3273 /* Generate code for BGE, BGT, BLE and BLT intrinsics. */
3275 gfc_conv_intrinsic_bitcomp (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
3279 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3281 /* Convert both arguments to the unsigned type of the same size. */
3282 args
[0] = fold_convert (unsigned_type_for (TREE_TYPE (args
[0])), args
[0]);
3283 args
[1] = fold_convert (unsigned_type_for (TREE_TYPE (args
[1])), args
[1]);
3285 /* If they have unequal type size, convert to the larger one. */
3286 if (TYPE_PRECISION (TREE_TYPE (args
[0]))
3287 > TYPE_PRECISION (TREE_TYPE (args
[1])))
3288 args
[1] = fold_convert (TREE_TYPE (args
[0]), args
[1]);
3289 else if (TYPE_PRECISION (TREE_TYPE (args
[1]))
3290 > TYPE_PRECISION (TREE_TYPE (args
[0])))
3291 args
[0] = fold_convert (TREE_TYPE (args
[1]), args
[0]);
3293 /* Now, we compare them. */
3294 se
->expr
= fold_build2_loc (input_location
, op
, boolean_type_node
,
3299 /* Generate code to perform the specified operation. */
3301 gfc_conv_intrinsic_bitop (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
3305 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3306 se
->expr
= fold_build2_loc (input_location
, op
, TREE_TYPE (args
[0]),
3312 gfc_conv_intrinsic_not (gfc_se
* se
, gfc_expr
* expr
)
3316 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
3317 se
->expr
= fold_build1_loc (input_location
, BIT_NOT_EXPR
,
3318 TREE_TYPE (arg
), arg
);
3321 /* Set or clear a single bit. */
3323 gfc_conv_intrinsic_singlebitop (gfc_se
* se
, gfc_expr
* expr
, int set
)
3330 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3331 type
= TREE_TYPE (args
[0]);
3333 tmp
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
,
3334 build_int_cst (type
, 1), args
[1]);
3340 tmp
= fold_build1_loc (input_location
, BIT_NOT_EXPR
, type
, tmp
);
3342 se
->expr
= fold_build2_loc (input_location
, op
, type
, args
[0], tmp
);
3345 /* Extract a sequence of bits.
3346 IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN). */
3348 gfc_conv_intrinsic_ibits (gfc_se
* se
, gfc_expr
* expr
)
3355 gfc_conv_intrinsic_function_args (se
, expr
, args
, 3);
3356 type
= TREE_TYPE (args
[0]);
3358 mask
= build_int_cst (type
, -1);
3359 mask
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
, mask
, args
[2]);
3360 mask
= fold_build1_loc (input_location
, BIT_NOT_EXPR
, type
, mask
);
3362 tmp
= fold_build2_loc (input_location
, RSHIFT_EXPR
, type
, args
[0], args
[1]);
3364 se
->expr
= fold_build2_loc (input_location
, BIT_AND_EXPR
, type
, tmp
, mask
);
3368 gfc_conv_intrinsic_shift (gfc_se
* se
, gfc_expr
* expr
, bool right_shift
,
3371 tree args
[2], type
, num_bits
, cond
;
3373 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3375 args
[0] = gfc_evaluate_now (args
[0], &se
->pre
);
3376 args
[1] = gfc_evaluate_now (args
[1], &se
->pre
);
3377 type
= TREE_TYPE (args
[0]);
3380 args
[0] = fold_convert (unsigned_type_for (type
), args
[0]);
3382 gcc_assert (right_shift
);
3384 se
->expr
= fold_build2_loc (input_location
,
3385 right_shift
? RSHIFT_EXPR
: LSHIFT_EXPR
,
3386 TREE_TYPE (args
[0]), args
[0], args
[1]);
3389 se
->expr
= fold_convert (type
, se
->expr
);
3391 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3392 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3394 num_bits
= build_int_cst (TREE_TYPE (args
[1]), TYPE_PRECISION (type
));
3395 cond
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
,
3398 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
, cond
,
3399 build_int_cst (type
, 0), se
->expr
);
3402 /* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
3404 : ((shift >= 0) ? i << shift : i >> -shift)
3405 where all shifts are logical shifts. */
3407 gfc_conv_intrinsic_ishft (gfc_se
* se
, gfc_expr
* expr
)
3419 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3421 args
[0] = gfc_evaluate_now (args
[0], &se
->pre
);
3422 args
[1] = gfc_evaluate_now (args
[1], &se
->pre
);
3424 type
= TREE_TYPE (args
[0]);
3425 utype
= unsigned_type_for (type
);
3427 width
= fold_build1_loc (input_location
, ABS_EXPR
, TREE_TYPE (args
[1]),
3430 /* Left shift if positive. */
3431 lshift
= fold_build2_loc (input_location
, LSHIFT_EXPR
, type
, args
[0], width
);
3433 /* Right shift if negative.
3434 We convert to an unsigned type because we want a logical shift.
3435 The standard doesn't define the case of shifting negative
3436 numbers, and we try to be compatible with other compilers, most
3437 notably g77, here. */
3438 rshift
= fold_convert (type
, fold_build2_loc (input_location
, RSHIFT_EXPR
,
3439 utype
, convert (utype
, args
[0]), width
));
3441 tmp
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
, args
[1],
3442 build_int_cst (TREE_TYPE (args
[1]), 0));
3443 tmp
= fold_build3_loc (input_location
, COND_EXPR
, type
, tmp
, lshift
, rshift
);
3445 /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
3446 gcc requires a shift width < BIT_SIZE(I), so we have to catch this
3448 num_bits
= build_int_cst (TREE_TYPE (args
[1]), TYPE_PRECISION (type
));
3449 cond
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
, width
,
3451 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
, cond
,
3452 build_int_cst (type
, 0), tmp
);
3456 /* Circular shift. AKA rotate or barrel shift. */
3459 gfc_conv_intrinsic_ishftc (gfc_se
* se
, gfc_expr
* expr
)
3467 unsigned int num_args
;
3469 num_args
= gfc_intrinsic_argument_list_length (expr
);
3470 args
= XALLOCAVEC (tree
, num_args
);
3472 gfc_conv_intrinsic_function_args (se
, expr
, args
, num_args
);
3476 /* Use a library function for the 3 parameter version. */
3477 tree int4type
= gfc_get_int_type (4);
3479 type
= TREE_TYPE (args
[0]);
3480 /* We convert the first argument to at least 4 bytes, and
3481 convert back afterwards. This removes the need for library
3482 functions for all argument sizes, and function will be
3483 aligned to at least 32 bits, so there's no loss. */
3484 if (expr
->ts
.kind
< 4)
3485 args
[0] = convert (int4type
, args
[0]);
3487 /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
3488 need loads of library functions. They cannot have values >
3489 BIT_SIZE (I) so the conversion is safe. */
3490 args
[1] = convert (int4type
, args
[1]);
3491 args
[2] = convert (int4type
, args
[2]);
3493 switch (expr
->ts
.kind
)
3498 tmp
= gfor_fndecl_math_ishftc4
;
3501 tmp
= gfor_fndecl_math_ishftc8
;
3504 tmp
= gfor_fndecl_math_ishftc16
;
3509 se
->expr
= build_call_expr_loc (input_location
,
3510 tmp
, 3, args
[0], args
[1], args
[2]);
3511 /* Convert the result back to the original type, if we extended
3512 the first argument's width above. */
3513 if (expr
->ts
.kind
< 4)
3514 se
->expr
= convert (type
, se
->expr
);
3518 type
= TREE_TYPE (args
[0]);
3520 /* Evaluate arguments only once. */
3521 args
[0] = gfc_evaluate_now (args
[0], &se
->pre
);
3522 args
[1] = gfc_evaluate_now (args
[1], &se
->pre
);
3524 /* Rotate left if positive. */
3525 lrot
= fold_build2_loc (input_location
, LROTATE_EXPR
, type
, args
[0], args
[1]);
3527 /* Rotate right if negative. */
3528 tmp
= fold_build1_loc (input_location
, NEGATE_EXPR
, TREE_TYPE (args
[1]),
3530 rrot
= fold_build2_loc (input_location
,RROTATE_EXPR
, type
, args
[0], tmp
);
3532 zero
= build_int_cst (TREE_TYPE (args
[1]), 0);
3533 tmp
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
, args
[1],
3535 rrot
= fold_build3_loc (input_location
, COND_EXPR
, type
, tmp
, lrot
, rrot
);
3537 /* Do nothing if shift == 0. */
3538 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, args
[1],
3540 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
, tmp
, args
[0],
3545 /* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
3546 : __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))
3548 The conditional expression is necessary because the result of LEADZ(0)
3549 is defined, but the result of __builtin_clz(0) is undefined for most
3552 For INTEGER kinds smaller than the C 'int' type, we have to subtract the
3553 difference in bit size between the argument of LEADZ and the C int. */
3556 gfc_conv_intrinsic_leadz (gfc_se
* se
, gfc_expr
* expr
)
3568 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
3569 argsize
= TYPE_PRECISION (TREE_TYPE (arg
));
3571 /* Which variant of __builtin_clz* should we call? */
3572 if (argsize
<= INT_TYPE_SIZE
)
3574 arg_type
= unsigned_type_node
;
3575 func
= built_in_decls
[BUILT_IN_CLZ
];
3577 else if (argsize
<= LONG_TYPE_SIZE
)
3579 arg_type
= long_unsigned_type_node
;
3580 func
= built_in_decls
[BUILT_IN_CLZL
];
3582 else if (argsize
<= LONG_LONG_TYPE_SIZE
)
3584 arg_type
= long_long_unsigned_type_node
;
3585 func
= built_in_decls
[BUILT_IN_CLZLL
];
3589 gcc_assert (argsize
== 2 * LONG_LONG_TYPE_SIZE
);
3590 arg_type
= gfc_build_uint_type (argsize
);
3594 /* Convert the actual argument twice: first, to the unsigned type of the
3595 same size; then, to the proper argument type for the built-in
3596 function. But the return type is of the default INTEGER kind. */
3597 arg
= fold_convert (gfc_build_uint_type (argsize
), arg
);
3598 arg
= fold_convert (arg_type
, arg
);
3599 arg
= gfc_evaluate_now (arg
, &se
->pre
);
3600 result_type
= gfc_get_int_type (gfc_default_integer_kind
);
3602 /* Compute LEADZ for the case i .ne. 0. */
3605 s
= TYPE_PRECISION (arg_type
) - argsize
;
3606 tmp
= fold_convert (result_type
,
3607 build_call_expr_loc (input_location
, func
,
3609 leadz
= fold_build2_loc (input_location
, MINUS_EXPR
, result_type
,
3610 tmp
, build_int_cst (result_type
, s
));
3614 /* We end up here if the argument type is larger than 'long long'.
3615 We generate this code:
3617 if (x & (ULL_MAX << ULL_SIZE) != 0)
3618 return clzll ((unsigned long long) (x >> ULLSIZE));
3620 return ULL_SIZE + clzll ((unsigned long long) x);
3621 where ULL_MAX is the largest value that a ULL_MAX can hold
3622 (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
3623 is the bit-size of the long long type (64 in this example). */
3624 tree ullsize
, ullmax
, tmp1
, tmp2
;
3626 ullsize
= build_int_cst (result_type
, LONG_LONG_TYPE_SIZE
);
3627 ullmax
= fold_build1_loc (input_location
, BIT_NOT_EXPR
,
3628 long_long_unsigned_type_node
,
3629 build_int_cst (long_long_unsigned_type_node
,
3632 cond
= fold_build2_loc (input_location
, LSHIFT_EXPR
, arg_type
,
3633 fold_convert (arg_type
, ullmax
), ullsize
);
3634 cond
= fold_build2_loc (input_location
, BIT_AND_EXPR
, arg_type
,
3636 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
3637 cond
, build_int_cst (arg_type
, 0));
3639 tmp1
= fold_build2_loc (input_location
, RSHIFT_EXPR
, arg_type
,
3641 tmp1
= fold_convert (long_long_unsigned_type_node
, tmp1
);
3642 tmp1
= fold_convert (result_type
,
3643 build_call_expr_loc (input_location
,
3644 built_in_decls
[BUILT_IN_CLZLL
],
3647 tmp2
= fold_convert (long_long_unsigned_type_node
, arg
);
3648 tmp2
= fold_convert (result_type
,
3649 build_call_expr_loc (input_location
,
3650 built_in_decls
[BUILT_IN_CLZLL
],
3652 tmp2
= fold_build2_loc (input_location
, PLUS_EXPR
, result_type
,
3655 leadz
= fold_build3_loc (input_location
, COND_EXPR
, result_type
,
3659 /* Build BIT_SIZE. */
3660 bit_size
= build_int_cst (result_type
, argsize
);
3662 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
3663 arg
, build_int_cst (arg_type
, 0));
3664 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, result_type
, cond
,
3669 /* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)
3671 The conditional expression is necessary because the result of TRAILZ(0)
3672 is defined, but the result of __builtin_ctz(0) is undefined for most
3676 gfc_conv_intrinsic_trailz (gfc_se
* se
, gfc_expr
*expr
)
3687 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
3688 argsize
= TYPE_PRECISION (TREE_TYPE (arg
));
3690 /* Which variant of __builtin_ctz* should we call? */
3691 if (argsize
<= INT_TYPE_SIZE
)
3693 arg_type
= unsigned_type_node
;
3694 func
= built_in_decls
[BUILT_IN_CTZ
];
3696 else if (argsize
<= LONG_TYPE_SIZE
)
3698 arg_type
= long_unsigned_type_node
;
3699 func
= built_in_decls
[BUILT_IN_CTZL
];
3701 else if (argsize
<= LONG_LONG_TYPE_SIZE
)
3703 arg_type
= long_long_unsigned_type_node
;
3704 func
= built_in_decls
[BUILT_IN_CTZLL
];
3708 gcc_assert (argsize
== 2 * LONG_LONG_TYPE_SIZE
);
3709 arg_type
= gfc_build_uint_type (argsize
);
3713 /* Convert the actual argument twice: first, to the unsigned type of the
3714 same size; then, to the proper argument type for the built-in
3715 function. But the return type is of the default INTEGER kind. */
3716 arg
= fold_convert (gfc_build_uint_type (argsize
), arg
);
3717 arg
= fold_convert (arg_type
, arg
);
3718 arg
= gfc_evaluate_now (arg
, &se
->pre
);
3719 result_type
= gfc_get_int_type (gfc_default_integer_kind
);
3721 /* Compute TRAILZ for the case i .ne. 0. */
3723 trailz
= fold_convert (result_type
, build_call_expr_loc (input_location
,
3727 /* We end up here if the argument type is larger than 'long long'.
3728 We generate this code:
3730 if ((x & ULL_MAX) == 0)
3731 return ULL_SIZE + ctzll ((unsigned long long) (x >> ULLSIZE));
3733 return ctzll ((unsigned long long) x);
3735 where ULL_MAX is the largest value that a ULL_MAX can hold
3736 (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
3737 is the bit-size of the long long type (64 in this example). */
3738 tree ullsize
, ullmax
, tmp1
, tmp2
;
3740 ullsize
= build_int_cst (result_type
, LONG_LONG_TYPE_SIZE
);
3741 ullmax
= fold_build1_loc (input_location
, BIT_NOT_EXPR
,
3742 long_long_unsigned_type_node
,
3743 build_int_cst (long_long_unsigned_type_node
, 0));
3745 cond
= fold_build2_loc (input_location
, BIT_AND_EXPR
, arg_type
, arg
,
3746 fold_convert (arg_type
, ullmax
));
3747 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, cond
,
3748 build_int_cst (arg_type
, 0));
3750 tmp1
= fold_build2_loc (input_location
, RSHIFT_EXPR
, arg_type
,
3752 tmp1
= fold_convert (long_long_unsigned_type_node
, tmp1
);
3753 tmp1
= fold_convert (result_type
,
3754 build_call_expr_loc (input_location
,
3755 built_in_decls
[BUILT_IN_CTZLL
],
3757 tmp1
= fold_build2_loc (input_location
, PLUS_EXPR
, result_type
,
3760 tmp2
= fold_convert (long_long_unsigned_type_node
, arg
);
3761 tmp2
= fold_convert (result_type
,
3762 build_call_expr_loc (input_location
,
3763 built_in_decls
[BUILT_IN_CTZLL
],
3766 trailz
= fold_build3_loc (input_location
, COND_EXPR
, result_type
,
3770 /* Build BIT_SIZE. */
3771 bit_size
= build_int_cst (result_type
, argsize
);
3773 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
3774 arg
, build_int_cst (arg_type
, 0));
3775 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, result_type
, cond
,
3779 /* Using __builtin_popcount for POPCNT and __builtin_parity for POPPAR;
3780 for types larger than "long long", we call the long long built-in for
3781 the lower and higher bits and combine the result. */
3784 gfc_conv_intrinsic_popcnt_poppar (gfc_se
* se
, gfc_expr
*expr
, int parity
)
3792 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
3793 argsize
= TYPE_PRECISION (TREE_TYPE (arg
));
3794 result_type
= gfc_get_int_type (gfc_default_integer_kind
);
3796 /* Which variant of the builtin should we call? */
3797 if (argsize
<= INT_TYPE_SIZE
)
3799 arg_type
= unsigned_type_node
;
3800 func
= built_in_decls
[parity
? BUILT_IN_PARITY
: BUILT_IN_POPCOUNT
];
3802 else if (argsize
<= LONG_TYPE_SIZE
)
3804 arg_type
= long_unsigned_type_node
;
3805 func
= built_in_decls
[parity
? BUILT_IN_PARITYL
: BUILT_IN_POPCOUNTL
];
3807 else if (argsize
<= LONG_LONG_TYPE_SIZE
)
3809 arg_type
= long_long_unsigned_type_node
;
3810 func
= built_in_decls
[parity
? BUILT_IN_PARITYLL
: BUILT_IN_POPCOUNTLL
];
3814 /* Our argument type is larger than 'long long', which mean none
3815 of the POPCOUNT builtins covers it. We thus call the 'long long'
3816 variant multiple times, and add the results. */
3817 tree utype
, arg2
, call1
, call2
;
3819 /* For now, we only cover the case where argsize is twice as large
3821 gcc_assert (argsize
== 2 * LONG_LONG_TYPE_SIZE
);
3823 func
= built_in_decls
[parity
? BUILT_IN_PARITYLL
: BUILT_IN_POPCOUNTLL
];
3825 /* Convert it to an integer, and store into a variable. */
3826 utype
= gfc_build_uint_type (argsize
);
3827 arg
= fold_convert (utype
, arg
);
3828 arg
= gfc_evaluate_now (arg
, &se
->pre
);
3830 /* Call the builtin twice. */
3831 call1
= build_call_expr_loc (input_location
, func
, 1,
3832 fold_convert (long_long_unsigned_type_node
,
3835 arg2
= fold_build2_loc (input_location
, RSHIFT_EXPR
, utype
, arg
,
3836 build_int_cst (utype
, LONG_LONG_TYPE_SIZE
));
3837 call2
= build_call_expr_loc (input_location
, func
, 1,
3838 fold_convert (long_long_unsigned_type_node
,
3841 /* Combine the results. */
3843 se
->expr
= fold_build2_loc (input_location
, BIT_XOR_EXPR
, result_type
,
3846 se
->expr
= fold_build2_loc (input_location
, PLUS_EXPR
, result_type
,
3852 /* Convert the actual argument twice: first, to the unsigned type of the
3853 same size; then, to the proper argument type for the built-in
3855 arg
= fold_convert (gfc_build_uint_type (argsize
), arg
);
3856 arg
= fold_convert (arg_type
, arg
);
3858 se
->expr
= fold_convert (result_type
,
3859 build_call_expr_loc (input_location
, func
, 1, arg
));
3863 /* Process an intrinsic with unspecified argument-types that has an optional
3864 argument (which could be of type character), e.g. EOSHIFT. For those, we
3865 need to append the string length of the optional argument if it is not
3866 present and the type is really character.
3867 primary specifies the position (starting at 1) of the non-optional argument
3868 specifying the type and optional gives the position of the optional
3869 argument in the arglist. */
3872 conv_generic_with_optional_char_arg (gfc_se
* se
, gfc_expr
* expr
,
3873 unsigned primary
, unsigned optional
)
3875 gfc_actual_arglist
* prim_arg
;
3876 gfc_actual_arglist
* opt_arg
;
3878 gfc_actual_arglist
* arg
;
3880 VEC(tree
,gc
) *append_args
;
3882 /* Find the two arguments given as position. */
3886 for (arg
= expr
->value
.function
.actual
; arg
; arg
= arg
->next
)
3890 if (cur_pos
== primary
)
3892 if (cur_pos
== optional
)
3895 if (cur_pos
>= primary
&& cur_pos
>= optional
)
3898 gcc_assert (prim_arg
);
3899 gcc_assert (prim_arg
->expr
);
3900 gcc_assert (opt_arg
);
3902 /* If we do have type CHARACTER and the optional argument is really absent,
3903 append a dummy 0 as string length. */
3905 if (prim_arg
->expr
->ts
.type
== BT_CHARACTER
&& !opt_arg
->expr
)
3909 dummy
= build_int_cst (gfc_charlen_type_node
, 0);
3910 append_args
= VEC_alloc (tree
, gc
, 1);
3911 VEC_quick_push (tree
, append_args
, dummy
);
3914 /* Build the call itself. */
3915 sym
= gfc_get_symbol_for_expr (expr
);
3916 gfc_conv_procedure_call (se
, sym
, expr
->value
.function
.actual
, expr
,
3922 /* The length of a character string. */
3924 gfc_conv_intrinsic_len (gfc_se
* se
, gfc_expr
* expr
)
3934 gcc_assert (!se
->ss
);
3936 arg
= expr
->value
.function
.actual
->expr
;
3938 type
= gfc_typenode_for_spec (&expr
->ts
);
3939 switch (arg
->expr_type
)
3942 len
= build_int_cst (NULL_TREE
, arg
->value
.character
.length
);
3946 /* Obtain the string length from the function used by
3947 trans-array.c(gfc_trans_array_constructor). */
3949 get_array_ctor_strlen (&se
->pre
, arg
->value
.constructor
, &len
);
3953 if (arg
->ref
== NULL
3954 || (arg
->ref
->next
== NULL
&& arg
->ref
->type
== REF_ARRAY
))
3956 /* This doesn't catch all cases.
3957 See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
3958 and the surrounding thread. */
3959 sym
= arg
->symtree
->n
.sym
;
3960 decl
= gfc_get_symbol_decl (sym
);
3961 if (decl
== current_function_decl
&& sym
->attr
.function
3962 && (sym
->result
== sym
))
3963 decl
= gfc_get_fake_result_decl (sym
, 0);
3965 len
= sym
->ts
.u
.cl
->backend_decl
;
3970 /* Otherwise fall through. */
3973 /* Anybody stupid enough to do this deserves inefficient code. */
3974 ss
= gfc_walk_expr (arg
);
3975 gfc_init_se (&argse
, se
);
3976 if (ss
== gfc_ss_terminator
)
3977 gfc_conv_expr (&argse
, arg
);
3979 gfc_conv_expr_descriptor (&argse
, arg
, ss
);
3980 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
3981 gfc_add_block_to_block (&se
->post
, &argse
.post
);
3982 len
= argse
.string_length
;
3985 se
->expr
= convert (type
, len
);
3988 /* The length of a character string not including trailing blanks. */
3990 gfc_conv_intrinsic_len_trim (gfc_se
* se
, gfc_expr
* expr
)
3992 int kind
= expr
->value
.function
.actual
->expr
->ts
.kind
;
3993 tree args
[2], type
, fndecl
;
3995 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
3996 type
= gfc_typenode_for_spec (&expr
->ts
);
3999 fndecl
= gfor_fndecl_string_len_trim
;
4001 fndecl
= gfor_fndecl_string_len_trim_char4
;
4005 se
->expr
= build_call_expr_loc (input_location
,
4006 fndecl
, 2, args
[0], args
[1]);
4007 se
->expr
= convert (type
, se
->expr
);
4011 /* Returns the starting position of a substring within a string. */
4014 gfc_conv_intrinsic_index_scan_verify (gfc_se
* se
, gfc_expr
* expr
,
4017 tree logical4_type_node
= gfc_get_logical_type (4);
4021 unsigned int num_args
;
4023 args
= XALLOCAVEC (tree
, 5);
4025 /* Get number of arguments; characters count double due to the
4026 string length argument. Kind= is not passed to the library
4027 and thus ignored. */
4028 if (expr
->value
.function
.actual
->next
->next
->expr
== NULL
)
4033 gfc_conv_intrinsic_function_args (se
, expr
, args
, num_args
);
4034 type
= gfc_typenode_for_spec (&expr
->ts
);
4037 args
[4] = build_int_cst (logical4_type_node
, 0);
4039 args
[4] = convert (logical4_type_node
, args
[4]);
4041 fndecl
= build_addr (function
, current_function_decl
);
4042 se
->expr
= build_call_array_loc (input_location
,
4043 TREE_TYPE (TREE_TYPE (function
)), fndecl
,
4045 se
->expr
= convert (type
, se
->expr
);
4049 /* The ascii value for a single character. */
4051 gfc_conv_intrinsic_ichar (gfc_se
* se
, gfc_expr
* expr
)
4053 tree args
[2], type
, pchartype
;
4055 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
4056 gcc_assert (POINTER_TYPE_P (TREE_TYPE (args
[1])));
4057 pchartype
= gfc_get_pchar_type (expr
->value
.function
.actual
->expr
->ts
.kind
);
4058 args
[1] = fold_build1_loc (input_location
, NOP_EXPR
, pchartype
, args
[1]);
4059 type
= gfc_typenode_for_spec (&expr
->ts
);
4061 se
->expr
= build_fold_indirect_ref_loc (input_location
,
4063 se
->expr
= convert (type
, se
->expr
);
4067 /* Intrinsic ISNAN calls __builtin_isnan. */
4070 gfc_conv_intrinsic_isnan (gfc_se
* se
, gfc_expr
* expr
)
4074 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
4075 se
->expr
= build_call_expr_loc (input_location
,
4076 built_in_decls
[BUILT_IN_ISNAN
], 1, arg
);
4077 STRIP_TYPE_NOPS (se
->expr
);
4078 se
->expr
= fold_convert (gfc_typenode_for_spec (&expr
->ts
), se
->expr
);
4082 /* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
4083 their argument against a constant integer value. */
4086 gfc_conv_has_intvalue (gfc_se
* se
, gfc_expr
* expr
, const int value
)
4090 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
4091 se
->expr
= fold_build2_loc (input_location
, EQ_EXPR
,
4092 gfc_typenode_for_spec (&expr
->ts
),
4093 arg
, build_int_cst (TREE_TYPE (arg
), value
));
4098 /* MERGE (tsource, fsource, mask) = mask ? tsource : fsource. */
4101 gfc_conv_intrinsic_merge (gfc_se
* se
, gfc_expr
* expr
)
4109 unsigned int num_args
;
4111 num_args
= gfc_intrinsic_argument_list_length (expr
);
4112 args
= XALLOCAVEC (tree
, num_args
);
4114 gfc_conv_intrinsic_function_args (se
, expr
, args
, num_args
);
4115 if (expr
->ts
.type
!= BT_CHARACTER
)
4123 /* We do the same as in the non-character case, but the argument
4124 list is different because of the string length arguments. We
4125 also have to set the string length for the result. */
4132 gfc_trans_same_strlen_check ("MERGE intrinsic", &expr
->where
, len
, len2
,
4134 se
->string_length
= len
;
4136 type
= TREE_TYPE (tsource
);
4137 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
, type
, mask
, tsource
,
4138 fold_convert (type
, fsource
));
4142 /* MERGE_BITS (I, J, MASK) = (I & MASK) | (I & (~MASK)). */
4145 gfc_conv_intrinsic_merge_bits (gfc_se
* se
, gfc_expr
* expr
)
4147 tree args
[3], mask
, type
;
4149 gfc_conv_intrinsic_function_args (se
, expr
, args
, 3);
4150 mask
= gfc_evaluate_now (args
[2], &se
->pre
);
4152 type
= TREE_TYPE (args
[0]);
4153 gcc_assert (TREE_TYPE (args
[1]) == type
);
4154 gcc_assert (TREE_TYPE (mask
) == type
);
4156 args
[0] = fold_build2_loc (input_location
, BIT_AND_EXPR
, type
, args
[0], mask
);
4157 args
[1] = fold_build2_loc (input_location
, BIT_AND_EXPR
, type
, args
[1],
4158 fold_build1_loc (input_location
, BIT_NOT_EXPR
,
4160 se
->expr
= fold_build2_loc (input_location
, BIT_IOR_EXPR
, type
,
4165 /* MASKL(n) = n == 0 ? 0 : (~0) << (BIT_SIZE - n)
4166 MASKR(n) = n == BIT_SIZE ? ~0 : ~((~0) << n) */
4169 gfc_conv_intrinsic_mask (gfc_se
* se
, gfc_expr
* expr
, int left
)
4171 tree arg
, allones
, type
, utype
, res
, cond
, bitsize
;
4174 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
4175 arg
= gfc_evaluate_now (arg
, &se
->pre
);
4177 type
= gfc_get_int_type (expr
->ts
.kind
);
4178 utype
= unsigned_type_for (type
);
4180 i
= gfc_validate_kind (BT_INTEGER
, expr
->ts
.kind
, false);
4181 bitsize
= build_int_cst (TREE_TYPE (arg
), gfc_integer_kinds
[i
].bit_size
);
4183 allones
= fold_build1_loc (input_location
, BIT_NOT_EXPR
, utype
,
4184 build_int_cst (utype
, 0));
4188 /* Left-justified mask. */
4189 res
= fold_build2_loc (input_location
, MINUS_EXPR
, TREE_TYPE (arg
),
4191 res
= fold_build2_loc (input_location
, LSHIFT_EXPR
, utype
, allones
,
4192 fold_convert (utype
, res
));
4194 /* Special case arg == 0, because SHIFT_EXPR wants a shift strictly
4195 smaller than type width. */
4196 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, arg
,
4197 build_int_cst (TREE_TYPE (arg
), 0));
4198 res
= fold_build3_loc (input_location
, COND_EXPR
, utype
, cond
,
4199 build_int_cst (utype
, 0), res
);
4203 /* Right-justified mask. */
4204 res
= fold_build2_loc (input_location
, LSHIFT_EXPR
, utype
, allones
,
4205 fold_convert (utype
, arg
));
4206 res
= fold_build1_loc (input_location
, BIT_NOT_EXPR
, utype
, res
);
4208 /* Special case agr == bit_size, because SHIFT_EXPR wants a shift
4209 strictly smaller than type width. */
4210 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
4212 res
= fold_build3_loc (input_location
, COND_EXPR
, utype
,
4213 cond
, allones
, res
);
4216 se
->expr
= fold_convert (type
, res
);
4220 /* FRACTION (s) is translated into frexp (s, &dummy_int). */
4222 gfc_conv_intrinsic_fraction (gfc_se
* se
, gfc_expr
* expr
)
4224 tree arg
, type
, tmp
, frexp
;
4226 frexp
= gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP
, expr
->ts
.kind
);
4228 type
= gfc_typenode_for_spec (&expr
->ts
);
4229 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
4230 tmp
= gfc_create_var (integer_type_node
, NULL
);
4231 se
->expr
= build_call_expr_loc (input_location
, frexp
, 2,
4232 fold_convert (type
, arg
),
4233 gfc_build_addr_expr (NULL_TREE
, tmp
));
4234 se
->expr
= fold_convert (type
, se
->expr
);
4238 /* NEAREST (s, dir) is translated into
4239 tmp = copysign (HUGE_VAL, dir);
4240 return nextafter (s, tmp);
4243 gfc_conv_intrinsic_nearest (gfc_se
* se
, gfc_expr
* expr
)
4245 tree args
[2], type
, tmp
, nextafter
, copysign
, huge_val
;
4247 nextafter
= gfc_builtin_decl_for_float_kind (BUILT_IN_NEXTAFTER
, expr
->ts
.kind
);
4248 copysign
= gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN
, expr
->ts
.kind
);
4250 type
= gfc_typenode_for_spec (&expr
->ts
);
4251 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
4253 huge_val
= gfc_build_inf_or_huge (type
, expr
->ts
.kind
);
4254 tmp
= build_call_expr_loc (input_location
, copysign
, 2, huge_val
,
4255 fold_convert (type
, args
[1]));
4256 se
->expr
= build_call_expr_loc (input_location
, nextafter
, 2,
4257 fold_convert (type
, args
[0]), tmp
);
4258 se
->expr
= fold_convert (type
, se
->expr
);
4262 /* SPACING (s) is translated into
4270 e = MAX_EXPR (e, emin);
4271 res = scalbn (1., e);
4275 where prec is the precision of s, gfc_real_kinds[k].digits,
4276 emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
4277 and tiny is tiny(s), gfc_real_kinds[k].tiny. */
4280 gfc_conv_intrinsic_spacing (gfc_se
* se
, gfc_expr
* expr
)
4282 tree arg
, type
, prec
, emin
, tiny
, res
, e
;
4283 tree cond
, tmp
, frexp
, scalbn
;
4287 k
= gfc_validate_kind (BT_REAL
, expr
->ts
.kind
, false);
4288 prec
= build_int_cst (NULL_TREE
, gfc_real_kinds
[k
].digits
);
4289 emin
= build_int_cst (NULL_TREE
, gfc_real_kinds
[k
].min_exponent
- 1);
4290 tiny
= gfc_conv_mpfr_to_tree (gfc_real_kinds
[k
].tiny
, expr
->ts
.kind
, 0);
4292 frexp
= gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP
, expr
->ts
.kind
);
4293 scalbn
= gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN
, expr
->ts
.kind
);
4295 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
4296 arg
= gfc_evaluate_now (arg
, &se
->pre
);
4298 type
= gfc_typenode_for_spec (&expr
->ts
);
4299 e
= gfc_create_var (integer_type_node
, NULL
);
4300 res
= gfc_create_var (type
, NULL
);
4303 /* Build the block for s /= 0. */
4304 gfc_start_block (&block
);
4305 tmp
= build_call_expr_loc (input_location
, frexp
, 2, arg
,
4306 gfc_build_addr_expr (NULL_TREE
, e
));
4307 gfc_add_expr_to_block (&block
, tmp
);
4309 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, integer_type_node
, e
,
4311 gfc_add_modify (&block
, e
, fold_build2_loc (input_location
, MAX_EXPR
,
4312 integer_type_node
, tmp
, emin
));
4314 tmp
= build_call_expr_loc (input_location
, scalbn
, 2,
4315 build_real_from_int_cst (type
, integer_one_node
), e
);
4316 gfc_add_modify (&block
, res
, tmp
);
4318 /* Finish by building the IF statement. */
4319 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, arg
,
4320 build_real_from_int_cst (type
, integer_zero_node
));
4321 tmp
= build3_v (COND_EXPR
, cond
, build2_v (MODIFY_EXPR
, res
, tiny
),
4322 gfc_finish_block (&block
));
4324 gfc_add_expr_to_block (&se
->pre
, tmp
);
4329 /* RRSPACING (s) is translated into
4336 x = scalbn (x, precision - e);
4340 where precision is gfc_real_kinds[k].digits. */
4343 gfc_conv_intrinsic_rrspacing (gfc_se
* se
, gfc_expr
* expr
)
4345 tree arg
, type
, e
, x
, cond
, stmt
, tmp
, frexp
, scalbn
, fabs
;
4349 k
= gfc_validate_kind (BT_REAL
, expr
->ts
.kind
, false);
4350 prec
= gfc_real_kinds
[k
].digits
;
4352 frexp
= gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP
, expr
->ts
.kind
);
4353 scalbn
= gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN
, expr
->ts
.kind
);
4354 fabs
= gfc_builtin_decl_for_float_kind (BUILT_IN_FABS
, expr
->ts
.kind
);
4356 type
= gfc_typenode_for_spec (&expr
->ts
);
4357 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
4358 arg
= gfc_evaluate_now (arg
, &se
->pre
);
4360 e
= gfc_create_var (integer_type_node
, NULL
);
4361 x
= gfc_create_var (type
, NULL
);
4362 gfc_add_modify (&se
->pre
, x
,
4363 build_call_expr_loc (input_location
, fabs
, 1, arg
));
4366 gfc_start_block (&block
);
4367 tmp
= build_call_expr_loc (input_location
, frexp
, 2, arg
,
4368 gfc_build_addr_expr (NULL_TREE
, e
));
4369 gfc_add_expr_to_block (&block
, tmp
);
4371 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, integer_type_node
,
4372 build_int_cst (NULL_TREE
, prec
), e
);
4373 tmp
= build_call_expr_loc (input_location
, scalbn
, 2, x
, tmp
);
4374 gfc_add_modify (&block
, x
, tmp
);
4375 stmt
= gfc_finish_block (&block
);
4377 cond
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, x
,
4378 build_real_from_int_cst (type
, integer_zero_node
));
4379 tmp
= build3_v (COND_EXPR
, cond
, stmt
, build_empty_stmt (input_location
));
4380 gfc_add_expr_to_block (&se
->pre
, tmp
);
4382 se
->expr
= fold_convert (type
, x
);
4386 /* SCALE (s, i) is translated into scalbn (s, i). */
4388 gfc_conv_intrinsic_scale (gfc_se
* se
, gfc_expr
* expr
)
4390 tree args
[2], type
, scalbn
;
4392 scalbn
= gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN
, expr
->ts
.kind
);
4394 type
= gfc_typenode_for_spec (&expr
->ts
);
4395 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
4396 se
->expr
= build_call_expr_loc (input_location
, scalbn
, 2,
4397 fold_convert (type
, args
[0]),
4398 fold_convert (integer_type_node
, args
[1]));
4399 se
->expr
= fold_convert (type
, se
->expr
);
4403 /* SET_EXPONENT (s, i) is translated into
4404 scalbn (frexp (s, &dummy_int), i). */
4406 gfc_conv_intrinsic_set_exponent (gfc_se
* se
, gfc_expr
* expr
)
4408 tree args
[2], type
, tmp
, frexp
, scalbn
;
4410 frexp
= gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP
, expr
->ts
.kind
);
4411 scalbn
= gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN
, expr
->ts
.kind
);
4413 type
= gfc_typenode_for_spec (&expr
->ts
);
4414 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
4416 tmp
= gfc_create_var (integer_type_node
, NULL
);
4417 tmp
= build_call_expr_loc (input_location
, frexp
, 2,
4418 fold_convert (type
, args
[0]),
4419 gfc_build_addr_expr (NULL_TREE
, tmp
));
4420 se
->expr
= build_call_expr_loc (input_location
, scalbn
, 2, tmp
,
4421 fold_convert (integer_type_node
, args
[1]));
4422 se
->expr
= fold_convert (type
, se
->expr
);
4427 gfc_conv_intrinsic_size (gfc_se
* se
, gfc_expr
* expr
)
4429 gfc_actual_arglist
*actual
;
4437 gfc_init_se (&argse
, NULL
);
4438 actual
= expr
->value
.function
.actual
;
4440 ss
= gfc_walk_expr (actual
->expr
);
4441 gcc_assert (ss
!= gfc_ss_terminator
);
4442 argse
.want_pointer
= 1;
4443 argse
.data_not_needed
= 1;
4444 gfc_conv_expr_descriptor (&argse
, actual
->expr
, ss
);
4445 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4446 gfc_add_block_to_block (&se
->post
, &argse
.post
);
4447 arg1
= gfc_evaluate_now (argse
.expr
, &se
->pre
);
4449 /* Build the call to size0. */
4450 fncall0
= build_call_expr_loc (input_location
,
4451 gfor_fndecl_size0
, 1, arg1
);
4453 actual
= actual
->next
;
4457 gfc_init_se (&argse
, NULL
);
4458 gfc_conv_expr_type (&argse
, actual
->expr
,
4459 gfc_array_index_type
);
4460 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4462 /* Unusually, for an intrinsic, size does not exclude
4463 an optional arg2, so we must test for it. */
4464 if (actual
->expr
->expr_type
== EXPR_VARIABLE
4465 && actual
->expr
->symtree
->n
.sym
->attr
.dummy
4466 && actual
->expr
->symtree
->n
.sym
->attr
.optional
)
4469 /* Build the call to size1. */
4470 fncall1
= build_call_expr_loc (input_location
,
4471 gfor_fndecl_size1
, 2,
4474 gfc_init_se (&argse
, NULL
);
4475 argse
.want_pointer
= 1;
4476 argse
.data_not_needed
= 1;
4477 gfc_conv_expr (&argse
, actual
->expr
);
4478 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4479 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
4480 argse
.expr
, null_pointer_node
);
4481 tmp
= gfc_evaluate_now (tmp
, &se
->pre
);
4482 se
->expr
= fold_build3_loc (input_location
, COND_EXPR
,
4483 pvoid_type_node
, tmp
, fncall1
, fncall0
);
4487 se
->expr
= NULL_TREE
;
4488 argse
.expr
= fold_build2_loc (input_location
, MINUS_EXPR
,
4489 gfc_array_index_type
,
4490 argse
.expr
, gfc_index_one_node
);
4493 else if (expr
->value
.function
.actual
->expr
->rank
== 1)
4495 argse
.expr
= gfc_index_zero_node
;
4496 se
->expr
= NULL_TREE
;
4501 if (se
->expr
== NULL_TREE
)
4503 tree ubound
, lbound
;
4505 arg1
= build_fold_indirect_ref_loc (input_location
,
4507 ubound
= gfc_conv_descriptor_ubound_get (arg1
, argse
.expr
);
4508 lbound
= gfc_conv_descriptor_lbound_get (arg1
, argse
.expr
);
4509 se
->expr
= fold_build2_loc (input_location
, MINUS_EXPR
,
4510 gfc_array_index_type
, ubound
, lbound
);
4511 se
->expr
= fold_build2_loc (input_location
, PLUS_EXPR
,
4512 gfc_array_index_type
,
4513 se
->expr
, gfc_index_one_node
);
4514 se
->expr
= fold_build2_loc (input_location
, MAX_EXPR
,
4515 gfc_array_index_type
, se
->expr
,
4516 gfc_index_zero_node
);
4519 type
= gfc_typenode_for_spec (&expr
->ts
);
4520 se
->expr
= convert (type
, se
->expr
);
4524 /* Helper function to compute the size of a character variable,
4525 excluding the terminating null characters. The result has
4526 gfc_array_index_type type. */
4529 size_of_string_in_bytes (int kind
, tree string_length
)
4532 int i
= gfc_validate_kind (BT_CHARACTER
, kind
, false);
4534 bytesize
= build_int_cst (gfc_array_index_type
,
4535 gfc_character_kinds
[i
].bit_size
/ 8);
4537 return fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
4539 fold_convert (gfc_array_index_type
, string_length
));
4544 gfc_conv_intrinsic_sizeof (gfc_se
*se
, gfc_expr
*expr
)
4556 arg
= expr
->value
.function
.actual
->expr
;
4558 gfc_init_se (&argse
, NULL
);
4559 ss
= gfc_walk_expr (arg
);
4561 if (ss
== gfc_ss_terminator
)
4563 if (arg
->ts
.type
== BT_CLASS
)
4564 gfc_add_data_component (arg
);
4566 gfc_conv_expr_reference (&argse
, arg
);
4568 type
= TREE_TYPE (build_fold_indirect_ref_loc (input_location
,
4571 /* Obtain the source word length. */
4572 if (arg
->ts
.type
== BT_CHARACTER
)
4573 se
->expr
= size_of_string_in_bytes (arg
->ts
.kind
,
4574 argse
.string_length
);
4576 se
->expr
= fold_convert (gfc_array_index_type
, size_in_bytes (type
));
4580 source_bytes
= gfc_create_var (gfc_array_index_type
, "bytes");
4581 argse
.want_pointer
= 0;
4582 gfc_conv_expr_descriptor (&argse
, arg
, ss
);
4583 type
= gfc_get_element_type (TREE_TYPE (argse
.expr
));
4585 /* Obtain the argument's word length. */
4586 if (arg
->ts
.type
== BT_CHARACTER
)
4587 tmp
= size_of_string_in_bytes (arg
->ts
.kind
, argse
.string_length
);
4589 tmp
= fold_convert (gfc_array_index_type
,
4590 size_in_bytes (type
));
4591 gfc_add_modify (&argse
.pre
, source_bytes
, tmp
);
4593 /* Obtain the size of the array in bytes. */
4594 for (n
= 0; n
< arg
->rank
; n
++)
4597 idx
= gfc_rank_cst
[n
];
4598 lower
= gfc_conv_descriptor_lbound_get (argse
.expr
, idx
);
4599 upper
= gfc_conv_descriptor_ubound_get (argse
.expr
, idx
);
4600 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4601 gfc_array_index_type
, upper
, lower
);
4602 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4603 gfc_array_index_type
, tmp
, gfc_index_one_node
);
4604 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
4605 gfc_array_index_type
, tmp
, source_bytes
);
4606 gfc_add_modify (&argse
.pre
, source_bytes
, tmp
);
4608 se
->expr
= source_bytes
;
4611 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4616 gfc_conv_intrinsic_storage_size (gfc_se
*se
, gfc_expr
*expr
)
4621 tree type
, result_type
, tmp
;
4623 arg
= expr
->value
.function
.actual
->expr
;
4624 gfc_init_se (&eight
, NULL
);
4625 gfc_conv_expr (&eight
, gfc_get_int_expr (expr
->ts
.kind
, NULL
, 8));
4627 gfc_init_se (&argse
, NULL
);
4628 ss
= gfc_walk_expr (arg
);
4629 result_type
= gfc_get_int_type (expr
->ts
.kind
);
4631 if (ss
== gfc_ss_terminator
)
4633 if (arg
->ts
.type
== BT_CLASS
)
4635 gfc_add_vptr_component (arg
);
4636 gfc_add_size_component (arg
);
4637 gfc_conv_expr (&argse
, arg
);
4638 tmp
= fold_convert (result_type
, argse
.expr
);
4642 gfc_conv_expr_reference (&argse
, arg
);
4643 type
= TREE_TYPE (build_fold_indirect_ref_loc (input_location
,
4648 argse
.want_pointer
= 0;
4649 gfc_conv_expr_descriptor (&argse
, arg
, ss
);
4650 type
= gfc_get_element_type (TREE_TYPE (argse
.expr
));
4653 /* Obtain the argument's word length. */
4654 if (arg
->ts
.type
== BT_CHARACTER
)
4655 tmp
= size_of_string_in_bytes (arg
->ts
.kind
, argse
.string_length
);
4657 tmp
= fold_convert (result_type
, size_in_bytes (type
));
4660 se
->expr
= fold_build2_loc (input_location
, MULT_EXPR
, result_type
, tmp
,
4662 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4666 /* Intrinsic string comparison functions. */
4669 gfc_conv_intrinsic_strcmp (gfc_se
* se
, gfc_expr
* expr
, enum tree_code op
)
4673 gfc_conv_intrinsic_function_args (se
, expr
, args
, 4);
4676 = gfc_build_compare_string (args
[0], args
[1], args
[2], args
[3],
4677 expr
->value
.function
.actual
->expr
->ts
.kind
,
4679 se
->expr
= fold_build2_loc (input_location
, op
,
4680 gfc_typenode_for_spec (&expr
->ts
), se
->expr
,
4681 build_int_cst (TREE_TYPE (se
->expr
), 0));
4684 /* Generate a call to the adjustl/adjustr library function. */
4686 gfc_conv_intrinsic_adjust (gfc_se
* se
, gfc_expr
* expr
, tree fndecl
)
4694 gfc_conv_intrinsic_function_args (se
, expr
, &args
[1], 2);
4697 type
= TREE_TYPE (args
[2]);
4698 var
= gfc_conv_string_tmp (se
, type
, len
);
4701 tmp
= build_call_expr_loc (input_location
,
4702 fndecl
, 3, args
[0], args
[1], args
[2]);
4703 gfc_add_expr_to_block (&se
->pre
, tmp
);
4705 se
->string_length
= len
;
4709 /* Generate code for the TRANSFER intrinsic:
4711 DEST = TRANSFER (SOURCE, MOLD)
4713 typeof<DEST> = typeof<MOLD>
4718 DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
4720 typeof<DEST> = typeof<MOLD>
4722 N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
4723 sizeof (DEST(0) * SIZE). */
4725 gfc_conv_intrinsic_transfer (gfc_se
* se
, gfc_expr
* expr
)
4741 gfc_actual_arglist
*arg
;
4751 info
= &se
->ss
->data
.info
;
4753 /* Convert SOURCE. The output from this stage is:-
4754 source_bytes = length of the source in bytes
4755 source = pointer to the source data. */
4756 arg
= expr
->value
.function
.actual
;
4758 /* Ensure double transfer through LOGICAL preserves all
4760 if (arg
->expr
->expr_type
== EXPR_FUNCTION
4761 && arg
->expr
->value
.function
.esym
== NULL
4762 && arg
->expr
->value
.function
.isym
!= NULL
4763 && arg
->expr
->value
.function
.isym
->id
== GFC_ISYM_TRANSFER
4764 && arg
->expr
->ts
.type
== BT_LOGICAL
4765 && expr
->ts
.type
!= arg
->expr
->ts
.type
)
4766 arg
->expr
->value
.function
.name
= "__transfer_in_transfer";
4768 gfc_init_se (&argse
, NULL
);
4769 ss
= gfc_walk_expr (arg
->expr
);
4771 source_bytes
= gfc_create_var (gfc_array_index_type
, NULL
);
4773 /* Obtain the pointer to source and the length of source in bytes. */
4774 if (ss
== gfc_ss_terminator
)
4776 gfc_conv_expr_reference (&argse
, arg
->expr
);
4777 source
= argse
.expr
;
4779 source_type
= TREE_TYPE (build_fold_indirect_ref_loc (input_location
,
4782 /* Obtain the source word length. */
4783 if (arg
->expr
->ts
.type
== BT_CHARACTER
)
4784 tmp
= size_of_string_in_bytes (arg
->expr
->ts
.kind
,
4785 argse
.string_length
);
4787 tmp
= fold_convert (gfc_array_index_type
,
4788 size_in_bytes (source_type
));
4792 argse
.want_pointer
= 0;
4793 gfc_conv_expr_descriptor (&argse
, arg
->expr
, ss
);
4794 source
= gfc_conv_descriptor_data_get (argse
.expr
);
4795 source_type
= gfc_get_element_type (TREE_TYPE (argse
.expr
));
4797 /* Repack the source if not a full variable array. */
4798 if (arg
->expr
->expr_type
== EXPR_VARIABLE
4799 && arg
->expr
->ref
->u
.ar
.type
!= AR_FULL
)
4801 tmp
= gfc_build_addr_expr (NULL_TREE
, argse
.expr
);
4803 if (gfc_option
.warn_array_temp
)
4804 gfc_warning ("Creating array temporary at %L", &expr
->where
);
4806 source
= build_call_expr_loc (input_location
,
4807 gfor_fndecl_in_pack
, 1, tmp
);
4808 source
= gfc_evaluate_now (source
, &argse
.pre
);
4810 /* Free the temporary. */
4811 gfc_start_block (&block
);
4812 tmp
= gfc_call_free (convert (pvoid_type_node
, source
));
4813 gfc_add_expr_to_block (&block
, tmp
);
4814 stmt
= gfc_finish_block (&block
);
4816 /* Clean up if it was repacked. */
4817 gfc_init_block (&block
);
4818 tmp
= gfc_conv_array_data (argse
.expr
);
4819 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
4821 tmp
= build3_v (COND_EXPR
, tmp
, stmt
,
4822 build_empty_stmt (input_location
));
4823 gfc_add_expr_to_block (&block
, tmp
);
4824 gfc_add_block_to_block (&block
, &se
->post
);
4825 gfc_init_block (&se
->post
);
4826 gfc_add_block_to_block (&se
->post
, &block
);
4829 /* Obtain the source word length. */
4830 if (arg
->expr
->ts
.type
== BT_CHARACTER
)
4831 tmp
= size_of_string_in_bytes (arg
->expr
->ts
.kind
,
4832 argse
.string_length
);
4834 tmp
= fold_convert (gfc_array_index_type
,
4835 size_in_bytes (source_type
));
4837 /* Obtain the size of the array in bytes. */
4838 extent
= gfc_create_var (gfc_array_index_type
, NULL
);
4839 for (n
= 0; n
< arg
->expr
->rank
; n
++)
4842 idx
= gfc_rank_cst
[n
];
4843 gfc_add_modify (&argse
.pre
, source_bytes
, tmp
);
4844 lower
= gfc_conv_descriptor_lbound_get (argse
.expr
, idx
);
4845 upper
= gfc_conv_descriptor_ubound_get (argse
.expr
, idx
);
4846 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
,
4847 gfc_array_index_type
, upper
, lower
);
4848 gfc_add_modify (&argse
.pre
, extent
, tmp
);
4849 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
,
4850 gfc_array_index_type
, extent
,
4851 gfc_index_one_node
);
4852 tmp
= fold_build2_loc (input_location
, MULT_EXPR
,
4853 gfc_array_index_type
, tmp
, source_bytes
);
4857 gfc_add_modify (&argse
.pre
, source_bytes
, tmp
);
4858 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4859 gfc_add_block_to_block (&se
->post
, &argse
.post
);
4861 /* Now convert MOLD. The outputs are:
4862 mold_type = the TREE type of MOLD
4863 dest_word_len = destination word length in bytes. */
4866 gfc_init_se (&argse
, NULL
);
4867 ss
= gfc_walk_expr (arg
->expr
);
4869 scalar_mold
= arg
->expr
->rank
== 0;
4871 if (ss
== gfc_ss_terminator
)
4873 gfc_conv_expr_reference (&argse
, arg
->expr
);
4874 mold_type
= TREE_TYPE (build_fold_indirect_ref_loc (input_location
,
4879 gfc_init_se (&argse
, NULL
);
4880 argse
.want_pointer
= 0;
4881 gfc_conv_expr_descriptor (&argse
, arg
->expr
, ss
);
4882 mold_type
= gfc_get_element_type (TREE_TYPE (argse
.expr
));
4885 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4886 gfc_add_block_to_block (&se
->post
, &argse
.post
);
4888 if (strcmp (expr
->value
.function
.name
, "__transfer_in_transfer") == 0)
4890 /* If this TRANSFER is nested in another TRANSFER, use a type
4891 that preserves all bits. */
4892 if (arg
->expr
->ts
.type
== BT_LOGICAL
)
4893 mold_type
= gfc_get_int_type (arg
->expr
->ts
.kind
);
4896 if (arg
->expr
->ts
.type
== BT_CHARACTER
)
4898 tmp
= size_of_string_in_bytes (arg
->expr
->ts
.kind
, argse
.string_length
);
4899 mold_type
= gfc_get_character_type_len (arg
->expr
->ts
.kind
, tmp
);
4902 tmp
= fold_convert (gfc_array_index_type
,
4903 size_in_bytes (mold_type
));
4905 dest_word_len
= gfc_create_var (gfc_array_index_type
, NULL
);
4906 gfc_add_modify (&se
->pre
, dest_word_len
, tmp
);
4908 /* Finally convert SIZE, if it is present. */
4910 size_words
= gfc_create_var (gfc_array_index_type
, NULL
);
4914 gfc_init_se (&argse
, NULL
);
4915 gfc_conv_expr_reference (&argse
, arg
->expr
);
4916 tmp
= convert (gfc_array_index_type
,
4917 build_fold_indirect_ref_loc (input_location
,
4919 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
4920 gfc_add_block_to_block (&se
->post
, &argse
.post
);
4925 /* Separate array and scalar results. */
4926 if (scalar_mold
&& tmp
== NULL_TREE
)
4927 goto scalar_transfer
;
4929 size_bytes
= gfc_create_var (gfc_array_index_type
, NULL
);
4930 if (tmp
!= NULL_TREE
)
4931 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_array_index_type
,
4932 tmp
, dest_word_len
);
4936 gfc_add_modify (&se
->pre
, size_bytes
, tmp
);
4937 gfc_add_modify (&se
->pre
, size_words
,
4938 fold_build2_loc (input_location
, CEIL_DIV_EXPR
,
4939 gfc_array_index_type
,
4940 size_bytes
, dest_word_len
));
4942 /* Evaluate the bounds of the result. If the loop range exists, we have
4943 to check if it is too large. If so, we modify loop->to be consistent
4944 with min(size, size(source)). Otherwise, size is made consistent with
4945 the loop range, so that the right number of bytes is transferred.*/
4946 n
= se
->loop
->order
[0];
4947 if (se
->loop
->to
[n
] != NULL_TREE
)
4949 tmp
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
4950 se
->loop
->to
[n
], se
->loop
->from
[n
]);
4951 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
4952 tmp
, gfc_index_one_node
);
4953 tmp
= fold_build2_loc (input_location
, MIN_EXPR
, gfc_array_index_type
,
4955 gfc_add_modify (&se
->pre
, size_words
, tmp
);
4956 gfc_add_modify (&se
->pre
, size_bytes
,
4957 fold_build2_loc (input_location
, MULT_EXPR
,
4958 gfc_array_index_type
,
4959 size_words
, dest_word_len
));
4960 upper
= fold_build2_loc (input_location
, PLUS_EXPR
, gfc_array_index_type
,
4961 size_words
, se
->loop
->from
[n
]);
4962 upper
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
4963 upper
, gfc_index_one_node
);
4967 upper
= fold_build2_loc (input_location
, MINUS_EXPR
, gfc_array_index_type
,
4968 size_words
, gfc_index_one_node
);
4969 se
->loop
->from
[n
] = gfc_index_zero_node
;
4972 se
->loop
->to
[n
] = upper
;
4974 /* Build a destination descriptor, using the pointer, source, as the
4976 gfc_trans_create_temp_array (&se
->pre
, &se
->post
, se
->loop
,
4977 info
, mold_type
, NULL_TREE
, false, true, false,
4980 /* Cast the pointer to the result. */
4981 tmp
= gfc_conv_descriptor_data_get (info
->descriptor
);
4982 tmp
= fold_convert (pvoid_type_node
, tmp
);
4984 /* Use memcpy to do the transfer. */
4985 tmp
= build_call_expr_loc (input_location
,
4986 built_in_decls
[BUILT_IN_MEMCPY
],
4989 fold_convert (pvoid_type_node
, source
),
4990 fold_build2_loc (input_location
, MIN_EXPR
,
4991 gfc_array_index_type
,
4992 size_bytes
, source_bytes
));
4993 gfc_add_expr_to_block (&se
->pre
, tmp
);
4995 se
->expr
= info
->descriptor
;
4996 if (expr
->ts
.type
== BT_CHARACTER
)
4997 se
->string_length
= fold_convert (gfc_charlen_type_node
, dest_word_len
);
5001 /* Deal with scalar results. */
5003 extent
= fold_build2_loc (input_location
, MIN_EXPR
, gfc_array_index_type
,
5004 dest_word_len
, source_bytes
);
5005 extent
= fold_build2_loc (input_location
, MAX_EXPR
, gfc_array_index_type
,
5006 extent
, gfc_index_zero_node
);
5008 if (expr
->ts
.type
== BT_CHARACTER
)
5013 ptr
= convert (gfc_get_pchar_type (expr
->ts
.kind
), source
);
5014 tmpdecl
= gfc_create_var (gfc_get_pchar_type (expr
->ts
.kind
),
5017 /* If source is longer than the destination, use a pointer to
5018 the source directly. */
5019 gfc_init_block (&block
);
5020 gfc_add_modify (&block
, tmpdecl
, ptr
);
5021 direct
= gfc_finish_block (&block
);
5023 /* Otherwise, allocate a string with the length of the destination
5024 and copy the source into it. */
5025 gfc_init_block (&block
);
5026 tmp
= gfc_get_pchar_type (expr
->ts
.kind
);
5027 tmp
= gfc_call_malloc (&block
, tmp
, dest_word_len
);
5028 gfc_add_modify (&block
, tmpdecl
,
5029 fold_convert (TREE_TYPE (ptr
), tmp
));
5030 tmp
= build_call_expr_loc (input_location
,
5031 built_in_decls
[BUILT_IN_MEMCPY
], 3,
5032 fold_convert (pvoid_type_node
, tmpdecl
),
5033 fold_convert (pvoid_type_node
, ptr
),
5035 gfc_add_expr_to_block (&block
, tmp
);
5036 indirect
= gfc_finish_block (&block
);
5038 /* Wrap it up with the condition. */
5039 tmp
= fold_build2_loc (input_location
, LE_EXPR
, boolean_type_node
,
5040 dest_word_len
, source_bytes
);
5041 tmp
= build3_v (COND_EXPR
, tmp
, direct
, indirect
);
5042 gfc_add_expr_to_block (&se
->pre
, tmp
);
5045 se
->string_length
= dest_word_len
;
5049 tmpdecl
= gfc_create_var (mold_type
, "transfer");
5051 ptr
= convert (build_pointer_type (mold_type
), source
);
5053 /* Use memcpy to do the transfer. */
5054 tmp
= gfc_build_addr_expr (NULL_TREE
, tmpdecl
);
5055 tmp
= build_call_expr_loc (input_location
,
5056 built_in_decls
[BUILT_IN_MEMCPY
], 3,
5057 fold_convert (pvoid_type_node
, tmp
),
5058 fold_convert (pvoid_type_node
, ptr
),
5060 gfc_add_expr_to_block (&se
->pre
, tmp
);
5067 /* Generate code for the ALLOCATED intrinsic.
5068 Generate inline code that directly check the address of the argument. */
5071 gfc_conv_allocated (gfc_se
*se
, gfc_expr
*expr
)
5073 gfc_actual_arglist
*arg1
;
5078 gfc_init_se (&arg1se
, NULL
);
5079 arg1
= expr
->value
.function
.actual
;
5080 ss1
= gfc_walk_expr (arg1
->expr
);
5082 if (ss1
== gfc_ss_terminator
)
5084 /* Allocatable scalar. */
5085 arg1se
.want_pointer
= 1;
5086 if (arg1
->expr
->ts
.type
== BT_CLASS
)
5087 gfc_add_data_component (arg1
->expr
);
5088 gfc_conv_expr (&arg1se
, arg1
->expr
);
5093 /* Allocatable array. */
5094 arg1se
.descriptor_only
= 1;
5095 gfc_conv_expr_descriptor (&arg1se
, arg1
->expr
, ss1
);
5096 tmp
= gfc_conv_descriptor_data_get (arg1se
.expr
);
5099 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, tmp
,
5100 fold_convert (TREE_TYPE (tmp
), null_pointer_node
));
5101 se
->expr
= convert (gfc_typenode_for_spec (&expr
->ts
), tmp
);
5105 /* Generate code for the ASSOCIATED intrinsic.
5106 If both POINTER and TARGET are arrays, generate a call to library function
5107 _gfor_associated, and pass descriptors of POINTER and TARGET to it.
5108 In other cases, generate inline code that directly compare the address of
5109 POINTER with the address of TARGET. */
5112 gfc_conv_associated (gfc_se
*se
, gfc_expr
*expr
)
5114 gfc_actual_arglist
*arg1
;
5115 gfc_actual_arglist
*arg2
;
5120 tree nonzero_charlen
;
5121 tree nonzero_arraylen
;
5124 gfc_init_se (&arg1se
, NULL
);
5125 gfc_init_se (&arg2se
, NULL
);
5126 arg1
= expr
->value
.function
.actual
;
5127 if (arg1
->expr
->ts
.type
== BT_CLASS
)
5128 gfc_add_data_component (arg1
->expr
);
5130 ss1
= gfc_walk_expr (arg1
->expr
);
5134 /* No optional target. */
5135 if (ss1
== gfc_ss_terminator
)
5137 /* A pointer to a scalar. */
5138 arg1se
.want_pointer
= 1;
5139 gfc_conv_expr (&arg1se
, arg1
->expr
);
5144 /* A pointer to an array. */
5145 gfc_conv_expr_descriptor (&arg1se
, arg1
->expr
, ss1
);
5146 tmp2
= gfc_conv_descriptor_data_get (arg1se
.expr
);
5148 gfc_add_block_to_block (&se
->pre
, &arg1se
.pre
);
5149 gfc_add_block_to_block (&se
->post
, &arg1se
.post
);
5150 tmp
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
, tmp2
,
5151 fold_convert (TREE_TYPE (tmp2
), null_pointer_node
));
5156 /* An optional target. */
5157 if (arg2
->expr
->ts
.type
== BT_CLASS
)
5158 gfc_add_data_component (arg2
->expr
);
5159 ss2
= gfc_walk_expr (arg2
->expr
);
5161 nonzero_charlen
= NULL_TREE
;
5162 if (arg1
->expr
->ts
.type
== BT_CHARACTER
)
5163 nonzero_charlen
= fold_build2_loc (input_location
, NE_EXPR
,
5165 arg1
->expr
->ts
.u
.cl
->backend_decl
,
5168 if (ss1
== gfc_ss_terminator
)
5170 /* A pointer to a scalar. */
5171 gcc_assert (ss2
== gfc_ss_terminator
);
5172 arg1se
.want_pointer
= 1;
5173 gfc_conv_expr (&arg1se
, arg1
->expr
);
5174 arg2se
.want_pointer
= 1;
5175 gfc_conv_expr (&arg2se
, arg2
->expr
);
5176 gfc_add_block_to_block (&se
->pre
, &arg1se
.pre
);
5177 gfc_add_block_to_block (&se
->post
, &arg1se
.post
);
5178 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
5179 arg1se
.expr
, arg2se
.expr
);
5180 tmp2
= fold_build2_loc (input_location
, NE_EXPR
, boolean_type_node
,
5181 arg1se
.expr
, null_pointer_node
);
5182 se
->expr
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
5183 boolean_type_node
, tmp
, tmp2
);
5187 /* An array pointer of zero length is not associated if target is
5189 arg1se
.descriptor_only
= 1;
5190 gfc_conv_expr_lhs (&arg1se
, arg1
->expr
);
5191 tmp
= gfc_conv_descriptor_stride_get (arg1se
.expr
,
5192 gfc_rank_cst
[arg1
->expr
->rank
- 1]);
5193 nonzero_arraylen
= fold_build2_loc (input_location
, NE_EXPR
,
5194 boolean_type_node
, tmp
,
5195 build_int_cst (TREE_TYPE (tmp
), 0));
5197 /* A pointer to an array, call library function _gfor_associated. */
5198 gcc_assert (ss2
!= gfc_ss_terminator
);
5199 arg1se
.want_pointer
= 1;
5200 gfc_conv_expr_descriptor (&arg1se
, arg1
->expr
, ss1
);
5202 arg2se
.want_pointer
= 1;
5203 gfc_conv_expr_descriptor (&arg2se
, arg2
->expr
, ss2
);
5204 gfc_add_block_to_block (&se
->pre
, &arg2se
.pre
);
5205 gfc_add_block_to_block (&se
->post
, &arg2se
.post
);
5206 se
->expr
= build_call_expr_loc (input_location
,
5207 gfor_fndecl_associated
, 2,
5208 arg1se
.expr
, arg2se
.expr
);
5209 se
->expr
= convert (boolean_type_node
, se
->expr
);
5210 se
->expr
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
5211 boolean_type_node
, se
->expr
,
5215 /* If target is present zero character length pointers cannot
5217 if (nonzero_charlen
!= NULL_TREE
)
5218 se
->expr
= fold_build2_loc (input_location
, TRUTH_AND_EXPR
,
5220 se
->expr
, nonzero_charlen
);
5223 se
->expr
= convert (gfc_typenode_for_spec (&expr
->ts
), se
->expr
);
5227 /* Generate code for the SAME_TYPE_AS intrinsic.
5228 Generate inline code that directly checks the vindices. */
5231 gfc_conv_same_type_as (gfc_se
*se
, gfc_expr
*expr
)
5237 gfc_init_se (&se1
, NULL
);
5238 gfc_init_se (&se2
, NULL
);
5240 a
= expr
->value
.function
.actual
->expr
;
5241 b
= expr
->value
.function
.actual
->next
->expr
;
5243 if (a
->ts
.type
== BT_CLASS
)
5245 gfc_add_vptr_component (a
);
5246 gfc_add_hash_component (a
);
5248 else if (a
->ts
.type
== BT_DERIVED
)
5249 a
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
,
5250 a
->ts
.u
.derived
->hash_value
);
5252 if (b
->ts
.type
== BT_CLASS
)
5254 gfc_add_vptr_component (b
);
5255 gfc_add_hash_component (b
);
5257 else if (b
->ts
.type
== BT_DERIVED
)
5258 b
= gfc_get_int_expr (gfc_default_integer_kind
, NULL
,
5259 b
->ts
.u
.derived
->hash_value
);
5261 gfc_conv_expr (&se1
, a
);
5262 gfc_conv_expr (&se2
, b
);
5264 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
,
5265 se1
.expr
, fold_convert (TREE_TYPE (se1
.expr
), se2
.expr
));
5266 se
->expr
= convert (gfc_typenode_for_spec (&expr
->ts
), tmp
);
5270 /* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function. */
5273 gfc_conv_intrinsic_sc_kind (gfc_se
*se
, gfc_expr
*expr
)
5277 gfc_conv_intrinsic_function_args (se
, expr
, args
, 2);
5278 se
->expr
= build_call_expr_loc (input_location
,
5279 gfor_fndecl_sc_kind
, 2, args
[0], args
[1]);
5280 se
->expr
= fold_convert (gfc_typenode_for_spec (&expr
->ts
), se
->expr
);
5284 /* Generate code for SELECTED_INT_KIND (R) intrinsic function. */
5287 gfc_conv_intrinsic_si_kind (gfc_se
*se
, gfc_expr
*expr
)
5291 gfc_conv_intrinsic_function_args (se
, expr
, &arg
, 1);
5293 /* The argument to SELECTED_INT_KIND is INTEGER(4). */
5294 type
= gfc_get_int_type (4);
5295 arg
= gfc_build_addr_expr (NULL_TREE
, fold_convert (type
, arg
));
5297 /* Convert it to the required type. */
5298 type
= gfc_typenode_for_spec (&expr
->ts
);
5299 se
->expr
= build_call_expr_loc (input_location
,
5300 gfor_fndecl_si_kind
, 1, arg
);
5301 se
->expr
= fold_convert (type
, se
->expr
);
5305 /* Generate code for SELECTED_REAL_KIND (P, R) intrinsic function. */
5308 gfc_conv_intrinsic_sr_kind (gfc_se
*se
, gfc_expr
*expr
)
5310 gfc_actual_arglist
*actual
;
5313 VEC(tree
,gc
) *args
= NULL
;
5315 for (actual
= expr
->value
.function
.actual
; actual
; actual
= actual
->next
)
5317 gfc_init_se (&argse
, se
);
5319 /* Pass a NULL pointer for an absent arg. */
5320 if (actual
->expr
== NULL
)
5321 argse
.expr
= null_pointer_node
;
5327 if (actual
->expr
->ts
.kind
!= gfc_c_int_kind
)
5329 /* The arguments to SELECTED_REAL_KIND are INTEGER(4). */
5330 ts
.type
= BT_INTEGER
;
5331 ts
.kind
= gfc_c_int_kind
;
5332 gfc_convert_type (actual
->expr
, &ts
, 2);
5334 gfc_conv_expr_reference (&argse
, actual
->expr
);
5337 gfc_add_block_to_block (&se
->pre
, &argse
.pre
);
5338 gfc_add_block_to_block (&se
->post
, &argse
.post
);
5339 VEC_safe_push (tree
, gc
, args
, argse
.expr
);
5342 /* Convert it to the required type. */
5343 type
= gfc_typenode_for_spec (&expr
->ts
);
5344 se
->expr
= build_call_expr_loc_vec (input_location
,
5345 gfor_fndecl_sr_kind
, args
);
5346 se
->expr
= fold_convert (type
, se
->expr
);
5350 /* Generate code for TRIM (A) intrinsic function. */
5353 gfc_conv_intrinsic_trim (gfc_se
* se
, gfc_expr
* expr
)
5363 unsigned int num_args
;
5365 num_args
= gfc_intrinsic_argument_list_length (expr
) + 2;
5366 args
= XALLOCAVEC (tree
, num_args
);
5368 var
= gfc_create_var (gfc_get_pchar_type (expr
->ts
.kind
), "pstr");
5369 addr
= gfc_build_addr_expr (ppvoid_type_node
, var
);
5370 len
= gfc_create_var (gfc_charlen_type_node
, "len");
5372 gfc_conv_intrinsic_function_args (se
, expr
, &args
[2], num_args
- 2);
5373 args
[0] = gfc_build_addr_expr (NULL_TREE
, len
);
5376 if (expr
->ts
.kind
== 1)
5377 function
= gfor_fndecl_string_trim
;
5378 else if (expr
->ts
.kind
== 4)
5379 function
= gfor_fndecl_string_trim_char4
;
5383 fndecl
= build_addr (function
, current_function_decl
);
5384 tmp
= build_call_array_loc (input_location
,
5385 TREE_TYPE (TREE_TYPE (function
)), fndecl
,
5387 gfc_add_expr_to_block (&se
->pre
, tmp
);
5389 /* Free the temporary afterwards, if necessary. */
5390 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
5391 len
, build_int_cst (TREE_TYPE (len
), 0));
5392 tmp
= gfc_call_free (var
);
5393 tmp
= build3_v (COND_EXPR
, cond
, tmp
, build_empty_stmt (input_location
));
5394 gfc_add_expr_to_block (&se
->post
, tmp
);
5397 se
->string_length
= len
;
5401 /* Generate code for REPEAT (STRING, NCOPIES) intrinsic function. */
5404 gfc_conv_intrinsic_repeat (gfc_se
* se
, gfc_expr
* expr
)
5406 tree args
[3], ncopies
, dest
, dlen
, src
, slen
, ncopies_type
;
5407 tree type
, cond
, tmp
, count
, exit_label
, n
, max
, largest
;
5409 stmtblock_t block
, body
;
5412 /* We store in charsize the size of a character. */
5413 i
= gfc_validate_kind (BT_CHARACTER
, expr
->ts
.kind
, false);
5414 size
= build_int_cst (size_type_node
, gfc_character_kinds
[i
].bit_size
/ 8);
5416 /* Get the arguments. */
5417 gfc_conv_intrinsic_function_args (se
, expr
, args
, 3);
5418 slen
= fold_convert (size_type_node
, gfc_evaluate_now (args
[0], &se
->pre
));
5420 ncopies
= gfc_evaluate_now (args
[2], &se
->pre
);
5421 ncopies_type
= TREE_TYPE (ncopies
);
5423 /* Check that NCOPIES is not negative. */
5424 cond
= fold_build2_loc (input_location
, LT_EXPR
, boolean_type_node
, ncopies
,
5425 build_int_cst (ncopies_type
, 0));
5426 gfc_trans_runtime_check (true, false, cond
, &se
->pre
, &expr
->where
,
5427 "Argument NCOPIES of REPEAT intrinsic is negative "
5428 "(its value is %lld)",
5429 fold_convert (long_integer_type_node
, ncopies
));
5431 /* If the source length is zero, any non negative value of NCOPIES
5432 is valid, and nothing happens. */
5433 n
= gfc_create_var (ncopies_type
, "ncopies");
5434 cond
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, slen
,
5435 build_int_cst (size_type_node
, 0));
5436 tmp
= fold_build3_loc (input_location
, COND_EXPR
, ncopies_type
, cond
,
5437 build_int_cst (ncopies_type
, 0), ncopies
);
5438 gfc_add_modify (&se
->pre
, n
, tmp
);
5441 /* Check that ncopies is not too large: ncopies should be less than
5442 (or equal to) MAX / slen, where MAX is the maximal integer of
5443 the gfc_charlen_type_node type. If slen == 0, we need a special
5444 case to avoid the division by zero. */
5445 i
= gfc_validate_kind (BT_INTEGER
, gfc_charlen_int_kind
, false);
5446 max
= gfc_conv_mpz_to_tree (gfc_integer_kinds
[i
].huge
, gfc_charlen_int_kind
);
5447 max
= fold_build2_loc (input_location
, TRUNC_DIV_EXPR
, size_type_node
,
5448 fold_convert (size_type_node
, max
), slen
);
5449 largest
= TYPE_PRECISION (size_type_node
) > TYPE_PRECISION (ncopies_type
)
5450 ? size_type_node
: ncopies_type
;
5451 cond
= fold_build2_loc (input_location
, GT_EXPR
, boolean_type_node
,
5452 fold_convert (largest
, ncopies
),
5453 fold_convert (largest
, max
));
5454 tmp
= fold_build2_loc (input_location
, EQ_EXPR
, boolean_type_node
, slen
,
5455 build_int_cst (size_type_node
, 0));
5456 cond
= fold_build3_loc (input_location
, COND_EXPR
, boolean_type_node
, tmp
,
5457 boolean_false_node
, cond
);
5458 gfc_trans_runtime_check (true, false, cond
, &se
->pre
, &expr
->where
,
5459 "Argument NCOPIES of REPEAT intrinsic is too large");
5461 /* Compute the destination length. */
5462 dlen
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_charlen_type_node
,
5463 fold_convert (gfc_charlen_type_node
, slen
),
5464 fold_convert (gfc_charlen_type_node
, ncopies
));
5465 type
= gfc_get_character_type (expr
->ts
.kind
, expr
->ts
.u
.cl
);
5466 dest
= gfc_conv_string_tmp (se
, build_pointer_type (type
), dlen
);
5468 /* Generate the code to do the repeat operation:
5469 for (i = 0; i < ncopies; i++)
5470 memmove (dest + (i * slen * size), src, slen*size); */
5471 gfc_start_block (&block
);
5472 count
= gfc_create_var (ncopies_type
, "count");
5473 gfc_add_modify (&block
, count
, build_int_cst (ncopies_type
, 0));
5474 exit_label
= gfc_build_label_decl (NULL_TREE
);
5476 /* Start the loop body. */
5477 gfc_start_block (&body
);
5479 /* Exit the loop if count >= ncopies. */
5480 cond
= fold_build2_loc (input_location
, GE_EXPR
, boolean_type_node
, count
,
5482 tmp
= build1_v (GOTO_EXPR
, exit_label
);
5483 TREE_USED (exit_label
) = 1;
5484 tmp
= fold_build3_loc (input_location
, COND_EXPR
, void_type_node
, cond
, tmp
,
5485 build_empty_stmt (input_location
));
5486 gfc_add_expr_to_block (&body
, tmp
);
5488 /* Call memmove (dest + (i*slen*size), src, slen*size). */
5489 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_charlen_type_node
,
5490 fold_convert (gfc_charlen_type_node
, slen
),
5491 fold_convert (gfc_charlen_type_node
, count
));
5492 tmp
= fold_build2_loc (input_location
, MULT_EXPR
, gfc_charlen_type_node
,
5493 tmp
, fold_convert (gfc_charlen_type_node
, size
));
5494 tmp
= fold_build2_loc (input_location
, POINTER_PLUS_EXPR
, pvoid_type_node
,
5495 fold_convert (pvoid_type_node
, dest
),
5496 fold_convert (sizetype
, tmp
));
5497 tmp
= build_call_expr_loc (input_location
,
5498 built_in_decls
[BUILT_IN_MEMMOVE
], 3, tmp
, src
,
5499 fold_build2_loc (input_location
, MULT_EXPR
,
5500 size_type_node
, slen
,
5501 fold_convert (size_type_node
,
5503 gfc_add_expr_to_block (&body
, tmp
);
5505 /* Increment count. */
5506 tmp
= fold_build2_loc (input_location
, PLUS_EXPR
, ncopies_type
,
5507 count
, build_int_cst (TREE_TYPE (count
), 1));
5508 gfc_add_modify (&body
, count
, tmp
);
5510 /* Build the loop. */
5511 tmp
= build1_v (LOOP_EXPR
, gfc_finish_block (&body
));
5512 gfc_add_expr_to_block (&block
, tmp
);
5514 /* Add the exit label. */
5515 tmp
= build1_v (LABEL_EXPR
, exit_label
);
5516 gfc_add_expr_to_block (&block
, tmp
);
5518 /* Finish the block. */
5519 tmp
= gfc_finish_block (&block
);
5520 gfc_add_expr_to_block (&se
->pre
, tmp
);
5522 /* Set the result value. */
5524 se
->string_length
= dlen
;
5528 /* Generate code for the IARGC intrinsic. */
5531 gfc_conv_intrinsic_iargc (gfc_se
* se
, gfc_expr
* expr
)
5537 /* Call the library function. This always returns an INTEGER(4). */
5538 fndecl
= gfor_fndecl_iargc
;
5539 tmp
= build_call_expr_loc (input_location
,
5542 /* Convert it to the required type. */
5543 type
= gfc_typenode_for_spec (&expr
->ts
);
5544 tmp
= fold_convert (type
, tmp
);
5550 /* The loc intrinsic returns the address of its argument as
5551 gfc_index_integer_kind integer. */
5554 gfc_conv_intrinsic_loc (gfc_se
* se
, gfc_expr
* expr
)
5560 gcc_assert (!se
->ss
);
5562 arg_expr
= expr
->value
.function
.actual
->expr
;
5563 ss
= gfc_walk_expr (arg_expr
);
5564 if (ss
== gfc_ss_terminator
)
5565 gfc_conv_expr_reference (se
, arg_expr
);
5567 gfc_conv_array_parameter (se
, arg_expr
, ss
, true, NULL
, NULL
, NULL
);
5568 se
->expr
= convert (gfc_get_int_type (gfc_index_integer_kind
), se
->expr
);
5570 /* Create a temporary variable for loc return value. Without this,
5571 we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1). */
5572 temp_var
= gfc_create_var (gfc_get_int_type (gfc_index_integer_kind
), NULL
);
5573 gfc_add_modify (&se
->pre
, temp_var
, se
->expr
);
5574 se
->expr
= temp_var
;
5577 /* Generate code for an intrinsic function. Some map directly to library
5578 calls, others get special handling. In some cases the name of the function
5579 used depends on the type specifiers. */
5582 gfc_conv_intrinsic_function (gfc_se
* se
, gfc_expr
* expr
)
5588 name
= &expr
->value
.function
.name
[2];
5592 lib
= gfc_is_intrinsic_libcall (expr
);
5596 se
->ignore_optional
= 1;
5598 switch (expr
->value
.function
.isym
->id
)
5600 case GFC_ISYM_EOSHIFT
:
5602 case GFC_ISYM_RESHAPE
:
5603 /* For all of those the first argument specifies the type and the
5604 third is optional. */
5605 conv_generic_with_optional_char_arg (se
, expr
, 1, 3);
5609 gfc_conv_intrinsic_funcall (se
, expr
);
5617 switch (expr
->value
.function
.isym
->id
)
5622 case GFC_ISYM_REPEAT
:
5623 gfc_conv_intrinsic_repeat (se
, expr
);
5627 gfc_conv_intrinsic_trim (se
, expr
);
5630 case GFC_ISYM_SC_KIND
:
5631 gfc_conv_intrinsic_sc_kind (se
, expr
);
5634 case GFC_ISYM_SI_KIND
:
5635 gfc_conv_intrinsic_si_kind (se
, expr
);
5638 case GFC_ISYM_SR_KIND
:
5639 gfc_conv_intrinsic_sr_kind (se
, expr
);
5642 case GFC_ISYM_EXPONENT
:
5643 gfc_conv_intrinsic_exponent (se
, expr
);
5647 kind
= expr
->value
.function
.actual
->expr
->ts
.kind
;
5649 fndecl
= gfor_fndecl_string_scan
;
5651 fndecl
= gfor_fndecl_string_scan_char4
;
5655 gfc_conv_intrinsic_index_scan_verify (se
, expr
, fndecl
);
5658 case GFC_ISYM_VERIFY
:
5659 kind
= expr
->value
.function
.actual
->expr
->ts
.kind
;
5661 fndecl
= gfor_fndecl_string_verify
;
5663 fndecl
= gfor_fndecl_string_verify_char4
;
5667 gfc_conv_intrinsic_index_scan_verify (se
, expr
, fndecl
);
5670 case GFC_ISYM_ALLOCATED
:
5671 gfc_conv_allocated (se
, expr
);
5674 case GFC_ISYM_ASSOCIATED
:
5675 gfc_conv_associated(se
, expr
);
5678 case GFC_ISYM_SAME_TYPE_AS
:
5679 gfc_conv_same_type_as (se
, expr
);
5683 gfc_conv_intrinsic_abs (se
, expr
);
5686 case GFC_ISYM_ADJUSTL
:
5687 if (expr
->ts
.kind
== 1)
5688 fndecl
= gfor_fndecl_adjustl
;
5689 else if (expr
->ts
.kind
== 4)
5690 fndecl
= gfor_fndecl_adjustl_char4
;
5694 gfc_conv_intrinsic_adjust (se
, expr
, fndecl
);
5697 case GFC_ISYM_ADJUSTR
:
5698 if (expr
->ts
.kind
== 1)
5699 fndecl
= gfor_fndecl_adjustr
;
5700 else if (expr
->ts
.kind
== 4)
5701 fndecl
= gfor_fndecl_adjustr_char4
;
5705 gfc_conv_intrinsic_adjust (se
, expr
, fndecl
);
5708 case GFC_ISYM_AIMAG
:
5709 gfc_conv_intrinsic_imagpart (se
, expr
);
5713 gfc_conv_intrinsic_aint (se
, expr
, RND_TRUNC
);
5717 gfc_conv_intrinsic_anyall (se
, expr
, EQ_EXPR
);
5720 case GFC_ISYM_ANINT
:
5721 gfc_conv_intrinsic_aint (se
, expr
, RND_ROUND
);
5725 gfc_conv_intrinsic_bitop (se
, expr
, BIT_AND_EXPR
);
5729 gfc_conv_intrinsic_anyall (se
, expr
, NE_EXPR
);
5732 case GFC_ISYM_BTEST
:
5733 gfc_conv_intrinsic_btest (se
, expr
);
5737 gfc_conv_intrinsic_bitcomp (se
, expr
, GE_EXPR
);
5741 gfc_conv_intrinsic_bitcomp (se
, expr
, GT_EXPR
);
5745 gfc_conv_intrinsic_bitcomp (se
, expr
, LE_EXPR
);
5749 gfc_conv_intrinsic_bitcomp (se
, expr
, LT_EXPR
);
5752 case GFC_ISYM_ACHAR
:
5754 gfc_conv_intrinsic_char (se
, expr
);
5757 case GFC_ISYM_CONVERSION
:
5759 case GFC_ISYM_LOGICAL
:
5761 gfc_conv_intrinsic_conversion (se
, expr
);
5764 /* Integer conversions are handled separately to make sure we get the
5765 correct rounding mode. */
5770 gfc_conv_intrinsic_int (se
, expr
, RND_TRUNC
);
5774 gfc_conv_intrinsic_int (se
, expr
, RND_ROUND
);
5777 case GFC_ISYM_CEILING
:
5778 gfc_conv_intrinsic_int (se
, expr
, RND_CEIL
);
5781 case GFC_ISYM_FLOOR
:
5782 gfc_conv_intrinsic_int (se
, expr
, RND_FLOOR
);
5786 gfc_conv_intrinsic_mod (se
, expr
, 0);
5789 case GFC_ISYM_MODULO
:
5790 gfc_conv_intrinsic_mod (se
, expr
, 1);
5793 case GFC_ISYM_CMPLX
:
5794 gfc_conv_intrinsic_cmplx (se
, expr
, name
[5] == '1');
5797 case GFC_ISYM_COMMAND_ARGUMENT_COUNT
:
5798 gfc_conv_intrinsic_iargc (se
, expr
);
5801 case GFC_ISYM_COMPLEX
:
5802 gfc_conv_intrinsic_cmplx (se
, expr
, 1);
5805 case GFC_ISYM_CONJG
:
5806 gfc_conv_intrinsic_conjg (se
, expr
);
5809 case GFC_ISYM_COUNT
:
5810 gfc_conv_intrinsic_count (se
, expr
);
5813 case GFC_ISYM_CTIME
:
5814 gfc_conv_intrinsic_ctime (se
, expr
);
5818 gfc_conv_intrinsic_dim (se
, expr
);
5821 case GFC_ISYM_DOT_PRODUCT
:
5822 gfc_conv_intrinsic_dot_product (se
, expr
);
5825 case GFC_ISYM_DPROD
:
5826 gfc_conv_intrinsic_dprod (se
, expr
);
5829 case GFC_ISYM_DSHIFTL
:
5830 gfc_conv_intrinsic_dshift (se
, expr
, true);
5833 case GFC_ISYM_DSHIFTR
:
5834 gfc_conv_intrinsic_dshift (se
, expr
, false);
5837 case GFC_ISYM_FDATE
:
5838 gfc_conv_intrinsic_fdate (se
, expr
);
5841 case GFC_ISYM_FRACTION
:
5842 gfc_conv_intrinsic_fraction (se
, expr
);
5846 gfc_conv_intrinsic_arith (se
, expr
, BIT_AND_EXPR
, false);
5850 gfc_conv_intrinsic_bitop (se
, expr
, BIT_AND_EXPR
);
5854 gfc_conv_intrinsic_arith (se
, expr
, BIT_IOR_EXPR
, false);
5857 case GFC_ISYM_IBCLR
:
5858 gfc_conv_intrinsic_singlebitop (se
, expr
, 0);
5861 case GFC_ISYM_IBITS
:
5862 gfc_conv_intrinsic_ibits (se
, expr
);
5865 case GFC_ISYM_IBSET
:
5866 gfc_conv_intrinsic_singlebitop (se
, expr
, 1);
5869 case GFC_ISYM_IACHAR
:
5870 case GFC_ISYM_ICHAR
:
5871 /* We assume ASCII character sequence. */
5872 gfc_conv_intrinsic_ichar (se
, expr
);
5875 case GFC_ISYM_IARGC
:
5876 gfc_conv_intrinsic_iargc (se
, expr
);
5880 gfc_conv_intrinsic_bitop (se
, expr
, BIT_XOR_EXPR
);
5883 case GFC_ISYM_INDEX
:
5884 kind
= expr
->value
.function
.actual
->expr
->ts
.kind
;
5886 fndecl
= gfor_fndecl_string_index
;
5888 fndecl
= gfor_fndecl_string_index_char4
;
5892 gfc_conv_intrinsic_index_scan_verify (se
, expr
, fndecl
);
5896 gfc_conv_intrinsic_bitop (se
, expr
, BIT_IOR_EXPR
);
5899 case GFC_ISYM_IPARITY
:
5900 gfc_conv_intrinsic_arith (se
, expr
, BIT_XOR_EXPR
, false);
5903 case GFC_ISYM_IS_IOSTAT_END
:
5904 gfc_conv_has_intvalue (se
, expr
, LIBERROR_END
);
5907 case GFC_ISYM_IS_IOSTAT_EOR
:
5908 gfc_conv_has_intvalue (se
, expr
, LIBERROR_EOR
);
5911 case GFC_ISYM_ISNAN
:
5912 gfc_conv_intrinsic_isnan (se
, expr
);
5915 case GFC_ISYM_LSHIFT
:
5916 gfc_conv_intrinsic_shift (se
, expr
, false, false);
5919 case GFC_ISYM_RSHIFT
:
5920 gfc_conv_intrinsic_shift (se
, expr
, true, true);
5923 case GFC_ISYM_SHIFTA
:
5924 gfc_conv_intrinsic_shift (se
, expr
, true, true);
5927 case GFC_ISYM_SHIFTL
:
5928 gfc_conv_intrinsic_shift (se
, expr
, false, false);
5931 case GFC_ISYM_SHIFTR
:
5932 gfc_conv_intrinsic_shift (se
, expr
, true, false);
5935 case GFC_ISYM_ISHFT
:
5936 gfc_conv_intrinsic_ishft (se
, expr
);
5939 case GFC_ISYM_ISHFTC
:
5940 gfc_conv_intrinsic_ishftc (se
, expr
);
5943 case GFC_ISYM_LEADZ
:
5944 gfc_conv_intrinsic_leadz (se
, expr
);
5947 case GFC_ISYM_TRAILZ
:
5948 gfc_conv_intrinsic_trailz (se
, expr
);
5951 case GFC_ISYM_POPCNT
:
5952 gfc_conv_intrinsic_popcnt_poppar (se
, expr
, 0);
5955 case GFC_ISYM_POPPAR
:
5956 gfc_conv_intrinsic_popcnt_poppar (se
, expr
, 1);
5959 case GFC_ISYM_LBOUND
:
5960 gfc_conv_intrinsic_bound (se
, expr
, 0);
5963 case GFC_ISYM_TRANSPOSE
:
5964 /* The scalarizer has already been set up for reversed dimension access
5965 order ; now we just get the argument value normally. */
5966 gfc_conv_expr (se
, expr
->value
.function
.actual
->expr
);
5970 gfc_conv_intrinsic_len (se
, expr
);
5973 case GFC_ISYM_LEN_TRIM
:
5974 gfc_conv_intrinsic_len_trim (se
, expr
);
5978 gfc_conv_intrinsic_strcmp (se
, expr
, GE_EXPR
);
5982 gfc_conv_intrinsic_strcmp (se
, expr
, GT_EXPR
);
5986 gfc_conv_intrinsic_strcmp (se
, expr
, LE_EXPR
);
5990 gfc_conv_intrinsic_strcmp (se
, expr
, LT_EXPR
);
5993 case GFC_ISYM_MASKL
:
5994 gfc_conv_intrinsic_mask (se
, expr
, 1);
5997 case GFC_ISYM_MASKR
:
5998 gfc_conv_intrinsic_mask (se
, expr
, 0);
6002 if (expr
->ts
.type
== BT_CHARACTER
)
6003 gfc_conv_intrinsic_minmax_char (se
, expr
, 1);
6005 gfc_conv_intrinsic_minmax (se
, expr
, GT_EXPR
);
6008 case GFC_ISYM_MAXLOC
:
6009 gfc_conv_intrinsic_minmaxloc (se
, expr
, GT_EXPR
);
6012 case GFC_ISYM_MAXVAL
:
6013 gfc_conv_intrinsic_minmaxval (se
, expr
, GT_EXPR
);
6016 case GFC_ISYM_MERGE
:
6017 gfc_conv_intrinsic_merge (se
, expr
);
6020 case GFC_ISYM_MERGE_BITS
:
6021 gfc_conv_intrinsic_merge_bits (se
, expr
);
6025 if (expr
->ts
.type
== BT_CHARACTER
)
6026 gfc_conv_intrinsic_minmax_char (se
, expr
, -1);
6028 gfc_conv_intrinsic_minmax (se
, expr
, LT_EXPR
);
6031 case GFC_ISYM_MINLOC
:
6032 gfc_conv_intrinsic_minmaxloc (se
, expr
, LT_EXPR
);
6035 case GFC_ISYM_MINVAL
:
6036 gfc_conv_intrinsic_minmaxval (se
, expr
, LT_EXPR
);
6039 case GFC_ISYM_NEAREST
:
6040 gfc_conv_intrinsic_nearest (se
, expr
);
6043 case GFC_ISYM_NORM2
:
6044 gfc_conv_intrinsic_arith (se
, expr
, PLUS_EXPR
, true);
6048 gfc_conv_intrinsic_not (se
, expr
);
6052 gfc_conv_intrinsic_bitop (se
, expr
, BIT_IOR_EXPR
);
6055 case GFC_ISYM_PARITY
:
6056 gfc_conv_intrinsic_arith (se
, expr
, NE_EXPR
, false);
6059 case GFC_ISYM_PRESENT
:
6060 gfc_conv_intrinsic_present (se
, expr
);
6063 case GFC_ISYM_PRODUCT
:
6064 gfc_conv_intrinsic_arith (se
, expr
, MULT_EXPR
, false);
6067 case GFC_ISYM_RRSPACING
:
6068 gfc_conv_intrinsic_rrspacing (se
, expr
);
6071 case GFC_ISYM_SET_EXPONENT
:
6072 gfc_conv_intrinsic_set_exponent (se
, expr
);
6075 case GFC_ISYM_SCALE
:
6076 gfc_conv_intrinsic_scale (se
, expr
);
6080 gfc_conv_intrinsic_sign (se
, expr
);
6084 gfc_conv_intrinsic_size (se
, expr
);
6087 case GFC_ISYM_SIZEOF
:
6088 case GFC_ISYM_C_SIZEOF
:
6089 gfc_conv_intrinsic_sizeof (se
, expr
);
6092 case GFC_ISYM_STORAGE_SIZE
:
6093 gfc_conv_intrinsic_storage_size (se
, expr
);
6096 case GFC_ISYM_SPACING
:
6097 gfc_conv_intrinsic_spacing (se
, expr
);
6101 gfc_conv_intrinsic_arith (se
, expr
, PLUS_EXPR
, false);
6104 case GFC_ISYM_TRANSFER
:
6105 if (se
->ss
&& se
->ss
->useflags
)
6106 /* Access the previously obtained result. */
6107 gfc_conv_tmp_array_ref (se
);
6109 gfc_conv_intrinsic_transfer (se
, expr
);
6112 case GFC_ISYM_TTYNAM
:
6113 gfc_conv_intrinsic_ttynam (se
, expr
);
6116 case GFC_ISYM_UBOUND
:
6117 gfc_conv_intrinsic_bound (se
, expr
, 1);
6121 gfc_conv_intrinsic_bitop (se
, expr
, BIT_XOR_EXPR
);
6125 gfc_conv_intrinsic_loc (se
, expr
);
6128 case GFC_ISYM_THIS_IMAGE
:
6129 trans_this_image (se
, expr
);
6132 case GFC_ISYM_NUM_IMAGES
:
6133 trans_num_images (se
);
6136 case GFC_ISYM_ACCESS
:
6137 case GFC_ISYM_CHDIR
:
6138 case GFC_ISYM_CHMOD
:
6139 case GFC_ISYM_DTIME
:
6140 case GFC_ISYM_ETIME
:
6141 case GFC_ISYM_EXTENDS_TYPE_OF
:
6143 case GFC_ISYM_FGETC
:
6146 case GFC_ISYM_FPUTC
:
6147 case GFC_ISYM_FSTAT
:
6148 case GFC_ISYM_FTELL
:
6149 case GFC_ISYM_GETCWD
:
6150 case GFC_ISYM_GETGID
:
6151 case GFC_ISYM_GETPID
:
6152 case GFC_ISYM_GETUID
:
6153 case GFC_ISYM_HOSTNM
:
6155 case GFC_ISYM_IERRNO
:
6156 case GFC_ISYM_IRAND
:
6157 case GFC_ISYM_ISATTY
:
6160 case GFC_ISYM_LSTAT
:
6161 case GFC_ISYM_MALLOC
:
6162 case GFC_ISYM_MATMUL
:
6163 case GFC_ISYM_MCLOCK
:
6164 case GFC_ISYM_MCLOCK8
:
6166 case GFC_ISYM_RENAME
:
6167 case GFC_ISYM_SECOND
:
6168 case GFC_ISYM_SECNDS
:
6169 case GFC_ISYM_SIGNAL
:
6171 case GFC_ISYM_SYMLNK
:
6172 case GFC_ISYM_SYSTEM
:
6174 case GFC_ISYM_TIME8
:
6175 case GFC_ISYM_UMASK
:
6176 case GFC_ISYM_UNLINK
:
6178 gfc_conv_intrinsic_funcall (se
, expr
);
6181 case GFC_ISYM_EOSHIFT
:
6183 case GFC_ISYM_RESHAPE
:
6184 /* For those, expr->rank should always be >0 and thus the if above the
6185 switch should have matched. */
6190 gfc_conv_intrinsic_lib_function (se
, expr
);
6197 walk_inline_intrinsic_transpose (gfc_ss
*ss
, gfc_expr
*expr
)
6199 gfc_ss
*arg_ss
, *tmp_ss
;
6200 gfc_actual_arglist
*arg
;
6202 arg
= expr
->value
.function
.actual
;
6204 gcc_assert (arg
->expr
);
6206 arg_ss
= gfc_walk_subexpr (gfc_ss_terminator
, arg
->expr
);
6207 gcc_assert (arg_ss
!= gfc_ss_terminator
);
6209 for (tmp_ss
= arg_ss
; ; tmp_ss
= tmp_ss
->next
)
6211 if (tmp_ss
->type
!= GFC_SS_SCALAR
6212 && tmp_ss
->type
!= GFC_SS_REFERENCE
)
6217 info
= &tmp_ss
->data
.info
;
6218 gcc_assert (info
->dimen
== 2);
6220 /* We just invert dimensions. */
6221 tmp_dim
= info
->dim
[0];
6222 info
->dim
[0] = info
->dim
[1];
6223 info
->dim
[1] = tmp_dim
;
6226 /* Stop when tmp_ss points to the last valid element of the chain... */
6227 if (tmp_ss
->next
== gfc_ss_terminator
)
6231 /* ... so that we can attach the rest of the chain to it. */
6239 walk_inline_intrinsic_function (gfc_ss
* ss
, gfc_expr
* expr
)
6242 switch (expr
->value
.function
.isym
->id
)
6244 case GFC_ISYM_TRANSPOSE
:
6245 return walk_inline_intrinsic_transpose (ss
, expr
);
6254 /* This generates code to execute before entering the scalarization loop.
6255 Currently does nothing. */
6258 gfc_add_intrinsic_ss_code (gfc_loopinfo
* loop ATTRIBUTE_UNUSED
, gfc_ss
* ss
)
6260 switch (ss
->expr
->value
.function
.isym
->id
)
6262 case GFC_ISYM_UBOUND
:
6263 case GFC_ISYM_LBOUND
:
6272 /* UBOUND and LBOUND intrinsics with one parameter are expanded into code
6273 inside the scalarization loop. */
6276 gfc_walk_intrinsic_bound (gfc_ss
* ss
, gfc_expr
* expr
)
6280 /* The two argument version returns a scalar. */
6281 if (expr
->value
.function
.actual
->next
->expr
)
6284 newss
= gfc_get_ss ();
6285 newss
->type
= GFC_SS_INTRINSIC
;
6288 newss
->data
.info
.dimen
= 1;
6294 /* Walk an intrinsic array libcall. */
6297 gfc_walk_intrinsic_libfunc (gfc_ss
* ss
, gfc_expr
* expr
)
6302 gcc_assert (expr
->rank
> 0);
6304 newss
= gfc_get_ss ();
6305 newss
->type
= GFC_SS_FUNCTION
;
6308 newss
->data
.info
.dimen
= expr
->rank
;
6309 for (n
= 0; n
< newss
->data
.info
.dimen
; n
++)
6310 newss
->data
.info
.dim
[n
] = n
;
6316 /* Return whether the function call expression EXPR will be expanded
6317 inline by gfc_conv_intrinsic_function. */
6320 gfc_inline_intrinsic_function_p (gfc_expr
*expr
)
6322 if (!expr
->value
.function
.isym
)
6325 switch (expr
->value
.function
.isym
->id
)
6327 case GFC_ISYM_TRANSPOSE
:
6336 /* Returns nonzero if the specified intrinsic function call maps directly to
6337 an external library call. Should only be used for functions that return
6341 gfc_is_intrinsic_libcall (gfc_expr
* expr
)
6343 gcc_assert (expr
->expr_type
== EXPR_FUNCTION
&& expr
->value
.function
.isym
);
6344 gcc_assert (expr
->rank
> 0);
6346 if (gfc_inline_intrinsic_function_p (expr
))
6349 switch (expr
->value
.function
.isym
->id
)
6353 case GFC_ISYM_COUNT
:
6357 case GFC_ISYM_IPARITY
:
6358 case GFC_ISYM_MATMUL
:
6359 case GFC_ISYM_MAXLOC
:
6360 case GFC_ISYM_MAXVAL
:
6361 case GFC_ISYM_MINLOC
:
6362 case GFC_ISYM_MINVAL
:
6363 case GFC_ISYM_NORM2
:
6364 case GFC_ISYM_PARITY
:
6365 case GFC_ISYM_PRODUCT
:
6367 case GFC_ISYM_SHAPE
:
6368 case GFC_ISYM_SPREAD
:
6370 /* Ignore absent optional parameters. */
6373 case GFC_ISYM_RESHAPE
:
6374 case GFC_ISYM_CSHIFT
:
6375 case GFC_ISYM_EOSHIFT
:
6377 case GFC_ISYM_UNPACK
:
6378 /* Pass absent optional parameters. */
6386 /* Walk an intrinsic function. */
6388 gfc_walk_intrinsic_function (gfc_ss
* ss
, gfc_expr
* expr
,
6389 gfc_intrinsic_sym
* isym
)
6393 if (isym
->elemental
)
6394 return gfc_walk_elemental_function_args (ss
, expr
->value
.function
.actual
,
6397 if (expr
->rank
== 0)
6400 if (gfc_inline_intrinsic_function_p (expr
))
6401 return walk_inline_intrinsic_function (ss
, expr
);
6403 if (gfc_is_intrinsic_libcall (expr
))
6404 return gfc_walk_intrinsic_libfunc (ss
, expr
);
6406 /* Special cases. */
6409 case GFC_ISYM_LBOUND
:
6410 case GFC_ISYM_UBOUND
:
6411 return gfc_walk_intrinsic_bound (ss
, expr
);
6413 case GFC_ISYM_TRANSFER
:
6414 return gfc_walk_intrinsic_libfunc (ss
, expr
);
6417 /* This probably meant someone forgot to add an intrinsic to the above
6418 list(s) when they implemented it, or something's gone horribly
6426 gfc_conv_intrinsic_move_alloc (gfc_code
*code
)
6428 if (code
->ext
.actual
->expr
->rank
== 0)
6430 /* Scalar arguments: Generate pointer assignments. */
6431 gfc_expr
*from
, *to
;
6435 from
= code
->ext
.actual
->expr
;
6436 to
= code
->ext
.actual
->next
->expr
;
6438 gfc_start_block (&block
);
6440 if (to
->ts
.type
== BT_CLASS
)
6441 tmp
= gfc_trans_class_assign (to
, from
, EXEC_POINTER_ASSIGN
);
6443 tmp
= gfc_trans_pointer_assignment (to
, from
);
6444 gfc_add_expr_to_block (&block
, tmp
);
6446 if (from
->ts
.type
== BT_CLASS
)
6447 tmp
= gfc_trans_class_assign (from
, gfc_get_null_expr (NULL
),
6448 EXEC_POINTER_ASSIGN
);
6450 tmp
= gfc_trans_pointer_assignment (from
,
6451 gfc_get_null_expr (NULL
));
6452 gfc_add_expr_to_block (&block
, tmp
);
6454 return gfc_finish_block (&block
);
6457 /* Array arguments: Generate library code. */
6458 return gfc_trans_call (code
, false, NULL_TREE
, NULL_TREE
, false);
6462 #include "gt-fortran-trans-intrinsic.h"