]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fortran/simplify.c
PR 78534, 83704 Large character lengths
[thirdparty/gcc.git] / gcc / fortran / simplify.c
CommitLineData
6de9cd9a 1/* Simplify intrinsic functions at compile-time.
85ec4feb 2 Copyright (C) 2000-2018 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Andy Vaught & Katherine Holcomb
4
9fc4d79b 5This file is part of GCC.
6de9cd9a 6
9fc4d79b
TS
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
d234d788 9Software Foundation; either version 3, or (at your option) any later
9fc4d79b 10version.
6de9cd9a 11
9fc4d79b
TS
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
6de9cd9a
DN
16
17You should have received a copy of the GNU General Public License
d234d788
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
20
21#include "config.h"
22#include "system.h"
953bee7c 23#include "coretypes.h"
2adfab87 24#include "tm.h" /* For BITS_PER_UNIT. */
6de9cd9a
DN
25#include "gfortran.h"
26#include "arith.h"
27#include "intrinsic.h"
7433458d 28#include "target-memory.h"
b7e75771 29#include "constructor.h"
1a8c1e35 30#include "version.h" /* For version_string. */
6de9cd9a 31
317fa064
TK
32/* Prototypes. */
33
a1d6c052 34static int min_max_choose (gfc_expr *, gfc_expr *, int);
7ba8c18c 35
6de9cd9a
DN
36gfc_expr gfc_bad_expr;
37
1634e53f
TB
38static gfc_expr *simplify_size (gfc_expr *, gfc_expr *, int);
39
6de9cd9a
DN
40
41/* Note that 'simplification' is not just transforming expressions.
42 For functions that are not simplified at compile time, range
43 checking is done if possible.
44
45 The return convention is that each simplification function returns:
46
47 A new expression node corresponding to the simplified arguments.
48 The original arguments are destroyed by the caller, and must not
49 be a part of the new expression.
50
51 NULL pointer indicating that no simplification was possible and
b7e75771 52 the original expression should remain intact.
6de9cd9a
DN
53
54 An expression pointer to gfc_bad_expr (a static placeholder)
b7e75771
JD
55 indicating that some error has prevented simplification. The
56 error is generated within the function and should be propagated
57 upwards
6de9cd9a
DN
58
59 By the time a simplification function gets control, it has been
60 decided that the function call is really supposed to be the
61 intrinsic. No type checking is strictly necessary, since only
62 valid types will be passed on. On the other hand, a simplification
63 subroutine may have to look at the type of an argument as part of
64 its processing.
65
b7e75771
JD
66 Array arguments are only passed to these subroutines that implement
67 the simplification of transformational intrinsics.
6de9cd9a
DN
68
69 The functions in this file don't have much comment with them, but
70 everything is reasonably straight-forward. The Standard, chapter 13
71 is the best comment you'll find for this file anyway. */
72
6de9cd9a
DN
73/* Range checks an expression node. If all goes well, returns the
74 node, otherwise returns &gfc_bad_expr and frees the node. */
75
76static gfc_expr *
edf1eac2 77range_check (gfc_expr *result, const char *name)
6de9cd9a 78{
e0f6835d
JD
79 if (result == NULL)
80 return &gfc_bad_expr;
81
69dcd06a
DK
82 if (result->expr_type != EXPR_CONSTANT)
83 return result;
84
54554825
JD
85 switch (gfc_range_check (result))
86 {
87 case ARITH_OK:
88 return result;
8b704316 89
54554825 90 case ARITH_OVERFLOW:
edf1eac2
SK
91 gfc_error ("Result of %s overflows its kind at %L", name,
92 &result->where);
54554825
JD
93 break;
94
95 case ARITH_UNDERFLOW:
edf1eac2
SK
96 gfc_error ("Result of %s underflows its kind at %L", name,
97 &result->where);
54554825
JD
98 break;
99
100 case ARITH_NAN:
101 gfc_error ("Result of %s is NaN at %L", name, &result->where);
102 break;
103
104 default:
edf1eac2
SK
105 gfc_error ("Result of %s gives range error for its kind at %L", name,
106 &result->where);
54554825
JD
107 break;
108 }
109
6de9cd9a
DN
110 gfc_free_expr (result);
111 return &gfc_bad_expr;
112}
113
114
115/* A helper function that gets an optional and possibly missing
116 kind parameter. Returns the kind, -1 if something went wrong. */
117
118static int
edf1eac2 119get_kind (bt type, gfc_expr *k, const char *name, int default_kind)
6de9cd9a
DN
120{
121 int kind;
122
123 if (k == NULL)
124 return default_kind;
125
126 if (k->expr_type != EXPR_CONSTANT)
127 {
128 gfc_error ("KIND parameter of %s at %L must be an initialization "
129 "expression", name, &k->where);
6de9cd9a
DN
130 return -1;
131 }
132
51f03c6b 133 if (gfc_extract_int (k, &kind)
e7a2d5fb 134 || gfc_validate_kind (type, kind, true) < 0)
6de9cd9a 135 {
6de9cd9a
DN
136 gfc_error ("Invalid KIND parameter of %s at %L", name, &k->where);
137 return -1;
138 }
139
140 return kind;
141}
142
143
f1dcb9bf
BM
144/* Converts an mpz_t signed variable into an unsigned one, assuming
145 two's complement representations and a binary width of bitsize.
146 The conversion is a no-op unless x is negative; otherwise, it can
147 be accomplished by masking out the high bits. */
5d24a977
TS
148
149static void
f1dcb9bf 150convert_mpz_to_unsigned (mpz_t x, int bitsize)
5d24a977
TS
151{
152 mpz_t mask;
5d24a977 153
f1dcb9bf
BM
154 if (mpz_sgn (x) < 0)
155 {
d01b2c21
TK
156 /* Confirm that no bits above the signed range are unset if we
157 are doing range checking. */
c61819ff 158 if (flag_range_check != 0)
d01b2c21 159 gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);
f1dcb9bf
BM
160
161 mpz_init_set_ui (mask, 1);
162 mpz_mul_2exp (mask, mask, bitsize);
163 mpz_sub_ui (mask, mask, 1);
164
165 mpz_and (x, x, mask);
166
167 mpz_clear (mask);
168 }
169 else
170 {
171 /* Confirm that no bits above the signed range are set. */
172 gcc_assert (mpz_scan1 (x, bitsize-1) == ULONG_MAX);
173 }
174}
175
176
177/* Converts an mpz_t unsigned variable into a signed one, assuming
178 two's complement representations and a binary width of bitsize.
179 If the bitsize-1 bit is set, this is taken as a sign bit and
180 the number is converted to the corresponding negative number. */
181
d01b2c21
TK
182void
183gfc_convert_mpz_to_signed (mpz_t x, int bitsize)
f1dcb9bf
BM
184{
185 mpz_t mask;
186
d01b2c21
TK
187 /* Confirm that no bits above the unsigned range are set if we are
188 doing range checking. */
c61819ff 189 if (flag_range_check != 0)
d01b2c21 190 gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);
f1dcb9bf 191
5d24a977
TS
192 if (mpz_tstbit (x, bitsize - 1) == 1)
193 {
f1dcb9bf
BM
194 mpz_init_set_ui (mask, 1);
195 mpz_mul_2exp (mask, mask, bitsize);
196 mpz_sub_ui (mask, mask, 1);
b7398e72
TS
197
198 /* We negate the number by hand, zeroing the high bits, that is
edf1eac2
SK
199 make it the corresponding positive number, and then have it
200 negated by GMP, giving the correct representation of the
201 negative number. */
5d24a977
TS
202 mpz_com (x, x);
203 mpz_add_ui (x, x, 1);
204 mpz_and (x, x, mask);
205
206 mpz_neg (x, x);
207
208 mpz_clear (mask);
209 }
210}
211
b7e75771
JD
212
213/* In-place convert BOZ to REAL of the specified kind. */
214
215static gfc_expr *
216convert_boz (gfc_expr *x, int kind)
217{
218 if (x && x->ts.type == BT_INTEGER && x->is_boz)
219 {
220 gfc_typespec ts;
221 gfc_clear_ts (&ts);
222 ts.type = BT_REAL;
223 ts.kind = kind;
224
225 if (!gfc_convert_boz (x, &ts))
226 return &gfc_bad_expr;
227 }
228
229 return x;
230}
231
232
a1d6c052 233/* Test that the expression is a constant array, simplifying if
6c6bde30 234 we are dealing with a parameter array. */
7ba8c18c
DF
235
236static bool
237is_constant_array_expr (gfc_expr *e)
238{
239 gfc_constructor *c;
240
241 if (e == NULL)
242 return true;
243
6c6bde30
TK
244 if (e->expr_type == EXPR_VARIABLE && e->rank > 0
245 && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
246 gfc_simplify_expr (e, 1);
247
7ba8c18c
DF
248 if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
249 return false;
250
b7e75771
JD
251 for (c = gfc_constructor_first (e->value.constructor);
252 c; c = gfc_constructor_next (c))
15c2ef5a
PT
253 if (c->expr->expr_type != EXPR_CONSTANT
254 && c->expr->expr_type != EXPR_STRUCTURE)
7ba8c18c
DF
255 return false;
256
257 return true;
258}
259
260
8ec259c1
DF
261/* Initialize a transformational result expression with a given value. */
262
263static void
264init_result_expr (gfc_expr *e, int init, gfc_expr *array)
265{
266 if (e && e->expr_type == EXPR_ARRAY)
267 {
b7e75771 268 gfc_constructor *ctor = gfc_constructor_first (e->value.constructor);
8ec259c1
DF
269 while (ctor)
270 {
271 init_result_expr (ctor->expr, init, array);
b7e75771 272 ctor = gfc_constructor_next (ctor);
8ec259c1
DF
273 }
274 }
275 else if (e && e->expr_type == EXPR_CONSTANT)
276 {
277 int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6b271a2e 278 HOST_WIDE_INT length;
8ec259c1
DF
279 gfc_char_t *string;
280
281 switch (e->ts.type)
282 {
283 case BT_LOGICAL:
284 e->value.logical = (init ? 1 : 0);
285 break;
286
287 case BT_INTEGER:
288 if (init == INT_MIN)
289 mpz_set (e->value.integer, gfc_integer_kinds[i].min_int);
290 else if (init == INT_MAX)
291 mpz_set (e->value.integer, gfc_integer_kinds[i].huge);
292 else
293 mpz_set_si (e->value.integer, init);
294 break;
295
296 case BT_REAL:
297 if (init == INT_MIN)
298 {
299 mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
300 mpfr_neg (e->value.real, e->value.real, GFC_RND_MODE);
301 }
302 else if (init == INT_MAX)
303 mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
304 else
305 mpfr_set_si (e->value.real, init, GFC_RND_MODE);
306 break;
307
308 case BT_COMPLEX:
eb6f9a86 309 mpc_set_si (e->value.complex, init, GFC_MPC_RND_MODE);
8ec259c1
DF
310 break;
311
312 case BT_CHARACTER:
313 if (init == INT_MIN)
314 {
315 gfc_expr *len = gfc_simplify_len (array, NULL);
6b271a2e 316 gfc_extract_hwi (len, &length);
8ec259c1
DF
317 string = gfc_get_wide_string (length + 1);
318 gfc_wide_memset (string, 0, length);
319 }
320 else if (init == INT_MAX)
321 {
322 gfc_expr *len = gfc_simplify_len (array, NULL);
6b271a2e 323 gfc_extract_hwi (len, &length);
8ec259c1
DF
324 string = gfc_get_wide_string (length + 1);
325 gfc_wide_memset (string, 255, length);
326 }
327 else
328 {
329 length = 0;
330 string = gfc_get_wide_string (1);
331 }
332
333 string[length] = '\0';
334 e->value.character.length = length;
335 e->value.character.string = string;
336 break;
337
338 default:
339 gcc_unreachable();
340 }
341 }
342 else
343 gcc_unreachable();
344}
345
346
eebb98a5
TB
347/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul;
348 if conj_a is true, the matrix_a is complex conjugated. */
8ec259c1
DF
349
350static gfc_expr *
b7e75771 351compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a,
eebb98a5
TB
352 gfc_expr *matrix_b, int stride_b, int offset_b,
353 bool conj_a)
8ec259c1 354{
eebb98a5 355 gfc_expr *result, *a, *b, *c;
8ec259c1 356
b7e75771
JD
357 result = gfc_get_constant_expr (matrix_a->ts.type, matrix_a->ts.kind,
358 &matrix_a->where);
8ec259c1
DF
359 init_result_expr (result, 0, NULL);
360
b7e75771
JD
361 a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
362 b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
363 while (a && b)
8ec259c1
DF
364 {
365 /* Copying of expressions is required as operands are free'd
366 by the gfc_arith routines. */
367 switch (result->ts.type)
368 {
369 case BT_LOGICAL:
370 result = gfc_or (result,
b7e75771
JD
371 gfc_and (gfc_copy_expr (a),
372 gfc_copy_expr (b)));
8ec259c1
DF
373 break;
374
375 case BT_INTEGER:
376 case BT_REAL:
377 case BT_COMPLEX:
eebb98a5
TB
378 if (conj_a && a->ts.type == BT_COMPLEX)
379 c = gfc_simplify_conjg (a);
380 else
381 c = gfc_copy_expr (a);
382 result = gfc_add (result, gfc_multiply (c, gfc_copy_expr (b)));
8ec259c1
DF
383 break;
384
385 default:
386 gcc_unreachable();
387 }
388
b7e75771
JD
389 offset_a += stride_a;
390 a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
391
392 offset_b += stride_b;
393 b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
8ec259c1
DF
394 }
395
396 return result;
397}
398
a16d978f 399
8b704316 400/* Build a result expression for transformational intrinsics,
1cc0e193 401 depending on DIM. */
a16d978f
DF
402
403static gfc_expr *
404transformational_result (gfc_expr *array, gfc_expr *dim, bt type,
405 int kind, locus* where)
406{
407 gfc_expr *result;
408 int i, nelem;
409
410 if (!dim || array->rank == 1)
b7e75771 411 return gfc_get_constant_expr (type, kind, where);
a16d978f 412
b7e75771 413 result = gfc_get_array_expr (type, kind, where);
a16d978f
DF
414 result->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
415 result->rank = array->rank - 1;
416
417 /* gfc_array_size() would count the number of elements in the constructor,
418 we have not built those yet. */
419 nelem = 1;
420 for (i = 0; i < result->rank; ++i)
421 nelem *= mpz_get_ui (result->shape[i]);
422
423 for (i = 0; i < nelem; ++i)
424 {
b7e75771
JD
425 gfc_constructor_append_expr (&result->value.constructor,
426 gfc_get_constant_expr (type, kind, where),
427 NULL);
a16d978f
DF
428 }
429
430 return result;
431}
432
433
434typedef gfc_expr* (*transformational_op)(gfc_expr*, gfc_expr*);
435
436/* Wrapper function, implements 'op1 += 1'. Only called if MASK
437 of COUNT intrinsic is .TRUE..
438
62732c30 439 Interface and implementation mimics arith functions as
a16d978f
DF
440 gfc_add, gfc_multiply, etc. */
441
317fa064
TK
442static gfc_expr *
443gfc_count (gfc_expr *op1, gfc_expr *op2)
a16d978f
DF
444{
445 gfc_expr *result;
446
447 gcc_assert (op1->ts.type == BT_INTEGER);
448 gcc_assert (op2->ts.type == BT_LOGICAL);
449 gcc_assert (op2->value.logical);
450
451 result = gfc_copy_expr (op1);
452 mpz_add_ui (result->value.integer, result->value.integer, 1);
453
454 gfc_free_expr (op1);
455 gfc_free_expr (op2);
456 return result;
457}
458
459
460/* Transforms an ARRAY with operation OP, according to MASK, to a
461 scalar RESULT. E.g. called if
462
463 REAL, PARAMETER :: array(n, m) = ...
464 REAL, PARAMETER :: s = SUM(array)
465
466 where OP == gfc_add(). */
467
468static gfc_expr *
469simplify_transformation_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
470 transformational_op op)
471{
472 gfc_expr *a, *m;
473 gfc_constructor *array_ctor, *mask_ctor;
474
475 /* Shortcut for constant .FALSE. MASK. */
476 if (mask
477 && mask->expr_type == EXPR_CONSTANT
478 && !mask->value.logical)
479 return result;
480
b7e75771 481 array_ctor = gfc_constructor_first (array->value.constructor);
a16d978f
DF
482 mask_ctor = NULL;
483 if (mask && mask->expr_type == EXPR_ARRAY)
b7e75771 484 mask_ctor = gfc_constructor_first (mask->value.constructor);
a16d978f
DF
485
486 while (array_ctor)
487 {
488 a = array_ctor->expr;
b7e75771 489 array_ctor = gfc_constructor_next (array_ctor);
a16d978f
DF
490
491 /* A constant MASK equals .TRUE. here and can be ignored. */
492 if (mask_ctor)
493 {
494 m = mask_ctor->expr;
b7e75771 495 mask_ctor = gfc_constructor_next (mask_ctor);
a16d978f
DF
496 if (!m->value.logical)
497 continue;
498 }
499
500 result = op (result, gfc_copy_expr (a));
e85921ee
SK
501 if (!result)
502 return result;
a16d978f
DF
503 }
504
505 return result;
506}
507
508/* Transforms an ARRAY with operation OP, according to MASK, to an
509 array RESULT. E.g. called if
510
511 REAL, PARAMETER :: array(n, m) = ...
512 REAL, PARAMETER :: s(n) = PROD(array, DIM=1)
513
1cc0e193
JV
514 where OP == gfc_multiply().
515 The result might be post processed using post_op. */
a16d978f
DF
516
517static gfc_expr *
518simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *dim,
0cd0559e
TB
519 gfc_expr *mask, transformational_op op,
520 transformational_op post_op)
a16d978f
DF
521{
522 mpz_t size;
523 int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
524 gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
525 gfc_constructor *array_ctor, *mask_ctor, *result_ctor;
526
527 int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
528 sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
529 tmpstride[GFC_MAX_DIMENSIONS];
530
531 /* Shortcut for constant .FALSE. MASK. */
532 if (mask
533 && mask->expr_type == EXPR_CONSTANT
534 && !mask->value.logical)
535 return result;
536
537 /* Build an indexed table for array element expressions to minimize
538 linked-list traversal. Masked elements are set to NULL. */
539 gfc_array_size (array, &size);
540 arraysize = mpz_get_ui (size);
9c85d38b 541 mpz_clear (size);
a16d978f 542
93acb62c 543 arrayvec = XCNEWVEC (gfc_expr*, arraysize);
a16d978f 544
b7e75771 545 array_ctor = gfc_constructor_first (array->value.constructor);
a16d978f
DF
546 mask_ctor = NULL;
547 if (mask && mask->expr_type == EXPR_ARRAY)
b7e75771 548 mask_ctor = gfc_constructor_first (mask->value.constructor);
a16d978f
DF
549
550 for (i = 0; i < arraysize; ++i)
551 {
552 arrayvec[i] = array_ctor->expr;
b7e75771 553 array_ctor = gfc_constructor_next (array_ctor);
a16d978f
DF
554
555 if (mask_ctor)
556 {
557 if (!mask_ctor->expr->value.logical)
558 arrayvec[i] = NULL;
559
b7e75771 560 mask_ctor = gfc_constructor_next (mask_ctor);
a16d978f
DF
561 }
562 }
563
564 /* Same for the result expression. */
565 gfc_array_size (result, &size);
566 resultsize = mpz_get_ui (size);
567 mpz_clear (size);
568
93acb62c 569 resultvec = XCNEWVEC (gfc_expr*, resultsize);
b7e75771 570 result_ctor = gfc_constructor_first (result->value.constructor);
a16d978f
DF
571 for (i = 0; i < resultsize; ++i)
572 {
573 resultvec[i] = result_ctor->expr;
b7e75771 574 result_ctor = gfc_constructor_next (result_ctor);
a16d978f
DF
575 }
576
577 gfc_extract_int (dim, &dim_index);
578 dim_index -= 1; /* zero-base index */
579 dim_extent = 0;
580 dim_stride = 0;
581
582 for (i = 0, n = 0; i < array->rank; ++i)
583 {
584 count[i] = 0;
585 tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
586 if (i == dim_index)
587 {
588 dim_extent = mpz_get_si (array->shape[i]);
589 dim_stride = tmpstride[i];
590 continue;
591 }
592
593 extent[n] = mpz_get_si (array->shape[i]);
594 sstride[n] = tmpstride[i];
595 dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
596 n += 1;
597 }
598
599 done = false;
600 base = arrayvec;
601 dest = resultvec;
602 while (!done)
603 {
604 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
605 if (*src)
606 *dest = op (*dest, gfc_copy_expr (*src));
607
608 count[0]++;
609 base += sstride[0];
610 dest += dstride[0];
611
612 n = 0;
613 while (!done && count[n] == extent[n])
614 {
615 count[n] = 0;
616 base -= sstride[n] * extent[n];
617 dest -= dstride[n] * extent[n];
618
619 n++;
620 if (n < result->rank)
621 {
e1d070a4
AO
622 /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
623 times, we'd warn for the last iteration, because the
624 array index will have already been incremented to the
625 array sizes, and we can't tell that this must make
626 the test against result->rank false, because ranks
627 must not exceed GFC_MAX_DIMENSIONS. */
75213cc0 628 GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
e1d070a4 629 count[n]++;
a16d978f
DF
630 base += sstride[n];
631 dest += dstride[n];
75213cc0 632 GCC_DIAGNOSTIC_POP
a16d978f
DF
633 }
634 else
635 done = true;
636 }
637 }
638
639 /* Place updated expression in result constructor. */
b7e75771 640 result_ctor = gfc_constructor_first (result->value.constructor);
a16d978f
DF
641 for (i = 0; i < resultsize; ++i)
642 {
0cd0559e
TB
643 if (post_op)
644 result_ctor->expr = post_op (result_ctor->expr, resultvec[i]);
645 else
646 result_ctor->expr = resultvec[i];
b7e75771 647 result_ctor = gfc_constructor_next (result_ctor);
a16d978f
DF
648 }
649
cede9502
JM
650 free (arrayvec);
651 free (resultvec);
a16d978f
DF
652 return result;
653}
654
655
195a95c4
TB
656static gfc_expr *
657simplify_transformation (gfc_expr *array, gfc_expr *dim, gfc_expr *mask,
658 int init_val, transformational_op op)
659{
660 gfc_expr *result;
661
662 if (!is_constant_array_expr (array)
663 || !gfc_is_constant_expr (dim))
664 return NULL;
665
666 if (mask
667 && !is_constant_array_expr (mask)
668 && mask->expr_type != EXPR_CONSTANT)
669 return NULL;
670
671 result = transformational_result (array, dim, array->ts.type,
672 array->ts.kind, &array->where);
317fa064 673 init_result_expr (result, init_val, array);
195a95c4
TB
674
675 return !dim || array->rank == 1 ?
676 simplify_transformation_to_scalar (result, array, mask, op) :
677 simplify_transformation_to_array (result, array, dim, mask, op, NULL);
678}
679
a16d978f 680
6de9cd9a
DN
681/********************** Simplification functions *****************************/
682
683gfc_expr *
edf1eac2 684gfc_simplify_abs (gfc_expr *e)
6de9cd9a
DN
685{
686 gfc_expr *result;
6de9cd9a
DN
687
688 if (e->expr_type != EXPR_CONSTANT)
689 return NULL;
690
691 switch (e->ts.type)
692 {
b7e75771
JD
693 case BT_INTEGER:
694 result = gfc_get_constant_expr (BT_INTEGER, e->ts.kind, &e->where);
695 mpz_abs (result->value.integer, e->value.integer);
696 return range_check (result, "IABS");
6de9cd9a 697
b7e75771
JD
698 case BT_REAL:
699 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
700 mpfr_abs (result->value.real, e->value.real, GFC_RND_MODE);
701 return range_check (result, "ABS");
6de9cd9a 702
b7e75771
JD
703 case BT_COMPLEX:
704 gfc_set_model_kind (e->ts.kind);
705 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
706 mpc_abs (result->value.real, e->value.complex, GFC_RND_MODE);
707 return range_check (result, "CABS");
6de9cd9a 708
b7e75771
JD
709 default:
710 gfc_internal_error ("gfc_simplify_abs(): Bad type");
6de9cd9a 711 }
6de9cd9a
DN
712}
713
714
d393bbd7
FXC
715static gfc_expr *
716simplify_achar_char (gfc_expr *e, gfc_expr *k, const char *name, bool ascii)
6de9cd9a
DN
717{
718 gfc_expr *result;
d393bbd7
FXC
719 int kind;
720 bool too_large = false;
6de9cd9a
DN
721
722 if (e->expr_type != EXPR_CONSTANT)
723 return NULL;
724
d393bbd7 725 kind = get_kind (BT_CHARACTER, k, name, gfc_default_character_kind);
719e72fb
FXC
726 if (kind == -1)
727 return &gfc_bad_expr;
728
d393bbd7
FXC
729 if (mpz_cmp_si (e->value.integer, 0) < 0)
730 {
731 gfc_error ("Argument of %s function at %L is negative", name,
732 &e->where);
733 return &gfc_bad_expr;
734 }
34462c28 735
73e42eef 736 if (ascii && warn_surprising && mpz_cmp_si (e->value.integer, 127) > 0)
48749dbc
MLI
737 gfc_warning (OPT_Wsurprising,
738 "Argument of %s function at %L outside of range [0,127]",
d393bbd7 739 name, &e->where);
34462c28 740
d393bbd7
FXC
741 if (kind == 1 && mpz_cmp_si (e->value.integer, 255) > 0)
742 too_large = true;
743 else if (kind == 4)
744 {
745 mpz_t t;
746 mpz_init_set_ui (t, 2);
747 mpz_pow_ui (t, t, 32);
748 mpz_sub_ui (t, t, 1);
749 if (mpz_cmp (e->value.integer, t) > 0)
750 too_large = true;
751 mpz_clear (t);
752 }
6de9cd9a 753
d393bbd7
FXC
754 if (too_large)
755 {
756 gfc_error ("Argument of %s function at %L is too large for the "
757 "collating sequence of kind %d", name, &e->where, kind);
758 return &gfc_bad_expr;
759 }
6de9cd9a 760
b7e75771 761 result = gfc_get_character_expr (kind, &e->where, NULL, 1);
d393bbd7 762 result->value.character.string[0] = mpz_get_ui (e->value.integer);
b7e75771 763
6de9cd9a
DN
764 return result;
765}
766
767
d393bbd7
FXC
768
769/* We use the processor's collating sequence, because all
770 systems that gfortran currently works on are ASCII. */
771
772gfc_expr *
773gfc_simplify_achar (gfc_expr *e, gfc_expr *k)
774{
775 return simplify_achar_char (e, k, "ACHAR", true);
776}
777
778
6de9cd9a 779gfc_expr *
edf1eac2 780gfc_simplify_acos (gfc_expr *x)
6de9cd9a
DN
781{
782 gfc_expr *result;
6de9cd9a
DN
783
784 if (x->expr_type != EXPR_CONSTANT)
785 return NULL;
786
504ed63a 787 switch (x->ts.type)
6de9cd9a 788 {
504ed63a
TB
789 case BT_REAL:
790 if (mpfr_cmp_si (x->value.real, 1) > 0
791 || mpfr_cmp_si (x->value.real, -1) < 0)
792 {
793 gfc_error ("Argument of ACOS at %L must be between -1 and 1",
794 &x->where);
795 return &gfc_bad_expr;
796 }
b7e75771 797 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271 798 mpfr_acos (result->value.real, x->value.real, GFC_RND_MODE);
504ed63a 799 break;
b7e75771 800
504ed63a 801 case BT_COMPLEX:
b7e75771 802 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
803 mpc_acos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
804 break;
b7e75771 805
504ed63a 806 default:
67749498 807 gfc_internal_error ("in gfc_simplify_acos(): Bad type");
6de9cd9a
DN
808 }
809
6de9cd9a
DN
810 return range_check (result, "ACOS");
811}
812
1e399e23 813gfc_expr *
edf1eac2 814gfc_simplify_acosh (gfc_expr *x)
1e399e23
JD
815{
816 gfc_expr *result;
817
818 if (x->expr_type != EXPR_CONSTANT)
819 return NULL;
820
504ed63a 821 switch (x->ts.type)
1e399e23 822 {
504ed63a
TB
823 case BT_REAL:
824 if (mpfr_cmp_si (x->value.real, 1) < 0)
825 {
826 gfc_error ("Argument of ACOSH at %L must not be less than 1",
827 &x->where);
828 return &gfc_bad_expr;
829 }
1e399e23 830
b7e75771 831 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
504ed63a
TB
832 mpfr_acosh (result->value.real, x->value.real, GFC_RND_MODE);
833 break;
b7e75771 834
504ed63a 835 case BT_COMPLEX:
b7e75771 836 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
837 mpc_acosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
838 break;
b7e75771 839
504ed63a 840 default:
67749498 841 gfc_internal_error ("in gfc_simplify_acosh(): Bad type");
504ed63a 842 }
1e399e23
JD
843
844 return range_check (result, "ACOSH");
845}
6de9cd9a
DN
846
847gfc_expr *
edf1eac2 848gfc_simplify_adjustl (gfc_expr *e)
6de9cd9a
DN
849{
850 gfc_expr *result;
851 int count, i, len;
00660189 852 gfc_char_t ch;
6de9cd9a
DN
853
854 if (e->expr_type != EXPR_CONSTANT)
855 return NULL;
856
857 len = e->value.character.length;
858
6de9cd9a
DN
859 for (count = 0, i = 0; i < len; ++i)
860 {
861 ch = e->value.character.string[i];
862 if (ch != ' ')
863 break;
864 ++count;
865 }
866
b7e75771 867 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
6de9cd9a 868 for (i = 0; i < len - count; ++i)
edf1eac2 869 result->value.character.string[i] = e->value.character.string[count + i];
6de9cd9a 870
6de9cd9a
DN
871 return result;
872}
873
874
875gfc_expr *
edf1eac2 876gfc_simplify_adjustr (gfc_expr *e)
6de9cd9a
DN
877{
878 gfc_expr *result;
879 int count, i, len;
00660189 880 gfc_char_t ch;
6de9cd9a
DN
881
882 if (e->expr_type != EXPR_CONSTANT)
883 return NULL;
884
885 len = e->value.character.length;
886
6de9cd9a
DN
887 for (count = 0, i = len - 1; i >= 0; --i)
888 {
889 ch = e->value.character.string[i];
890 if (ch != ' ')
891 break;
892 ++count;
893 }
894
b7e75771 895 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
6de9cd9a 896 for (i = 0; i < count; ++i)
edf1eac2 897 result->value.character.string[i] = ' ';
6de9cd9a
DN
898
899 for (i = count; i < len; ++i)
edf1eac2 900 result->value.character.string[i] = e->value.character.string[i - count];
6de9cd9a 901
6de9cd9a
DN
902 return result;
903}
904
905
906gfc_expr *
edf1eac2 907gfc_simplify_aimag (gfc_expr *e)
6de9cd9a
DN
908{
909 gfc_expr *result;
910
911 if (e->expr_type != EXPR_CONSTANT)
912 return NULL;
913
b7e75771 914 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
eb6f9a86 915 mpfr_set (result->value.real, mpc_imagref (e->value.complex), GFC_RND_MODE);
6de9cd9a
DN
916
917 return range_check (result, "AIMAG");
918}
919
920
921gfc_expr *
edf1eac2 922gfc_simplify_aint (gfc_expr *e, gfc_expr *k)
6de9cd9a
DN
923{
924 gfc_expr *rtrunc, *result;
925 int kind;
926
927 kind = get_kind (BT_REAL, k, "AINT", e->ts.kind);
928 if (kind == -1)
929 return &gfc_bad_expr;
930
931 if (e->expr_type != EXPR_CONSTANT)
932 return NULL;
933
934 rtrunc = gfc_copy_expr (e);
f8e566e5 935 mpfr_trunc (rtrunc->value.real, e->value.real);
6de9cd9a
DN
936
937 result = gfc_real2real (rtrunc, kind);
b7e75771 938
6de9cd9a
DN
939 gfc_free_expr (rtrunc);
940
941 return range_check (result, "AINT");
942}
943
944
a16d978f
DF
945gfc_expr *
946gfc_simplify_all (gfc_expr *mask, gfc_expr *dim)
947{
195a95c4 948 return simplify_transformation (mask, dim, NULL, true, gfc_and);
a16d978f
DF
949}
950
951
6de9cd9a 952gfc_expr *
edf1eac2 953gfc_simplify_dint (gfc_expr *e)
6de9cd9a
DN
954{
955 gfc_expr *rtrunc, *result;
956
957 if (e->expr_type != EXPR_CONSTANT)
958 return NULL;
959
960 rtrunc = gfc_copy_expr (e);
f8e566e5 961 mpfr_trunc (rtrunc->value.real, e->value.real);
6de9cd9a 962
9d64df18 963 result = gfc_real2real (rtrunc, gfc_default_double_kind);
b7e75771 964
6de9cd9a
DN
965 gfc_free_expr (rtrunc);
966
967 return range_check (result, "DINT");
6de9cd9a
DN
968}
969
970
02c74373
FXC
971gfc_expr *
972gfc_simplify_dreal (gfc_expr *e)
973{
974 gfc_expr *result = NULL;
975
976 if (e->expr_type != EXPR_CONSTANT)
977 return NULL;
978
979 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
980 mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);
981
982 return range_check (result, "DREAL");
983}
984
985
6de9cd9a 986gfc_expr *
edf1eac2 987gfc_simplify_anint (gfc_expr *e, gfc_expr *k)
6de9cd9a 988{
8e1fa5d6
SK
989 gfc_expr *result;
990 int kind;
6de9cd9a
DN
991
992 kind = get_kind (BT_REAL, k, "ANINT", e->ts.kind);
993 if (kind == -1)
994 return &gfc_bad_expr;
995
996 if (e->expr_type != EXPR_CONSTANT)
997 return NULL;
998
b7e75771 999 result = gfc_get_constant_expr (e->ts.type, kind, &e->where);
8e1fa5d6 1000 mpfr_round (result->value.real, e->value.real);
6de9cd9a
DN
1001
1002 return range_check (result, "ANINT");
1003}
1004
1005
5d723e54 1006gfc_expr *
edf1eac2 1007gfc_simplify_and (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
1008{
1009 gfc_expr *result;
1010 int kind;
1011
1012 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
1013 return NULL;
1014
1015 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771
JD
1016
1017 switch (x->ts.type)
5d723e54 1018 {
b7e75771
JD
1019 case BT_INTEGER:
1020 result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
1021 mpz_and (result->value.integer, x->value.integer, y->value.integer);
1022 return range_check (result, "AND");
1023
1024 case BT_LOGICAL:
1025 return gfc_get_logical_expr (kind, &x->where,
1026 x->value.logical && y->value.logical);
1027
1028 default:
1029 gcc_unreachable ();
5d723e54 1030 }
5d723e54
FXC
1031}
1032
1033
a16d978f
DF
1034gfc_expr *
1035gfc_simplify_any (gfc_expr *mask, gfc_expr *dim)
1036{
195a95c4 1037 return simplify_transformation (mask, dim, NULL, false, gfc_or);
a16d978f
DF
1038}
1039
1040
6de9cd9a 1041gfc_expr *
edf1eac2 1042gfc_simplify_dnint (gfc_expr *e)
6de9cd9a 1043{
8e1fa5d6 1044 gfc_expr *result;
6de9cd9a
DN
1045
1046 if (e->expr_type != EXPR_CONSTANT)
1047 return NULL;
1048
b7e75771 1049 result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &e->where);
8e1fa5d6 1050 mpfr_round (result->value.real, e->value.real);
6de9cd9a
DN
1051
1052 return range_check (result, "DNINT");
1053}
1054
1055
1056gfc_expr *
edf1eac2 1057gfc_simplify_asin (gfc_expr *x)
6de9cd9a
DN
1058{
1059 gfc_expr *result;
6de9cd9a
DN
1060
1061 if (x->expr_type != EXPR_CONSTANT)
1062 return NULL;
1063
504ed63a 1064 switch (x->ts.type)
6de9cd9a 1065 {
504ed63a
TB
1066 case BT_REAL:
1067 if (mpfr_cmp_si (x->value.real, 1) > 0
1068 || mpfr_cmp_si (x->value.real, -1) < 0)
1069 {
1070 gfc_error ("Argument of ASIN at %L must be between -1 and 1",
1071 &x->where);
1072 return &gfc_bad_expr;
1073 }
b7e75771 1074 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
504ed63a
TB
1075 mpfr_asin (result->value.real, x->value.real, GFC_RND_MODE);
1076 break;
b7e75771 1077
504ed63a 1078 case BT_COMPLEX:
b7e75771 1079 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
1080 mpc_asin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1081 break;
b7e75771 1082
504ed63a 1083 default:
67749498 1084 gfc_internal_error ("in gfc_simplify_asin(): Bad type");
6de9cd9a
DN
1085 }
1086
6de9cd9a
DN
1087 return range_check (result, "ASIN");
1088}
1089
1090
1091gfc_expr *
edf1eac2 1092gfc_simplify_asinh (gfc_expr *x)
6de9cd9a
DN
1093{
1094 gfc_expr *result;
1095
1096 if (x->expr_type != EXPR_CONSTANT)
1097 return NULL;
1098
b7e75771
JD
1099 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1100
504ed63a
TB
1101 switch (x->ts.type)
1102 {
1103 case BT_REAL:
504ed63a
TB
1104 mpfr_asinh (result->value.real, x->value.real, GFC_RND_MODE);
1105 break;
b7e75771 1106
504ed63a 1107 case BT_COMPLEX:
8e70c271
KG
1108 mpc_asinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1109 break;
b7e75771 1110
504ed63a 1111 default:
67749498 1112 gfc_internal_error ("in gfc_simplify_asinh(): Bad type");
504ed63a 1113 }
1e399e23
JD
1114
1115 return range_check (result, "ASINH");
1116}
1117
1118
1119gfc_expr *
edf1eac2 1120gfc_simplify_atan (gfc_expr *x)
1e399e23
JD
1121{
1122 gfc_expr *result;
1123
1124 if (x->expr_type != EXPR_CONSTANT)
1125 return NULL;
b7e75771
JD
1126
1127 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1128
504ed63a
TB
1129 switch (x->ts.type)
1130 {
1131 case BT_REAL:
504ed63a
TB
1132 mpfr_atan (result->value.real, x->value.real, GFC_RND_MODE);
1133 break;
b7e75771 1134
504ed63a 1135 case BT_COMPLEX:
8e70c271
KG
1136 mpc_atan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1137 break;
b7e75771 1138
504ed63a 1139 default:
67749498 1140 gfc_internal_error ("in gfc_simplify_atan(): Bad type");
504ed63a 1141 }
6de9cd9a
DN
1142
1143 return range_check (result, "ATAN");
1e399e23
JD
1144}
1145
1146
1147gfc_expr *
edf1eac2 1148gfc_simplify_atanh (gfc_expr *x)
1e399e23
JD
1149{
1150 gfc_expr *result;
6de9cd9a 1151
1e399e23
JD
1152 if (x->expr_type != EXPR_CONSTANT)
1153 return NULL;
1154
504ed63a 1155 switch (x->ts.type)
1e399e23 1156 {
504ed63a
TB
1157 case BT_REAL:
1158 if (mpfr_cmp_si (x->value.real, 1) >= 0
1159 || mpfr_cmp_si (x->value.real, -1) <= 0)
1160 {
1161 gfc_error ("Argument of ATANH at %L must be inside the range -1 "
1162 "to 1", &x->where);
1163 return &gfc_bad_expr;
1164 }
b7e75771 1165 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
504ed63a
TB
1166 mpfr_atanh (result->value.real, x->value.real, GFC_RND_MODE);
1167 break;
b7e75771 1168
504ed63a 1169 case BT_COMPLEX:
b7e75771 1170 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
8e70c271
KG
1171 mpc_atanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1172 break;
b7e75771 1173
504ed63a 1174 default:
67749498 1175 gfc_internal_error ("in gfc_simplify_atanh(): Bad type");
504ed63a 1176 }
1e399e23
JD
1177
1178 return range_check (result, "ATANH");
6de9cd9a
DN
1179}
1180
1181
1182gfc_expr *
edf1eac2 1183gfc_simplify_atan2 (gfc_expr *y, gfc_expr *x)
6de9cd9a
DN
1184{
1185 gfc_expr *result;
1186
1187 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
1188 return NULL;
1189
d2af8cc6 1190 if (mpfr_zero_p (y->value.real) && mpfr_zero_p (x->value.real))
6de9cd9a 1191 {
edf1eac2
SK
1192 gfc_error ("If first argument of ATAN2 %L is zero, then the "
1193 "second argument must not be zero", &x->where);
6de9cd9a
DN
1194 return &gfc_bad_expr;
1195 }
1196
b7e75771 1197 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
e48d66a9 1198 mpfr_atan2 (result->value.real, y->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
1199
1200 return range_check (result, "ATAN2");
6de9cd9a
DN
1201}
1202
1203
3c3f4265 1204gfc_expr *
b7e75771 1205gfc_simplify_bessel_j0 (gfc_expr *x)
3c3f4265 1206{
3c3f4265
TB
1207 gfc_expr *result;
1208
1209 if (x->expr_type != EXPR_CONSTANT)
1210 return NULL;
1211
b7e75771 1212 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1213 mpfr_j0 (result->value.real, x->value.real, GFC_RND_MODE);
1214
1215 return range_check (result, "BESSEL_J0");
3c3f4265
TB
1216}
1217
1218
1219gfc_expr *
b7e75771 1220gfc_simplify_bessel_j1 (gfc_expr *x)
3c3f4265 1221{
3c3f4265
TB
1222 gfc_expr *result;
1223
1224 if (x->expr_type != EXPR_CONSTANT)
1225 return NULL;
1226
b7e75771 1227 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1228 mpfr_j1 (result->value.real, x->value.real, GFC_RND_MODE);
1229
1230 return range_check (result, "BESSEL_J1");
3c3f4265
TB
1231}
1232
1233
1234gfc_expr *
b7e75771 1235gfc_simplify_bessel_jn (gfc_expr *order, gfc_expr *x)
3c3f4265 1236{
3c3f4265
TB
1237 gfc_expr *result;
1238 long n;
1239
1240 if (x->expr_type != EXPR_CONSTANT || order->expr_type != EXPR_CONSTANT)
1241 return NULL;
1242
1243 n = mpz_get_si (order->value.integer);
b7e75771 1244 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1245 mpfr_jn (result->value.real, n, x->value.real, GFC_RND_MODE);
1246
1247 return range_check (result, "BESSEL_JN");
3c3f4265
TB
1248}
1249
1250
29698e0f
TB
1251/* Simplify transformational form of JN and YN. */
1252
1253static gfc_expr *
1254gfc_simplify_bessel_n2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x,
1255 bool jn)
1256{
1257 gfc_expr *result;
1258 gfc_expr *e;
1259 long n1, n2;
1260 int i;
1261 mpfr_t x2rev, last1, last2;
1262
1263 if (x->expr_type != EXPR_CONSTANT || order1->expr_type != EXPR_CONSTANT
1264 || order2->expr_type != EXPR_CONSTANT)
47b99694 1265 return NULL;
29698e0f
TB
1266
1267 n1 = mpz_get_si (order1->value.integer);
1268 n2 = mpz_get_si (order2->value.integer);
1269 result = gfc_get_array_expr (x->ts.type, x->ts.kind, &x->where);
1270 result->rank = 1;
1271 result->shape = gfc_get_shape (1);
1272 mpz_init_set_ui (result->shape[0], MAX (n2-n1+1, 0));
1273
1274 if (n2 < n1)
1275 return result;
1276
1277 /* Special case: x == 0; it is J0(0.0) == 1, JN(N > 0, 0.0) == 0; and
1278 YN(N, 0.0) = -Inf. */
1279
1280 if (mpfr_cmp_ui (x->value.real, 0.0) == 0)
1281 {
c61819ff 1282 if (!jn && flag_range_check)
29698e0f
TB
1283 {
1284 gfc_error ("Result of BESSEL_YN is -INF at %L", &result->where);
1285 gfc_free_expr (result);
1286 return &gfc_bad_expr;
1287 }
1288
1289 if (jn && n1 == 0)
1290 {
1291 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
4c6e913c 1292 mpfr_set_ui (e->value.real, 1, GFC_RND_MODE);
29698e0f
TB
1293 gfc_constructor_append_expr (&result->value.constructor, e,
1294 &x->where);
1295 n1++;
1296 }
1297
1298 for (i = n1; i <= n2; i++)
1299 {
1300 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1301 if (jn)
4c6e913c 1302 mpfr_set_ui (e->value.real, 0, GFC_RND_MODE);
29698e0f 1303 else
47b99694 1304 mpfr_set_inf (e->value.real, -1);
29698e0f
TB
1305 gfc_constructor_append_expr (&result->value.constructor, e,
1306 &x->where);
1307 }
1308
1309 return result;
1310 }
1311
d76799c7 1312 /* Use the faster but more verbose recurrence algorithm. Bessel functions
29698e0f
TB
1313 are stable for downward recursion and Neumann functions are stable
1314 for upward recursion. It is
1315 x2rev = 2.0/x,
1316 J(N-1, x) = x2rev * N * J(N, x) - J(N+1, x),
1317 Y(N+1, x) = x2rev * N * Y(N, x) - Y(N-1, x).
1318 Cf. http://dlmf.nist.gov/10.74#iv and http://dlmf.nist.gov/10.6#E1 */
1319
1320 gfc_set_model_kind (x->ts.kind);
1321
1322 /* Get first recursion anchor. */
1323
1324 mpfr_init (last1);
1325 if (jn)
1326 mpfr_jn (last1, n2, x->value.real, GFC_RND_MODE);
1327 else
1328 mpfr_yn (last1, n1, x->value.real, GFC_RND_MODE);
1329
1330 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1331 mpfr_set (e->value.real, last1, GFC_RND_MODE);
1332 if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
1333 {
1334 mpfr_clear (last1);
1335 gfc_free_expr (e);
1336 gfc_free_expr (result);
1337 return &gfc_bad_expr;
1338 }
1339 gfc_constructor_append_expr (&result->value.constructor, e, &x->where);
1340
1341 if (n1 == n2)
1342 {
1343 mpfr_clear (last1);
1344 return result;
1345 }
8b704316 1346
29698e0f
TB
1347 /* Get second recursion anchor. */
1348
1349 mpfr_init (last2);
1350 if (jn)
1351 mpfr_jn (last2, n2-1, x->value.real, GFC_RND_MODE);
1352 else
1353 mpfr_yn (last2, n1+1, x->value.real, GFC_RND_MODE);
1354
1355 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
1356 mpfr_set (e->value.real, last2, GFC_RND_MODE);
1357 if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
1358 {
1359 mpfr_clear (last1);
1360 mpfr_clear (last2);
1361 gfc_free_expr (e);
1362 gfc_free_expr (result);
1363 return &gfc_bad_expr;
1364 }
1365 if (jn)
4c6e913c 1366 gfc_constructor_insert_expr (&result->value.constructor, e, &x->where, -2);
8b704316 1367 else
29698e0f
TB
1368 gfc_constructor_append_expr (&result->value.constructor, e, &x->where);
1369
1370 if (n1 + 1 == n2)
1371 {
1372 mpfr_clear (last1);
1373 mpfr_clear (last2);
1374 return result;
1375 }
1376
1377 /* Start actual recursion. */
1378
1379 mpfr_init (x2rev);
1380 mpfr_ui_div (x2rev, 2, x->value.real, GFC_RND_MODE);
8b704316 1381
29698e0f
TB
1382 for (i = 2; i <= n2-n1; i++)
1383 {
1384 e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
47b99694
TB
1385
1386 /* Special case: For YN, if the previous N gave -INF, set
1387 also N+1 to -INF. */
c61819ff 1388 if (!jn && !flag_range_check && mpfr_inf_p (last2))
47b99694
TB
1389 {
1390 mpfr_set_inf (e->value.real, -1);
1391 gfc_constructor_append_expr (&result->value.constructor, e,
1392 &x->where);
1393 continue;
1394 }
1395
29698e0f
TB
1396 mpfr_mul_si (e->value.real, x2rev, jn ? (n2-i+1) : (n1+i-1),
1397 GFC_RND_MODE);
1398 mpfr_mul (e->value.real, e->value.real, last2, GFC_RND_MODE);
1399 mpfr_sub (e->value.real, e->value.real, last1, GFC_RND_MODE);
1400
1401 if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
fd2805e1
TB
1402 {
1403 /* Range_check frees "e" in that case. */
1404 e = NULL;
1405 goto error;
1406 }
29698e0f
TB
1407
1408 if (jn)
1409 gfc_constructor_insert_expr (&result->value.constructor, e, &x->where,
1410 -i-1);
1411 else
1412 gfc_constructor_append_expr (&result->value.constructor, e, &x->where);
1413
1414 mpfr_set (last1, last2, GFC_RND_MODE);
1415 mpfr_set (last2, e->value.real, GFC_RND_MODE);
1416 }
1417
1418 mpfr_clear (last1);
1419 mpfr_clear (last2);
1420 mpfr_clear (x2rev);
1421 return result;
1422
1423error:
1424 mpfr_clear (last1);
1425 mpfr_clear (last2);
1426 mpfr_clear (x2rev);
1427 gfc_free_expr (e);
1428 gfc_free_expr (result);
1429 return &gfc_bad_expr;
1430}
1431
1432
1433gfc_expr *
1434gfc_simplify_bessel_jn2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x)
1435{
1436 return gfc_simplify_bessel_n2 (order1, order2, x, true);
1437}
1438
1439
3c3f4265 1440gfc_expr *
b7e75771 1441gfc_simplify_bessel_y0 (gfc_expr *x)
3c3f4265 1442{
3c3f4265
TB
1443 gfc_expr *result;
1444
1445 if (x->expr_type != EXPR_CONSTANT)
1446 return NULL;
1447
b7e75771 1448 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1449 mpfr_y0 (result->value.real, x->value.real, GFC_RND_MODE);
1450
1451 return range_check (result, "BESSEL_Y0");
3c3f4265
TB
1452}
1453
1454
1455gfc_expr *
b7e75771 1456gfc_simplify_bessel_y1 (gfc_expr *x)
3c3f4265 1457{
3c3f4265
TB
1458 gfc_expr *result;
1459
1460 if (x->expr_type != EXPR_CONSTANT)
1461 return NULL;
1462
b7e75771 1463 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1464 mpfr_y1 (result->value.real, x->value.real, GFC_RND_MODE);
1465
1466 return range_check (result, "BESSEL_Y1");
3c3f4265
TB
1467}
1468
1469
1470gfc_expr *
b7e75771 1471gfc_simplify_bessel_yn (gfc_expr *order, gfc_expr *x)
3c3f4265 1472{
3c3f4265
TB
1473 gfc_expr *result;
1474 long n;
1475
1476 if (x->expr_type != EXPR_CONSTANT || order->expr_type != EXPR_CONSTANT)
1477 return NULL;
1478
1479 n = mpz_get_si (order->value.integer);
b7e75771 1480 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
3c3f4265
TB
1481 mpfr_yn (result->value.real, n, x->value.real, GFC_RND_MODE);
1482
1483 return range_check (result, "BESSEL_YN");
3c3f4265
TB
1484}
1485
1486
29698e0f
TB
1487gfc_expr *
1488gfc_simplify_bessel_yn2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x)
1489{
1490 return gfc_simplify_bessel_n2 (order1, order2, x, false);
1491}
1492
1493
6de9cd9a 1494gfc_expr *
edf1eac2 1495gfc_simplify_bit_size (gfc_expr *e)
6de9cd9a 1496{
b7e75771
JD
1497 int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
1498 return gfc_get_int_expr (e->ts.kind, &e->where,
1499 gfc_integer_kinds[i].bit_size);
6de9cd9a
DN
1500}
1501
1502
1503gfc_expr *
edf1eac2 1504gfc_simplify_btest (gfc_expr *e, gfc_expr *bit)
6de9cd9a
DN
1505{
1506 int b;
1507
1508 if (e->expr_type != EXPR_CONSTANT || bit->expr_type != EXPR_CONSTANT)
1509 return NULL;
1510
51f03c6b 1511 if (gfc_extract_int (bit, &b) || b < 0)
b7e75771 1512 return gfc_get_logical_expr (gfc_default_logical_kind, &e->where, false);
6de9cd9a 1513
b7e75771
JD
1514 return gfc_get_logical_expr (gfc_default_logical_kind, &e->where,
1515 mpz_tstbit (e->value.integer, b));
6de9cd9a
DN
1516}
1517
1518
88a95a11
FXC
1519static int
1520compare_bitwise (gfc_expr *i, gfc_expr *j)
1521{
1522 mpz_t x, y;
1523 int k, res;
1524
1525 gcc_assert (i->ts.type == BT_INTEGER);
1526 gcc_assert (j->ts.type == BT_INTEGER);
1527
1528 mpz_init_set (x, i->value.integer);
1529 k = gfc_validate_kind (i->ts.type, i->ts.kind, false);
1530 convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);
1531
1532 mpz_init_set (y, j->value.integer);
1533 k = gfc_validate_kind (j->ts.type, j->ts.kind, false);
1534 convert_mpz_to_unsigned (y, gfc_integer_kinds[k].bit_size);
1535
1536 res = mpz_cmp (x, y);
1537 mpz_clear (x);
1538 mpz_clear (y);
1539 return res;
1540}
1541
1542
1543gfc_expr *
1544gfc_simplify_bge (gfc_expr *i, gfc_expr *j)
1545{
1546 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1547 return NULL;
1548
1549 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1550 compare_bitwise (i, j) >= 0);
1551}
1552
1553
1554gfc_expr *
1555gfc_simplify_bgt (gfc_expr *i, gfc_expr *j)
1556{
1557 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1558 return NULL;
1559
1560 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1561 compare_bitwise (i, j) > 0);
1562}
1563
1564
1565gfc_expr *
1566gfc_simplify_ble (gfc_expr *i, gfc_expr *j)
1567{
1568 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1569 return NULL;
1570
1571 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1572 compare_bitwise (i, j) <= 0);
1573}
1574
1575
1576gfc_expr *
1577gfc_simplify_blt (gfc_expr *i, gfc_expr *j)
1578{
1579 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
1580 return NULL;
1581
1582 return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
1583 compare_bitwise (i, j) < 0);
1584}
1585
1586
6de9cd9a 1587gfc_expr *
edf1eac2 1588gfc_simplify_ceiling (gfc_expr *e, gfc_expr *k)
6de9cd9a
DN
1589{
1590 gfc_expr *ceil, *result;
1591 int kind;
1592
145cf79b 1593 kind = get_kind (BT_INTEGER, k, "CEILING", gfc_default_integer_kind);
6de9cd9a
DN
1594 if (kind == -1)
1595 return &gfc_bad_expr;
1596
1597 if (e->expr_type != EXPR_CONSTANT)
1598 return NULL;
1599
6de9cd9a 1600 ceil = gfc_copy_expr (e);
f8e566e5 1601 mpfr_ceil (ceil->value.real, e->value.real);
b7e75771
JD
1602
1603 result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
7278e4dc 1604 gfc_mpfr_to_mpz (result->value.integer, ceil->value.real, &e->where);
6de9cd9a
DN
1605
1606 gfc_free_expr (ceil);
1607
1608 return range_check (result, "CEILING");
1609}
1610
1611
1612gfc_expr *
edf1eac2 1613gfc_simplify_char (gfc_expr *e, gfc_expr *k)
6de9cd9a 1614{
d393bbd7 1615 return simplify_achar_char (e, k, "CHAR", false);
6de9cd9a
DN
1616}
1617
1618
b7e75771 1619/* Common subroutine for simplifying CMPLX, COMPLEX and DCMPLX. */
6de9cd9a
DN
1620
1621static gfc_expr *
edf1eac2 1622simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind)
6de9cd9a
DN
1623{
1624 gfc_expr *result;
1625
b7e75771
JD
1626 if (convert_boz (x, kind) == &gfc_bad_expr)
1627 return &gfc_bad_expr;
1628
1629 if (convert_boz (y, kind) == &gfc_bad_expr)
1630 return &gfc_bad_expr;
1631
1632 if (x->expr_type != EXPR_CONSTANT
1633 || (y != NULL && y->expr_type != EXPR_CONSTANT))
1634 return NULL;
1635
1636 result = gfc_get_constant_expr (BT_COMPLEX, kind, &x->where);
6de9cd9a 1637
6de9cd9a
DN
1638 switch (x->ts.type)
1639 {
b7e75771 1640 case BT_INTEGER:
eb6f9a86 1641 mpc_set_z (result->value.complex, x->value.integer, GFC_MPC_RND_MODE);
b7e75771 1642 break;
6de9cd9a 1643
b7e75771
JD
1644 case BT_REAL:
1645 mpc_set_fr (result->value.complex, x->value.real, GFC_RND_MODE);
1646 break;
6de9cd9a 1647
b7e75771
JD
1648 case BT_COMPLEX:
1649 mpc_set (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1650 break;
6de9cd9a 1651
b7e75771
JD
1652 default:
1653 gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (x)");
6de9cd9a
DN
1654 }
1655
b7e75771
JD
1656 if (!y)
1657 return range_check (result, name);
6de9cd9a 1658
b7e75771 1659 switch (y->ts.type)
00a4618b 1660 {
b7e75771
JD
1661 case BT_INTEGER:
1662 mpfr_set_z (mpc_imagref (result->value.complex),
1663 y->value.integer, GFC_RND_MODE);
1664 break;
00a4618b 1665
b7e75771
JD
1666 case BT_REAL:
1667 mpfr_set (mpc_imagref (result->value.complex),
1668 y->value.real, GFC_RND_MODE);
1669 break;
1670
1671 default:
1672 gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (y)");
00a4618b
TB
1673 }
1674
6de9cd9a
DN
1675 return range_check (result, name);
1676}
1677
1678
1679gfc_expr *
edf1eac2 1680gfc_simplify_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *k)
6de9cd9a
DN
1681{
1682 int kind;
1683
b7e75771 1684 kind = get_kind (BT_REAL, k, "CMPLX", gfc_default_complex_kind);
6de9cd9a
DN
1685 if (kind == -1)
1686 return &gfc_bad_expr;
1687
1688 return simplify_cmplx ("CMPLX", x, y, kind);
1689}
1690
1691
5d723e54 1692gfc_expr *
edf1eac2 1693gfc_simplify_complex (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
1694{
1695 int kind;
1696
b7e75771
JD
1697 if (x->ts.type == BT_INTEGER && y->ts.type == BT_INTEGER)
1698 kind = gfc_default_complex_kind;
1699 else if (x->ts.type == BT_REAL || y->ts.type == BT_INTEGER)
1700 kind = x->ts.kind;
1701 else if (x->ts.type == BT_INTEGER || y->ts.type == BT_REAL)
1702 kind = y->ts.kind;
1703 else if (x->ts.type == BT_REAL && y->ts.type == BT_REAL)
1704 kind = (x->ts.kind > y->ts.kind) ? x->ts.kind : y->ts.kind;
5d723e54 1705 else
b7e75771 1706 gcc_unreachable ();
6401bf9c 1707
5d723e54
FXC
1708 return simplify_cmplx ("COMPLEX", x, y, kind);
1709}
1710
1711
6de9cd9a 1712gfc_expr *
edf1eac2 1713gfc_simplify_conjg (gfc_expr *e)
6de9cd9a
DN
1714{
1715 gfc_expr *result;
1716
1717 if (e->expr_type != EXPR_CONSTANT)
1718 return NULL;
1719
1720 result = gfc_copy_expr (e);
eb6f9a86 1721 mpc_conj (result->value.complex, result->value.complex, GFC_MPC_RND_MODE);
b7e75771 1722
6de9cd9a
DN
1723 return range_check (result, "CONJG");
1724}
1725
8e8c2744
FR
1726/* Return the simplification of the constant expression in icall, or NULL
1727 if the expression is not constant. */
1728
1729static gfc_expr *
1730simplify_trig_call (gfc_expr *icall)
1731{
1732 gfc_isym_id func = icall->value.function.isym->id;
1733 gfc_expr *x = icall->value.function.actual->expr;
1734
1735 /* The actual simplifiers will return NULL for non-constant x. */
1736 switch (func)
0a4613f0 1737 {
8e8c2744 1738 case GFC_ISYM_ACOS:
0a4613f0 1739 return gfc_simplify_acos (x);
8e8c2744 1740 case GFC_ISYM_ASIN:
0a4613f0 1741 return gfc_simplify_asin (x);
8e8c2744 1742 case GFC_ISYM_ATAN:
0a4613f0 1743 return gfc_simplify_atan (x);
8e8c2744 1744 case GFC_ISYM_COS:
0a4613f0 1745 return gfc_simplify_cos (x);
8e8c2744 1746 case GFC_ISYM_COTAN:
0a4613f0 1747 return gfc_simplify_cotan (x);
8e8c2744 1748 case GFC_ISYM_SIN:
0a4613f0 1749 return gfc_simplify_sin (x);
8e8c2744 1750 case GFC_ISYM_TAN:
0a4613f0 1751 return gfc_simplify_tan (x);
8e8c2744 1752 default:
0a4613f0
JJ
1753 gfc_internal_error ("in simplify_trig_call(): Bad intrinsic");
1754 }
8e8c2744
FR
1755}
1756
1757/* Convert a floating-point number from radians to degrees. */
1758
1759static void
1760degrees_f (mpfr_t x, mp_rnd_t rnd_mode)
1761{
0a4613f0
JJ
1762 mpfr_t tmp;
1763 mpfr_init (tmp);
8e8c2744 1764
0a4613f0
JJ
1765 /* Set x = x % 2pi to avoid offsets with large angles. */
1766 mpfr_const_pi (tmp, rnd_mode);
1767 mpfr_mul_ui (tmp, tmp, 2, rnd_mode);
1768 mpfr_fmod (tmp, x, tmp, rnd_mode);
8e8c2744 1769
0a4613f0
JJ
1770 /* Set x = x * 180. */
1771 mpfr_mul_ui (x, x, 180, rnd_mode);
8e8c2744 1772
0a4613f0
JJ
1773 /* Set x = x / pi. */
1774 mpfr_const_pi (tmp, rnd_mode);
1775 mpfr_div (x, x, tmp, rnd_mode);
8e8c2744 1776
0a4613f0 1777 mpfr_clear (tmp);
8e8c2744
FR
1778}
1779
1780/* Convert a floating-point number from degrees to radians. */
1781
1782static void
1783radians_f (mpfr_t x, mp_rnd_t rnd_mode)
1784{
0a4613f0
JJ
1785 mpfr_t tmp;
1786 mpfr_init (tmp);
8e8c2744 1787
0a4613f0
JJ
1788 /* Set x = x % 360 to avoid offsets with large angles. */
1789 mpfr_set_ui (tmp, 360, rnd_mode);
1790 mpfr_fmod (tmp, x, tmp, rnd_mode);
8e8c2744 1791
0a4613f0
JJ
1792 /* Set x = x * pi. */
1793 mpfr_const_pi (tmp, rnd_mode);
1794 mpfr_mul (x, x, tmp, rnd_mode);
8e8c2744 1795
0a4613f0
JJ
1796 /* Set x = x / 180. */
1797 mpfr_div_ui (x, x, 180, rnd_mode);
8e8c2744 1798
0a4613f0 1799 mpfr_clear (tmp);
8e8c2744
FR
1800}
1801
1802
1803/* Convert argument to radians before calling a trig function. */
1804
1805gfc_expr *
1806gfc_simplify_trigd (gfc_expr *icall)
1807{
1808 gfc_expr *arg;
1809
1810 arg = icall->value.function.actual->expr;
1811
1812 if (arg->ts.type != BT_REAL)
1813 gfc_internal_error ("in gfc_simplify_trigd(): Bad type");
1814
1815 if (arg->expr_type == EXPR_CONSTANT)
1816 /* Convert constant to radians before passing off to simplifier. */
1817 radians_f (arg->value.real, GFC_RND_MODE);
1818
1819 /* Let the usual simplifier take over - we just simplified the arg. */
1820 return simplify_trig_call (icall);
1821}
1822
1823/* Convert result of an inverse trig function to degrees. */
1824
1825gfc_expr *
1826gfc_simplify_atrigd (gfc_expr *icall)
1827{
1828 gfc_expr *result;
1829
1830 if (icall->value.function.actual->expr->ts.type != BT_REAL)
1831 gfc_internal_error ("in gfc_simplify_atrigd(): Bad type");
1832
1833 /* See if another simplifier has work to do first. */
1834 result = simplify_trig_call (icall);
1835
1836 if (result && result->expr_type == EXPR_CONSTANT)
0a4613f0 1837 {
8e8c2744
FR
1838 /* Convert constant to degrees after passing off to actual simplifier. */
1839 degrees_f (result->value.real, GFC_RND_MODE);
1840 return result;
0a4613f0 1841 }
8e8c2744
FR
1842
1843 /* Let gfc_resolve_atrigd take care of the non-constant case. */
1844 return NULL;
1845}
1846
1847/* Convert the result of atan2 to degrees. */
1848
1849gfc_expr *
1850gfc_simplify_atan2d (gfc_expr *y, gfc_expr *x)
1851{
1852 gfc_expr *result;
1853
1854 if (x->ts.type != BT_REAL || y->ts.type != BT_REAL)
1855 gfc_internal_error ("in gfc_simplify_atan2d(): Bad type");
1856
1857 if (x->expr_type == EXPR_CONSTANT && y->expr_type == EXPR_CONSTANT)
1858 {
1859 result = gfc_simplify_atan2 (y, x);
1860 if (result != NULL)
1861 {
1862 degrees_f (result->value.real, GFC_RND_MODE);
1863 return result;
1864 }
1865 }
1866
1867 /* Let gfc_resolve_atan2d take care of the non-constant case. */
1868 return NULL;
1869}
6de9cd9a
DN
1870
1871gfc_expr *
edf1eac2 1872gfc_simplify_cos (gfc_expr *x)
6de9cd9a
DN
1873{
1874 gfc_expr *result;
6de9cd9a
DN
1875
1876 if (x->expr_type != EXPR_CONSTANT)
1877 return NULL;
1878
b7e75771 1879 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a
DN
1880
1881 switch (x->ts.type)
1882 {
b7e75771
JD
1883 case BT_REAL:
1884 mpfr_cos (result->value.real, x->value.real, GFC_RND_MODE);
1885 break;
1886
1887 case BT_COMPLEX:
1888 gfc_set_model_kind (x->ts.kind);
1889 mpc_cos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1890 break;
1891
1892 default:
1893 gfc_internal_error ("in gfc_simplify_cos(): Bad type");
6de9cd9a
DN
1894 }
1895
1896 return range_check (result, "COS");
6de9cd9a
DN
1897}
1898
1899
1900gfc_expr *
edf1eac2 1901gfc_simplify_cosh (gfc_expr *x)
6de9cd9a
DN
1902{
1903 gfc_expr *result;
1904
1905 if (x->expr_type != EXPR_CONSTANT)
1906 return NULL;
1907
b7e75771 1908 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 1909
b7e75771
JD
1910 switch (x->ts.type)
1911 {
1912 case BT_REAL:
1913 mpfr_cosh (result->value.real, x->value.real, GFC_RND_MODE);
1914 break;
1915
1916 case BT_COMPLEX:
1917 mpc_cosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
1918 break;
8b704316 1919
b7e75771
JD
1920 default:
1921 gcc_unreachable ();
1922 }
6de9cd9a
DN
1923
1924 return range_check (result, "COSH");
1925}
1926
1927
a16d978f
DF
1928gfc_expr *
1929gfc_simplify_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
1930{
1931 gfc_expr *result;
1932
1933 if (!is_constant_array_expr (mask)
1934 || !gfc_is_constant_expr (dim)
1935 || !gfc_is_constant_expr (kind))
1936 return NULL;
1937
1938 result = transformational_result (mask, dim,
1939 BT_INTEGER,
1940 get_kind (BT_INTEGER, kind, "COUNT",
1941 gfc_default_integer_kind),
1942 &mask->where);
1943
1944 init_result_expr (result, 0, NULL);
1945
1946 /* Passing MASK twice, once as data array, once as mask.
1947 Whenever gfc_count is called, '1' is added to the result. */
1948 return !dim || mask->rank == 1 ?
1949 simplify_transformation_to_scalar (result, mask, mask, gfc_count) :
0cd0559e 1950 simplify_transformation_to_array (result, mask, dim, mask, gfc_count, NULL);
a16d978f
DF
1951}
1952
a9ec0cfc
TK
1953/* Simplification routine for cshift. This works by copying the array
1954 expressions into a one-dimensional array, shuffling the values into another
1955 one-dimensional array and creating the new array expression from this. The
1956 shuffling part is basically taken from the library routine. */
a16d978f 1957
b1c1d761
SK
1958gfc_expr *
1959gfc_simplify_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim)
1960{
a9ec0cfc
TK
1961 gfc_expr *result;
1962 int which;
1963 gfc_expr **arrayvec, **resultvec;
1964 gfc_expr **rptr, **sptr;
1965 mpz_t size;
1966 size_t arraysize, shiftsize, i;
1967 gfc_constructor *array_ctor, *shift_ctor;
1968 ssize_t *shiftvec, *hptr;
1969 ssize_t shift_val, len;
1970 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
1971 hs_ex[GFC_MAX_DIMENSIONS],
1972 hstride[GFC_MAX_DIMENSIONS], sstride[GFC_MAX_DIMENSIONS],
1973 a_extent[GFC_MAX_DIMENSIONS], a_stride[GFC_MAX_DIMENSIONS],
1974 h_extent[GFC_MAX_DIMENSIONS],
1975 ss_ex[GFC_MAX_DIMENSIONS];
1976 ssize_t rsoffset;
1977 int d, n;
1978 bool continue_loop;
1979 gfc_expr **src, **dest;
1980
1981 if (!is_constant_array_expr (array))
1982 return NULL;
b1c1d761 1983
a9ec0cfc
TK
1984 if (shift->rank > 0)
1985 gfc_simplify_expr (shift, 1);
1986
1987 if (!gfc_is_constant_expr (shift))
1988 return NULL;
1989
1990 /* Make dim zero-based. */
b1c1d761
SK
1991 if (dim)
1992 {
1993 if (!gfc_is_constant_expr (dim))
1994 return NULL;
a9ec0cfc 1995 which = mpz_get_si (dim->value.integer) - 1;
b1c1d761
SK
1996 }
1997 else
a9ec0cfc 1998 which = 0;
b1c1d761 1999
a9ec0cfc
TK
2000 gfc_array_size (array, &size);
2001 arraysize = mpz_get_ui (size);
2002 mpz_clear (size);
b1c1d761 2003
a9ec0cfc
TK
2004 result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
2005 result->shape = gfc_copy_shape (array->shape, array->rank);
2006 result->rank = array->rank;
2007 result->ts.u.derived = array->ts.u.derived;
b1c1d761 2008
a9ec0cfc
TK
2009 if (arraysize == 0)
2010 return result;
b1c1d761 2011
a9ec0cfc
TK
2012 arrayvec = XCNEWVEC (gfc_expr *, arraysize);
2013 array_ctor = gfc_constructor_first (array->value.constructor);
2014 for (i = 0; i < arraysize; i++)
2015 {
2016 arrayvec[i] = array_ctor->expr;
2017 array_ctor = gfc_constructor_next (array_ctor);
2018 }
b1c1d761 2019
a9ec0cfc 2020 resultvec = XCNEWVEC (gfc_expr *, arraysize);
b1c1d761 2021
a9ec0cfc
TK
2022 extent[0] = 1;
2023 count[0] = 0;
b1c1d761 2024
a9ec0cfc
TK
2025 for (d=0; d < array->rank; d++)
2026 {
2027 a_extent[d] = mpz_get_si (array->shape[d]);
2028 a_stride[d] = d == 0 ? 1 : a_stride[d-1] * a_extent[d-1];
2029 }
b1c1d761 2030
a9ec0cfc
TK
2031 if (shift->rank > 0)
2032 {
2033 gfc_array_size (shift, &size);
2034 shiftsize = mpz_get_ui (size);
2035 mpz_clear (size);
2036 shiftvec = XCNEWVEC (ssize_t, shiftsize);
2037 shift_ctor = gfc_constructor_first (shift->value.constructor);
2038 for (d = 0; d < shift->rank; d++)
b1c1d761 2039 {
a9ec0cfc
TK
2040 h_extent[d] = mpz_get_si (shift->shape[d]);
2041 hstride[d] = d == 0 ? 1 : hstride[d-1] * h_extent[d-1];
b1c1d761 2042 }
a9ec0cfc
TK
2043 }
2044 else
2045 shiftvec = NULL;
2046
2047 /* Shut up compiler */
2048 len = 1;
2049 rsoffset = 1;
2050
2051 n = 0;
2052 for (d=0; d < array->rank; d++)
2053 {
2054 if (d == which)
2055 {
2056 rsoffset = a_stride[d];
2057 len = a_extent[d];
2058 }
2059 else
2060 {
2061 count[n] = 0;
2062 extent[n] = a_extent[d];
2063 sstride[n] = a_stride[d];
2064 ss_ex[n] = sstride[n] * extent[n];
2065 if (shiftvec)
2066 hs_ex[n] = hstride[n] * extent[n];
2067 n++;
2068 }
2069 }
b1c1d761 2070
a9ec0cfc
TK
2071 if (shiftvec)
2072 {
2073 for (i = 0; i < shiftsize; i++)
2074 {
2075 ssize_t val;
2076 val = mpz_get_si (shift_ctor->expr->value.integer);
2077 val = val % len;
2078 if (val < 0)
2079 val += len;
2080 shiftvec[i] = val;
2081 shift_ctor = gfc_constructor_next (shift_ctor);
2082 }
2083 shift_val = 0;
b1c1d761
SK
2084 }
2085 else
2086 {
a9ec0cfc
TK
2087 shift_val = mpz_get_si (shift->value.integer);
2088 shift_val = shift_val % len;
2089 if (shift_val < 0)
2090 shift_val += len;
2091 }
2092
2093 continue_loop = true;
2094 d = array->rank;
2095 rptr = resultvec;
2096 sptr = arrayvec;
2097 hptr = shiftvec;
fcae71a3 2098
a9ec0cfc
TK
2099 while (continue_loop)
2100 {
2101 ssize_t sh;
2102 if (shiftvec)
2103 sh = *hptr;
2104 else
2105 sh = shift_val;
2106
2107 src = &sptr[sh * rsoffset];
2108 dest = rptr;
2109 for (n = 0; n < len - sh; n++)
2110 {
2111 *dest = *src;
2112 dest += rsoffset;
2113 src += rsoffset;
2114 }
2115 src = sptr;
2116 for ( n = 0; n < sh; n++)
2117 {
2118 *dest = *src;
2119 dest += rsoffset;
2120 src += rsoffset;
2121 }
2122 rptr += sstride[0];
2123 sptr += sstride[0];
2124 if (shiftvec)
2125 hptr += hstride[0];
2126 count[0]++;
2127 n = 0;
2128 while (count[n] == extent[n])
2129 {
2130 count[n] = 0;
2131 rptr -= ss_ex[n];
2132 sptr -= ss_ex[n];
2133 if (shiftvec)
2134 hptr -= hs_ex[n];
2135 n++;
2136 if (n >= d - 1)
2137 {
2138 continue_loop = false;
2139 break;
2140 }
2141 else
2142 {
2143 count[n]++;
2144 rptr += sstride[n];
2145 sptr += sstride[n];
2146 if (shiftvec)
2147 hptr += hstride[n];
2148 }
2149 }
b1c1d761
SK
2150 }
2151
a9ec0cfc
TK
2152 for (i = 0; i < arraysize; i++)
2153 {
2154 gfc_constructor_append_expr (&result->value.constructor,
2155 gfc_copy_expr (resultvec[i]),
2156 NULL);
2157 }
2158 return result;
b1c1d761
SK
2159}
2160
2161
6de9cd9a 2162gfc_expr *
edf1eac2 2163gfc_simplify_dcmplx (gfc_expr *x, gfc_expr *y)
6de9cd9a 2164{
9d64df18 2165 return simplify_cmplx ("DCMPLX", x, y, gfc_default_double_kind);
6de9cd9a
DN
2166}
2167
2168
2169gfc_expr *
edf1eac2 2170gfc_simplify_dble (gfc_expr *e)
6de9cd9a 2171{
9e23c1aa 2172 gfc_expr *result = NULL;
6de9cd9a
DN
2173
2174 if (e->expr_type != EXPR_CONSTANT)
2175 return NULL;
2176
b7e75771
JD
2177 if (convert_boz (e, gfc_default_double_kind) == &gfc_bad_expr)
2178 return &gfc_bad_expr;
6de9cd9a 2179
b7e75771
JD
2180 result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind);
2181 if (result == &gfc_bad_expr)
2182 return &gfc_bad_expr;
00a4618b 2183
6de9cd9a
DN
2184 return range_check (result, "DBLE");
2185}
2186
2187
2188gfc_expr *
edf1eac2 2189gfc_simplify_digits (gfc_expr *x)
6de9cd9a
DN
2190{
2191 int i, digits;
2192
e7a2d5fb 2193 i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
b7e75771 2194
6de9cd9a
DN
2195 switch (x->ts.type)
2196 {
b7e75771
JD
2197 case BT_INTEGER:
2198 digits = gfc_integer_kinds[i].digits;
2199 break;
6de9cd9a 2200
b7e75771
JD
2201 case BT_REAL:
2202 case BT_COMPLEX:
2203 digits = gfc_real_kinds[i].digits;
2204 break;
6de9cd9a 2205
b7e75771
JD
2206 default:
2207 gcc_unreachable ();
6de9cd9a
DN
2208 }
2209
b7e75771 2210 return gfc_get_int_expr (gfc_default_integer_kind, NULL, digits);
6de9cd9a
DN
2211}
2212
2213
2214gfc_expr *
edf1eac2 2215gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
2216{
2217 gfc_expr *result;
991bb832 2218 int kind;
6de9cd9a
DN
2219
2220 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
2221 return NULL;
2222
991bb832 2223 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771 2224 result = gfc_get_constant_expr (x->ts.type, kind, &x->where);
6de9cd9a
DN
2225
2226 switch (x->ts.type)
2227 {
b7e75771
JD
2228 case BT_INTEGER:
2229 if (mpz_cmp (x->value.integer, y->value.integer) > 0)
2230 mpz_sub (result->value.integer, x->value.integer, y->value.integer);
2231 else
2232 mpz_set_ui (result->value.integer, 0);
6de9cd9a 2233
b7e75771 2234 break;
6de9cd9a 2235
b7e75771
JD
2236 case BT_REAL:
2237 if (mpfr_cmp (x->value.real, y->value.real) > 0)
2238 mpfr_sub (result->value.real, x->value.real, y->value.real,
2239 GFC_RND_MODE);
2240 else
2241 mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6de9cd9a 2242
b7e75771 2243 break;
6de9cd9a 2244
b7e75771
JD
2245 default:
2246 gfc_internal_error ("gfc_simplify_dim(): Bad type");
6de9cd9a
DN
2247 }
2248
2249 return range_check (result, "DIM");
2250}
2251
2252
8ec259c1
DF
2253gfc_expr*
2254gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
2255{
4d051340
TK
2256
2257 gfc_expr temp;
2258
8ec259c1
DF
2259 if (!is_constant_array_expr (vector_a)
2260 || !is_constant_array_expr (vector_b))
2261 return NULL;
2262
2263 gcc_assert (vector_a->rank == 1);
2264 gcc_assert (vector_b->rank == 1);
4d051340
TK
2265
2266 temp.expr_type = EXPR_OP;
2267 gfc_clear_ts (&temp.ts);
2268 temp.value.op.op = INTRINSIC_NONE;
2269 temp.value.op.op1 = vector_a;
2270 temp.value.op.op2 = vector_b;
2271 gfc_type_convert_binary (&temp, 1);
8ec259c1 2272
eebb98a5 2273 return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0, true);
8ec259c1
DF
2274}
2275
2276
6de9cd9a 2277gfc_expr *
edf1eac2 2278gfc_simplify_dprod (gfc_expr *x, gfc_expr *y)
6de9cd9a 2279{
f8e566e5 2280 gfc_expr *a1, *a2, *result;
6de9cd9a
DN
2281
2282 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
2283 return NULL;
2284
9d64df18
TS
2285 a1 = gfc_real2real (x, gfc_default_double_kind);
2286 a2 = gfc_real2real (y, gfc_default_double_kind);
6de9cd9a 2287
b7e75771 2288 result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &x->where);
f8e566e5 2289 mpfr_mul (result->value.real, a1->value.real, a2->value.real, GFC_RND_MODE);
6de9cd9a 2290
f8e566e5 2291 gfc_free_expr (a2);
b7e75771 2292 gfc_free_expr (a1);
6de9cd9a
DN
2293
2294 return range_check (result, "DPROD");
2295}
2296
2297
88a95a11
FXC
2298static gfc_expr *
2299simplify_dshift (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg,
2300 bool right)
2301{
2302 gfc_expr *result;
2303 int i, k, size, shift;
2304
2305 if (arg1->expr_type != EXPR_CONSTANT || arg2->expr_type != EXPR_CONSTANT
2306 || shiftarg->expr_type != EXPR_CONSTANT)
2307 return NULL;
2308
2309 k = gfc_validate_kind (BT_INTEGER, arg1->ts.kind, false);
2310 size = gfc_integer_kinds[k].bit_size;
2311
58a9e3c4 2312 gfc_extract_int (shiftarg, &shift);
88a95a11
FXC
2313
2314 /* DSHIFTR(I,J,SHIFT) = DSHIFTL(I,J,SIZE-SHIFT). */
2315 if (right)
2316 shift = size - shift;
2317
2318 result = gfc_get_constant_expr (BT_INTEGER, arg1->ts.kind, &arg1->where);
2319 mpz_set_ui (result->value.integer, 0);
2320
2321 for (i = 0; i < shift; i++)
2322 if (mpz_tstbit (arg2->value.integer, size - shift + i))
2323 mpz_setbit (result->value.integer, i);
2324
2325 for (i = 0; i < size - shift; i++)
2326 if (mpz_tstbit (arg1->value.integer, i))
2327 mpz_setbit (result->value.integer, shift + i);
2328
2329 /* Convert to a signed value. */
d01b2c21 2330 gfc_convert_mpz_to_signed (result->value.integer, size);
88a95a11
FXC
2331
2332 return result;
2333}
2334
2335
2336gfc_expr *
2337gfc_simplify_dshiftr (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg)
2338{
2339 return simplify_dshift (arg1, arg2, shiftarg, true);
2340}
2341
2342
2343gfc_expr *
2344gfc_simplify_dshiftl (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg)
2345{
2346 return simplify_dshift (arg1, arg2, shiftarg, false);
2347}
2348
2349
fbd35ba1
TK
2350gfc_expr *
2351gfc_simplify_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
2352 gfc_expr *dim)
2353{
2354 bool temp_boundary;
2355 gfc_expr *bnd;
2356 gfc_expr *result;
2357 int which;
2358 gfc_expr **arrayvec, **resultvec;
2359 gfc_expr **rptr, **sptr;
2360 mpz_t size;
2361 size_t arraysize, i;
2362 gfc_constructor *array_ctor, *shift_ctor, *bnd_ctor;
2363 ssize_t shift_val, len;
2364 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
2365 sstride[GFC_MAX_DIMENSIONS], a_extent[GFC_MAX_DIMENSIONS],
2366 a_stride[GFC_MAX_DIMENSIONS], ss_ex[GFC_MAX_DIMENSIONS];
2367 ssize_t rsoffset;
2368 int d, n;
2369 bool continue_loop;
2370 gfc_expr **src, **dest;
2371 size_t s_len;
2372
2373 if (!is_constant_array_expr (array))
2374 return NULL;
2375
2376 if (shift->rank > 0)
2377 gfc_simplify_expr (shift, 1);
2378
2379 if (!gfc_is_constant_expr (shift))
2380 return NULL;
2381
2382 if (boundary)
2383 {
2384 if (boundary->rank > 0)
2385 gfc_simplify_expr (boundary, 1);
2386
2387 if (!gfc_is_constant_expr (boundary))
2388 return NULL;
2389 }
2390
2391 if (dim)
2392 {
2393 if (!gfc_is_constant_expr (dim))
2394 return NULL;
2395 which = mpz_get_si (dim->value.integer) - 1;
2396 }
2397 else
2398 which = 0;
2399
2400 s_len = 0;
2401 if (boundary == NULL)
2402 {
2403 temp_boundary = true;
2404 switch (array->ts.type)
2405 {
2406
2407 case BT_INTEGER:
2408 bnd = gfc_get_int_expr (array->ts.kind, NULL, 0);
2409 break;
2410
2411 case BT_LOGICAL:
2412 bnd = gfc_get_logical_expr (array->ts.kind, NULL, 0);
2413 break;
2414
2415 case BT_REAL:
2416 bnd = gfc_get_constant_expr (array->ts.type, array->ts.kind, &gfc_current_locus);
2417 mpfr_set_ui (bnd->value.real, 0, GFC_RND_MODE);
2418 break;
2419
2420 case BT_COMPLEX:
2421 bnd = gfc_get_constant_expr (array->ts.type, array->ts.kind, &gfc_current_locus);
2422 mpc_set_ui (bnd->value.complex, 0, GFC_RND_MODE);
2423 break;
2424
2425 case BT_CHARACTER:
2426 s_len = mpz_get_ui (array->ts.u.cl->length->value.integer);
2427 bnd = gfc_get_character_expr (array->ts.kind, &gfc_current_locus, NULL, s_len);
2428 break;
2429
2430 default:
2431 gcc_unreachable();
2432
2433 }
2434 }
2435 else
2436 {
2437 temp_boundary = false;
2438 bnd = boundary;
2439 }
2440
2441 gfc_array_size (array, &size);
2442 arraysize = mpz_get_ui (size);
2443 mpz_clear (size);
2444
2445 result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
2446 result->shape = gfc_copy_shape (array->shape, array->rank);
2447 result->rank = array->rank;
2448 result->ts = array->ts;
2449
2450 if (arraysize == 0)
2451 goto final;
2452
2453 arrayvec = XCNEWVEC (gfc_expr *, arraysize);
2454 array_ctor = gfc_constructor_first (array->value.constructor);
2455 for (i = 0; i < arraysize; i++)
2456 {
2457 arrayvec[i] = array_ctor->expr;
2458 array_ctor = gfc_constructor_next (array_ctor);
2459 }
2460
2461 resultvec = XCNEWVEC (gfc_expr *, arraysize);
2462
2463 extent[0] = 1;
2464 count[0] = 0;
2465
2466 for (d=0; d < array->rank; d++)
2467 {
2468 a_extent[d] = mpz_get_si (array->shape[d]);
2469 a_stride[d] = d == 0 ? 1 : a_stride[d-1] * a_extent[d-1];
2470 }
2471
2472 if (shift->rank > 0)
2473 {
2474 shift_ctor = gfc_constructor_first (shift->value.constructor);
2475 shift_val = 0;
2476 }
2477 else
2478 {
2479 shift_ctor = NULL;
2480 shift_val = mpz_get_si (shift->value.integer);
2481 }
2482
2483 if (bnd->rank > 0)
2484 bnd_ctor = gfc_constructor_first (bnd->value.constructor);
2485 else
2486 bnd_ctor = NULL;
2487
2488 /* Shut up compiler */
2489 len = 1;
2490 rsoffset = 1;
2491
2492 n = 0;
2493 for (d=0; d < array->rank; d++)
2494 {
2495 if (d == which)
2496 {
2497 rsoffset = a_stride[d];
2498 len = a_extent[d];
2499 }
2500 else
2501 {
2502 count[n] = 0;
2503 extent[n] = a_extent[d];
2504 sstride[n] = a_stride[d];
2505 ss_ex[n] = sstride[n] * extent[n];
2506 n++;
2507 }
2508 }
2509
2510 continue_loop = true;
2511 d = array->rank;
2512 rptr = resultvec;
2513 sptr = arrayvec;
2514
2515 while (continue_loop)
2516 {
2517 ssize_t sh, delta;
2518
2519 if (shift_ctor)
2520 sh = mpz_get_si (shift_ctor->expr->value.integer);
2521 else
2522 sh = shift_val;
2523
2524 if (( sh >= 0 ? sh : -sh ) > len)
2525 {
2526 delta = len;
2527 sh = len;
2528 }
2529 else
2530 delta = (sh >= 0) ? sh: -sh;
2531
2532 if (sh > 0)
2533 {
2534 src = &sptr[delta * rsoffset];
2535 dest = rptr;
2536 }
2537 else
2538 {
2539 src = sptr;
2540 dest = &rptr[delta * rsoffset];
2541 }
2542
2543 for (n = 0; n < len - delta; n++)
2544 {
2545 *dest = *src;
2546 dest += rsoffset;
2547 src += rsoffset;
2548 }
2549
2550 if (sh < 0)
2551 dest = rptr;
2552
2553 n = delta;
2554
2555 if (bnd_ctor)
2556 {
2557 while (n--)
2558 {
2559 *dest = gfc_copy_expr (bnd_ctor->expr);
2560 dest += rsoffset;
2561 }
2562 }
2563 else
2564 {
2565 while (n--)
2566 {
2567 *dest = gfc_copy_expr (bnd);
2568 dest += rsoffset;
2569 }
2570 }
2571 rptr += sstride[0];
2572 sptr += sstride[0];
2573 if (shift_ctor)
2574 shift_ctor = gfc_constructor_next (shift_ctor);
2575
2576 if (bnd_ctor)
2577 bnd_ctor = gfc_constructor_next (bnd_ctor);
2578
2579 count[0]++;
2580 n = 0;
2581 while (count[n] == extent[n])
2582 {
2583 count[n] = 0;
2584 rptr -= ss_ex[n];
2585 sptr -= ss_ex[n];
2586 n++;
2587 if (n >= d - 1)
2588 {
2589 continue_loop = false;
2590 break;
2591 }
2592 else
2593 {
2594 count[n]++;
2595 rptr += sstride[n];
2596 sptr += sstride[n];
2597 }
2598 }
2599 }
2600
2601 for (i = 0; i < arraysize; i++)
2602 {
2603 gfc_constructor_append_expr (&result->value.constructor,
2604 gfc_copy_expr (resultvec[i]),
2605 NULL);
2606 }
2607
2608 final:
2609 if (temp_boundary)
2610 gfc_free_expr (bnd);
2611
2612 return result;
2613}
2614
fdc54e88
FXC
2615gfc_expr *
2616gfc_simplify_erf (gfc_expr *x)
2617{
2618 gfc_expr *result;
2619
2620 if (x->expr_type != EXPR_CONSTANT)
2621 return NULL;
2622
b7e75771 2623 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
fdc54e88
FXC
2624 mpfr_erf (result->value.real, x->value.real, GFC_RND_MODE);
2625
2626 return range_check (result, "ERF");
2627}
2628
2629
2630gfc_expr *
2631gfc_simplify_erfc (gfc_expr *x)
2632{
2633 gfc_expr *result;
2634
2635 if (x->expr_type != EXPR_CONSTANT)
2636 return NULL;
2637
b7e75771 2638 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
fdc54e88
FXC
2639 mpfr_erfc (result->value.real, x->value.real, GFC_RND_MODE);
2640
2641 return range_check (result, "ERFC");
2642}
2643
2644
9b33a6a1
FXC
2645/* Helper functions to simplify ERFC_SCALED(x) = ERFC(x) * EXP(X**2). */
2646
2647#define MAX_ITER 200
2648#define ARG_LIMIT 12
2649
2650/* Calculate ERFC_SCALED directly by its definition:
2651
2652 ERFC_SCALED(x) = ERFC(x) * EXP(X**2)
2653
2654 using a large precision for intermediate results. This is used for all
2655 but large values of the argument. */
2656static void
2657fullprec_erfc_scaled (mpfr_t res, mpfr_t arg)
2658{
2659 mp_prec_t prec;
2660 mpfr_t a, b;
2661
2662 prec = mpfr_get_default_prec ();
2663 mpfr_set_default_prec (10 * prec);
2664
2665 mpfr_init (a);
2666 mpfr_init (b);
2667
2668 mpfr_set (a, arg, GFC_RND_MODE);
2669 mpfr_sqr (b, a, GFC_RND_MODE);
2670 mpfr_exp (b, b, GFC_RND_MODE);
2671 mpfr_erfc (a, a, GFC_RND_MODE);
2672 mpfr_mul (a, a, b, GFC_RND_MODE);
2673
2674 mpfr_set (res, a, GFC_RND_MODE);
2675 mpfr_set_default_prec (prec);
2676
2677 mpfr_clear (a);
2678 mpfr_clear (b);
2679}
2680
2681/* Calculate ERFC_SCALED using a power series expansion in 1/arg:
2682
2683 ERFC_SCALED(x) = 1 / (x * sqrt(pi))
2684 * (1 + Sum_n (-1)**n * (1 * 3 * 5 * ... * (2n-1))
2685 / (2 * x**2)**n)
2686
2687 This is used for large values of the argument. Intermediate calculations
2688 are performed with twice the precision. We don't do a fixed number of
2689 iterations of the sum, but stop when it has converged to the required
2690 precision. */
2691static void
2692asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
2693{
2694 mpfr_t sum, x, u, v, w, oldsum, sumtrunc;
2695 mpz_t num;
2696 mp_prec_t prec;
2697 unsigned i;
2698
2699 prec = mpfr_get_default_prec ();
2700 mpfr_set_default_prec (2 * prec);
2701
2702 mpfr_init (sum);
2703 mpfr_init (x);
2704 mpfr_init (u);
2705 mpfr_init (v);
2706 mpfr_init (w);
2707 mpz_init (num);
2708
2709 mpfr_init (oldsum);
2710 mpfr_init (sumtrunc);
2711 mpfr_set_prec (oldsum, prec);
2712 mpfr_set_prec (sumtrunc, prec);
2713
2714 mpfr_set (x, arg, GFC_RND_MODE);
2715 mpfr_set_ui (sum, 1, GFC_RND_MODE);
2716 mpz_set_ui (num, 1);
2717
2718 mpfr_set (u, x, GFC_RND_MODE);
2719 mpfr_sqr (u, u, GFC_RND_MODE);
2720 mpfr_mul_ui (u, u, 2, GFC_RND_MODE);
2721 mpfr_pow_si (u, u, -1, GFC_RND_MODE);
2722
2723 for (i = 1; i < MAX_ITER; i++)
2724 {
2725 mpfr_set (oldsum, sum, GFC_RND_MODE);
2726
2727 mpz_mul_ui (num, num, 2 * i - 1);
2728 mpz_neg (num, num);
2729
2730 mpfr_set (w, u, GFC_RND_MODE);
2731 mpfr_pow_ui (w, w, i, GFC_RND_MODE);
2732
2733 mpfr_set_z (v, num, GFC_RND_MODE);
2734 mpfr_mul (v, v, w, GFC_RND_MODE);
2735
2736 mpfr_add (sum, sum, v, GFC_RND_MODE);
2737
2738 mpfr_set (sumtrunc, sum, GFC_RND_MODE);
2739 if (mpfr_cmp (sumtrunc, oldsum) == 0)
2740 break;
2741 }
2742
2743 /* We should have converged by now; otherwise, ARG_LIMIT is probably
2744 set too low. */
2745 gcc_assert (i < MAX_ITER);
2746
2747 /* Divide by x * sqrt(Pi). */
2748 mpfr_const_pi (u, GFC_RND_MODE);
2749 mpfr_sqrt (u, u, GFC_RND_MODE);
2750 mpfr_mul (u, u, x, GFC_RND_MODE);
2751 mpfr_div (sum, sum, u, GFC_RND_MODE);
2752
2753 mpfr_set (res, sum, GFC_RND_MODE);
2754 mpfr_set_default_prec (prec);
2755
2756 mpfr_clears (sum, x, u, v, w, oldsum, sumtrunc, NULL);
2757 mpz_clear (num);
2758}
2759
2760
2761gfc_expr *
2762gfc_simplify_erfc_scaled (gfc_expr *x)
2763{
2764 gfc_expr *result;
2765
2766 if (x->expr_type != EXPR_CONSTANT)
2767 return NULL;
2768
b7e75771 2769 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
9b33a6a1
FXC
2770 if (mpfr_cmp_d (x->value.real, ARG_LIMIT) >= 0)
2771 asympt_erfc_scaled (result->value.real, x->value.real);
2772 else
2773 fullprec_erfc_scaled (result->value.real, x->value.real);
2774
2775 return range_check (result, "ERFC_SCALED");
2776}
2777
2778#undef MAX_ITER
2779#undef ARG_LIMIT
2780
2781
6de9cd9a 2782gfc_expr *
edf1eac2 2783gfc_simplify_epsilon (gfc_expr *e)
6de9cd9a
DN
2784{
2785 gfc_expr *result;
2786 int i;
2787
e7a2d5fb 2788 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6de9cd9a 2789
b7e75771 2790 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
f8e566e5 2791 mpfr_set (result->value.real, gfc_real_kinds[i].epsilon, GFC_RND_MODE);
6de9cd9a
DN
2792
2793 return range_check (result, "EPSILON");
2794}
2795
2796
2797gfc_expr *
edf1eac2 2798gfc_simplify_exp (gfc_expr *x)
6de9cd9a
DN
2799{
2800 gfc_expr *result;
6de9cd9a
DN
2801
2802 if (x->expr_type != EXPR_CONSTANT)
2803 return NULL;
2804
b7e75771 2805 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 2806
6de9cd9a
DN
2807 switch (x->ts.type)
2808 {
b7e75771
JD
2809 case BT_REAL:
2810 mpfr_exp (result->value.real, x->value.real, GFC_RND_MODE);
2811 break;
6de9cd9a 2812
b7e75771
JD
2813 case BT_COMPLEX:
2814 gfc_set_model_kind (x->ts.kind);
2815 mpc_exp (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
2816 break;
6de9cd9a 2817
b7e75771
JD
2818 default:
2819 gfc_internal_error ("in gfc_simplify_exp(): Bad type");
6de9cd9a
DN
2820 }
2821
2822 return range_check (result, "EXP");
2823}
2824
d0a4a61c 2825
6de9cd9a 2826gfc_expr *
edf1eac2 2827gfc_simplify_exponent (gfc_expr *x)
6de9cd9a 2828{
d2af8cc6 2829 long int val;
6de9cd9a
DN
2830 gfc_expr *result;
2831
2832 if (x->expr_type != EXPR_CONSTANT)
2833 return NULL;
2834
b7e75771
JD
2835 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
2836 &x->where);
6de9cd9a 2837
d2af8cc6
FXC
2838 /* EXPONENT(inf) = EXPONENT(nan) = HUGE(0) */
2839 if (mpfr_inf_p (x->value.real) || mpfr_nan_p (x->value.real))
2840 {
2841 int i = gfc_validate_kind (BT_INTEGER, gfc_default_integer_kind, false);
2842 mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
2843 return result;
2844 }
f8e566e5 2845
d2af8cc6
FXC
2846 /* EXPONENT(+/- 0.0) = 0 */
2847 if (mpfr_zero_p (x->value.real))
6de9cd9a
DN
2848 {
2849 mpz_set_ui (result->value.integer, 0);
2850 return result;
2851 }
2852
d2af8cc6
FXC
2853 gfc_set_model (x->value.real);
2854
2855 val = (long int) mpfr_get_exp (x->value.real);
2856 mpz_set_si (result->value.integer, val);
6de9cd9a
DN
2857
2858 return range_check (result, "EXPONENT");
2859}
2860
2861
ef78bc3c
AV
2862gfc_expr *
2863gfc_simplify_failed_or_stopped_images (gfc_expr *team ATTRIBUTE_UNUSED,
2864 gfc_expr *kind)
2865{
2866 if (flag_coarray == GFC_FCOARRAY_NONE)
2867 {
2868 gfc_current_locus = *gfc_current_intrinsic_where;
2869 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
2870 return &gfc_bad_expr;
2871 }
2872
2873 if (flag_coarray == GFC_FCOARRAY_SINGLE)
2874 {
2875 gfc_expr *result;
2876 int actual_kind;
2877 if (kind)
2878 gfc_extract_int (kind, &actual_kind);
2879 else
2880 actual_kind = gfc_default_integer_kind;
2881
2882 result = gfc_get_array_expr (BT_INTEGER, actual_kind, &gfc_current_locus);
2883 result->rank = 1;
2884 return result;
2885 }
2886
2887 /* For fcoarray = lib no simplification is possible, because it is not known
2888 what images failed or are stopped at compile time. */
2889 return NULL;
2890}
2891
2892
6de9cd9a 2893gfc_expr *
edf1eac2 2894gfc_simplify_float (gfc_expr *a)
6de9cd9a
DN
2895{
2896 gfc_expr *result;
2897
2898 if (a->expr_type != EXPR_CONSTANT)
2899 return NULL;
2900
00a4618b
TB
2901 if (a->is_boz)
2902 {
b7e75771
JD
2903 if (convert_boz (a, gfc_default_real_kind) == &gfc_bad_expr)
2904 return &gfc_bad_expr;
00a4618b
TB
2905
2906 result = gfc_copy_expr (a);
00a4618b
TB
2907 }
2908 else
2909 result = gfc_int2real (a, gfc_default_real_kind);
b7e75771 2910
6de9cd9a
DN
2911 return range_check (result, "FLOAT");
2912}
2913
2914
eaf31d82
TB
2915static bool
2916is_last_ref_vtab (gfc_expr *e)
2917{
2918 gfc_ref *ref;
2919 gfc_component *comp = NULL;
2920
2921 if (e->expr_type != EXPR_VARIABLE)
2922 return false;
2923
2924 for (ref = e->ref; ref; ref = ref->next)
2925 if (ref->type == REF_COMPONENT)
2926 comp = ref->u.c.component;
2927
2928 if (!e->ref || !comp)
2929 return e->symtree->n.sym->attr.vtab;
2930
2931 if (comp->name[0] == '_' && strcmp (comp->name, "_vptr") == 0)
2932 return true;
2933
2934 return false;
2935}
2936
2937
2938gfc_expr *
2939gfc_simplify_extends_type_of (gfc_expr *a, gfc_expr *mold)
2940{
2941 /* Avoid simplification of resolved symbols. */
2942 if (is_last_ref_vtab (a) || is_last_ref_vtab (mold))
2943 return NULL;
2944
2945 if (a->ts.type == BT_DERIVED && mold->ts.type == BT_DERIVED)
2946 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
2947 gfc_type_is_extension_of (mold->ts.u.derived,
2948 a->ts.u.derived));
8b704316
PT
2949
2950 if (UNLIMITED_POLY (a) || UNLIMITED_POLY (mold))
2951 return NULL;
2952
04f1c830 2953 /* Return .false. if the dynamic type can never be an extension. */
eaf31d82
TB
2954 if ((a->ts.type == BT_CLASS && mold->ts.type == BT_CLASS
2955 && !gfc_type_is_extension_of
2956 (mold->ts.u.derived->components->ts.u.derived,
2957 a->ts.u.derived->components->ts.u.derived)
2958 && !gfc_type_is_extension_of
2959 (a->ts.u.derived->components->ts.u.derived,
2960 mold->ts.u.derived->components->ts.u.derived))
2961 || (a->ts.type == BT_DERIVED && mold->ts.type == BT_CLASS
eaf31d82
TB
2962 && !gfc_type_is_extension_of
2963 (mold->ts.u.derived->components->ts.u.derived,
2964 a->ts.u.derived))
2965 || (a->ts.type == BT_CLASS && mold->ts.type == BT_DERIVED
2966 && !gfc_type_is_extension_of
2967 (mold->ts.u.derived,
04f1c830
JW
2968 a->ts.u.derived->components->ts.u.derived)
2969 && !gfc_type_is_extension_of
2970 (a->ts.u.derived->components->ts.u.derived,
2971 mold->ts.u.derived)))
eaf31d82
TB
2972 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, false);
2973
04f1c830
JW
2974 /* Return .true. if the dynamic type is guaranteed to be an extension. */
2975 if (a->ts.type == BT_CLASS && mold->ts.type == BT_DERIVED
eaf31d82
TB
2976 && gfc_type_is_extension_of (mold->ts.u.derived,
2977 a->ts.u.derived->components->ts.u.derived))
2978 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, true);
2979
2980 return NULL;
2981}
2982
2983
2984gfc_expr *
2985gfc_simplify_same_type_as (gfc_expr *a, gfc_expr *b)
2986{
2987 /* Avoid simplification of resolved symbols. */
2988 if (is_last_ref_vtab (a) || is_last_ref_vtab (b))
2989 return NULL;
2990
2991 /* Return .false. if the dynamic type can never be the
2992 same. */
67b1d004
JW
2993 if (((a->ts.type == BT_CLASS && gfc_expr_attr (a).class_ok)
2994 || (b->ts.type == BT_CLASS && gfc_expr_attr (b).class_ok))
eaf31d82
TB
2995 && !gfc_type_compatible (&a->ts, &b->ts)
2996 && !gfc_type_compatible (&b->ts, &a->ts))
2997 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, false);
2998
2999 if (a->ts.type != BT_DERIVED || b->ts.type != BT_DERIVED)
3000 return NULL;
3001
3002 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
3003 gfc_compare_derived_types (a->ts.u.derived,
3004 b->ts.u.derived));
3005}
3006
3007
6de9cd9a 3008gfc_expr *
edf1eac2 3009gfc_simplify_floor (gfc_expr *e, gfc_expr *k)
6de9cd9a
DN
3010{
3011 gfc_expr *result;
f8e566e5 3012 mpfr_t floor;
6de9cd9a
DN
3013 int kind;
3014
145cf79b 3015 kind = get_kind (BT_INTEGER, k, "FLOOR", gfc_default_integer_kind);
6de9cd9a
DN
3016 if (kind == -1)
3017 gfc_internal_error ("gfc_simplify_floor(): Bad kind");
3018
3019 if (e->expr_type != EXPR_CONSTANT)
3020 return NULL;
3021
ff7097f2 3022 mpfr_init2 (floor, mpfr_get_prec (e->value.real));
f8e566e5
SK
3023 mpfr_floor (floor, e->value.real);
3024
b7e75771 3025 result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
7278e4dc 3026 gfc_mpfr_to_mpz (result->value.integer, floor, &e->where);
f8e566e5
SK
3027
3028 mpfr_clear (floor);
6de9cd9a
DN
3029
3030 return range_check (result, "FLOOR");
3031}
3032
3033
3034gfc_expr *
edf1eac2 3035gfc_simplify_fraction (gfc_expr *x)
6de9cd9a
DN
3036{
3037 gfc_expr *result;
03a8a2d5
TB
3038
3039#if MPFR_VERSION < MPFR_VERSION_NUM(3,1,0)
03ddaf35 3040 mpfr_t absv, exp, pow2;
03a8a2d5
TB
3041#else
3042 mpfr_exp_t e;
3043#endif
6de9cd9a
DN
3044
3045 if (x->expr_type != EXPR_CONSTANT)
3046 return NULL;
3047
b7e75771 3048 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
6de9cd9a 3049
d2af8cc6
FXC
3050 /* FRACTION(inf) = NaN. */
3051 if (mpfr_inf_p (x->value.real))
3052 {
3053 mpfr_set_nan (result->value.real);
3054 return result;
3055 }
3056
03a8a2d5
TB
3057#if MPFR_VERSION < MPFR_VERSION_NUM(3,1,0)
3058
3059 /* MPFR versions before 3.1.0 do not include mpfr_frexp.
3060 TODO: remove the kludge when MPFR 3.1.0 or newer will be required */
3061
03ddaf35 3062 if (mpfr_sgn (x->value.real) == 0)
6de9cd9a 3063 {
03a8a2d5 3064 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
3065 return result;
3066 }
3067
7306494a 3068 gfc_set_model_kind (x->ts.kind);
03ddaf35 3069 mpfr_init (exp);
f8e566e5 3070 mpfr_init (absv);
f8e566e5 3071 mpfr_init (pow2);
6de9cd9a 3072
f8e566e5 3073 mpfr_abs (absv, x->value.real, GFC_RND_MODE);
03ddaf35 3074 mpfr_log2 (exp, absv, GFC_RND_MODE);
6de9cd9a 3075
03ddaf35
TS
3076 mpfr_trunc (exp, exp);
3077 mpfr_add_ui (exp, exp, 1, GFC_RND_MODE);
6de9cd9a 3078
03ddaf35 3079 mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE);
6de9cd9a 3080
03a8a2d5 3081 mpfr_div (result->value.real, x->value.real, pow2, GFC_RND_MODE);
6de9cd9a 3082
7306494a 3083 mpfr_clears (exp, absv, pow2, NULL);
6de9cd9a 3084
03a8a2d5
TB
3085#else
3086
d2af8cc6 3087 /* mpfr_frexp() correctly handles zeros and NaNs. */
03a8a2d5
TB
3088 mpfr_frexp (&e, result->value.real, x->value.real, GFC_RND_MODE);
3089
3090#endif
3091
6de9cd9a
DN
3092 return range_check (result, "FRACTION");
3093}
3094
3095
75be5dc0
TB
3096gfc_expr *
3097gfc_simplify_gamma (gfc_expr *x)
3098{
3099 gfc_expr *result;
3100
3101 if (x->expr_type != EXPR_CONSTANT)
3102 return NULL;
3103
b7e75771 3104 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
75be5dc0
TB
3105 mpfr_gamma (result->value.real, x->value.real, GFC_RND_MODE);
3106
3107 return range_check (result, "GAMMA");
3108}
3109
3110
6de9cd9a 3111gfc_expr *
edf1eac2 3112gfc_simplify_huge (gfc_expr *e)
6de9cd9a
DN
3113{
3114 gfc_expr *result;
3115 int i;
3116
e7a2d5fb 3117 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
b7e75771 3118 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a
DN
3119
3120 switch (e->ts.type)
3121 {
b7e75771
JD
3122 case BT_INTEGER:
3123 mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
3124 break;
6de9cd9a 3125
b7e75771
JD
3126 case BT_REAL:
3127 mpfr_set (result->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
3128 break;
6de9cd9a 3129
b7e75771
JD
3130 default:
3131 gcc_unreachable ();
6de9cd9a
DN
3132 }
3133
3134 return result;
3135}
3136
f489fba1
FXC
3137
3138gfc_expr *
3139gfc_simplify_hypot (gfc_expr *x, gfc_expr *y)
3140{
3141 gfc_expr *result;
3142
3143 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3144 return NULL;
3145
b7e75771 3146 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
f489fba1
FXC
3147 mpfr_hypot (result->value.real, x->value.real, y->value.real, GFC_RND_MODE);
3148 return range_check (result, "HYPOT");
3149}
3150
3151
34462c28 3152/* We use the processor's collating sequence, because all
65de695f 3153 systems that gfortran currently works on are ASCII. */
6de9cd9a
DN
3154
3155gfc_expr *
5cda5098 3156gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
3157{
3158 gfc_expr *result;
00660189 3159 gfc_char_t index;
b7e75771 3160 int k;
6de9cd9a
DN
3161
3162 if (e->expr_type != EXPR_CONSTANT)
3163 return NULL;
3164
3165 if (e->value.character.length != 1)
3166 {
3167 gfc_error ("Argument of IACHAR at %L must be of length one", &e->where);
3168 return &gfc_bad_expr;
3169 }
3170
00660189 3171 index = e->value.character.string[0];
34462c28 3172
73e42eef 3173 if (warn_surprising && index > 127)
48749dbc
MLI
3174 gfc_warning (OPT_Wsurprising,
3175 "Argument of IACHAR function at %L outside of range 0..127",
34462c28 3176 &e->where);
6de9cd9a 3177
b7e75771
JD
3178 k = get_kind (BT_INTEGER, kind, "IACHAR", gfc_default_integer_kind);
3179 if (k == -1)
5cda5098
FXC
3180 return &gfc_bad_expr;
3181
b7e75771 3182 result = gfc_get_int_expr (k, &e->where, index);
6de9cd9a
DN
3183
3184 return range_check (result, "IACHAR");
3185}
3186
3187
195a95c4
TB
3188static gfc_expr *
3189do_bit_and (gfc_expr *result, gfc_expr *e)
3190{
3191 gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
3192 gcc_assert (result->ts.type == BT_INTEGER
3193 && result->expr_type == EXPR_CONSTANT);
3194
3195 mpz_and (result->value.integer, result->value.integer, e->value.integer);
3196 return result;
3197}
3198
3199
3200gfc_expr *
3201gfc_simplify_iall (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
3202{
3203 return simplify_transformation (array, dim, mask, -1, do_bit_and);
3204}
3205
3206
3207static gfc_expr *
3208do_bit_ior (gfc_expr *result, gfc_expr *e)
3209{
3210 gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
3211 gcc_assert (result->ts.type == BT_INTEGER
3212 && result->expr_type == EXPR_CONSTANT);
3213
3214 mpz_ior (result->value.integer, result->value.integer, e->value.integer);
3215 return result;
3216}
3217
3218
3219gfc_expr *
3220gfc_simplify_iany (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
3221{
3222 return simplify_transformation (array, dim, mask, 0, do_bit_ior);
3223}
3224
3225
6de9cd9a 3226gfc_expr *
edf1eac2 3227gfc_simplify_iand (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3228{
3229 gfc_expr *result;
3230
3231 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3232 return NULL;
3233
b7e75771 3234 result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
6de9cd9a
DN
3235 mpz_and (result->value.integer, x->value.integer, y->value.integer);
3236
3237 return range_check (result, "IAND");
3238}
3239
3240
3241gfc_expr *
edf1eac2 3242gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3243{
3244 gfc_expr *result;
3245 int k, pos;
3246
3247 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3248 return NULL;
3249
58a9e3c4 3250 gfc_extract_int (y, &pos);
6de9cd9a 3251
e7a2d5fb 3252 k = gfc_validate_kind (x->ts.type, x->ts.kind, false);
6de9cd9a 3253
6de9cd9a
DN
3254 result = gfc_copy_expr (x);
3255
f1dcb9bf
BM
3256 convert_mpz_to_unsigned (result->value.integer,
3257 gfc_integer_kinds[k].bit_size);
3258
6de9cd9a 3259 mpz_clrbit (result->value.integer, pos);
f1dcb9bf 3260
d01b2c21 3261 gfc_convert_mpz_to_signed (result->value.integer,
f1dcb9bf
BM
3262 gfc_integer_kinds[k].bit_size);
3263
c05800b6 3264 return result;
6de9cd9a
DN
3265}
3266
3267
3268gfc_expr *
edf1eac2 3269gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_expr *z)
6de9cd9a
DN
3270{
3271 gfc_expr *result;
3272 int pos, len;
3273 int i, k, bitsize;
3274 int *bits;
3275
3276 if (x->expr_type != EXPR_CONSTANT
3277 || y->expr_type != EXPR_CONSTANT
3278 || z->expr_type != EXPR_CONSTANT)
3279 return NULL;
3280
58a9e3c4
SK
3281 gfc_extract_int (y, &pos);
3282 gfc_extract_int (z, &len);
6de9cd9a 3283
e7a2d5fb 3284 k = gfc_validate_kind (BT_INTEGER, x->ts.kind, false);
6de9cd9a
DN
3285
3286 bitsize = gfc_integer_kinds[k].bit_size;
3287
3288 if (pos + len > bitsize)
3289 {
f1dcb9bf
BM
3290 gfc_error ("Sum of second and third arguments of IBITS exceeds "
3291 "bit size at %L", &y->where);
6de9cd9a
DN
3292 return &gfc_bad_expr;
3293 }
3294
b7e75771 3295 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
c05800b6
JD
3296 convert_mpz_to_unsigned (result->value.integer,
3297 gfc_integer_kinds[k].bit_size);
6de9cd9a 3298
ece3f663 3299 bits = XCNEWVEC (int, bitsize);
6de9cd9a
DN
3300
3301 for (i = 0; i < bitsize; i++)
3302 bits[i] = 0;
3303
3304 for (i = 0; i < len; i++)
3305 bits[i] = mpz_tstbit (x->value.integer, i + pos);
3306
3307 for (i = 0; i < bitsize; i++)
3308 {
3309 if (bits[i] == 0)
edf1eac2 3310 mpz_clrbit (result->value.integer, i);
6de9cd9a 3311 else if (bits[i] == 1)
edf1eac2 3312 mpz_setbit (result->value.integer, i);
6de9cd9a 3313 else
edf1eac2 3314 gfc_internal_error ("IBITS: Bad bit");
6de9cd9a
DN
3315 }
3316
cede9502 3317 free (bits);
6de9cd9a 3318
d01b2c21 3319 gfc_convert_mpz_to_signed (result->value.integer,
c05800b6
JD
3320 gfc_integer_kinds[k].bit_size);
3321
3322 return result;
6de9cd9a
DN
3323}
3324
3325
3326gfc_expr *
edf1eac2 3327gfc_simplify_ibset (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3328{
3329 gfc_expr *result;
3330 int k, pos;
3331
3332 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3333 return NULL;
3334
58a9e3c4 3335 gfc_extract_int (y, &pos);
6de9cd9a 3336
e7a2d5fb 3337 k = gfc_validate_kind (x->ts.type, x->ts.kind, false);
6de9cd9a 3338
6de9cd9a
DN
3339 result = gfc_copy_expr (x);
3340
f1dcb9bf
BM
3341 convert_mpz_to_unsigned (result->value.integer,
3342 gfc_integer_kinds[k].bit_size);
3343
6de9cd9a 3344 mpz_setbit (result->value.integer, pos);
ef98c52a 3345
d01b2c21 3346 gfc_convert_mpz_to_signed (result->value.integer,
f1dcb9bf 3347 gfc_integer_kinds[k].bit_size);
ef98c52a 3348
c05800b6 3349 return result;
6de9cd9a
DN
3350}
3351
3352
3353gfc_expr *
5cda5098 3354gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
3355{
3356 gfc_expr *result;
00660189 3357 gfc_char_t index;
b7e75771 3358 int k;
6de9cd9a
DN
3359
3360 if (e->expr_type != EXPR_CONSTANT)
3361 return NULL;
3362
3363 if (e->value.character.length != 1)
3364 {
3365 gfc_error ("Argument of ICHAR at %L must be of length one", &e->where);
3366 return &gfc_bad_expr;
3367 }
3368
00660189 3369 index = e->value.character.string[0];
6de9cd9a 3370
b7e75771
JD
3371 k = get_kind (BT_INTEGER, kind, "ICHAR", gfc_default_integer_kind);
3372 if (k == -1)
5cda5098
FXC
3373 return &gfc_bad_expr;
3374
b7e75771
JD
3375 result = gfc_get_int_expr (k, &e->where, index);
3376
6de9cd9a
DN
3377 return range_check (result, "ICHAR");
3378}
3379
3380
3381gfc_expr *
edf1eac2 3382gfc_simplify_ieor (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3383{
3384 gfc_expr *result;
3385
3386 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3387 return NULL;
3388
b7e75771 3389 result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
6de9cd9a
DN
3390 mpz_xor (result->value.integer, x->value.integer, y->value.integer);
3391
3392 return range_check (result, "IEOR");
3393}
3394
3395
3396gfc_expr *
5cda5098 3397gfc_simplify_index (gfc_expr *x, gfc_expr *y, gfc_expr *b, gfc_expr *kind)
6de9cd9a
DN
3398{
3399 gfc_expr *result;
3400 int back, len, lensub;
3401 int i, j, k, count, index = 0, start;
3402
8b704316 3403 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT
00113de8 3404 || ( b != NULL && b->expr_type != EXPR_CONSTANT))
6de9cd9a
DN
3405 return NULL;
3406
3407 if (b != NULL && b->value.logical != 0)
3408 back = 1;
3409 else
3410 back = 0;
3411
8b704316 3412 k = get_kind (BT_INTEGER, kind, "INDEX", gfc_default_integer_kind);
5cda5098
FXC
3413 if (k == -1)
3414 return &gfc_bad_expr;
3415
b7e75771 3416 result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);
6de9cd9a
DN
3417
3418 len = x->value.character.length;
3419 lensub = y->value.character.length;
3420
3421 if (len < lensub)
3422 {
3423 mpz_set_si (result->value.integer, 0);
3424 return result;
3425 }
3426
3427 if (back == 0)
3428 {
6de9cd9a
DN
3429 if (lensub == 0)
3430 {
3431 mpz_set_si (result->value.integer, 1);
3432 return result;
3433 }
3434 else if (lensub == 1)
3435 {
3436 for (i = 0; i < len; i++)
3437 {
3438 for (j = 0; j < lensub; j++)
3439 {
edf1eac2
SK
3440 if (y->value.character.string[j]
3441 == x->value.character.string[i])
6de9cd9a
DN
3442 {
3443 index = i + 1;
3444 goto done;
3445 }
3446 }
3447 }
3448 }
3449 else
3450 {
3451 for (i = 0; i < len; i++)
3452 {
3453 for (j = 0; j < lensub; j++)
3454 {
edf1eac2
SK
3455 if (y->value.character.string[j]
3456 == x->value.character.string[i])
6de9cd9a
DN
3457 {
3458 start = i;
3459 count = 0;
3460
3461 for (k = 0; k < lensub; k++)
3462 {
edf1eac2
SK
3463 if (y->value.character.string[k]
3464 == x->value.character.string[k + start])
6de9cd9a
DN
3465 count++;
3466 }
3467
3468 if (count == lensub)
3469 {
3470 index = start + 1;
3471 goto done;
3472 }
3473 }
3474 }
3475 }
3476 }
3477
3478 }
3479 else
3480 {
6de9cd9a
DN
3481 if (lensub == 0)
3482 {
3483 mpz_set_si (result->value.integer, len + 1);
3484 return result;
3485 }
3486 else if (lensub == 1)
3487 {
3488 for (i = 0; i < len; i++)
3489 {
3490 for (j = 0; j < lensub; j++)
3491 {
edf1eac2
SK
3492 if (y->value.character.string[j]
3493 == x->value.character.string[len - i])
6de9cd9a
DN
3494 {
3495 index = len - i + 1;
3496 goto done;
3497 }
3498 }
3499 }
3500 }
3501 else
3502 {
3503 for (i = 0; i < len; i++)
3504 {
3505 for (j = 0; j < lensub; j++)
3506 {
edf1eac2
SK
3507 if (y->value.character.string[j]
3508 == x->value.character.string[len - i])
6de9cd9a
DN
3509 {
3510 start = len - i;
3511 if (start <= len - lensub)
3512 {
3513 count = 0;
3514 for (k = 0; k < lensub; k++)
edf1eac2
SK
3515 if (y->value.character.string[k]
3516 == x->value.character.string[k + start])
6de9cd9a
DN
3517 count++;
3518
3519 if (count == lensub)
3520 {
3521 index = start + 1;
3522 goto done;
3523 }
3524 }
3525 else
3526 {
3527 continue;
3528 }
3529 }
3530 }
3531 }
3532 }
3533 }
3534
3535done:
3536 mpz_set_si (result->value.integer, index);
3537 return range_check (result, "INDEX");
3538}
3539
3540
b7e75771
JD
3541static gfc_expr *
3542simplify_intconv (gfc_expr *e, int kind, const char *name)
6de9cd9a 3543{
d93712d9 3544 gfc_expr *result = NULL;
6de9cd9a
DN
3545
3546 if (e->expr_type != EXPR_CONSTANT)
3547 return NULL;
3548
b7e75771
JD
3549 result = gfc_convert_constant (e, BT_INTEGER, kind);
3550 if (result == &gfc_bad_expr)
3551 return &gfc_bad_expr;
6de9cd9a 3552
b7e75771 3553 return range_check (result, name);
6de9cd9a
DN
3554}
3555
3556
b7e75771
JD
3557gfc_expr *
3558gfc_simplify_int (gfc_expr *e, gfc_expr *k)
bf3fb7e4 3559{
b7e75771 3560 int kind;
bf3fb7e4 3561
b7e75771
JD
3562 kind = get_kind (BT_INTEGER, k, "INT", gfc_default_integer_kind);
3563 if (kind == -1)
3564 return &gfc_bad_expr;
bf3fb7e4 3565
b7e75771 3566 return simplify_intconv (e, kind, "INT");
bf3fb7e4
FXC
3567}
3568
3569gfc_expr *
edf1eac2 3570gfc_simplify_int2 (gfc_expr *e)
bf3fb7e4 3571{
d93712d9 3572 return simplify_intconv (e, 2, "INT2");
bf3fb7e4
FXC
3573}
3574
edf1eac2 3575
bf3fb7e4 3576gfc_expr *
edf1eac2 3577gfc_simplify_int8 (gfc_expr *e)
bf3fb7e4 3578{
d93712d9 3579 return simplify_intconv (e, 8, "INT8");
bf3fb7e4
FXC
3580}
3581
edf1eac2 3582
bf3fb7e4 3583gfc_expr *
edf1eac2 3584gfc_simplify_long (gfc_expr *e)
bf3fb7e4 3585{
d93712d9 3586 return simplify_intconv (e, 4, "LONG");
bf3fb7e4
FXC
3587}
3588
3589
6de9cd9a 3590gfc_expr *
edf1eac2 3591gfc_simplify_ifix (gfc_expr *e)
6de9cd9a
DN
3592{
3593 gfc_expr *rtrunc, *result;
3594
3595 if (e->expr_type != EXPR_CONSTANT)
3596 return NULL;
3597
6de9cd9a 3598 rtrunc = gfc_copy_expr (e);
f8e566e5 3599 mpfr_trunc (rtrunc->value.real, e->value.real);
b7e75771
JD
3600
3601 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
3602 &e->where);
7278e4dc 3603 gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);
6de9cd9a
DN
3604
3605 gfc_free_expr (rtrunc);
b7e75771 3606
6de9cd9a
DN
3607 return range_check (result, "IFIX");
3608}
3609
3610
3611gfc_expr *
edf1eac2 3612gfc_simplify_idint (gfc_expr *e)
6de9cd9a
DN
3613{
3614 gfc_expr *rtrunc, *result;
3615
3616 if (e->expr_type != EXPR_CONSTANT)
3617 return NULL;
3618
6de9cd9a 3619 rtrunc = gfc_copy_expr (e);
f8e566e5 3620 mpfr_trunc (rtrunc->value.real, e->value.real);
b7e75771
JD
3621
3622 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
3623 &e->where);
7278e4dc 3624 gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);
6de9cd9a
DN
3625
3626 gfc_free_expr (rtrunc);
b7e75771 3627
6de9cd9a
DN
3628 return range_check (result, "IDINT");
3629}
3630
3631
3632gfc_expr *
edf1eac2 3633gfc_simplify_ior (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
3634{
3635 gfc_expr *result;
3636
3637 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
3638 return NULL;
3639
b7e75771 3640 result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
6de9cd9a 3641 mpz_ior (result->value.integer, x->value.integer, y->value.integer);
b7e75771 3642
6de9cd9a
DN
3643 return range_check (result, "IOR");
3644}
3645
3646
195a95c4
TB
3647static gfc_expr *
3648do_bit_xor (gfc_expr *result, gfc_expr *e)
3649{
3650 gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
3651 gcc_assert (result->ts.type == BT_INTEGER
3652 && result->expr_type == EXPR_CONSTANT);
3653
3654 mpz_xor (result->value.integer, result->value.integer, e->value.integer);
3655 return result;
3656}
3657
3658
3659gfc_expr *
3660gfc_simplify_iparity (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
3661{
3662 return simplify_transformation (array, dim, mask, 0, do_bit_xor);
3663}
3664
3665
4ec80803
FXC
3666gfc_expr *
3667gfc_simplify_is_iostat_end (gfc_expr *x)
3668{
4ec80803
FXC
3669 if (x->expr_type != EXPR_CONSTANT)
3670 return NULL;
3671
b7e75771
JD
3672 return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
3673 mpz_cmp_si (x->value.integer,
3674 LIBERROR_END) == 0);
4ec80803
FXC
3675}
3676
3677
3678gfc_expr *
3679gfc_simplify_is_iostat_eor (gfc_expr *x)
3680{
4ec80803
FXC
3681 if (x->expr_type != EXPR_CONSTANT)
3682 return NULL;
3683
b7e75771
JD
3684 return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
3685 mpz_cmp_si (x->value.integer,
3686 LIBERROR_EOR) == 0);
4ec80803
FXC
3687}
3688
3689
3690gfc_expr *
3691gfc_simplify_isnan (gfc_expr *x)
3692{
4ec80803
FXC
3693 if (x->expr_type != EXPR_CONSTANT)
3694 return NULL;
3695
b7e75771
JD
3696 return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
3697 mpfr_nan_p (x->value.real));
4ec80803
FXC
3698}
3699
3700
88a95a11
FXC
3701/* Performs a shift on its first argument. Depending on the last
3702 argument, the shift can be arithmetic, i.e. with filling from the
3703 left like in the SHIFTA intrinsic. */
3704static gfc_expr *
3705simplify_shift (gfc_expr *e, gfc_expr *s, const char *name,
3706 bool arithmetic, int direction)
6de9cd9a
DN
3707{
3708 gfc_expr *result;
88a95a11 3709 int ashift, *bits, i, k, bitsize, shift;
6de9cd9a
DN
3710
3711 if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
3712 return NULL;
58a9e3c4
SK
3713
3714 gfc_extract_int (s, &shift);
6de9cd9a 3715
e7a2d5fb 3716 k = gfc_validate_kind (BT_INTEGER, e->ts.kind, false);
88a95a11 3717 bitsize = gfc_integer_kinds[k].bit_size;
6de9cd9a 3718
88a95a11 3719 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a 3720
88a95a11
FXC
3721 if (shift == 0)
3722 {
3723 mpz_set (result->value.integer, e->value.integer);
3724 return result;
3725 }
6de9cd9a 3726
88a95a11 3727 if (direction > 0 && shift < 0)
6de9cd9a 3728 {
88a95a11
FXC
3729 /* Left shift, as in SHIFTL. */
3730 gfc_error ("Second argument of %s is negative at %L", name, &e->where);
6de9cd9a
DN
3731 return &gfc_bad_expr;
3732 }
88a95a11
FXC
3733 else if (direction < 0)
3734 {
3735 /* Right shift, as in SHIFTR or SHIFTA. */
3736 if (shift < 0)
3737 {
3738 gfc_error ("Second argument of %s is negative at %L",
3739 name, &e->where);
3740 return &gfc_bad_expr;
3741 }
6de9cd9a 3742
88a95a11
FXC
3743 shift = -shift;
3744 }
6de9cd9a 3745
88a95a11
FXC
3746 ashift = (shift >= 0 ? shift : -shift);
3747
3748 if (ashift > bitsize)
6de9cd9a 3749 {
88a95a11
FXC
3750 gfc_error ("Magnitude of second argument of %s exceeds bit size "
3751 "at %L", name, &e->where);
3752 return &gfc_bad_expr;
6de9cd9a 3753 }
5d24a977 3754
88a95a11
FXC
3755 bits = XCNEWVEC (int, bitsize);
3756
3757 for (i = 0; i < bitsize; i++)
5d24a977 3758 bits[i] = mpz_tstbit (e->value.integer, i);
6de9cd9a
DN
3759
3760 if (shift > 0)
5d24a977 3761 {
88a95a11 3762 /* Left shift. */
5d24a977
TS
3763 for (i = 0; i < shift; i++)
3764 mpz_clrbit (result->value.integer, i);
3765
88a95a11 3766 for (i = 0; i < bitsize - shift; i++)
5d24a977
TS
3767 {
3768 if (bits[i] == 0)
3769 mpz_clrbit (result->value.integer, i + shift);
3770 else
3771 mpz_setbit (result->value.integer, i + shift);
3772 }
3773 }
6de9cd9a 3774 else
5d24a977 3775 {
88a95a11
FXC
3776 /* Right shift. */
3777 if (arithmetic && bits[bitsize - 1])
3778 for (i = bitsize - 1; i >= bitsize - ashift; i--)
3779 mpz_setbit (result->value.integer, i);
3780 else
3781 for (i = bitsize - 1; i >= bitsize - ashift; i--)
3782 mpz_clrbit (result->value.integer, i);
5d24a977 3783
88a95a11 3784 for (i = bitsize - 1; i >= ashift; i--)
5d24a977
TS
3785 {
3786 if (bits[i] == 0)
3787 mpz_clrbit (result->value.integer, i - ashift);
3788 else
3789 mpz_setbit (result->value.integer, i - ashift);
3790 }
3791 }
6de9cd9a 3792
d01b2c21 3793 gfc_convert_mpz_to_signed (result->value.integer, bitsize);
cede9502 3794 free (bits);
88a95a11 3795
5d24a977 3796 return result;
6de9cd9a
DN
3797}
3798
3799
88a95a11
FXC
3800gfc_expr *
3801gfc_simplify_ishft (gfc_expr *e, gfc_expr *s)
3802{
3803 return simplify_shift (e, s, "ISHFT", false, 0);
3804}
3805
3806
3807gfc_expr *
3808gfc_simplify_lshift (gfc_expr *e, gfc_expr *s)
3809{
3810 return simplify_shift (e, s, "LSHIFT", false, 1);
3811}
3812
3813
3814gfc_expr *
3815gfc_simplify_rshift (gfc_expr *e, gfc_expr *s)
3816{
3817 return simplify_shift (e, s, "RSHIFT", true, -1);
3818}
3819
3820
3821gfc_expr *
3822gfc_simplify_shifta (gfc_expr *e, gfc_expr *s)
3823{
3824 return simplify_shift (e, s, "SHIFTA", true, -1);
3825}
3826
3827
3828gfc_expr *
3829gfc_simplify_shiftl (gfc_expr *e, gfc_expr *s)
3830{
3831 return simplify_shift (e, s, "SHIFTL", false, 1);
3832}
3833
3834
3835gfc_expr *
3836gfc_simplify_shiftr (gfc_expr *e, gfc_expr *s)
3837{
3838 return simplify_shift (e, s, "SHIFTR", false, -1);
3839}
3840
3841
6de9cd9a 3842gfc_expr *
edf1eac2 3843gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
6de9cd9a
DN
3844{
3845 gfc_expr *result;
f1dcb9bf 3846 int shift, ashift, isize, ssize, delta, k;
6de9cd9a
DN
3847 int i, *bits;
3848
3849 if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
3850 return NULL;
3851
58a9e3c4 3852 gfc_extract_int (s, &shift);
6de9cd9a 3853
e7a2d5fb 3854 k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
f1dcb9bf 3855 isize = gfc_integer_kinds[k].bit_size;
6de9cd9a
DN
3856
3857 if (sz != NULL)
3858 {
f1dcb9bf 3859 if (sz->expr_type != EXPR_CONSTANT)
edf1eac2 3860 return NULL;
f1dcb9bf 3861
58a9e3c4 3862 gfc_extract_int (sz, &ssize);
6de9cd9a
DN
3863 }
3864 else
f1dcb9bf 3865 ssize = isize;
6de9cd9a
DN
3866
3867 if (shift >= 0)
3868 ashift = shift;
3869 else
3870 ashift = -shift;
3871
f1dcb9bf 3872 if (ashift > ssize)
6de9cd9a 3873 {
58a9e3c4 3874 if (sz == NULL)
f1dcb9bf 3875 gfc_error ("Magnitude of second argument of ISHFTC exceeds "
c20f6223
JD
3876 "BIT_SIZE of first argument at %C");
3877 else
3878 gfc_error ("Absolute value of SHIFT shall be less than or equal "
3879 "to SIZE at %C");
6de9cd9a
DN
3880 return &gfc_bad_expr;
3881 }
3882
b7e75771 3883 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a 3884
f1dcb9bf
BM
3885 mpz_set (result->value.integer, e->value.integer);
3886
5d24a977 3887 if (shift == 0)
f1dcb9bf 3888 return result;
5d24a977 3889
f1dcb9bf 3890 convert_mpz_to_unsigned (result->value.integer, isize);
6de9cd9a 3891
ece3f663 3892 bits = XCNEWVEC (int, ssize);
f1dcb9bf
BM
3893
3894 for (i = 0; i < ssize; i++)
6de9cd9a
DN
3895 bits[i] = mpz_tstbit (e->value.integer, i);
3896
f1dcb9bf 3897 delta = ssize - ashift;
6de9cd9a 3898
5d24a977 3899 if (shift > 0)
6de9cd9a
DN
3900 {
3901 for (i = 0; i < delta; i++)
3902 {
3903 if (bits[i] == 0)
3904 mpz_clrbit (result->value.integer, i + shift);
5d24a977 3905 else
6de9cd9a
DN
3906 mpz_setbit (result->value.integer, i + shift);
3907 }
3908
f1dcb9bf 3909 for (i = delta; i < ssize; i++)
6de9cd9a
DN
3910 {
3911 if (bits[i] == 0)
3912 mpz_clrbit (result->value.integer, i - delta);
5d24a977 3913 else
6de9cd9a
DN
3914 mpz_setbit (result->value.integer, i - delta);
3915 }
6de9cd9a
DN
3916 }
3917 else
3918 {
3919 for (i = 0; i < ashift; i++)
3920 {
3921 if (bits[i] == 0)
3922 mpz_clrbit (result->value.integer, i + delta);
5d24a977 3923 else
6de9cd9a
DN
3924 mpz_setbit (result->value.integer, i + delta);
3925 }
3926
f1dcb9bf 3927 for (i = ashift; i < ssize; i++)
6de9cd9a
DN
3928 {
3929 if (bits[i] == 0)
3930 mpz_clrbit (result->value.integer, i + shift);
5d24a977 3931 else
6de9cd9a
DN
3932 mpz_setbit (result->value.integer, i + shift);
3933 }
6de9cd9a 3934 }
5d24a977 3935
d01b2c21 3936 gfc_convert_mpz_to_signed (result->value.integer, isize);
5d24a977 3937
cede9502 3938 free (bits);
5d24a977 3939 return result;
6de9cd9a
DN
3940}
3941
3942
3943gfc_expr *
edf1eac2 3944gfc_simplify_kind (gfc_expr *e)
6de9cd9a 3945{
b7e75771 3946 return gfc_get_int_expr (gfc_default_integer_kind, NULL, e->ts.kind);
6de9cd9a
DN
3947}
3948
3949
3950static gfc_expr *
5cda5098 3951simplify_bound_dim (gfc_expr *array, gfc_expr *kind, int d, int upper,
64f002ed 3952 gfc_array_spec *as, gfc_ref *ref, bool coarray)
6de9cd9a 3953{
9f1dce56 3954 gfc_expr *l, *u, *result;
5cda5098 3955 int k;
6de9cd9a 3956
69dcd06a 3957 k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
8b704316 3958 gfc_default_integer_kind);
69dcd06a
DK
3959 if (k == -1)
3960 return &gfc_bad_expr;
3961
3962 result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
3963
3964 /* For non-variables, LBOUND(expr, DIM=n) = 1 and
3965 UBOUND(expr, DIM=n) = SIZE(expr, DIM=n). */
3966 if (!coarray && array->expr_type != EXPR_VARIABLE)
3967 {
3968 if (upper)
3969 {
3970 gfc_expr* dim = result;
3971 mpz_set_si (dim->value.integer, d);
3972
1634e53f 3973 result = simplify_size (array, dim, k);
69dcd06a
DK
3974 gfc_free_expr (dim);
3975 if (!result)
3976 goto returnNull;
3977 }
3978 else
3979 mpz_set_si (result->value.integer, 1);
3980
3981 goto done;
3982 }
3983
3984 /* Otherwise, we have a variable expression. */
3985 gcc_assert (array->expr_type == EXPR_VARIABLE);
3986 gcc_assert (as);
3987
524af0d6 3988 if (!gfc_resolve_array_spec (as, 0))
0423b64a
MM
3989 return NULL;
3990
fc9f54d5 3991 /* The last dimension of an assumed-size array is special. */
64f002ed 3992 if ((!coarray && d == as->rank && as->type == AS_ASSUMED_SIZE && !upper)
155e5d5f 3993 || (coarray && d == as->rank + as->corank
f19626cf 3994 && (!upper || flag_coarray == GFC_FCOARRAY_SINGLE)))
fc9f54d5
FXC
3995 {
3996 if (as->lower[d-1]->expr_type == EXPR_CONSTANT)
69dcd06a
DK
3997 {
3998 gfc_free_expr (result);
3999 return gfc_copy_expr (as->lower[d-1]);
4000 }
6de9cd9a 4001
69dcd06a
DK
4002 goto returnNull;
4003 }
5cda5098 4004
b7e75771 4005 result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
fc9f54d5 4006
543af7ab 4007 /* Then, we need to know the extent of the given dimension. */
11642de8 4008 if (coarray || (ref->u.ar.type == AR_FULL && !ref->next))
fc9f54d5 4009 {
22fa926f
MM
4010 gfc_expr *declared_bound;
4011 int empty_bound;
4012 bool constant_lbound, constant_ubound;
4013
543af7ab
TK
4014 l = as->lower[d-1];
4015 u = as->upper[d-1];
4016
22fa926f
MM
4017 gcc_assert (l != NULL);
4018
4019 constant_lbound = l->expr_type == EXPR_CONSTANT;
4020 constant_ubound = u && u->expr_type == EXPR_CONSTANT;
4021
4022 empty_bound = upper ? 0 : 1;
4023 declared_bound = upper ? u : l;
4024
4025 if ((!upper && !constant_lbound)
4026 || (upper && !constant_ubound))
69dcd06a 4027 goto returnNull;
543af7ab 4028
22fa926f 4029 if (!coarray)
543af7ab 4030 {
22fa926f
MM
4031 /* For {L,U}BOUND, the value depends on whether the array
4032 is empty. We can nevertheless simplify if the declared bound
4033 has the same value as that of an empty array, in which case
4034 the result isn't dependent on the array emptyness. */
4035 if (mpz_cmp_si (declared_bound->value.integer, empty_bound) == 0)
4036 mpz_set_si (result->value.integer, empty_bound);
4037 else if (!constant_lbound || !constant_ubound)
4038 /* Array emptyness can't be determined, we can't simplify. */
4039 goto returnNull;
4040 else if (mpz_cmp (l->value.integer, u->value.integer) > 0)
4041 mpz_set_si (result->value.integer, empty_bound);
543af7ab 4042 else
22fa926f 4043 mpz_set (result->value.integer, declared_bound->value.integer);
543af7ab 4044 }
fc9f54d5 4045 else
22fa926f 4046 mpz_set (result->value.integer, declared_bound->value.integer);
fc9f54d5
FXC
4047 }
4048 else
4049 {
fc9f54d5 4050 if (upper)
543af7ab 4051 {
524af0d6 4052 if (!gfc_ref_dimen_size (&ref->u.ar, d - 1, &result->value.integer, NULL))
69dcd06a 4053 goto returnNull;
543af7ab 4054 }
fc9f54d5 4055 else
543af7ab 4056 mpz_set_si (result->value.integer, (long int) 1);
fc9f54d5
FXC
4057 }
4058
69dcd06a 4059done:
fc9f54d5 4060 return range_check (result, upper ? "UBOUND" : "LBOUND");
69dcd06a
DK
4061
4062returnNull:
4063 gfc_free_expr (result);
4064 return NULL;
fc9f54d5
FXC
4065}
4066
4067
4068static gfc_expr *
5cda5098 4069simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
fc9f54d5
FXC
4070{
4071 gfc_ref *ref;
4072 gfc_array_spec *as;
4073 int d;
4074
c49ea23d
PT
4075 if (array->ts.type == BT_CLASS)
4076 return NULL;
4077
9f1dce56 4078 if (array->expr_type != EXPR_VARIABLE)
69dcd06a
DK
4079 {
4080 as = NULL;
4081 ref = NULL;
4082 goto done;
4083 }
9f1dce56 4084
6de9cd9a
DN
4085 /* Follow any component references. */
4086 as = array->symtree->n.sym->as;
2a4a7830
TS
4087 for (ref = array->ref; ref; ref = ref->next)
4088 {
4089 switch (ref->type)
4090 {
4091 case REF_ARRAY:
4092 switch (ref->u.ar.type)
4093 {
4094 case AR_ELEMENT:
4095 as = NULL;
4096 continue;
4097
4098 case AR_FULL:
4099 /* We're done because 'as' has already been set in the
4100 previous iteration. */
11642de8 4101 goto done;
2a4a7830 4102
2a4a7830
TS
4103 case AR_UNKNOWN:
4104 return NULL;
543af7ab
TK
4105
4106 case AR_SECTION:
4107 as = ref->u.ar.as;
4108 goto done;
2a4a7830
TS
4109 }
4110
4111 gcc_unreachable ();
4112
4113 case REF_COMPONENT:
4114 as = ref->u.c.component->as;
4115 continue;
4116
4117 case REF_SUBSTRING:
4118 continue;
4119 }
4120 }
4121
4122 gcc_unreachable ();
4123
4124 done:
fc9f54d5 4125
22fa926f
MM
4126 if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_RANK
4127 || (as->type == AS_ASSUMED_SHAPE && upper)))
2a4a7830
TS
4128 return NULL;
4129
22fa926f
MM
4130 gcc_assert (!as
4131 || (as->type != AS_DEFERRED
4132 && array->expr_type == EXPR_VARIABLE
21cd397e
MM
4133 && !gfc_expr_attr (array).allocatable
4134 && !gfc_expr_attr (array).pointer));
22fa926f 4135
fc9f54d5 4136 if (dim == NULL)
6de9cd9a 4137 {
fc9f54d5
FXC
4138 /* Multi-dimensional bounds. */
4139 gfc_expr *bounds[GFC_MAX_DIMENSIONS];
4140 gfc_expr *e;
5cda5098 4141 int k;
6de9cd9a 4142
fc9f54d5 4143 /* UBOUND(ARRAY) is not valid for an assumed-size array. */
69dcd06a 4144 if (upper && as && as->type == AS_ASSUMED_SIZE)
fc9f54d5
FXC
4145 {
4146 /* An error message will be emitted in
4147 check_assumed_size_reference (resolve.c). */
4148 return &gfc_bad_expr;
4149 }
2a4a7830 4150
fc9f54d5
FXC
4151 /* Simplify the bounds for each dimension. */
4152 for (d = 0; d < array->rank; d++)
4153 {
64f002ed
TB
4154 bounds[d] = simplify_bound_dim (array, kind, d + 1, upper, as, ref,
4155 false);
fc9f54d5
FXC
4156 if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
4157 {
4158 int j;
9f1dce56 4159
fc9f54d5
FXC
4160 for (j = 0; j < d; j++)
4161 gfc_free_expr (bounds[j]);
4162 return bounds[d];
4163 }
4164 }
2a4a7830 4165
fc9f54d5 4166 /* Allocate the result expression. */
5cda5098 4167 k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
b7e75771 4168 gfc_default_integer_kind);
5cda5098 4169 if (k == -1)
b7e75771
JD
4170 return &gfc_bad_expr;
4171
4172 e = gfc_get_array_expr (BT_INTEGER, k, &array->where);
fc9f54d5
FXC
4173
4174 /* The result is a rank 1 array; its size is the rank of the first
4175 argument to {L,U}BOUND. */
4176 e->rank = 1;
4177 e->shape = gfc_get_shape (1);
4178 mpz_init_set_ui (e->shape[0], array->rank);
4179
4180 /* Create the constructor for this array. */
fc9f54d5 4181 for (d = 0; d < array->rank; d++)
b7e75771
JD
4182 gfc_constructor_append_expr (&e->value.constructor,
4183 bounds[d], &e->where);
fc9f54d5
FXC
4184
4185 return e;
9f1dce56
FXC
4186 }
4187 else
4188 {
fc9f54d5
FXC
4189 /* A DIM argument is specified. */
4190 if (dim->expr_type != EXPR_CONSTANT)
4191 return NULL;
9f1dce56 4192
fc9f54d5
FXC
4193 d = mpz_get_si (dim->value.integer);
4194
c62c6622 4195 if ((d < 1 || d > array->rank)
69dcd06a 4196 || (d == array->rank && as && as->type == AS_ASSUMED_SIZE && upper))
fc9f54d5
FXC
4197 {
4198 gfc_error ("DIM argument at %L is out of bounds", &dim->where);
4199 return &gfc_bad_expr;
4200 }
4201
c62c6622
TB
4202 if (as && as->type == AS_ASSUMED_RANK)
4203 return NULL;
4204
64f002ed
TB
4205 return simplify_bound_dim (array, kind, d, upper, as, ref, false);
4206 }
4207}
4208
4209
4210static gfc_expr *
4211simplify_cobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
4212{
4213 gfc_ref *ref;
4214 gfc_array_spec *as;
4215 int d;
4216
4217 if (array->expr_type != EXPR_VARIABLE)
4218 return NULL;
4219
4220 /* Follow any component references. */
c49ea23d
PT
4221 as = (array->ts.type == BT_CLASS && array->ts.u.derived->components)
4222 ? array->ts.u.derived->components->as
4223 : array->symtree->n.sym->as;
64f002ed
TB
4224 for (ref = array->ref; ref; ref = ref->next)
4225 {
4226 switch (ref->type)
4227 {
4228 case REF_ARRAY:
4229 switch (ref->u.ar.type)
4230 {
4231 case AR_ELEMENT:
dbeebc56 4232 if (ref->u.ar.as->corank > 0)
a10da381 4233 {
dbeebc56 4234 gcc_assert (as == ref->u.ar.as);
a10da381
TB
4235 goto done;
4236 }
64f002ed
TB
4237 as = NULL;
4238 continue;
4239
4240 case AR_FULL:
4241 /* We're done because 'as' has already been set in the
4242 previous iteration. */
11642de8 4243 goto done;
64f002ed
TB
4244
4245 case AR_UNKNOWN:
4246 return NULL;
4247
4248 case AR_SECTION:
4249 as = ref->u.ar.as;
4250 goto done;
4251 }
4252
4253 gcc_unreachable ();
4254
4255 case REF_COMPONENT:
4256 as = ref->u.c.component->as;
4257 continue;
4258
4259 case REF_SUBSTRING:
4260 continue;
4261 }
4262 }
4263
c49ea23d
PT
4264 if (!as)
4265 gcc_unreachable ();
64f002ed
TB
4266
4267 done:
4268
c49ea23d 4269 if (as->cotype == AS_DEFERRED || as->cotype == AS_ASSUMED_SHAPE)
64f002ed
TB
4270 return NULL;
4271
4272 if (dim == NULL)
4273 {
4274 /* Multi-dimensional cobounds. */
4275 gfc_expr *bounds[GFC_MAX_DIMENSIONS];
4276 gfc_expr *e;
4277 int k;
4278
4279 /* Simplify the cobounds for each dimension. */
4280 for (d = 0; d < as->corank; d++)
4281 {
c49ea23d 4282 bounds[d] = simplify_bound_dim (array, kind, d + 1 + as->rank,
64f002ed
TB
4283 upper, as, ref, true);
4284 if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
4285 {
4286 int j;
4287
4288 for (j = 0; j < d; j++)
4289 gfc_free_expr (bounds[j]);
4290 return bounds[d];
4291 }
4292 }
4293
4294 /* Allocate the result expression. */
4295 e = gfc_get_expr ();
4296 e->where = array->where;
4297 e->expr_type = EXPR_ARRAY;
4298 e->ts.type = BT_INTEGER;
4299 k = get_kind (BT_INTEGER, kind, upper ? "UCOBOUND" : "LCOBOUND",
8b704316 4300 gfc_default_integer_kind);
64f002ed
TB
4301 if (k == -1)
4302 {
4303 gfc_free_expr (e);
4304 return &gfc_bad_expr;
4305 }
4306 e->ts.kind = k;
4307
4308 /* The result is a rank 1 array; its size is the rank of the first
4309 argument to {L,U}COBOUND. */
4310 e->rank = 1;
4311 e->shape = gfc_get_shape (1);
4312 mpz_init_set_ui (e->shape[0], as->corank);
4313
4314 /* Create the constructor for this array. */
4315 for (d = 0; d < as->corank; d++)
4316 gfc_constructor_append_expr (&e->value.constructor,
4317 bounds[d], &e->where);
4318 return e;
4319 }
4320 else
4321 {
4322 /* A DIM argument is specified. */
4323 if (dim->expr_type != EXPR_CONSTANT)
4324 return NULL;
4325
4326 d = mpz_get_si (dim->value.integer);
4327
4328 if (d < 1 || d > as->corank)
4329 {
4330 gfc_error ("DIM argument at %L is out of bounds", &dim->where);
4331 return &gfc_bad_expr;
4332 }
4333
c49ea23d 4334 return simplify_bound_dim (array, kind, d+as->rank, upper, as, ref, true);
fc9f54d5 4335 }
6de9cd9a
DN
4336}
4337
4338
4339gfc_expr *
5cda5098 4340gfc_simplify_lbound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
6de9cd9a 4341{
5cda5098 4342 return simplify_bound (array, dim, kind, 0);
6de9cd9a
DN
4343}
4344
4345
64f002ed
TB
4346gfc_expr *
4347gfc_simplify_lcobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
4348{
a3935ffc 4349 return simplify_cobound (array, dim, kind, 0);
64f002ed
TB
4350}
4351
414f00e9
SB
4352gfc_expr *
4353gfc_simplify_leadz (gfc_expr *e)
4354{
414f00e9
SB
4355 unsigned long lz, bs;
4356 int i;
4357
4358 if (e->expr_type != EXPR_CONSTANT)
4359 return NULL;
4360
4361 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
4362 bs = gfc_integer_kinds[i].bit_size;
4363 if (mpz_cmp_si (e->value.integer, 0) == 0)
4364 lz = bs;
0a05c536
FXC
4365 else if (mpz_cmp_si (e->value.integer, 0) < 0)
4366 lz = 0;
414f00e9
SB
4367 else
4368 lz = bs - mpz_sizeinbase (e->value.integer, 2);
4369
b7e75771 4370 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, lz);
414f00e9
SB
4371}
4372
4373
6de9cd9a 4374gfc_expr *
5cda5098 4375gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
4376{
4377 gfc_expr *result;
5cda5098
FXC
4378 int k = get_kind (BT_INTEGER, kind, "LEN", gfc_default_integer_kind);
4379
4380 if (k == -1)
4381 return &gfc_bad_expr;
6de9cd9a 4382
49914d03
FXC
4383 if (e->expr_type == EXPR_CONSTANT)
4384 {
b7e75771 4385 result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
49914d03 4386 mpz_set_si (result->value.integer, e->value.character.length);
b7e75771 4387 return range_check (result, "LEN");
49914d03 4388 }
b7e75771
JD
4389 else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
4390 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
4391 && e->ts.u.cl->length->ts.type == BT_INTEGER)
49914d03 4392 {
b7e75771 4393 result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
bc21d315 4394 mpz_set (result->value.integer, e->ts.u.cl->length->value.integer);
b7e75771 4395 return range_check (result, "LEN");
49914d03 4396 }
5b384b3d
PT
4397 else if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
4398 && e->symtree->n.sym
1f8dd420 4399 && e->symtree->n.sym->ts.type != BT_DERIVED
5b384b3d 4400 && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target
1f8dd420
AV
4401 && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED
4402 && e->symtree->n.sym->assoc->target->symtree->n.sym
4403 && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym))
4404
5b384b3d
PT
4405 /* The expression in assoc->target points to a ref to the _data component
4406 of the unlimited polymorphic entity. To get the _len component the last
4407 _data ref needs to be stripped and a ref to the _len component added. */
4408 return gfc_get_len_component (e->symtree->n.sym->assoc->target);
b7e75771
JD
4409 else
4410 return NULL;
6de9cd9a
DN
4411}
4412
4413
4414gfc_expr *
5cda5098 4415gfc_simplify_len_trim (gfc_expr *e, gfc_expr *kind)
6de9cd9a
DN
4416{
4417 gfc_expr *result;
6b271a2e 4418 size_t count, len, i;
5cda5098
FXC
4419 int k = get_kind (BT_INTEGER, kind, "LEN_TRIM", gfc_default_integer_kind);
4420
4421 if (k == -1)
4422 return &gfc_bad_expr;
6de9cd9a
DN
4423
4424 if (e->expr_type != EXPR_CONSTANT)
4425 return NULL;
4426
6de9cd9a 4427 len = e->value.character.length;
6de9cd9a
DN
4428 for (count = 0, i = 1; i <= len; i++)
4429 if (e->value.character.string[len - i] == ' ')
4430 count++;
4431 else
4432 break;
4433
b7e75771 4434 result = gfc_get_int_expr (k, &e->where, len - count);
6de9cd9a
DN
4435 return range_check (result, "LEN_TRIM");
4436}
4437
75be5dc0 4438gfc_expr *
b7e75771 4439gfc_simplify_lgamma (gfc_expr *x)
75be5dc0 4440{
75be5dc0 4441 gfc_expr *result;
5b550abd 4442 int sg;
75be5dc0
TB
4443
4444 if (x->expr_type != EXPR_CONSTANT)
4445 return NULL;
4446
b7e75771 4447 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
5b550abd 4448 mpfr_lgamma (result->value.real, &sg, x->value.real, GFC_RND_MODE);
75be5dc0
TB
4449
4450 return range_check (result, "LGAMMA");
75be5dc0
TB
4451}
4452
6de9cd9a
DN
4453
4454gfc_expr *
edf1eac2 4455gfc_simplify_lge (gfc_expr *a, gfc_expr *b)
6de9cd9a 4456{
6de9cd9a
DN
4457 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4458 return NULL;
4459
b7e75771
JD
4460 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4461 gfc_compare_string (a, b) >= 0);
6de9cd9a
DN
4462}
4463
4464
4465gfc_expr *
edf1eac2 4466gfc_simplify_lgt (gfc_expr *a, gfc_expr *b)
6de9cd9a 4467{
6de9cd9a
DN
4468 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4469 return NULL;
4470
b7e75771
JD
4471 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4472 gfc_compare_string (a, b) > 0);
6de9cd9a
DN
4473}
4474
4475
4476gfc_expr *
edf1eac2 4477gfc_simplify_lle (gfc_expr *a, gfc_expr *b)
6de9cd9a 4478{
6de9cd9a
DN
4479 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4480 return NULL;
4481
b7e75771
JD
4482 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4483 gfc_compare_string (a, b) <= 0);
6de9cd9a
DN
4484}
4485
4486
4487gfc_expr *
edf1eac2 4488gfc_simplify_llt (gfc_expr *a, gfc_expr *b)
6de9cd9a 4489{
6de9cd9a
DN
4490 if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
4491 return NULL;
4492
b7e75771
JD
4493 return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
4494 gfc_compare_string (a, b) < 0);
6de9cd9a
DN
4495}
4496
4497
4498gfc_expr *
edf1eac2 4499gfc_simplify_log (gfc_expr *x)
6de9cd9a
DN
4500{
4501 gfc_expr *result;
6de9cd9a
DN
4502
4503 if (x->expr_type != EXPR_CONSTANT)
4504 return NULL;
4505
b7e75771 4506 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
f8e566e5 4507
6de9cd9a
DN
4508 switch (x->ts.type)
4509 {
4510 case BT_REAL:
03ddaf35 4511 if (mpfr_sgn (x->value.real) <= 0)
6de9cd9a 4512 {
edf1eac2
SK
4513 gfc_error ("Argument of LOG at %L cannot be less than or equal "
4514 "to zero", &x->where);
6de9cd9a
DN
4515 gfc_free_expr (result);
4516 return &gfc_bad_expr;
4517 }
4518
edf1eac2 4519 mpfr_log (result->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
4520 break;
4521
4522 case BT_COMPLEX:
d2af8cc6
FXC
4523 if (mpfr_zero_p (mpc_realref (x->value.complex))
4524 && mpfr_zero_p (mpc_imagref (x->value.complex)))
6de9cd9a
DN
4525 {
4526 gfc_error ("Complex argument of LOG at %L cannot be zero",
4527 &x->where);
4528 gfc_free_expr (result);
4529 return &gfc_bad_expr;
4530 }
4531
7306494a 4532 gfc_set_model_kind (x->ts.kind);
eb6f9a86 4533 mpc_log (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
6de9cd9a
DN
4534 break;
4535
4536 default:
4537 gfc_internal_error ("gfc_simplify_log: bad type");
4538 }
4539
4540 return range_check (result, "LOG");
4541}
4542
4543
4544gfc_expr *
edf1eac2 4545gfc_simplify_log10 (gfc_expr *x)
6de9cd9a
DN
4546{
4547 gfc_expr *result;
4548
4549 if (x->expr_type != EXPR_CONSTANT)
4550 return NULL;
4551
03ddaf35 4552 if (mpfr_sgn (x->value.real) <= 0)
6de9cd9a 4553 {
edf1eac2
SK
4554 gfc_error ("Argument of LOG10 at %L cannot be less than or equal "
4555 "to zero", &x->where);
6de9cd9a
DN
4556 return &gfc_bad_expr;
4557 }
4558
b7e75771 4559 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
f8e566e5 4560 mpfr_log10 (result->value.real, x->value.real, GFC_RND_MODE);
6de9cd9a
DN
4561
4562 return range_check (result, "LOG10");
4563}
4564
4565
4566gfc_expr *
edf1eac2 4567gfc_simplify_logical (gfc_expr *e, gfc_expr *k)
6de9cd9a 4568{
6de9cd9a
DN
4569 int kind;
4570
9d64df18 4571 kind = get_kind (BT_LOGICAL, k, "LOGICAL", gfc_default_logical_kind);
6de9cd9a
DN
4572 if (kind < 0)
4573 return &gfc_bad_expr;
4574
4575 if (e->expr_type != EXPR_CONSTANT)
4576 return NULL;
4577
b7e75771 4578 return gfc_get_logical_expr (kind, &e->where, e->value.logical);
6de9cd9a
DN
4579}
4580
4581
8ec259c1
DF
4582gfc_expr*
4583gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
4584{
4585 gfc_expr *result;
b7e75771
JD
4586 int row, result_rows, col, result_columns;
4587 int stride_a, offset_a, stride_b, offset_b;
8ec259c1
DF
4588
4589 if (!is_constant_array_expr (matrix_a)
4590 || !is_constant_array_expr (matrix_b))
4591 return NULL;
4592
f5240750
SK
4593 /* MATMUL should do mixed-mode arithmetic. Set the result type. */
4594 if (matrix_a->ts.type != matrix_b->ts.type)
4595 {
4596 gfc_expr e;
4597 e.expr_type = EXPR_OP;
4598 gfc_clear_ts (&e.ts);
4599 e.value.op.op = INTRINSIC_NONE;
4600 e.value.op.op1 = matrix_a;
4601 e.value.op.op2 = matrix_b;
4602 gfc_type_convert_binary (&e, 1);
4603 result = gfc_get_array_expr (e.ts.type, e.ts.kind, &matrix_a->where);
4604 }
4605 else
4606 {
4607 result = gfc_get_array_expr (matrix_a->ts.type, matrix_a->ts.kind,
4608 &matrix_a->where);
4609 }
8ec259c1
DF
4610
4611 if (matrix_a->rank == 1 && matrix_b->rank == 2)
4612 {
4613 result_rows = 1;
711db0a6 4614 result_columns = mpz_get_si (matrix_b->shape[1]);
8ec259c1
DF
4615 stride_a = 1;
4616 stride_b = mpz_get_si (matrix_b->shape[0]);
4617
4618 result->rank = 1;
4619 result->shape = gfc_get_shape (result->rank);
4620 mpz_init_set_si (result->shape[0], result_columns);
4621 }
4622 else if (matrix_a->rank == 2 && matrix_b->rank == 1)
4623 {
711db0a6 4624 result_rows = mpz_get_si (matrix_a->shape[0]);
8ec259c1
DF
4625 result_columns = 1;
4626 stride_a = mpz_get_si (matrix_a->shape[0]);
4627 stride_b = 1;
4628
4629 result->rank = 1;
4630 result->shape = gfc_get_shape (result->rank);
4631 mpz_init_set_si (result->shape[0], result_rows);
4632 }
4633 else if (matrix_a->rank == 2 && matrix_b->rank == 2)
4634 {
4635 result_rows = mpz_get_si (matrix_a->shape[0]);
4636 result_columns = mpz_get_si (matrix_b->shape[1]);
711db0a6 4637 stride_a = mpz_get_si (matrix_a->shape[0]);
8ec259c1
DF
4638 stride_b = mpz_get_si (matrix_b->shape[0]);
4639
4640 result->rank = 2;
4641 result->shape = gfc_get_shape (result->rank);
4642 mpz_init_set_si (result->shape[0], result_rows);
4643 mpz_init_set_si (result->shape[1], result_columns);
4644 }
4645 else
4646 gcc_unreachable();
4647
b7e75771 4648 offset_a = offset_b = 0;
8ec259c1
DF
4649 for (col = 0; col < result_columns; ++col)
4650 {
b7e75771 4651 offset_a = 0;
8ec259c1
DF
4652
4653 for (row = 0; row < result_rows; ++row)
4654 {
b7e75771 4655 gfc_expr *e = compute_dot_product (matrix_a, stride_a, offset_a,
eebb98a5 4656 matrix_b, 1, offset_b, false);
b7e75771
JD
4657 gfc_constructor_append_expr (&result->value.constructor,
4658 e, NULL);
8ec259c1 4659
b7e75771
JD
4660 offset_a += 1;
4661 }
8ec259c1 4662
b7e75771 4663 offset_b += stride_b;
8ec259c1
DF
4664 }
4665
4666 return result;
4667}
4668
4669
88a95a11
FXC
4670gfc_expr *
4671gfc_simplify_maskr (gfc_expr *i, gfc_expr *kind_arg)
4672{
4673 gfc_expr *result;
4674 int kind, arg, k;
88a95a11
FXC
4675
4676 if (i->expr_type != EXPR_CONSTANT)
4677 return NULL;
8b704316 4678
88a95a11
FXC
4679 kind = get_kind (BT_INTEGER, kind_arg, "MASKR", gfc_default_integer_kind);
4680 if (kind == -1)
4681 return &gfc_bad_expr;
4682 k = gfc_validate_kind (BT_INTEGER, kind, false);
4683
51f03c6b
JJ
4684 bool fail = gfc_extract_int (i, &arg);
4685 gcc_assert (!fail);
88a95a11
FXC
4686
4687 result = gfc_get_constant_expr (BT_INTEGER, kind, &i->where);
4688
4689 /* MASKR(n) = 2^n - 1 */
4690 mpz_set_ui (result->value.integer, 1);
4691 mpz_mul_2exp (result->value.integer, result->value.integer, arg);
4692 mpz_sub_ui (result->value.integer, result->value.integer, 1);
4693
d01b2c21 4694 gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
88a95a11
FXC
4695
4696 return result;
4697}
4698
4699
4700gfc_expr *
4701gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_arg)
4702{
4703 gfc_expr *result;
4704 int kind, arg, k;
88a95a11
FXC
4705 mpz_t z;
4706
4707 if (i->expr_type != EXPR_CONSTANT)
4708 return NULL;
8b704316 4709
88a95a11
FXC
4710 kind = get_kind (BT_INTEGER, kind_arg, "MASKL", gfc_default_integer_kind);
4711 if (kind == -1)
4712 return &gfc_bad_expr;
4713 k = gfc_validate_kind (BT_INTEGER, kind, false);
4714
51f03c6b
JJ
4715 bool fail = gfc_extract_int (i, &arg);
4716 gcc_assert (!fail);
88a95a11
FXC
4717
4718 result = gfc_get_constant_expr (BT_INTEGER, kind, &i->where);
4719
4720 /* MASKL(n) = 2^bit_size - 2^(bit_size - n) */
4721 mpz_init_set_ui (z, 1);
4722 mpz_mul_2exp (z, z, gfc_integer_kinds[k].bit_size);
4723 mpz_set_ui (result->value.integer, 1);
4724 mpz_mul_2exp (result->value.integer, result->value.integer,
4725 gfc_integer_kinds[k].bit_size - arg);
4726 mpz_sub (result->value.integer, z, result->value.integer);
4727 mpz_clear (z);
4728
d01b2c21 4729 gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
88a95a11
FXC
4730
4731 return result;
4732}
4733
4734
8f2b565d
DF
4735gfc_expr *
4736gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
4737{
03580130
TB
4738 gfc_expr * result;
4739 gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor;
4740
4741 if (mask->expr_type == EXPR_CONSTANT)
4742 return gfc_get_parentheses (gfc_copy_expr (mask->value.logical
4743 ? tsource : fsource));
4744
4745 if (!mask->rank || !is_constant_array_expr (mask)
4746 || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource))
8f2b565d
DF
4747 return NULL;
4748
03580130
TB
4749 result = gfc_get_array_expr (tsource->ts.type, tsource->ts.kind,
4750 &tsource->where);
4751 if (tsource->ts.type == BT_DERIVED)
4752 result->ts.u.derived = tsource->ts.u.derived;
4753 else if (tsource->ts.type == BT_CHARACTER)
4754 result->ts.u.cl = tsource->ts.u.cl;
4755
4756 tsource_ctor = gfc_constructor_first (tsource->value.constructor);
4757 fsource_ctor = gfc_constructor_first (fsource->value.constructor);
4758 mask_ctor = gfc_constructor_first (mask->value.constructor);
4759
4760 while (mask_ctor)
4761 {
4762 if (mask_ctor->expr->value.logical)
4763 gfc_constructor_append_expr (&result->value.constructor,
4764 gfc_copy_expr (tsource_ctor->expr),
4765 NULL);
4766 else
4767 gfc_constructor_append_expr (&result->value.constructor,
4768 gfc_copy_expr (fsource_ctor->expr),
4769 NULL);
4770 tsource_ctor = gfc_constructor_next (tsource_ctor);
4771 fsource_ctor = gfc_constructor_next (fsource_ctor);
4772 mask_ctor = gfc_constructor_next (mask_ctor);
4773 }
4774
4775 result->shape = gfc_get_shape (1);
4776 gfc_array_size (result, &result->shape[0]);
4777
4778 return result;
8f2b565d
DF
4779}
4780
4781
88a95a11
FXC
4782gfc_expr *
4783gfc_simplify_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask_expr)
4784{
4785 mpz_t arg1, arg2, mask;
4786 gfc_expr *result;
4787
4788 if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT
4789 || mask_expr->expr_type != EXPR_CONSTANT)
4790 return NULL;
4791
4792 result = gfc_get_constant_expr (BT_INTEGER, i->ts.kind, &i->where);
4793
4794 /* Convert all argument to unsigned. */
4795 mpz_init_set (arg1, i->value.integer);
4796 mpz_init_set (arg2, j->value.integer);
4797 mpz_init_set (mask, mask_expr->value.integer);
4798
4799 /* MERGE_BITS(I,J,MASK) = IOR (IAND (I, MASK), IAND (J, NOT (MASK))). */
4800 mpz_and (arg1, arg1, mask);
4801 mpz_com (mask, mask);
4802 mpz_and (arg2, arg2, mask);
4803 mpz_ior (result->value.integer, arg1, arg2);
4804
4805 mpz_clear (arg1);
4806 mpz_clear (arg2);
4807 mpz_clear (mask);
4808
4809 return result;
4810}
4811
4812
4813/* Selects between current value and extremum for simplify_min_max
5a0193ee 4814 and simplify_minval_maxval. */
a1d6c052 4815static int
5a0193ee
PT
4816min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign)
4817{
a1d6c052
TK
4818 int ret;
4819
5a0193ee
PT
4820 switch (arg->ts.type)
4821 {
4822 case BT_INTEGER:
a1d6c052
TK
4823 ret = mpz_cmp (arg->value.integer,
4824 extremum->value.integer) * sign;
4825 if (ret > 0)
4826 mpz_set (extremum->value.integer, arg->value.integer);
5a0193ee
PT
4827 break;
4828
4829 case BT_REAL:
a1d6c052
TK
4830 if (mpfr_nan_p (extremum->value.real))
4831 {
4832 ret = 1;
4833 mpfr_set (extremum->value.real, arg->value.real, GFC_RND_MODE);
4834 }
4835 else if (mpfr_nan_p (arg->value.real))
4836 ret = -1;
5a0193ee 4837 else
a1d6c052
TK
4838 {
4839 ret = mpfr_cmp (arg->value.real, extremum->value.real) * sign;
4840 if (ret > 0)
4841 mpfr_set (extremum->value.real, arg->value.real, GFC_RND_MODE);
4842 }
5a0193ee
PT
4843 break;
4844
4845 case BT_CHARACTER:
4846#define LENGTH(x) ((x)->value.character.length)
4847#define STRING(x) ((x)->value.character.string)
524af0d6 4848 if (LENGTH (extremum) < LENGTH(arg))
5a0193ee
PT
4849 {
4850 gfc_char_t *tmp = STRING(extremum);
4851
4852 STRING(extremum) = gfc_get_wide_string (LENGTH(arg) + 1);
4853 memcpy (STRING(extremum), tmp,
4854 LENGTH(extremum) * sizeof (gfc_char_t));
4855 gfc_wide_memset (&STRING(extremum)[LENGTH(extremum)], ' ',
4856 LENGTH(arg) - LENGTH(extremum));
4857 STRING(extremum)[LENGTH(arg)] = '\0'; /* For debugger */
4858 LENGTH(extremum) = LENGTH(arg);
cede9502 4859 free (tmp);
5a0193ee 4860 }
a1d6c052
TK
4861 ret = gfc_compare_string (arg, extremum) * sign;
4862 if (ret > 0)
5a0193ee 4863 {
cede9502 4864 free (STRING(extremum));
5a0193ee
PT
4865 STRING(extremum) = gfc_get_wide_string (LENGTH(extremum) + 1);
4866 memcpy (STRING(extremum), STRING(arg),
4867 LENGTH(arg) * sizeof (gfc_char_t));
4868 gfc_wide_memset (&STRING(extremum)[LENGTH(arg)], ' ',
4869 LENGTH(extremum) - LENGTH(arg));
4870 STRING(extremum)[LENGTH(extremum)] = '\0'; /* For debugger */
4871 }
4872#undef LENGTH
4873#undef STRING
4874 break;
8b704316 4875
5a0193ee
PT
4876 default:
4877 gfc_internal_error ("simplify_min_max(): Bad type in arglist");
4878 }
a1d6c052 4879 return ret;
5a0193ee
PT
4880}
4881
4882
6de9cd9a
DN
4883/* This function is special since MAX() can take any number of
4884 arguments. The simplified expression is a rewritten version of the
4885 argument list containing at most one constant element. Other
4886 constant elements are deleted. Because the argument list has
4887 already been checked, this function always succeeds. sign is 1 for
4888 MAX(), -1 for MIN(). */
4889
4890static gfc_expr *
edf1eac2 4891simplify_min_max (gfc_expr *expr, int sign)
6de9cd9a
DN
4892{
4893 gfc_actual_arglist *arg, *last, *extremum;
4894 gfc_intrinsic_sym * specific;
4895
4896 last = NULL;
4897 extremum = NULL;
4898 specific = expr->value.function.isym;
4899
4900 arg = expr->value.function.actual;
4901
4902 for (; arg; last = arg, arg = arg->next)
4903 {
4904 if (arg->expr->expr_type != EXPR_CONSTANT)
4905 continue;
4906
4907 if (extremum == NULL)
4908 {
4909 extremum = arg;
4910 continue;
4911 }
4912
5a0193ee 4913 min_max_choose (arg->expr, extremum->expr, sign);
6de9cd9a
DN
4914
4915 /* Delete the extra constant argument. */
99c25a87 4916 last->next = arg->next;
6de9cd9a
DN
4917
4918 arg->next = NULL;
4919 gfc_free_actual_arglist (arg);
4920 arg = last;
4921 }
4922
4923 /* If there is one value left, replace the function call with the
4924 expression. */
4925 if (expr->value.function.actual->next != NULL)
4926 return NULL;
4927
4928 /* Convert to the correct type and kind. */
8b704316 4929 if (expr->ts.type != BT_UNKNOWN)
6de9cd9a
DN
4930 return gfc_convert_constant (expr->value.function.actual->expr,
4931 expr->ts.type, expr->ts.kind);
4932
8b704316 4933 if (specific->ts.type != BT_UNKNOWN)
6de9cd9a 4934 return gfc_convert_constant (expr->value.function.actual->expr,
8b704316
PT
4935 specific->ts.type, specific->ts.kind);
4936
6de9cd9a
DN
4937 return gfc_copy_expr (expr->value.function.actual->expr);
4938}
4939
4940
4941gfc_expr *
edf1eac2 4942gfc_simplify_min (gfc_expr *e)
6de9cd9a 4943{
6de9cd9a
DN
4944 return simplify_min_max (e, -1);
4945}
4946
4947
4948gfc_expr *
edf1eac2 4949gfc_simplify_max (gfc_expr *e)
6de9cd9a 4950{
6de9cd9a
DN
4951 return simplify_min_max (e, 1);
4952}
4953
317fa064 4954/* Helper function for gfc_simplify_minval. */
5a0193ee
PT
4955
4956static gfc_expr *
317fa064 4957gfc_min (gfc_expr *op1, gfc_expr *op2)
5a0193ee 4958{
317fa064
TK
4959 min_max_choose (op1, op2, -1);
4960 gfc_free_expr (op1);
4961 return op2;
5a0193ee
PT
4962}
4963
317fa064 4964/* Simplify minval for constant arrays. */
5a0193ee
PT
4965
4966gfc_expr *
4967gfc_simplify_minval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
4968{
317fa064
TK
4969 return simplify_transformation (array, dim, mask, INT_MAX, gfc_min);
4970}
4971
4972/* Helper function for gfc_simplify_maxval. */
b7e75771 4973
317fa064
TK
4974static gfc_expr *
4975gfc_max (gfc_expr *op1, gfc_expr *op2)
4976{
4977 min_max_choose (op1, op2, 1);
4978 gfc_free_expr (op1);
4979 return op2;
5a0193ee
PT
4980}
4981
4982
317fa064
TK
4983/* Simplify maxval for constant arrays. */
4984
5a0193ee
PT
4985gfc_expr *
4986gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
4987{
317fa064 4988 return simplify_transformation (array, dim, mask, INT_MIN, gfc_max);
5a0193ee
PT
4989}
4990
4991
a1d6c052
TK
4992/* Transform minloc or maxloc of an array, according to MASK,
4993 to the scalar result. This code is mostly identical to
4994 simplify_transformation_to_scalar. */
4995
4996static gfc_expr *
4997simplify_minmaxloc_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
4998 gfc_expr *extremum, int sign)
4999{
5000 gfc_expr *a, *m;
5001 gfc_constructor *array_ctor, *mask_ctor;
5002 mpz_t count;
5003
5004 mpz_set_si (result->value.integer, 0);
5005
5006
5007 /* Shortcut for constant .FALSE. MASK. */
5008 if (mask
5009 && mask->expr_type == EXPR_CONSTANT
5010 && !mask->value.logical)
5011 return result;
5012
5013 array_ctor = gfc_constructor_first (array->value.constructor);
5014 if (mask && mask->expr_type == EXPR_ARRAY)
5015 mask_ctor = gfc_constructor_first (mask->value.constructor);
5016 else
5017 mask_ctor = NULL;
5018
5019 mpz_init_set_si (count, 0);
5020 while (array_ctor)
5021 {
5022 mpz_add_ui (count, count, 1);
5023 a = array_ctor->expr;
5024 array_ctor = gfc_constructor_next (array_ctor);
5025 /* A constant MASK equals .TRUE. here and can be ignored. */
5026 if (mask_ctor)
5027 {
5028 m = mask_ctor->expr;
5029 mask_ctor = gfc_constructor_next (mask_ctor);
5030 if (!m->value.logical)
5031 continue;
5032 }
5033 if (min_max_choose (a, extremum, sign) > 0)
5034 mpz_set (result->value.integer, count);
5035 }
5036 mpz_clear (count);
5037 gfc_free_expr (extremum);
5038 return result;
5039}
5040
5041/* Simplify minloc / maxloc in the absence of a dim argument. */
5042
5043static gfc_expr *
5044simplify_minmaxloc_nodim (gfc_expr *result, gfc_expr *extremum,
5045 gfc_expr *array, gfc_expr *mask, int sign)
5046{
5047 ssize_t res[GFC_MAX_DIMENSIONS];
5048 int i, n;
5049 gfc_constructor *result_ctor, *array_ctor, *mask_ctor;
5050 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
5051 sstride[GFC_MAX_DIMENSIONS];
5052 gfc_expr *a, *m;
5053 bool continue_loop;
5054 bool ma;
5055
5056 for (i = 0; i<array->rank; i++)
5057 res[i] = -1;
5058
5059 /* Shortcut for constant .FALSE. MASK. */
5060 if (mask
5061 && mask->expr_type == EXPR_CONSTANT
5062 && !mask->value.logical)
5063 goto finish;
5064
5065 for (i = 0; i < array->rank; i++)
5066 {
5067 count[i] = 0;
5068 sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
5069 extent[i] = mpz_get_si (array->shape[i]);
5070 if (extent[i] <= 0)
5071 goto finish;
5072 }
5073
5074 continue_loop = true;
5075 array_ctor = gfc_constructor_first (array->value.constructor);
5076 if (mask && mask->rank > 0)
5077 mask_ctor = gfc_constructor_first (mask->value.constructor);
5078 else
5079 mask_ctor = NULL;
5080
5081 /* Loop over the array elements (and mask), keeping track of
5082 the indices to return. */
5083 while (continue_loop)
5084 {
5085 do
5086 {
5087 a = array_ctor->expr;
5088 if (mask_ctor)
5089 {
5090 m = mask_ctor->expr;
5091 ma = m->value.logical;
5092 mask_ctor = gfc_constructor_next (mask_ctor);
5093 }
5094 else
5095 ma = true;
5096
5097 if (ma && min_max_choose (a, extremum, sign) > 0)
5098 {
5099 for (i = 0; i<array->rank; i++)
5100 res[i] = count[i];
5101 }
5102 array_ctor = gfc_constructor_next (array_ctor);
5103 count[0] ++;
5104 } while (count[0] != extent[0]);
5105 n = 0;
5106 do
5107 {
5108 /* When we get to the end of a dimension, reset it and increment
5109 the next dimension. */
5110 count[n] = 0;
5111 n++;
5112 if (n >= array->rank)
5113 {
5114 continue_loop = false;
5115 break;
5116 }
5117 else
5118 count[n] ++;
5119 } while (count[n] == extent[n]);
5120 }
5121
5122 finish:
5123 gfc_free_expr (extremum);
5124 result_ctor = gfc_constructor_first (result->value.constructor);
5125 for (i = 0; i<array->rank; i++)
5126 {
5127 gfc_expr *r_expr;
5128 r_expr = result_ctor->expr;
5129 mpz_set_si (r_expr->value.integer, res[i] + 1);
5130 result_ctor = gfc_constructor_next (result_ctor);
5131 }
5132 return result;
5133}
5134
5135/* Helper function for gfc_simplify_minmaxloc - build an array
5136 expression with n elements. */
5137
5138static gfc_expr *
5139new_array (bt type, int kind, int n, locus *where)
5140{
5141 gfc_expr *result;
5142 int i;
5143
5144 result = gfc_get_array_expr (type, kind, where);
5145 result->rank = 1;
5146 result->shape = gfc_get_shape(1);
5147 mpz_init_set_si (result->shape[0], n);
5148 for (i = 0; i < n; i++)
5149 {
5150 gfc_constructor_append_expr (&result->value.constructor,
5151 gfc_get_constant_expr (type, kind, where),
5152 NULL);
5153 }
5154
5155 return result;
5156}
5157
5158/* Simplify minloc and maxloc. This code is mostly identical to
5159 simplify_transformation_to_array. */
5160
5161static gfc_expr *
5162simplify_minmaxloc_to_array (gfc_expr *result, gfc_expr *array,
5163 gfc_expr *dim, gfc_expr *mask,
5164 gfc_expr *extremum, int sign)
5165{
5166 mpz_t size;
5167 int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
5168 gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
5169 gfc_constructor *array_ctor, *mask_ctor, *result_ctor;
5170
5171 int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
5172 sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
5173 tmpstride[GFC_MAX_DIMENSIONS];
5174
5175 /* Shortcut for constant .FALSE. MASK. */
5176 if (mask
5177 && mask->expr_type == EXPR_CONSTANT
5178 && !mask->value.logical)
5179 return result;
5180
5181 /* Build an indexed table for array element expressions to minimize
5182 linked-list traversal. Masked elements are set to NULL. */
5183 gfc_array_size (array, &size);
5184 arraysize = mpz_get_ui (size);
5185 mpz_clear (size);
5186
5187 arrayvec = XCNEWVEC (gfc_expr*, arraysize);
5188
5189 array_ctor = gfc_constructor_first (array->value.constructor);
5190 mask_ctor = NULL;
5191 if (mask && mask->expr_type == EXPR_ARRAY)
5192 mask_ctor = gfc_constructor_first (mask->value.constructor);
5193
5194 for (i = 0; i < arraysize; ++i)
5195 {
5196 arrayvec[i] = array_ctor->expr;
5197 array_ctor = gfc_constructor_next (array_ctor);
5198
5199 if (mask_ctor)
5200 {
5201 if (!mask_ctor->expr->value.logical)
5202 arrayvec[i] = NULL;
5203
5204 mask_ctor = gfc_constructor_next (mask_ctor);
5205 }
5206 }
5207
5208 /* Same for the result expression. */
5209 gfc_array_size (result, &size);
5210 resultsize = mpz_get_ui (size);
5211 mpz_clear (size);
5212
5213 resultvec = XCNEWVEC (gfc_expr*, resultsize);
5214 result_ctor = gfc_constructor_first (result->value.constructor);
5215 for (i = 0; i < resultsize; ++i)
5216 {
5217 resultvec[i] = result_ctor->expr;
5218 result_ctor = gfc_constructor_next (result_ctor);
5219 }
5220
5221 gfc_extract_int (dim, &dim_index);
5222 dim_index -= 1; /* zero-base index */
5223 dim_extent = 0;
5224 dim_stride = 0;
5225
5226 for (i = 0, n = 0; i < array->rank; ++i)
5227 {
5228 count[i] = 0;
5229 tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
5230 if (i == dim_index)
5231 {
5232 dim_extent = mpz_get_si (array->shape[i]);
5233 dim_stride = tmpstride[i];
5234 continue;
5235 }
5236
5237 extent[n] = mpz_get_si (array->shape[i]);
5238 sstride[n] = tmpstride[i];
5239 dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
5240 n += 1;
5241 }
5242
5243 done = false;
5244 base = arrayvec;
5245 dest = resultvec;
5246 while (!done)
5247 {
5248 gfc_expr *ex;
5249 ex = gfc_copy_expr (extremum);
5250 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
5251 {
5252 if (*src && min_max_choose (*src, ex, sign) > 0)
5253 mpz_set_si ((*dest)->value.integer, n + 1);
5254 }
5255
5256 count[0]++;
5257 base += sstride[0];
5258 dest += dstride[0];
5259 gfc_free_expr (ex);
5260
5261 n = 0;
5262 while (!done && count[n] == extent[n])
5263 {
5264 count[n] = 0;
5265 base -= sstride[n] * extent[n];
5266 dest -= dstride[n] * extent[n];
5267
5268 n++;
5269 if (n < result->rank)
5270 {
5271 /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
5272 times, we'd warn for the last iteration, because the
5273 array index will have already been incremented to the
5274 array sizes, and we can't tell that this must make
5275 the test against result->rank false, because ranks
5276 must not exceed GFC_MAX_DIMENSIONS. */
5277 GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
5278 count[n]++;
5279 base += sstride[n];
5280 dest += dstride[n];
5281 GCC_DIAGNOSTIC_POP
5282 }
5283 else
5284 done = true;
5285 }
5286 }
5287
5288 /* Place updated expression in result constructor. */
5289 result_ctor = gfc_constructor_first (result->value.constructor);
5290 for (i = 0; i < resultsize; ++i)
5291 {
5292 result_ctor->expr = resultvec[i];
5293 result_ctor = gfc_constructor_next (result_ctor);
5294 }
5295
5296 free (arrayvec);
5297 free (resultvec);
5298 free (extremum);
5299 return result;
5300}
5301
5302/* Simplify minloc and maxloc for constant arrays. */
5303
5304gfc_expr *
5305gfc_simplify_minmaxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask,
5306 gfc_expr *kind, int sign)
5307{
5308 gfc_expr *result;
5309 gfc_expr *extremum;
5310 int ikind;
5311 int init_val;
5312
5313 if (!is_constant_array_expr (array)
5314 || !gfc_is_constant_expr (dim))
5315 return NULL;
5316
5317 if (mask
5318 && !is_constant_array_expr (mask)
5319 && mask->expr_type != EXPR_CONSTANT)
5320 return NULL;
5321
5322 if (kind)
5323 {
5324 if (gfc_extract_int (kind, &ikind, -1))
5325 return NULL;
5326 }
5327 else
5328 ikind = gfc_default_integer_kind;
5329
5330 if (sign < 0)
5331 init_val = INT_MAX;
5332 else if (sign > 0)
5333 init_val = INT_MIN;
5334 else
5335 gcc_unreachable();
5336
5337 extremum = gfc_get_constant_expr (array->ts.type, array->ts.kind, &array->where);
5338 init_result_expr (extremum, init_val, array);
5339
5340 if (dim)
5341 {
5342 result = transformational_result (array, dim, BT_INTEGER,
5343 ikind, &array->where);
5344 init_result_expr (result, 0, array);
5345
5346 if (array->rank == 1)
5347 return simplify_minmaxloc_to_scalar (result, array, mask, extremum, sign);
5348 else
5349 return simplify_minmaxloc_to_array (result, array, dim, mask, extremum, sign);
5350 }
5351 else
5352 {
5353 result = new_array (BT_INTEGER, ikind, array->rank, &array->where);
5354 return simplify_minmaxloc_nodim (result, extremum, array, mask, sign);
5355 }
5356}
5357
5358gfc_expr *
64b1806b
TK
5359gfc_simplify_minloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind,
5360 gfc_expr *back ATTRIBUTE_UNUSED)
a1d6c052
TK
5361{
5362 return gfc_simplify_minmaxloc (array, dim, mask, kind, -1);
5363}
5364
5365gfc_expr *
64b1806b
TK
5366gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind,
5367 gfc_expr *back ATTRIBUTE_UNUSED)
a1d6c052
TK
5368{
5369 return gfc_simplify_minmaxloc (array, dim, mask, kind, 1);
5370}
5371
6de9cd9a 5372gfc_expr *
edf1eac2 5373gfc_simplify_maxexponent (gfc_expr *x)
6de9cd9a 5374{
b7e75771
JD
5375 int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
5376 return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
5377 gfc_real_kinds[i].max_exponent);
6de9cd9a
DN
5378}
5379
5380
5381gfc_expr *
edf1eac2 5382gfc_simplify_minexponent (gfc_expr *x)
6de9cd9a 5383{
b7e75771
JD
5384 int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
5385 return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
5386 gfc_real_kinds[i].min_exponent);
6de9cd9a
DN
5387}
5388
5389
5390gfc_expr *
edf1eac2 5391gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
6de9cd9a
DN
5392{
5393 gfc_expr *result;
991bb832 5394 int kind;
6de9cd9a
DN
5395
5396 if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT)
5397 return NULL;
5398
991bb832 5399 kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
b7e75771 5400 result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
6de9cd9a
DN
5401
5402 switch (a->ts.type)
5403 {
b7e75771
JD
5404 case BT_INTEGER:
5405 if (mpz_cmp_ui (p->value.integer, 0) == 0)
5406 {
5407 /* Result is processor-dependent. */
5408 gfc_error ("Second argument MOD at %L is zero", &a->where);
5409 gfc_free_expr (result);
5410 return &gfc_bad_expr;
5411 }
5412 mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
5413 break;
6de9cd9a 5414
b7e75771
JD
5415 case BT_REAL:
5416 if (mpfr_cmp_ui (p->value.real, 0) == 0)
5417 {
5418 /* Result is processor-dependent. */
5419 gfc_error ("Second argument of MOD at %L is zero", &p->where);
5420 gfc_free_expr (result);
5421 return &gfc_bad_expr;
5422 }
6de9cd9a 5423
b7e75771 5424 gfc_set_model_kind (kind);
8b704316 5425 mpfr_fmod (result->value.real, a->value.real, p->value.real,
4ecad771 5426 GFC_RND_MODE);
b7e75771 5427 break;
6de9cd9a 5428
b7e75771
JD
5429 default:
5430 gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
6de9cd9a
DN
5431 }
5432
5433 return range_check (result, "MOD");
5434}
5435
5436
5437gfc_expr *
edf1eac2 5438gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
6de9cd9a
DN
5439{
5440 gfc_expr *result;
991bb832 5441 int kind;
6de9cd9a
DN
5442
5443 if (a->expr_type != EXPR_CONSTANT || p->expr_type != EXPR_CONSTANT)
5444 return NULL;
5445
991bb832 5446 kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
b7e75771 5447 result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
6de9cd9a
DN
5448
5449 switch (a->ts.type)
5450 {
b7e75771
JD
5451 case BT_INTEGER:
5452 if (mpz_cmp_ui (p->value.integer, 0) == 0)
5453 {
5454 /* Result is processor-dependent. This processor just opts
5455 to not handle it at all. */
5456 gfc_error ("Second argument of MODULO at %L is zero", &a->where);
5457 gfc_free_expr (result);
5458 return &gfc_bad_expr;
5459 }
5460 mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
6de9cd9a 5461
b7e75771 5462 break;
6de9cd9a 5463
b7e75771
JD
5464 case BT_REAL:
5465 if (mpfr_cmp_ui (p->value.real, 0) == 0)
5466 {
5467 /* Result is processor-dependent. */
5468 gfc_error ("Second argument of MODULO at %L is zero", &p->where);
5469 gfc_free_expr (result);
5470 return &gfc_bad_expr;
5471 }
6de9cd9a 5472
b7e75771 5473 gfc_set_model_kind (kind);
8b704316 5474 mpfr_fmod (result->value.real, a->value.real, p->value.real,
4ecad771
JB
5475 GFC_RND_MODE);
5476 if (mpfr_cmp_ui (result->value.real, 0) != 0)
5477 {
5478 if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
5479 mpfr_add (result->value.real, result->value.real, p->value.real,
5480 GFC_RND_MODE);
5481 }
5482 else
8b704316 5483 mpfr_copysign (result->value.real, result->value.real,
4ecad771 5484 p->value.real, GFC_RND_MODE);
b7e75771 5485 break;
6de9cd9a 5486
b7e75771
JD
5487 default:
5488 gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
6de9cd9a
DN
5489 }
5490
5491 return range_check (result, "MODULO");
5492}
5493
5494
6de9cd9a 5495gfc_expr *
edf1eac2 5496gfc_simplify_nearest (gfc_expr *x, gfc_expr *s)
6de9cd9a
DN
5497{
5498 gfc_expr *result;
b6f63e89
TB
5499 mp_exp_t emin, emax;
5500 int kind;
6de9cd9a 5501
9f32d037 5502 if (x->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
5503 return NULL;
5504
e48d66a9
SK
5505 result = gfc_copy_expr (x);
5506
b6f63e89
TB
5507 /* Save current values of emin and emax. */
5508 emin = mpfr_get_emin ();
5509 emax = mpfr_get_emax ();
5510
5511 /* Set emin and emax for the current model number. */
5512 kind = gfc_validate_kind (BT_REAL, x->ts.kind, 0);
5513 mpfr_set_emin ((mp_exp_t) gfc_real_kinds[kind].min_exponent -
5514 mpfr_get_prec(result->value.real) + 1);
5515 mpfr_set_emax ((mp_exp_t) gfc_real_kinds[kind].max_exponent - 1);
ca430085 5516 mpfr_check_range (result->value.real, 0, GMP_RNDU);
b6f63e89
TB
5517
5518 if (mpfr_sgn (s->value.real) > 0)
5519 {
5520 mpfr_nextabove (result->value.real);
5521 mpfr_subnormalize (result->value.real, 0, GMP_RNDU);
5522 }
5523 else
5524 {
5525 mpfr_nextbelow (result->value.real);
5526 mpfr_subnormalize (result->value.real, 0, GMP_RNDD);
5527 }
5528
5529 mpfr_set_emin (emin);
5530 mpfr_set_emax (emax);
6de9cd9a 5531
b6f63e89
TB
5532 /* Only NaN can occur. Do not use range check as it gives an
5533 error for denormal numbers. */
c61819ff 5534 if (mpfr_nan_p (result->value.real) && flag_range_check)
b6f63e89
TB
5535 {
5536 gfc_error ("Result of NEAREST is NaN at %L", &result->where);
d93712d9 5537 gfc_free_expr (result);
b6f63e89
TB
5538 return &gfc_bad_expr;
5539 }
5540
5541 return result;
6de9cd9a
DN
5542}
5543
5544
5545static gfc_expr *
edf1eac2 5546simplify_nint (const char *name, gfc_expr *e, gfc_expr *k)
6de9cd9a 5547{
8e1fa5d6
SK
5548 gfc_expr *itrunc, *result;
5549 int kind;
6de9cd9a 5550
9d64df18 5551 kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind);
6de9cd9a
DN
5552 if (kind == -1)
5553 return &gfc_bad_expr;
5554
5555 if (e->expr_type != EXPR_CONSTANT)
5556 return NULL;
5557
6de9cd9a 5558 itrunc = gfc_copy_expr (e);
edf1eac2 5559 mpfr_round (itrunc->value.real, e->value.real);
6de9cd9a 5560
b7e75771 5561 result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
7278e4dc 5562 gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real, &e->where);
6de9cd9a
DN
5563
5564 gfc_free_expr (itrunc);
6de9cd9a
DN
5565
5566 return range_check (result, name);
5567}
5568
5569
bec93d79 5570gfc_expr *
edf1eac2 5571gfc_simplify_new_line (gfc_expr *e)
bec93d79
TB
5572{
5573 gfc_expr *result;
5574
b7e75771 5575 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, 1);
bec93d79 5576 result->value.character.string[0] = '\n';
b7e75771 5577
bec93d79
TB
5578 return result;
5579}
5580
5581
6de9cd9a 5582gfc_expr *
edf1eac2 5583gfc_simplify_nint (gfc_expr *e, gfc_expr *k)
6de9cd9a 5584{
6de9cd9a
DN
5585 return simplify_nint ("NINT", e, k);
5586}
5587
5588
5589gfc_expr *
edf1eac2 5590gfc_simplify_idnint (gfc_expr *e)
6de9cd9a 5591{
6de9cd9a
DN
5592 return simplify_nint ("IDNINT", e, NULL);
5593}
5594
5595
0cd0559e
TB
5596static gfc_expr *
5597add_squared (gfc_expr *result, gfc_expr *e)
5598{
5599 mpfr_t tmp;
5600
5601 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
5602 gcc_assert (result->ts.type == BT_REAL
5603 && result->expr_type == EXPR_CONSTANT);
5604
5605 gfc_set_model_kind (result->ts.kind);
5606 mpfr_init (tmp);
5607 mpfr_pow_ui (tmp, e->value.real, 2, GFC_RND_MODE);
5608 mpfr_add (result->value.real, result->value.real, tmp,
5609 GFC_RND_MODE);
5610 mpfr_clear (tmp);
5611
5612 return result;
5613}
5614
5615
5616static gfc_expr *
5617do_sqrt (gfc_expr *result, gfc_expr *e)
5618{
5619 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
5620 gcc_assert (result->ts.type == BT_REAL
5621 && result->expr_type == EXPR_CONSTANT);
5622
5623 mpfr_set (result->value.real, e->value.real, GFC_RND_MODE);
5624 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
5625 return result;
5626}
5627
5628
5629gfc_expr *
5630gfc_simplify_norm2 (gfc_expr *e, gfc_expr *dim)
5631{
5632 gfc_expr *result;
5633
5634 if (!is_constant_array_expr (e)
5635 || (dim != NULL && !gfc_is_constant_expr (dim)))
5636 return NULL;
5637
5638 result = transformational_result (e, dim, e->ts.type, e->ts.kind, &e->where);
5639 init_result_expr (result, 0, NULL);
5640
5641 if (!dim || e->rank == 1)
5642 {
5643 result = simplify_transformation_to_scalar (result, e, NULL,
5644 add_squared);
5645 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
5646 }
5647 else
5648 result = simplify_transformation_to_array (result, e, dim, NULL,
5649 add_squared, &do_sqrt);
5650
5651 return result;
5652}
5653
5654
6de9cd9a 5655gfc_expr *
edf1eac2 5656gfc_simplify_not (gfc_expr *e)
6de9cd9a
DN
5657{
5658 gfc_expr *result;
6de9cd9a
DN
5659
5660 if (e->expr_type != EXPR_CONSTANT)
5661 return NULL;
5662
b7e75771 5663 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
6de9cd9a
DN
5664 mpz_com (result->value.integer, e->value.integer);
5665
6de9cd9a
DN
5666 return range_check (result, "NOT");
5667}
5668
5669
5670gfc_expr *
edf1eac2 5671gfc_simplify_null (gfc_expr *mold)
6de9cd9a
DN
5672{
5673 gfc_expr *result;
5674
b7e75771 5675 if (mold)
6de9cd9a 5676 {
b7e75771
JD
5677 result = gfc_copy_expr (mold);
5678 result->expr_type = EXPR_NULL;
6de9cd9a 5679 }
def66134 5680 else
b7e75771 5681 result = gfc_get_null_expr (NULL);
6de9cd9a
DN
5682
5683 return result;
5684}
5685
5686
d0a4a61c 5687gfc_expr *
05fc16dd 5688gfc_simplify_num_images (gfc_expr *distance ATTRIBUTE_UNUSED, gfc_expr *failed)
d0a4a61c
TB
5689{
5690 gfc_expr *result;
64f002ed 5691
f19626cf 5692 if (flag_coarray == GFC_FCOARRAY_NONE)
64f002ed 5693 {
ddc05d11 5694 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
64f002ed
TB
5695 return &gfc_bad_expr;
5696 }
5697
f19626cf 5698 if (flag_coarray != GFC_FCOARRAY_SINGLE)
60386f50
TB
5699 return NULL;
5700
05fc16dd
TB
5701 if (failed && failed->expr_type != EXPR_CONSTANT)
5702 return NULL;
5703
d0a4a61c 5704 /* FIXME: gfc_current_locus is wrong. */
b7e75771
JD
5705 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
5706 &gfc_current_locus);
05fc16dd
TB
5707
5708 if (failed && failed->value.logical != 0)
5709 mpz_set_si (result->value.integer, 0);
5710 else
5711 mpz_set_si (result->value.integer, 1);
5712
d0a4a61c
TB
5713 return result;
5714}
5715
5716
5d723e54 5717gfc_expr *
edf1eac2 5718gfc_simplify_or (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
5719{
5720 gfc_expr *result;
5721 int kind;
5722
5723 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
5724 return NULL;
5725
5726 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771
JD
5727
5728 switch (x->ts.type)
5d723e54 5729 {
b7e75771
JD
5730 case BT_INTEGER:
5731 result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
5732 mpz_ior (result->value.integer, x->value.integer, y->value.integer);
5733 return range_check (result, "OR");
5734
5735 case BT_LOGICAL:
5736 return gfc_get_logical_expr (kind, &x->where,
5737 x->value.logical || y->value.logical);
5738 default:
5739 gcc_unreachable();
5d723e54 5740 }
5d723e54
FXC
5741}
5742
5743
7ba8c18c
DF
5744gfc_expr *
5745gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
5746{
5747 gfc_expr *result;
5748 gfc_constructor *array_ctor, *mask_ctor, *vector_ctor;
5749
524af0d6
JB
5750 if (!is_constant_array_expr (array)
5751 || !is_constant_array_expr (vector)
7ba8c18c 5752 || (!gfc_is_constant_expr (mask)
524af0d6 5753 && !is_constant_array_expr (mask)))
7ba8c18c
DF
5754 return NULL;
5755
b7e75771 5756 result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
15c2ef5a
PT
5757 if (array->ts.type == BT_DERIVED)
5758 result->ts.u.derived = array->ts.u.derived;
7ba8c18c 5759
b7e75771
JD
5760 array_ctor = gfc_constructor_first (array->value.constructor);
5761 vector_ctor = vector
5762 ? gfc_constructor_first (vector->value.constructor)
5763 : NULL;
7ba8c18c
DF
5764
5765 if (mask->expr_type == EXPR_CONSTANT
5766 && mask->value.logical)
5767 {
5768 /* Copy all elements of ARRAY to RESULT. */
5769 while (array_ctor)
5770 {
b7e75771
JD
5771 gfc_constructor_append_expr (&result->value.constructor,
5772 gfc_copy_expr (array_ctor->expr),
5773 NULL);
7ba8c18c 5774
b7e75771
JD
5775 array_ctor = gfc_constructor_next (array_ctor);
5776 vector_ctor = gfc_constructor_next (vector_ctor);
7ba8c18c
DF
5777 }
5778 }
5779 else if (mask->expr_type == EXPR_ARRAY)
5780 {
8b704316 5781 /* Copy only those elements of ARRAY to RESULT whose
7ba8c18c 5782 MASK equals .TRUE.. */
b7e75771 5783 mask_ctor = gfc_constructor_first (mask->value.constructor);
7ba8c18c
DF
5784 while (mask_ctor)
5785 {
5786 if (mask_ctor->expr->value.logical)
5787 {
b7e75771
JD
5788 gfc_constructor_append_expr (&result->value.constructor,
5789 gfc_copy_expr (array_ctor->expr),
5790 NULL);
5791 vector_ctor = gfc_constructor_next (vector_ctor);
7ba8c18c
DF
5792 }
5793
b7e75771
JD
5794 array_ctor = gfc_constructor_next (array_ctor);
5795 mask_ctor = gfc_constructor_next (mask_ctor);
7ba8c18c
DF
5796 }
5797 }
5798
5799 /* Append any left-over elements from VECTOR to RESULT. */
5800 while (vector_ctor)
5801 {
b7e75771
JD
5802 gfc_constructor_append_expr (&result->value.constructor,
5803 gfc_copy_expr (vector_ctor->expr),
5804 NULL);
5805 vector_ctor = gfc_constructor_next (vector_ctor);
7ba8c18c
DF
5806 }
5807
5808 result->shape = gfc_get_shape (1);
5809 gfc_array_size (result, &result->shape[0]);
5810
5811 if (array->ts.type == BT_CHARACTER)
bc21d315 5812 result->ts.u.cl = array->ts.u.cl;
7ba8c18c
DF
5813
5814 return result;
5815}
5816
5817
0cd0559e
TB
5818static gfc_expr *
5819do_xor (gfc_expr *result, gfc_expr *e)
5820{
5821 gcc_assert (e->ts.type == BT_LOGICAL && e->expr_type == EXPR_CONSTANT);
5822 gcc_assert (result->ts.type == BT_LOGICAL
5823 && result->expr_type == EXPR_CONSTANT);
5824
5825 result->value.logical = result->value.logical != e->value.logical;
5826 return result;
5827}
5828
5829
5830
5831gfc_expr *
5832gfc_simplify_parity (gfc_expr *e, gfc_expr *dim)
5833{
195a95c4 5834 return simplify_transformation (e, dim, NULL, 0, do_xor);
0cd0559e
TB
5835}
5836
5837
ad5f4de2
FXC
5838gfc_expr *
5839gfc_simplify_popcnt (gfc_expr *e)
5840{
5841 int res, k;
5842 mpz_t x;
5843
5844 if (e->expr_type != EXPR_CONSTANT)
5845 return NULL;
5846
5847 k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
5848
5849 /* Convert argument to unsigned, then count the '1' bits. */
5850 mpz_init_set (x, e->value.integer);
5851 convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);
5852 res = mpz_popcount (x);
5853 mpz_clear (x);
5854
5855 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, res);
5856}
5857
5858
5859gfc_expr *
5860gfc_simplify_poppar (gfc_expr *e)
5861{
5862 gfc_expr *popcnt;
ad5f4de2
FXC
5863 int i;
5864
5865 if (e->expr_type != EXPR_CONSTANT)
5866 return NULL;
5867
5868 popcnt = gfc_simplify_popcnt (e);
5869 gcc_assert (popcnt);
5870
51f03c6b
JJ
5871 bool fail = gfc_extract_int (popcnt, &i);
5872 gcc_assert (!fail);
ad5f4de2
FXC
5873
5874 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i % 2);
5875}
5876
5877
6de9cd9a 5878gfc_expr *
edf1eac2 5879gfc_simplify_precision (gfc_expr *e)
6de9cd9a 5880{
b7e75771
JD
5881 int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
5882 return gfc_get_int_expr (gfc_default_integer_kind, &e->where,
5883 gfc_real_kinds[i].precision);
6de9cd9a
DN
5884}
5885
5886
a16d978f
DF
5887gfc_expr *
5888gfc_simplify_product (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
5889{
195a95c4 5890 return simplify_transformation (array, dim, mask, 1, gfc_multiply);
a16d978f
DF
5891}
5892
5893
6de9cd9a 5894gfc_expr *
edf1eac2 5895gfc_simplify_radix (gfc_expr *e)
6de9cd9a 5896{
6de9cd9a 5897 int i;
e7a2d5fb 5898 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
b7e75771 5899
6de9cd9a
DN
5900 switch (e->ts.type)
5901 {
b7e75771
JD
5902 case BT_INTEGER:
5903 i = gfc_integer_kinds[i].radix;
5904 break;
6de9cd9a 5905
b7e75771
JD
5906 case BT_REAL:
5907 i = gfc_real_kinds[i].radix;
5908 break;
6de9cd9a 5909
b7e75771
JD
5910 default:
5911 gcc_unreachable ();
6de9cd9a
DN
5912 }
5913
b7e75771 5914 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
6de9cd9a
DN
5915}
5916
5917
5918gfc_expr *
edf1eac2 5919gfc_simplify_range (gfc_expr *e)
6de9cd9a 5920{
6de9cd9a 5921 int i;
e7a2d5fb 5922 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
6de9cd9a
DN
5923
5924 switch (e->ts.type)
5925 {
b7e75771
JD
5926 case BT_INTEGER:
5927 i = gfc_integer_kinds[i].range;
5928 break;
6de9cd9a 5929
b7e75771
JD
5930 case BT_REAL:
5931 case BT_COMPLEX:
5932 i = gfc_real_kinds[i].range;
5933 break;
6de9cd9a 5934
b7e75771
JD
5935 default:
5936 gcc_unreachable ();
6de9cd9a
DN
5937 }
5938
b7e75771 5939 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
6de9cd9a
DN
5940}
5941
5942
2514987f
TB
5943gfc_expr *
5944gfc_simplify_rank (gfc_expr *e)
5945{
c62c6622
TB
5946 /* Assumed rank. */
5947 if (e->rank == -1)
5948 return NULL;
5949
2514987f
TB
5950 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, e->rank);
5951}
5952
5953
6de9cd9a 5954gfc_expr *
edf1eac2 5955gfc_simplify_real (gfc_expr *e, gfc_expr *k)
6de9cd9a 5956{
9e23c1aa 5957 gfc_expr *result = NULL;
6de9cd9a
DN
5958 int kind;
5959
5960 if (e->ts.type == BT_COMPLEX)
5961 kind = get_kind (BT_REAL, k, "REAL", e->ts.kind);
5962 else
9d64df18 5963 kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind);
6de9cd9a
DN
5964
5965 if (kind == -1)
5966 return &gfc_bad_expr;
5967
5968 if (e->expr_type != EXPR_CONSTANT)
5969 return NULL;
5970
b7e75771
JD
5971 if (convert_boz (e, kind) == &gfc_bad_expr)
5972 return &gfc_bad_expr;
6de9cd9a 5973
b7e75771
JD
5974 result = gfc_convert_constant (e, BT_REAL, kind);
5975 if (result == &gfc_bad_expr)
5976 return &gfc_bad_expr;
d93712d9 5977
6de9cd9a
DN
5978 return range_check (result, "REAL");
5979}
5980
6970fcc8
SK
5981
5982gfc_expr *
edf1eac2 5983gfc_simplify_realpart (gfc_expr *e)
6970fcc8
SK
5984{
5985 gfc_expr *result;
5986
5987 if (e->expr_type != EXPR_CONSTANT)
5988 return NULL;
5989
b7e75771 5990 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
eb6f9a86 5991 mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);
b7e75771 5992
6970fcc8
SK
5993 return range_check (result, "REALPART");
5994}
5995
6de9cd9a 5996gfc_expr *
edf1eac2 5997gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
6de9cd9a
DN
5998{
5999 gfc_expr *result;
f622221a 6000 gfc_charlen_t len;
f1412ca5 6001 mpz_t ncopies;
64f4bedf 6002 bool have_length = false;
6de9cd9a 6003
f1412ca5
FXC
6004 /* If NCOPIES isn't a constant, there's nothing we can do. */
6005 if (n->expr_type != EXPR_CONSTANT)
6de9cd9a
DN
6006 return NULL;
6007
f1412ca5
FXC
6008 /* If NCOPIES is negative, it's an error. */
6009 if (mpz_sgn (n->value.integer) < 0)
6de9cd9a 6010 {
f1412ca5
FXC
6011 gfc_error ("Argument NCOPIES of REPEAT intrinsic is negative at %L",
6012 &n->where);
6de9cd9a
DN
6013 return &gfc_bad_expr;
6014 }
6015
f1412ca5 6016 /* If we don't know the character length, we can do no more. */
bc21d315
JW
6017 if (e->ts.u.cl && e->ts.u.cl->length
6018 && e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
64f4bedf 6019 {
f622221a 6020 len = gfc_mpz_get_hwi (e->ts.u.cl->length->value.integer);
64f4bedf
PT
6021 have_length = true;
6022 }
6023 else if (e->expr_type == EXPR_CONSTANT
bc21d315 6024 && (e->ts.u.cl == NULL || e->ts.u.cl->length == NULL))
64f4bedf
PT
6025 {
6026 len = e->value.character.length;
6027 }
6028 else
f1412ca5
FXC
6029 return NULL;
6030
6031 /* If the source length is 0, any value of NCOPIES is valid
6032 and everything behaves as if NCOPIES == 0. */
6033 mpz_init (ncopies);
64f4bedf 6034 if (len == 0)
f1412ca5
FXC
6035 mpz_set_ui (ncopies, 0);
6036 else
6037 mpz_set (ncopies, n->value.integer);
6038
6039 /* Check that NCOPIES isn't too large. */
64f4bedf 6040 if (len)
f1412ca5 6041 {
64f4bedf 6042 mpz_t max, mlen;
f1412ca5
FXC
6043 int i;
6044
6045 /* Compute the maximum value allowed for NCOPIES: huge(cl) / len. */
6046 mpz_init (max);
6047 i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);
64f4bedf
PT
6048
6049 if (have_length)
6050 {
6051 mpz_tdiv_q (max, gfc_integer_kinds[i].huge,
bc21d315 6052 e->ts.u.cl->length->value.integer);
64f4bedf
PT
6053 }
6054 else
6055 {
f622221a
JB
6056 mpz_init (mlen);
6057 gfc_mpz_set_hwi (mlen, len);
64f4bedf
PT
6058 mpz_tdiv_q (max, gfc_integer_kinds[i].huge, mlen);
6059 mpz_clear (mlen);
6060 }
f1412ca5
FXC
6061
6062 /* The check itself. */
6063 if (mpz_cmp (ncopies, max) > 0)
6064 {
6065 mpz_clear (max);
6066 mpz_clear (ncopies);
6067 gfc_error ("Argument NCOPIES of REPEAT intrinsic is too large at %L",
6068 &n->where);
6069 return &gfc_bad_expr;
6070 }
6071
6072 mpz_clear (max);
6073 }
6074 mpz_clear (ncopies);
6075
71172460 6076 /* For further simplification, we need the character string to be
f1412ca5
FXC
6077 constant. */
6078 if (e->expr_type != EXPR_CONSTANT)
6079 return NULL;
6080
f622221a 6081 HOST_WIDE_INT ncop;
8b704316
PT
6082 if (len ||
6083 (e->ts.u.cl->length &&
02205aa4 6084 mpz_sgn (e->ts.u.cl->length->value.integer) != 0))
f0fc6ae6 6085 {
f622221a 6086 bool fail = gfc_extract_hwi (n, &ncop);
51f03c6b 6087 gcc_assert (!fail);
f0fc6ae6 6088 }
f1412ca5
FXC
6089 else
6090 ncop = 0;
6091
f1412ca5 6092 if (ncop == 0)
b7e75771 6093 return gfc_get_character_expr (e->ts.kind, &e->where, NULL, 0);
6de9cd9a 6094
b7e75771 6095 len = e->value.character.length;
f622221a
JB
6096 gfc_charlen_t nlen = ncop * len;
6097
6098 /* Here's a semi-arbitrary limit. If the string is longer than 32 MB
6099 (8 * 2**20 elements * 4 bytes (wide chars) per element) defer to
6100 runtime instead of consuming (unbounded) memory and CPU at
6101 compile time. */
6102 if (nlen > 8388608)
6103 return NULL;
6de9cd9a 6104
b7e75771 6105 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, nlen);
f622221a
JB
6106 for (size_t i = 0; i < (size_t) ncop; i++)
6107 for (size_t j = 0; j < (size_t) len; j++)
00660189 6108 result->value.character.string[j+i*len]= e->value.character.string[j];
6de9cd9a
DN
6109
6110 result->value.character.string[nlen] = '\0'; /* For debugger */
6111 return result;
6112}
6113
6114
6115/* This one is a bear, but mainly has to do with shuffling elements. */
6116
6117gfc_expr *
edf1eac2
SK
6118gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
6119 gfc_expr *pad, gfc_expr *order_exp)
6de9cd9a 6120{
6de9cd9a
DN
6121 int order[GFC_MAX_DIMENSIONS], shape[GFC_MAX_DIMENSIONS];
6122 int i, rank, npad, x[GFC_MAX_DIMENSIONS];
6de9cd9a
DN
6123 mpz_t index, size;
6124 unsigned long j;
6125 size_t nsource;
b7e75771 6126 gfc_expr *e, *result;
6de9cd9a 6127
207bde5f 6128 /* Check that argument expression types are OK. */
535ff342
DF
6129 if (!is_constant_array_expr (source)
6130 || !is_constant_array_expr (shape_exp)
6131 || !is_constant_array_expr (pad)
6132 || !is_constant_array_expr (order_exp))
6de9cd9a
DN
6133 return NULL;
6134
a5edb32e
JD
6135 if (source->shape == NULL)
6136 return NULL;
6137
207bde5f
JD
6138 /* Proceed with simplification, unpacking the array. */
6139
6de9cd9a
DN
6140 mpz_init (index);
6141 rank = 0;
6de9cd9a
DN
6142
6143 for (;;)
6144 {
b7e75771 6145 e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank);
6de9cd9a
DN
6146 if (e == NULL)
6147 break;
6148
535ff342 6149 gfc_extract_int (e, &shape[rank]);
6de9cd9a 6150
535ff342
DF
6151 gcc_assert (rank >= 0 && rank < GFC_MAX_DIMENSIONS);
6152 gcc_assert (shape[rank] >= 0);
6de9cd9a
DN
6153
6154 rank++;
6155 }
6156
535ff342 6157 gcc_assert (rank > 0);
6de9cd9a
DN
6158
6159 /* Now unpack the order array if present. */
6160 if (order_exp == NULL)
6161 {
6162 for (i = 0; i < rank; i++)
6163 order[i] = i;
6de9cd9a
DN
6164 }
6165 else
6166 {
6de9cd9a
DN
6167 for (i = 0; i < rank; i++)
6168 x[i] = 0;
6169
6170 for (i = 0; i < rank; i++)
6171 {
b7e75771 6172 e = gfc_constructor_lookup_expr (order_exp->value.constructor, i);
535ff342 6173 gcc_assert (e);
6de9cd9a 6174
535ff342 6175 gfc_extract_int (e, &order[i]);
d93712d9 6176
535ff342
DF
6177 gcc_assert (order[i] >= 1 && order[i] <= rank);
6178 order[i]--;
6179 gcc_assert (x[order[i]] == 0);
6de9cd9a
DN
6180 x[order[i]] = 1;
6181 }
6182 }
6183
6184 /* Count the elements in the source and padding arrays. */
6185
6186 npad = 0;
6187 if (pad != NULL)
6188 {
6189 gfc_array_size (pad, &size);
6190 npad = mpz_get_ui (size);
6191 mpz_clear (size);
6192 }
6193
6194 gfc_array_size (source, &size);
6195 nsource = mpz_get_ui (size);
6196 mpz_clear (size);
6197
6198 /* If it weren't for that pesky permutation we could just loop
6199 through the source and round out any shortage with pad elements.
6200 But no, someone just had to have the compiler do something the
6201 user should be doing. */
6202
6203 for (i = 0; i < rank; i++)
6204 x[i] = 0;
6205
b7e75771
JD
6206 result = gfc_get_array_expr (source->ts.type, source->ts.kind,
6207 &source->where);
15c2ef5a
PT
6208 if (source->ts.type == BT_DERIVED)
6209 result->ts.u.derived = source->ts.u.derived;
b7e75771
JD
6210 result->rank = rank;
6211 result->shape = gfc_get_shape (rank);
6212 for (i = 0; i < rank; i++)
6213 mpz_init_set_ui (result->shape[i], shape[i]);
6214
f7cfd28c 6215 while (nsource > 0 || npad > 0)
6de9cd9a
DN
6216 {
6217 /* Figure out which element to extract. */
6218 mpz_set_ui (index, 0);
6219
6220 for (i = rank - 1; i >= 0; i--)
6221 {
6222 mpz_add_ui (index, index, x[order[i]]);
6223 if (i != 0)
6224 mpz_mul_ui (index, index, shape[order[i - 1]]);
6225 }
6226
6227 if (mpz_cmp_ui (index, INT_MAX) > 0)
d93712d9 6228 gfc_internal_error ("Reshaped array too large at %C");
6de9cd9a
DN
6229
6230 j = mpz_get_ui (index);
6231
6232 if (j < nsource)
b7e75771 6233 e = gfc_constructor_lookup_expr (source->value.constructor, j);
6de9cd9a
DN
6234 else
6235 {
b4cb2a41
SK
6236 if (npad <= 0)
6237 {
6238 mpz_clear (index);
6239 return NULL;
6240 }
535ff342 6241 j = j - nsource;
6de9cd9a 6242 j = j % npad;
b7e75771 6243 e = gfc_constructor_lookup_expr (pad->value.constructor, j);
6de9cd9a 6244 }
535ff342 6245 gcc_assert (e);
6de9cd9a 6246
b7e75771
JD
6247 gfc_constructor_append_expr (&result->value.constructor,
6248 gfc_copy_expr (e), &e->where);
6de9cd9a
DN
6249
6250 /* Calculate the next element. */
6251 i = 0;
6252
6253inc:
6254 if (++x[i] < shape[i])
6255 continue;
6256 x[i++] = 0;
6257 if (i < rank)
6258 goto inc;
6259
6260 break;
6261 }
6262
6263 mpz_clear (index);
6264
b7e75771 6265 return result;
6de9cd9a
DN
6266}
6267
6268
cc6d3bde 6269gfc_expr *
edf1eac2 6270gfc_simplify_rrspacing (gfc_expr *x)
cc6d3bde
SK
6271{
6272 gfc_expr *result;
6273 int i;
6274 long int e, p;
6275
6276 if (x->expr_type != EXPR_CONSTANT)
6277 return NULL;
6de9cd9a 6278
cc6d3bde
SK
6279 i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
6280
b7e75771 6281 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
cc6d3bde 6282
d2af8cc6
FXC
6283 /* RRSPACING(+/- 0.0) = 0.0 */
6284 if (mpfr_zero_p (x->value.real))
cc6d3bde
SK
6285 {
6286 mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6287 return result;
6288 }
6289
d2af8cc6
FXC
6290 /* RRSPACING(inf) = NaN */
6291 if (mpfr_inf_p (x->value.real))
6292 {
6293 mpfr_set_nan (result->value.real);
6294 return result;
6295 }
6296
6297 /* RRSPACING(NaN) = same NaN */
6298 if (mpfr_nan_p (x->value.real))
6299 {
6300 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
6301 return result;
6302 }
6303
cc6d3bde 6304 /* | x * 2**(-e) | * 2**p. */
d2af8cc6 6305 mpfr_abs (result->value.real, x->value.real, GFC_RND_MODE);
cc6d3bde
SK
6306 e = - (long int) mpfr_get_exp (x->value.real);
6307 mpfr_mul_2si (result->value.real, result->value.real, e, GFC_RND_MODE);
6308
6309 p = (long int) gfc_real_kinds[i].digits;
6310 mpfr_mul_2si (result->value.real, result->value.real, p, GFC_RND_MODE);
6311
6312 return range_check (result, "RRSPACING");
6313}
b814a64e 6314
6de9cd9a
DN
6315
6316gfc_expr *
edf1eac2 6317gfc_simplify_scale (gfc_expr *x, gfc_expr *i)
6de9cd9a
DN
6318{
6319 int k, neg_flag, power, exp_range;
f8e566e5 6320 mpfr_t scale, radix;
6de9cd9a
DN
6321 gfc_expr *result;
6322
6323 if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
6324 return NULL;
6325
b7e75771 6326 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
6de9cd9a 6327
d2af8cc6 6328 if (mpfr_zero_p (x->value.real))
6de9cd9a 6329 {
f8e566e5 6330 mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6de9cd9a
DN
6331 return result;
6332 }
6333
e7a2d5fb 6334 k = gfc_validate_kind (BT_REAL, x->ts.kind, false);
6de9cd9a
DN
6335
6336 exp_range = gfc_real_kinds[k].max_exponent - gfc_real_kinds[k].min_exponent;
6337
6338 /* This check filters out values of i that would overflow an int. */
6339 if (mpz_cmp_si (i->value.integer, exp_range + 2) > 0
6340 || mpz_cmp_si (i->value.integer, -exp_range - 2) < 0)
6341 {
6342 gfc_error ("Result of SCALE overflows its kind at %L", &result->where);
d93712d9 6343 gfc_free_expr (result);
6de9cd9a
DN
6344 return &gfc_bad_expr;
6345 }
6346
6347 /* Compute scale = radix ** power. */
6348 power = mpz_get_si (i->value.integer);
6349
6350 if (power >= 0)
6351 neg_flag = 0;
6352 else
6353 {
6354 neg_flag = 1;
6355 power = -power;
6356 }
6357
f8e566e5
SK
6358 gfc_set_model_kind (x->ts.kind);
6359 mpfr_init (scale);
6360 mpfr_init (radix);
6361 mpfr_set_ui (radix, gfc_real_kinds[k].radix, GFC_RND_MODE);
6362 mpfr_pow_ui (scale, radix, power, GFC_RND_MODE);
6de9cd9a
DN
6363
6364 if (neg_flag)
f8e566e5 6365 mpfr_div (result->value.real, x->value.real, scale, GFC_RND_MODE);
6de9cd9a 6366 else
f8e566e5 6367 mpfr_mul (result->value.real, x->value.real, scale, GFC_RND_MODE);
6de9cd9a 6368
7306494a 6369 mpfr_clears (scale, radix, NULL);
6de9cd9a
DN
6370
6371 return range_check (result, "SCALE");
6372}
6373
6374
00660189
FXC
6375/* Variants of strspn and strcspn that operate on wide characters. */
6376
6377static size_t
6378wide_strspn (const gfc_char_t *s1, const gfc_char_t *s2)
6379{
6380 size_t i = 0;
6381 const gfc_char_t *c;
6382
6383 while (s1[i])
6384 {
6385 for (c = s2; *c; c++)
6386 {
6387 if (s1[i] == *c)
6388 break;
6389 }
6390 if (*c == '\0')
6391 break;
6392 i++;
6393 }
6394
6395 return i;
6396}
6397
6398static size_t
6399wide_strcspn (const gfc_char_t *s1, const gfc_char_t *s2)
6400{
6401 size_t i = 0;
6402 const gfc_char_t *c;
6403
6404 while (s1[i])
6405 {
6406 for (c = s2; *c; c++)
6407 {
6408 if (s1[i] == *c)
6409 break;
6410 }
6411 if (*c)
6412 break;
6413 i++;
6414 }
6415
6416 return i;
6417}
6418
6419
6de9cd9a 6420gfc_expr *
5cda5098 6421gfc_simplify_scan (gfc_expr *e, gfc_expr *c, gfc_expr *b, gfc_expr *kind)
6de9cd9a
DN
6422{
6423 gfc_expr *result;
6424 int back;
6425 size_t i;
6426 size_t indx, len, lenc;
5cda5098
FXC
6427 int k = get_kind (BT_INTEGER, kind, "SCAN", gfc_default_integer_kind);
6428
6429 if (k == -1)
6430 return &gfc_bad_expr;
6de9cd9a 6431
61aa9333
TB
6432 if (e->expr_type != EXPR_CONSTANT || c->expr_type != EXPR_CONSTANT
6433 || ( b != NULL && b->expr_type != EXPR_CONSTANT))
6de9cd9a
DN
6434 return NULL;
6435
6436 if (b != NULL && b->value.logical != 0)
6437 back = 1;
6438 else
6439 back = 0;
6440
6de9cd9a
DN
6441 len = e->value.character.length;
6442 lenc = c->value.character.length;
6443
6444 if (len == 0 || lenc == 0)
6445 {
6446 indx = 0;
6447 }
6448 else
6449 {
6450 if (back == 0)
edf1eac2 6451 {
00660189
FXC
6452 indx = wide_strcspn (e->value.character.string,
6453 c->value.character.string) + 1;
edf1eac2
SK
6454 if (indx > len)
6455 indx = 0;
6456 }
6de9cd9a 6457 else
edf1eac2
SK
6458 {
6459 i = 0;
6460 for (indx = len; indx > 0; indx--)
6461 {
6462 for (i = 0; i < lenc; i++)
6463 {
6464 if (c->value.character.string[i]
6465 == e->value.character.string[indx - 1])
6466 break;
6467 }
6468 if (i < lenc)
6469 break;
6470 }
6471 }
6de9cd9a 6472 }
b7e75771
JD
6473
6474 result = gfc_get_int_expr (k, &e->where, indx);
6de9cd9a
DN
6475 return range_check (result, "SCAN");
6476}
6477
6478
a39fafac
FXC
6479gfc_expr *
6480gfc_simplify_selected_char_kind (gfc_expr *e)
6481{
6482 int kind;
a39fafac
FXC
6483
6484 if (e->expr_type != EXPR_CONSTANT)
6485 return NULL;
6486
6487 if (gfc_compare_with_Cstring (e, "ascii", false) == 0
6488 || gfc_compare_with_Cstring (e, "default", false) == 0)
6489 kind = 1;
dad80a1b
JD
6490 else if (gfc_compare_with_Cstring (e, "iso_10646", false) == 0)
6491 kind = 4;
a39fafac
FXC
6492 else
6493 kind = -1;
6494
b7e75771 6495 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
a39fafac
FXC
6496}
6497
6498
6de9cd9a 6499gfc_expr *
edf1eac2 6500gfc_simplify_selected_int_kind (gfc_expr *e)
6de9cd9a
DN
6501{
6502 int i, kind, range;
6de9cd9a 6503
51f03c6b 6504 if (e->expr_type != EXPR_CONSTANT || gfc_extract_int (e, &range))
6de9cd9a
DN
6505 return NULL;
6506
6507 kind = INT_MAX;
6508
6509 for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
6510 if (gfc_integer_kinds[i].range >= range
6511 && gfc_integer_kinds[i].kind < kind)
6512 kind = gfc_integer_kinds[i].kind;
6513
6514 if (kind == INT_MAX)
6515 kind = -1;
6516
b7e75771 6517 return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
6de9cd9a
DN
6518}
6519
6520
6521gfc_expr *
01349049 6522gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q, gfc_expr *rdx)
6de9cd9a 6523{
01349049
TB
6524 int range, precision, radix, i, kind, found_precision, found_range,
6525 found_radix;
6526 locus *loc = &gfc_current_locus;
6de9cd9a
DN
6527
6528 if (p == NULL)
6529 precision = 0;
6530 else
6531 {
6532 if (p->expr_type != EXPR_CONSTANT
51f03c6b 6533 || gfc_extract_int (p, &precision))
6de9cd9a 6534 return NULL;
01349049 6535 loc = &p->where;
6de9cd9a
DN
6536 }
6537
6538 if (q == NULL)
6539 range = 0;
6540 else
6541 {
6542 if (q->expr_type != EXPR_CONSTANT
51f03c6b 6543 || gfc_extract_int (q, &range))
6de9cd9a 6544 return NULL;
01349049
TB
6545
6546 if (!loc)
6547 loc = &q->where;
6548 }
6549
6550 if (rdx == NULL)
6551 radix = 0;
6552 else
6553 {
6554 if (rdx->expr_type != EXPR_CONSTANT
51f03c6b 6555 || gfc_extract_int (rdx, &radix))
01349049
TB
6556 return NULL;
6557
6558 if (!loc)
6559 loc = &rdx->where;
6de9cd9a
DN
6560 }
6561
6562 kind = INT_MAX;
6563 found_precision = 0;
6564 found_range = 0;
01349049 6565 found_radix = 0;
6de9cd9a
DN
6566
6567 for (i = 0; gfc_real_kinds[i].kind != 0; i++)
6568 {
6569 if (gfc_real_kinds[i].precision >= precision)
6570 found_precision = 1;
6571
6572 if (gfc_real_kinds[i].range >= range)
6573 found_range = 1;
6574
8b198102 6575 if (radix == 0 || gfc_real_kinds[i].radix == radix)
01349049
TB
6576 found_radix = 1;
6577
6de9cd9a 6578 if (gfc_real_kinds[i].precision >= precision
01349049 6579 && gfc_real_kinds[i].range >= range
8b198102
FXC
6580 && (radix == 0 || gfc_real_kinds[i].radix == radix)
6581 && gfc_real_kinds[i].kind < kind)
6de9cd9a
DN
6582 kind = gfc_real_kinds[i].kind;
6583 }
6584
6585 if (kind == INT_MAX)
6586 {
01349049 6587 if (found_radix && found_range && !found_precision)
6de9cd9a 6588 kind = -1;
01349049
TB
6589 else if (found_radix && found_precision && !found_range)
6590 kind = -2;
6591 else if (found_radix && !found_precision && !found_range)
6592 kind = -3;
6593 else if (found_radix)
6594 kind = -4;
6595 else
6596 kind = -5;
6de9cd9a
DN
6597 }
6598
01349049 6599 return gfc_get_int_expr (gfc_default_integer_kind, loc, kind);
6de9cd9a
DN
6600}
6601
6602
6603gfc_expr *
edf1eac2 6604gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i)
6de9cd9a
DN
6605{
6606 gfc_expr *result;
03ddaf35 6607 mpfr_t exp, absv, log2, pow2, frac;
6de9cd9a
DN
6608 unsigned long exp2;
6609
6610 if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
6611 return NULL;
6612
b7e75771 6613 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
6de9cd9a 6614
d2af8cc6
FXC
6615 /* SET_EXPONENT (+/-0.0, I) = +/- 0.0
6616 SET_EXPONENT (NaN) = same NaN */
6617 if (mpfr_zero_p (x->value.real) || mpfr_nan_p (x->value.real))
6de9cd9a 6618 {
d2af8cc6
FXC
6619 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
6620 return result;
6621 }
6622
6623 /* SET_EXPONENT (inf) = NaN */
6624 if (mpfr_inf_p (x->value.real))
6625 {
6626 mpfr_set_nan (result->value.real);
6de9cd9a
DN
6627 return result;
6628 }
6629
7306494a 6630 gfc_set_model_kind (x->ts.kind);
f8e566e5 6631 mpfr_init (absv);
03ddaf35
TS
6632 mpfr_init (log2);
6633 mpfr_init (exp);
f8e566e5
SK
6634 mpfr_init (pow2);
6635 mpfr_init (frac);
6de9cd9a 6636
f8e566e5 6637 mpfr_abs (absv, x->value.real, GFC_RND_MODE);
03ddaf35 6638 mpfr_log2 (log2, absv, GFC_RND_MODE);
6de9cd9a 6639
03ddaf35
TS
6640 mpfr_trunc (log2, log2);
6641 mpfr_add_ui (exp, log2, 1, GFC_RND_MODE);
6de9cd9a
DN
6642
6643 /* Old exponent value, and fraction. */
03ddaf35 6644 mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE);
6de9cd9a 6645
f8e566e5 6646 mpfr_div (frac, absv, pow2, GFC_RND_MODE);
6de9cd9a
DN
6647
6648 /* New exponent. */
6649 exp2 = (unsigned long) mpz_get_d (i->value.integer);
f8e566e5 6650 mpfr_mul_2exp (result->value.real, frac, exp2, GFC_RND_MODE);
6de9cd9a 6651
7306494a 6652 mpfr_clears (absv, log2, pow2, frac, NULL);
6de9cd9a
DN
6653
6654 return range_check (result, "SET_EXPONENT");
6655}
6656
6657
6658gfc_expr *
7320cf09 6659gfc_simplify_shape (gfc_expr *source, gfc_expr *kind)
6de9cd9a
DN
6660{
6661 mpz_t shape[GFC_MAX_DIMENSIONS];
6662 gfc_expr *result, *e, *f;
6663 gfc_array_ref *ar;
6664 int n;
524af0d6 6665 bool t;
7320cf09 6666 int k = get_kind (BT_INTEGER, kind, "SHAPE", gfc_default_integer_kind);
6de9cd9a 6667
d357d991
MM
6668 if (source->rank == -1)
6669 return NULL;
6670
7320cf09 6671 result = gfc_get_array_expr (BT_INTEGER, k, &source->where);
64a96f5b 6672
7320cf09
TB
6673 if (source->rank == 0)
6674 return result;
6de9cd9a 6675
69dcd06a
DK
6676 if (source->expr_type == EXPR_VARIABLE)
6677 {
6678 ar = gfc_find_array_ref (source);
6679 t = gfc_array_ref_shape (ar, shape);
6680 }
6681 else if (source->shape)
6682 {
524af0d6 6683 t = true;
69dcd06a
DK
6684 for (n = 0; n < source->rank; n++)
6685 {
6686 mpz_init (shape[n]);
6687 mpz_set (shape[n], source->shape[n]);
6688 }
6689 }
6690 else
524af0d6 6691 t = false;
6de9cd9a
DN
6692
6693 for (n = 0; n < source->rank; n++)
6694 {
7320cf09 6695 e = gfc_get_constant_expr (BT_INTEGER, k, &source->where);
6de9cd9a 6696
524af0d6 6697 if (t)
1634e53f 6698 mpz_set (e->value.integer, shape[n]);
6de9cd9a
DN
6699 else
6700 {
6701 mpz_set_ui (e->value.integer, n + 1);
6702
1634e53f 6703 f = simplify_size (source, e, k);
6de9cd9a
DN
6704 gfc_free_expr (e);
6705 if (f == NULL)
6706 {
6707 gfc_free_expr (result);
6708 return NULL;
6709 }
6710 else
69dcd06a 6711 e = f;
6de9cd9a
DN
6712 }
6713
1634e53f
TB
6714 if (e == &gfc_bad_expr || range_check (e, "SHAPE") == &gfc_bad_expr)
6715 {
6716 gfc_free_expr (result);
6717 if (t)
6718 gfc_clear_shape (shape, source->rank);
6719 return &gfc_bad_expr;
6720 }
6721
b7e75771 6722 gfc_constructor_append_expr (&result->value.constructor, e, NULL);
6de9cd9a
DN
6723 }
6724
1634e53f
TB
6725 if (t)
6726 gfc_clear_shape (shape, source->rank);
6727
6de9cd9a
DN
6728 return result;
6729}
6730
6731
1634e53f
TB
6732static gfc_expr *
6733simplify_size (gfc_expr *array, gfc_expr *dim, int k)
6de9cd9a
DN
6734{
6735 mpz_t size;
9231ff56 6736 gfc_expr *return_value;
6de9cd9a
DN
6737 int d;
6738
69dcd06a
DK
6739 /* For unary operations, the size of the result is given by the size
6740 of the operand. For binary ones, it's the size of the first operand
6741 unless it is scalar, then it is the size of the second. */
6742 if (array->expr_type == EXPR_OP && !array->value.op.uop)
6743 {
6744 gfc_expr* replacement;
6745 gfc_expr* simplified;
6746
6747 switch (array->value.op.op)
6748 {
6749 /* Unary operations. */
6750 case INTRINSIC_NOT:
6751 case INTRINSIC_UPLUS:
6752 case INTRINSIC_UMINUS:
1b3f07c7 6753 case INTRINSIC_PARENTHESES:
69dcd06a
DK
6754 replacement = array->value.op.op1;
6755 break;
6756
6757 /* Binary operations. If any one of the operands is scalar, take
6758 the other one's size. If both of them are arrays, it does not
6759 matter -- try to find one with known shape, if possible. */
6760 default:
6761 if (array->value.op.op1->rank == 0)
6762 replacement = array->value.op.op2;
6763 else if (array->value.op.op2->rank == 0)
6764 replacement = array->value.op.op1;
6765 else
6766 {
1634e53f 6767 simplified = simplify_size (array->value.op.op1, dim, k);
69dcd06a
DK
6768 if (simplified)
6769 return simplified;
6770
6771 replacement = array->value.op.op2;
6772 }
6773 break;
6774 }
6775
6776 /* Try to reduce it directly if possible. */
1634e53f 6777 simplified = simplify_size (replacement, dim, k);
69dcd06a
DK
6778
6779 /* Otherwise, we build a new SIZE call. This is hopefully at least
6780 simpler than the original one. */
6781 if (!simplified)
1634e53f
TB
6782 {
6783 gfc_expr *kind = gfc_get_int_expr (gfc_default_integer_kind, NULL, k);
6784 simplified = gfc_build_intrinsic_call (gfc_current_ns,
6785 GFC_ISYM_SIZE, "size",
6786 array->where, 3,
6787 gfc_copy_expr (replacement),
6788 gfc_copy_expr (dim),
6789 kind);
6790 }
69dcd06a
DK
6791 return simplified;
6792 }
6793
6de9cd9a
DN
6794 if (dim == NULL)
6795 {
524af0d6 6796 if (!gfc_array_size (array, &size))
6de9cd9a
DN
6797 return NULL;
6798 }
6799 else
6800 {
6801 if (dim->expr_type != EXPR_CONSTANT)
6802 return NULL;
6803
6804 d = mpz_get_ui (dim->value.integer) - 1;
524af0d6 6805 if (!gfc_array_dimen_size (array, d, &size))
6de9cd9a
DN
6806 return NULL;
6807 }
6808
1634e53f
TB
6809 return_value = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
6810 mpz_set (return_value->value.integer, size);
9231ff56 6811 mpz_clear (size);
1634e53f 6812
9231ff56 6813 return return_value;
6de9cd9a
DN
6814}
6815
6816
1634e53f
TB
6817gfc_expr *
6818gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
6819{
6820 gfc_expr *result;
6821 int k = get_kind (BT_INTEGER, kind, "SIZE", gfc_default_integer_kind);
6822
6823 if (k == -1)
6824 return &gfc_bad_expr;
6825
6826 result = simplify_size (array, dim, k);
6827 if (result == NULL || result == &gfc_bad_expr)
6828 return result;
6829
6830 return range_check (result, "SIZE");
6831}
6832
6833
1a8c1e35
TB
6834/* SIZEOF and C_SIZEOF return the size in bytes of an array element
6835 multiplied by the array size. */
6836
6837gfc_expr *
6838gfc_simplify_sizeof (gfc_expr *x)
6839{
6840 gfc_expr *result = NULL;
6841 mpz_t array_size;
6842
6843 if (x->ts.type == BT_CLASS || x->ts.deferred)
6844 return NULL;
6845
6846 if (x->ts.type == BT_CHARACTER
6847 && (!x->ts.u.cl || !x->ts.u.cl->length
6848 || x->ts.u.cl->length->expr_type != EXPR_CONSTANT))
6849 return NULL;
6850
6851 if (x->rank && x->expr_type != EXPR_ARRAY
524af0d6 6852 && !gfc_array_size (x, &array_size))
1a8c1e35
TB
6853 return NULL;
6854
6855 result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
6856 &x->where);
6857 mpz_set_si (result->value.integer, gfc_target_expr_size (x));
6858
1a8c1e35
TB
6859 return result;
6860}
6861
6862
6863/* STORAGE_SIZE returns the size in bits of a single array element. */
6864
6865gfc_expr *
6866gfc_simplify_storage_size (gfc_expr *x,
6867 gfc_expr *kind)
6868{
6869 gfc_expr *result = NULL;
6870 int k;
1a8c1e35
TB
6871
6872 if (x->ts.type == BT_CLASS || x->ts.deferred)
6873 return NULL;
6874
cc6be82e 6875 if (x->ts.type == BT_CHARACTER && x->expr_type != EXPR_CONSTANT
1a8c1e35
TB
6876 && (!x->ts.u.cl || !x->ts.u.cl->length
6877 || x->ts.u.cl->length->expr_type != EXPR_CONSTANT))
6878 return NULL;
6879
6880 k = get_kind (BT_INTEGER, kind, "STORAGE_SIZE", gfc_default_integer_kind);
6881 if (k == -1)
6882 return &gfc_bad_expr;
6883
a634323a 6884 result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);
e361d18d
JW
6885
6886 mpz_set_si (result->value.integer, gfc_element_size (x));
1a8c1e35 6887 mpz_mul_ui (result->value.integer, result->value.integer, BITS_PER_UNIT);
1634e53f
TB
6888
6889 return range_check (result, "STORAGE_SIZE");
1a8c1e35
TB
6890}
6891
6892
6de9cd9a 6893gfc_expr *
edf1eac2 6894gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
6de9cd9a
DN
6895{
6896 gfc_expr *result;
6897
6898 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
6899 return NULL;
6900
b7e75771 6901 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a
DN
6902
6903 switch (x->ts.type)
6904 {
b7e75771
JD
6905 case BT_INTEGER:
6906 mpz_abs (result->value.integer, x->value.integer);
6907 if (mpz_sgn (y->value.integer) < 0)
6908 mpz_neg (result->value.integer, result->value.integer);
6909 break;
6de9cd9a 6910
b7e75771 6911 case BT_REAL:
c61819ff 6912 if (flag_sign_zero)
b7e75771
JD
6913 mpfr_copysign (result->value.real, x->value.real, y->value.real,
6914 GFC_RND_MODE);
6915 else
6916 mpfr_setsign (result->value.real, x->value.real,
6917 mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
6918 break;
6de9cd9a 6919
b7e75771
JD
6920 default:
6921 gfc_internal_error ("Bad type in gfc_simplify_sign");
6de9cd9a
DN
6922 }
6923
6924 return result;
6925}
6926
6927
6928gfc_expr *
edf1eac2 6929gfc_simplify_sin (gfc_expr *x)
6de9cd9a
DN
6930{
6931 gfc_expr *result;
6de9cd9a
DN
6932
6933 if (x->expr_type != EXPR_CONSTANT)
6934 return NULL;
6935
b7e75771 6936 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a
DN
6937
6938 switch (x->ts.type)
6939 {
b7e75771
JD
6940 case BT_REAL:
6941 mpfr_sin (result->value.real, x->value.real, GFC_RND_MODE);
6942 break;
6de9cd9a 6943
b7e75771
JD
6944 case BT_COMPLEX:
6945 gfc_set_model (x->value.real);
6946 mpc_sin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
6947 break;
6de9cd9a 6948
b7e75771
JD
6949 default:
6950 gfc_internal_error ("in gfc_simplify_sin(): Bad type");
6de9cd9a
DN
6951 }
6952
6953 return range_check (result, "SIN");
6954}
6955
6956
6957gfc_expr *
edf1eac2 6958gfc_simplify_sinh (gfc_expr *x)
6de9cd9a
DN
6959{
6960 gfc_expr *result;
6961
6962 if (x->expr_type != EXPR_CONSTANT)
6963 return NULL;
6964
b7e75771 6965 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 6966
b7e75771
JD
6967 switch (x->ts.type)
6968 {
6969 case BT_REAL:
6970 mpfr_sinh (result->value.real, x->value.real, GFC_RND_MODE);
6971 break;
6972
6973 case BT_COMPLEX:
6974 mpc_sinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
6975 break;
504ed63a 6976
b7e75771
JD
6977 default:
6978 gcc_unreachable ();
6979 }
6de9cd9a
DN
6980
6981 return range_check (result, "SINH");
6982}
6983
6984
6985/* The argument is always a double precision real that is converted to
6986 single precision. TODO: Rounding! */
6987
6988gfc_expr *
edf1eac2 6989gfc_simplify_sngl (gfc_expr *a)
6de9cd9a
DN
6990{
6991 gfc_expr *result;
6992
6993 if (a->expr_type != EXPR_CONSTANT)
6994 return NULL;
6995
9d64df18 6996 result = gfc_real2real (a, gfc_default_real_kind);
6de9cd9a
DN
6997 return range_check (result, "SNGL");
6998}
6999
6de9cd9a 7000
cc6d3bde 7001gfc_expr *
edf1eac2 7002gfc_simplify_spacing (gfc_expr *x)
cc6d3bde
SK
7003{
7004 gfc_expr *result;
7005 int i;
7006 long int en, ep;
6de9cd9a 7007
cc6d3bde
SK
7008 if (x->expr_type != EXPR_CONSTANT)
7009 return NULL;
7010
7011 i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
b7e75771 7012 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);
cc6d3bde 7013
d2af8cc6
FXC
7014 /* SPACING(+/- 0.0) = SPACING(TINY(0.0)) = TINY(0.0) */
7015 if (mpfr_zero_p (x->value.real))
cc6d3bde
SK
7016 {
7017 mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);
7018 return result;
7019 }
7020
d2af8cc6
FXC
7021 /* SPACING(inf) = NaN */
7022 if (mpfr_inf_p (x->value.real))
7023 {
7024 mpfr_set_nan (result->value.real);
7025 return result;
7026 }
7027
7028 /* SPACING(NaN) = same NaN */
7029 if (mpfr_nan_p (x->value.real))
7030 {
7031 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
7032 return result;
7033 }
7034
cc6d3bde 7035 /* In the Fortran 95 standard, the result is b**(e - p) where b, e, and p
8b704316 7036 are the radix, exponent of x, and precision. This excludes the
cc6d3bde
SK
7037 possibility of subnormal numbers. Fortran 2003 states the result is
7038 b**max(e - p, emin - 1). */
7039
7040 ep = (long int) mpfr_get_exp (x->value.real) - gfc_real_kinds[i].digits;
7041 en = (long int) gfc_real_kinds[i].min_exponent - 1;
7042 en = en > ep ? en : ep;
7043
7044 mpfr_set_ui (result->value.real, 1, GFC_RND_MODE);
7045 mpfr_mul_2si (result->value.real, result->value.real, en, GFC_RND_MODE);
7046
7047 return range_check (result, "SPACING");
7048}
b814a64e 7049
6de9cd9a 7050
c430a6f9
DF
7051gfc_expr *
7052gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_expr)
7053{
9231aa17
SK
7054 gfc_expr *result = NULL;
7055 int nelem, i, j, dim, ncopies;
0e6640d8 7056 mpz_t size;
c430a6f9
DF
7057
7058 if ((!gfc_is_constant_expr (source)
7059 && !is_constant_array_expr (source))
7060 || !gfc_is_constant_expr (dim_expr)
7061 || !gfc_is_constant_expr (ncopies_expr))
7062 return NULL;
7063
7064 gcc_assert (dim_expr->ts.type == BT_INTEGER);
7065 gfc_extract_int (dim_expr, &dim);
7066 dim -= 1; /* zero-base DIM */
7067
7068 gcc_assert (ncopies_expr->ts.type == BT_INTEGER);
7069 gfc_extract_int (ncopies_expr, &ncopies);
7070 ncopies = MAX (ncopies, 0);
7071
0e6640d8
PT
7072 /* Do not allow the array size to exceed the limit for an array
7073 constructor. */
e5e85f2b
TB
7074 if (source->expr_type == EXPR_ARRAY)
7075 {
524af0d6 7076 if (!gfc_array_size (source, &size))
e5e85f2b
TB
7077 gfc_internal_error ("Failure getting length of a constant array.");
7078 }
7079 else
7080 mpz_init_set_ui (size, 1);
7081
9231aa17
SK
7082 nelem = mpz_get_si (size) * ncopies;
7083 if (nelem > flag_max_array_constructor)
7084 {
7085 if (gfc_current_ns->sym_root->n.sym->attr.flavor == FL_PARAMETER)
7086 {
7087 gfc_error ("The number of elements (%d) in the array constructor "
7088 "at %L requires an increase of the allowed %d upper "
7089 "limit. See %<-fmax-array-constructor%> option.",
7090 nelem, &source->where, flag_max_array_constructor);
7091 return &gfc_bad_expr;
7092 }
7093 else
7094 return NULL;
7095 }
0e6640d8 7096
c430a6f9
DF
7097 if (source->expr_type == EXPR_CONSTANT)
7098 {
7099 gcc_assert (dim == 0);
7100
b7e75771
JD
7101 result = gfc_get_array_expr (source->ts.type, source->ts.kind,
7102 &source->where);
15c2ef5a
PT
7103 if (source->ts.type == BT_DERIVED)
7104 result->ts.u.derived = source->ts.u.derived;
c430a6f9
DF
7105 result->rank = 1;
7106 result->shape = gfc_get_shape (result->rank);
7107 mpz_init_set_si (result->shape[0], ncopies);
7108
7109 for (i = 0; i < ncopies; ++i)
b7e75771
JD
7110 gfc_constructor_append_expr (&result->value.constructor,
7111 gfc_copy_expr (source), NULL);
c430a6f9
DF
7112 }
7113 else if (source->expr_type == EXPR_ARRAY)
7114 {
b7e75771
JD
7115 int offset, rstride[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS];
7116 gfc_constructor *source_ctor;
c430a6f9
DF
7117
7118 gcc_assert (source->rank < GFC_MAX_DIMENSIONS);
7119 gcc_assert (dim >= 0 && dim <= source->rank);
7120
b7e75771
JD
7121 result = gfc_get_array_expr (source->ts.type, source->ts.kind,
7122 &source->where);
15c2ef5a
PT
7123 if (source->ts.type == BT_DERIVED)
7124 result->ts.u.derived = source->ts.u.derived;
c430a6f9
DF
7125 result->rank = source->rank + 1;
7126 result->shape = gfc_get_shape (result->rank);
7127
c430a6f9
DF
7128 for (i = 0, j = 0; i < result->rank; ++i)
7129 {
7130 if (i != dim)
7131 mpz_init_set (result->shape[i], source->shape[j++]);
7132 else
7133 mpz_init_set_si (result->shape[i], ncopies);
7134
7135 extent[i] = mpz_get_si (result->shape[i]);
7136 rstride[i] = (i == 0) ? 1 : rstride[i-1] * extent[i-1];
c430a6f9
DF
7137 }
7138
b7e75771
JD
7139 offset = 0;
7140 for (source_ctor = gfc_constructor_first (source->value.constructor);
7141 source_ctor; source_ctor = gfc_constructor_next (source_ctor))
c430a6f9 7142 {
c430a6f9 7143 for (i = 0; i < ncopies; ++i)
b7e75771
JD
7144 gfc_constructor_insert_expr (&result->value.constructor,
7145 gfc_copy_expr (source_ctor->expr),
7146 NULL, offset + i * rstride[dim]);
c430a6f9 7147
b7e75771 7148 offset += (dim == 0 ? ncopies : 1);
c430a6f9
DF
7149 }
7150 }
7151 else
b1c1d761 7152 {
98d4439c 7153 gfc_error ("Simplification of SPREAD at %C not yet implemented");
b1c1d761
SK
7154 return &gfc_bad_expr;
7155 }
c430a6f9
DF
7156
7157 if (source->ts.type == BT_CHARACTER)
bc21d315 7158 result->ts.u.cl = source->ts.u.cl;
c430a6f9
DF
7159
7160 return result;
7161}
7162
7163
6de9cd9a 7164gfc_expr *
edf1eac2 7165gfc_simplify_sqrt (gfc_expr *e)
6de9cd9a 7166{
b7e75771 7167 gfc_expr *result = NULL;
6de9cd9a
DN
7168
7169 if (e->expr_type != EXPR_CONSTANT)
7170 return NULL;
7171
6de9cd9a
DN
7172 switch (e->ts.type)
7173 {
b7e75771
JD
7174 case BT_REAL:
7175 if (mpfr_cmp_si (e->value.real, 0) < 0)
7176 {
7177 gfc_error ("Argument of SQRT at %L has a negative value",
7178 &e->where);
7179 return &gfc_bad_expr;
7180 }
7181 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
7182 mpfr_sqrt (result->value.real, e->value.real, GFC_RND_MODE);
7183 break;
6de9cd9a 7184
b7e75771
JD
7185 case BT_COMPLEX:
7186 gfc_set_model (e->value.real);
6de9cd9a 7187
b7e75771
JD
7188 result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
7189 mpc_sqrt (result->value.complex, e->value.complex, GFC_MPC_RND_MODE);
7190 break;
6de9cd9a 7191
b7e75771
JD
7192 default:
7193 gfc_internal_error ("invalid argument of SQRT at %L", &e->where);
6de9cd9a
DN
7194 }
7195
7196 return range_check (result, "SQRT");
6de9cd9a
DN
7197}
7198
7199
a16d978f
DF
7200gfc_expr *
7201gfc_simplify_sum (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
7202{
195a95c4 7203 return simplify_transformation (array, dim, mask, 0, gfc_add);
a16d978f
DF
7204}
7205
7206
8e8c2744
FR
7207gfc_expr *
7208gfc_simplify_cotan (gfc_expr *x)
7209{
7210 gfc_expr *result;
7211 mpc_t swp, *val;
7212
7213 if (x->expr_type != EXPR_CONSTANT)
7214 return NULL;
7215
7216 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
7217
7218 switch (x->ts.type)
7219 {
0a4613f0
JJ
7220 case BT_REAL:
7221 mpfr_cot (result->value.real, x->value.real, GFC_RND_MODE);
7222 break;
8e8c2744 7223
0a4613f0
JJ
7224 case BT_COMPLEX:
7225 /* There is no builtin mpc_cot, so compute cot = cos / sin. */
7226 val = &result->value.complex;
7227 mpc_init2 (swp, mpfr_get_default_prec ());
7228 mpc_cos (swp, x->value.complex, GFC_MPC_RND_MODE);
7229 mpc_sin (*val, x->value.complex, GFC_MPC_RND_MODE);
7230 mpc_div (*val, swp, *val, GFC_MPC_RND_MODE);
7231 mpc_clear (swp);
7232 break;
8e8c2744 7233
0a4613f0
JJ
7234 default:
7235 gcc_unreachable ();
8e8c2744
FR
7236 }
7237
7238 return range_check (result, "COTAN");
7239}
7240
7241
6de9cd9a 7242gfc_expr *
edf1eac2 7243gfc_simplify_tan (gfc_expr *x)
6de9cd9a 7244{
f8e566e5 7245 gfc_expr *result;
6de9cd9a
DN
7246
7247 if (x->expr_type != EXPR_CONSTANT)
7248 return NULL;
7249
b7e75771 7250 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 7251
b7e75771
JD
7252 switch (x->ts.type)
7253 {
7254 case BT_REAL:
7255 mpfr_tan (result->value.real, x->value.real, GFC_RND_MODE);
7256 break;
7257
7258 case BT_COMPLEX:
7259 mpc_tan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
7260 break;
7261
7262 default:
7263 gcc_unreachable ();
7264 }
6de9cd9a
DN
7265
7266 return range_check (result, "TAN");
7267}
7268
7269
7270gfc_expr *
edf1eac2 7271gfc_simplify_tanh (gfc_expr *x)
6de9cd9a
DN
7272{
7273 gfc_expr *result;
6de9cd9a
DN
7274
7275 if (x->expr_type != EXPR_CONSTANT)
7276 return NULL;
7277
b7e75771 7278 result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6de9cd9a 7279
b7e75771
JD
7280 switch (x->ts.type)
7281 {
7282 case BT_REAL:
7283 mpfr_tanh (result->value.real, x->value.real, GFC_RND_MODE);
7284 break;
6de9cd9a 7285
b7e75771
JD
7286 case BT_COMPLEX:
7287 mpc_tanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
7288 break;
7289
7290 default:
7291 gcc_unreachable ();
7292 }
6de9cd9a 7293
b7e75771 7294 return range_check (result, "TANH");
6de9cd9a
DN
7295}
7296
7297
7298gfc_expr *
edf1eac2 7299gfc_simplify_tiny (gfc_expr *e)
6de9cd9a
DN
7300{
7301 gfc_expr *result;
7302 int i;
7303
e7a2d5fb 7304 i = gfc_validate_kind (BT_REAL, e->ts.kind, false);
6de9cd9a 7305
b7e75771 7306 result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
f8e566e5 7307 mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);
6de9cd9a
DN
7308
7309 return result;
7310}
7311
7312
414f00e9
SB
7313gfc_expr *
7314gfc_simplify_trailz (gfc_expr *e)
7315{
414f00e9
SB
7316 unsigned long tz, bs;
7317 int i;
7318
7319 if (e->expr_type != EXPR_CONSTANT)
7320 return NULL;
7321
7322 i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
7323 bs = gfc_integer_kinds[i].bit_size;
7324 tz = mpz_scan1 (e->value.integer, 0);
7325
b7e75771
JD
7326 return gfc_get_int_expr (gfc_default_integer_kind,
7327 &e->where, MIN (tz, bs));
414f00e9
SB
7328}
7329
7330
a4a11197 7331gfc_expr *
edf1eac2 7332gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
a4a11197 7333{
7433458d
PT
7334 gfc_expr *result;
7335 gfc_expr *mold_element;
7336 size_t source_size;
7337 size_t result_size;
7433458d
PT
7338 size_t buffer_size;
7339 mpz_t tmp;
7340 unsigned char *buffer;
86dbed7d
TK
7341 size_t result_length;
7342
a4a11197 7343
7433458d 7344 if (!gfc_is_constant_expr (source)
f2cbd86c 7345 || (gfc_init_expr_flag && !gfc_is_constant_expr (mold))
7433458d
PT
7346 || !gfc_is_constant_expr (size))
7347 return NULL;
7348
524af0d6
JB
7349 if (!gfc_calculate_transfer_sizes (source, mold, size, &source_size,
7350 &result_size, &result_length))
2dc95548
PT
7351 return NULL;
7352
7433458d 7353 /* Calculate the size of the source. */
b0369790 7354 if (source->expr_type == EXPR_ARRAY && !gfc_array_size (source, &tmp))
7433458d
PT
7355 gfc_internal_error ("Failure getting length of a constant array.");
7356
7433458d 7357 /* Create an empty new expression with the appropriate characteristics. */
b7e75771
JD
7358 result = gfc_get_constant_expr (mold->ts.type, mold->ts.kind,
7359 &source->where);
7433458d
PT
7360 result->ts = mold->ts;
7361
b0369790 7362 mold_element = (mold->expr_type == EXPR_ARRAY && mold->value.constructor)
b7e75771 7363 ? gfc_constructor_first (mold->value.constructor)->expr
7433458d
PT
7364 : mold;
7365
7366 /* Set result character length, if needed. Note that this needs to be
8b704316 7367 set even for array expressions, in order to pass this information into
7433458d 7368 gfc_target_interpret_expr. */
d9183bb7 7369 if (result->ts.type == BT_CHARACTER && gfc_is_constant_expr (mold_element))
7433458d 7370 result->value.character.length = mold_element->value.character.length;
8b704316 7371
7433458d 7372 /* Set the number of elements in the result, and determine its size. */
d9183bb7 7373
e7c8ff56 7374 if (mold->expr_type == EXPR_ARRAY || mold->rank || size)
7433458d 7375 {
7433458d
PT
7376 result->expr_type = EXPR_ARRAY;
7377 result->rank = 1;
7433458d
PT
7378 result->shape = gfc_get_shape (1);
7379 mpz_init_set_ui (result->shape[0], result_length);
7433458d
PT
7380 }
7381 else
86dbed7d 7382 result->rank = 0;
92ebaacd 7383
7433458d
PT
7384 /* Allocate the buffer to store the binary version of the source. */
7385 buffer_size = MAX (source_size, result_size);
7386 buffer = (unsigned char*)alloca (buffer_size);
47ed69db 7387 memset (buffer, 0, buffer_size);
7433458d
PT
7388
7389 /* Now write source to the buffer. */
7390 gfc_target_encode_expr (source, buffer, buffer_size);
7391
7392 /* And read the buffer back into the new expression. */
86dbed7d 7393 gfc_target_interpret_expr (buffer, buffer_size, result, false);
7433458d
PT
7394
7395 return result;
a4a11197
PT
7396}
7397
7398
8ec259c1
DF
7399gfc_expr *
7400gfc_simplify_transpose (gfc_expr *matrix)
7401{
b7e75771 7402 int row, matrix_rows, col, matrix_cols;
8ec259c1 7403 gfc_expr *result;
8ec259c1
DF
7404
7405 if (!is_constant_array_expr (matrix))
7406 return NULL;
7407
7408 gcc_assert (matrix->rank == 2);
7409
b7e75771
JD
7410 result = gfc_get_array_expr (matrix->ts.type, matrix->ts.kind,
7411 &matrix->where);
8ec259c1
DF
7412 result->rank = 2;
7413 result->shape = gfc_get_shape (result->rank);
7414 mpz_set (result->shape[0], matrix->shape[1]);
7415 mpz_set (result->shape[1], matrix->shape[0]);
7416
7417 if (matrix->ts.type == BT_CHARACTER)
bc21d315 7418 result->ts.u.cl = matrix->ts.u.cl;
15c2ef5a
PT
7419 else if (matrix->ts.type == BT_DERIVED)
7420 result->ts.u.derived = matrix->ts.u.derived;
8ec259c1
DF
7421
7422 matrix_rows = mpz_get_si (matrix->shape[0]);
b7e75771
JD
7423 matrix_cols = mpz_get_si (matrix->shape[1]);
7424 for (row = 0; row < matrix_rows; ++row)
7425 for (col = 0; col < matrix_cols; ++col)
7426 {
7427 gfc_expr *e = gfc_constructor_lookup_expr (matrix->value.constructor,
7428 col * matrix_rows + row);
8b704316 7429 gfc_constructor_insert_expr (&result->value.constructor,
b7e75771
JD
7430 gfc_copy_expr (e), &matrix->where,
7431 row * matrix_cols + col);
7432 }
8ec259c1
DF
7433
7434 return result;
7435}
7436
7437
6de9cd9a 7438gfc_expr *
edf1eac2 7439gfc_simplify_trim (gfc_expr *e)
6de9cd9a
DN
7440{
7441 gfc_expr *result;
7442 int count, i, len, lentrim;
7443
7444 if (e->expr_type != EXPR_CONSTANT)
7445 return NULL;
7446
7447 len = e->value.character.length;
6de9cd9a
DN
7448 for (count = 0, i = 1; i <= len; ++i)
7449 {
7450 if (e->value.character.string[len - i] == ' ')
7451 count++;
7452 else
7453 break;
7454 }
7455
7456 lentrim = len - count;
7457
b7e75771 7458 result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, lentrim);
6de9cd9a
DN
7459 for (i = 0; i < lentrim; i++)
7460 result->value.character.string[i] = e->value.character.string[i];
7461
6de9cd9a
DN
7462 return result;
7463}
7464
7465
64f002ed
TB
7466gfc_expr *
7467gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub)
7468{
7469 gfc_expr *result;
7470 gfc_ref *ref;
7471 gfc_array_spec *as;
7472 gfc_constructor *sub_cons;
7473 bool first_image;
7474 int d;
7475
7476 if (!is_constant_array_expr (sub))
5af07930 7477 return NULL;
64f002ed
TB
7478
7479 /* Follow any component references. */
7480 as = coarray->symtree->n.sym->as;
7481 for (ref = coarray->ref; ref; ref = ref->next)
7482 if (ref->type == REF_COMPONENT)
7483 as = ref->u.ar.as;
7484
7485 if (as->type == AS_DEFERRED)
5af07930 7486 return NULL;
64f002ed
TB
7487
7488 /* "valid sequence of cosubscripts" are required; thus, return 0 unless
7489 the cosubscript addresses the first image. */
7490
7491 sub_cons = gfc_constructor_first (sub->value.constructor);
7492 first_image = true;
7493
7494 for (d = 1; d <= as->corank; d++)
7495 {
7496 gfc_expr *ca_bound;
7497 int cmp;
7498
e84b920c 7499 gcc_assert (sub_cons != NULL);
64f002ed
TB
7500
7501 ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 0, as,
7502 NULL, true);
7503 if (ca_bound == NULL)
5af07930 7504 return NULL;
64f002ed
TB
7505
7506 if (ca_bound == &gfc_bad_expr)
7507 return ca_bound;
7508
7509 cmp = mpz_cmp (ca_bound->value.integer, sub_cons->expr->value.integer);
7510
7511 if (cmp == 0)
7512 {
7513 gfc_free_expr (ca_bound);
7514 sub_cons = gfc_constructor_next (sub_cons);
7515 continue;
7516 }
7517
7518 first_image = false;
7519
7520 if (cmp > 0)
7521 {
7522 gfc_error ("Out of bounds in IMAGE_INDEX at %L for dimension %d, "
7523 "SUB has %ld and COARRAY lower bound is %ld)",
7524 &coarray->where, d,
7525 mpz_get_si (sub_cons->expr->value.integer),
7526 mpz_get_si (ca_bound->value.integer));
7527 gfc_free_expr (ca_bound);
7528 return &gfc_bad_expr;
7529 }
7530
7531 gfc_free_expr (ca_bound);
7532
7533 /* Check whether upperbound is valid for the multi-images case. */
7534 if (d < as->corank)
7535 {
7536 ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 1, as,
7537 NULL, true);
7538 if (ca_bound == &gfc_bad_expr)
7539 return ca_bound;
7540
7541 if (ca_bound && ca_bound->expr_type == EXPR_CONSTANT
7542 && mpz_cmp (ca_bound->value.integer,
7543 sub_cons->expr->value.integer) < 0)
7544 {
7545 gfc_error ("Out of bounds in IMAGE_INDEX at %L for dimension %d, "
7546 "SUB has %ld and COARRAY upper bound is %ld)",
7547 &coarray->where, d,
7548 mpz_get_si (sub_cons->expr->value.integer),
7549 mpz_get_si (ca_bound->value.integer));
7550 gfc_free_expr (ca_bound);
7551 return &gfc_bad_expr;
7552 }
7553
7554 if (ca_bound)
7555 gfc_free_expr (ca_bound);
7556 }
7557
7558 sub_cons = gfc_constructor_next (sub_cons);
7559 }
7560
e84b920c 7561 gcc_assert (sub_cons == NULL);
5af07930 7562
f19626cf 7563 if (flag_coarray != GFC_FCOARRAY_SINGLE && !first_image)
5af07930
TB
7564 return NULL;
7565
64f002ed
TB
7566 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
7567 &gfc_current_locus);
7568 if (first_image)
7569 mpz_set_si (result->value.integer, 1);
7570 else
7571 mpz_set_si (result->value.integer, 0);
7572
7573 return result;
64f002ed
TB
7574}
7575
ef78bc3c
AV
7576gfc_expr *
7577gfc_simplify_image_status (gfc_expr *image, gfc_expr *team ATTRIBUTE_UNUSED)
7578{
7579 if (flag_coarray == GFC_FCOARRAY_NONE)
7580 {
7581 gfc_current_locus = *gfc_current_intrinsic_where;
7582 gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
7583 return &gfc_bad_expr;
7584 }
7585
7586 /* Simplification is possible for fcoarray = single only. For all other modes
7587 the result depends on runtime conditions. */
7588 if (flag_coarray != GFC_FCOARRAY_SINGLE)
7589 return NULL;
7590
7591 if (gfc_is_constant_expr (image))
7592 {
7593 gfc_expr *result;
7594 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
7595 &image->where);
7596 if (mpz_get_si (image->value.integer) == 1)
7597 mpz_set_si (result->value.integer, 0);
7598 else
7599 mpz_set_si (result->value.integer, GFC_STAT_STOPPED_IMAGE);
7600 return result;
7601 }
7602 else
7603 return NULL;
7604}
7605
64f002ed
TB
7606
7607gfc_expr *
05fc16dd
TB
7608gfc_simplify_this_image (gfc_expr *coarray, gfc_expr *dim,
7609 gfc_expr *distance ATTRIBUTE_UNUSED)
64f002ed 7610{
f19626cf 7611 if (flag_coarray != GFC_FCOARRAY_SINGLE)
60386f50
TB
7612 return NULL;
7613
05fc16dd
TB
7614 /* If no coarray argument has been passed or when the first argument
7615 is actually a distance argment. */
7616 if (coarray == NULL || !gfc_is_coarray (coarray))
64f002ed
TB
7617 {
7618 gfc_expr *result;
7619 /* FIXME: gfc_current_locus is wrong. */
7620 result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
7621 &gfc_current_locus);
7622 mpz_set_si (result->value.integer, 1);
7623 return result;
7624 }
7625
492792ed
TB
7626 /* For -fcoarray=single, this_image(A) is the same as lcobound(A). */
7627 return simplify_cobound (coarray, dim, NULL, 0);
64f002ed
TB
7628}
7629
7630
6de9cd9a 7631gfc_expr *
5cda5098 7632gfc_simplify_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
6de9cd9a 7633{
5cda5098 7634 return simplify_bound (array, dim, kind, 1);
6de9cd9a
DN
7635}
7636
64f002ed
TB
7637gfc_expr *
7638gfc_simplify_ucobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
7639{
a3935ffc 7640 return simplify_cobound (array, dim, kind, 1);
64f002ed
TB
7641}
7642
6de9cd9a 7643
c430a6f9
DF
7644gfc_expr *
7645gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
7646{
7647 gfc_expr *result, *e;
7648 gfc_constructor *vector_ctor, *mask_ctor, *field_ctor;
7649
7650 if (!is_constant_array_expr (vector)
7651 || !is_constant_array_expr (mask)
7652 || (!gfc_is_constant_expr (field)
524af0d6 7653 && !is_constant_array_expr (field)))
c430a6f9
DF
7654 return NULL;
7655
b7e75771
JD
7656 result = gfc_get_array_expr (vector->ts.type, vector->ts.kind,
7657 &vector->where);
15c2ef5a
PT
7658 if (vector->ts.type == BT_DERIVED)
7659 result->ts.u.derived = vector->ts.u.derived;
c430a6f9
DF
7660 result->rank = mask->rank;
7661 result->shape = gfc_copy_shape (mask->shape, mask->rank);
7662
7663 if (vector->ts.type == BT_CHARACTER)
bc21d315 7664 result->ts.u.cl = vector->ts.u.cl;
c430a6f9 7665
b7e75771
JD
7666 vector_ctor = gfc_constructor_first (vector->value.constructor);
7667 mask_ctor = gfc_constructor_first (mask->value.constructor);
7668 field_ctor
7669 = field->expr_type == EXPR_ARRAY
7670 ? gfc_constructor_first (field->value.constructor)
7671 : NULL;
c430a6f9
DF
7672
7673 while (mask_ctor)
7674 {
7675 if (mask_ctor->expr->value.logical)
7676 {
7677 gcc_assert (vector_ctor);
7678 e = gfc_copy_expr (vector_ctor->expr);
b7e75771 7679 vector_ctor = gfc_constructor_next (vector_ctor);
c430a6f9
DF
7680 }
7681 else if (field->expr_type == EXPR_ARRAY)
7682 e = gfc_copy_expr (field_ctor->expr);
7683 else
7684 e = gfc_copy_expr (field);
7685
b7e75771 7686 gfc_constructor_append_expr (&result->value.constructor, e, NULL);
c430a6f9 7687
b7e75771
JD
7688 mask_ctor = gfc_constructor_next (mask_ctor);
7689 field_ctor = gfc_constructor_next (field_ctor);
c430a6f9
DF
7690 }
7691
7692 return result;
7693}
7694
7695
6de9cd9a 7696gfc_expr *
5cda5098 7697gfc_simplify_verify (gfc_expr *s, gfc_expr *set, gfc_expr *b, gfc_expr *kind)
6de9cd9a
DN
7698{
7699 gfc_expr *result;
7700 int back;
7701 size_t index, len, lenset;
7702 size_t i;
5cda5098
FXC
7703 int k = get_kind (BT_INTEGER, kind, "VERIFY", gfc_default_integer_kind);
7704
7705 if (k == -1)
7706 return &gfc_bad_expr;
6de9cd9a 7707
61aa9333
TB
7708 if (s->expr_type != EXPR_CONSTANT || set->expr_type != EXPR_CONSTANT
7709 || ( b != NULL && b->expr_type != EXPR_CONSTANT))
6de9cd9a
DN
7710 return NULL;
7711
7712 if (b != NULL && b->value.logical != 0)
7713 back = 1;
7714 else
7715 back = 0;
7716
b7e75771 7717 result = gfc_get_constant_expr (BT_INTEGER, k, &s->where);
6de9cd9a
DN
7718
7719 len = s->value.character.length;
7720 lenset = set->value.character.length;
7721
7722 if (len == 0)
7723 {
7724 mpz_set_ui (result->value.integer, 0);
7725 return result;
7726 }
7727
7728 if (back == 0)
7729 {
7730 if (lenset == 0)
7731 {
9202989a 7732 mpz_set_ui (result->value.integer, 1);
6de9cd9a
DN
7733 return result;
7734 }
7735
00660189
FXC
7736 index = wide_strspn (s->value.character.string,
7737 set->value.character.string) + 1;
6de9cd9a
DN
7738 if (index > len)
7739 index = 0;
7740
7741 }
7742 else
7743 {
7744 if (lenset == 0)
7745 {
9202989a 7746 mpz_set_ui (result->value.integer, len);
6de9cd9a
DN
7747 return result;
7748 }
7749 for (index = len; index > 0; index --)
edf1eac2
SK
7750 {
7751 for (i = 0; i < lenset; i++)
7752 {
7753 if (s->value.character.string[index - 1]
7754 == set->value.character.string[i])
7755 break;
7756 }
7757 if (i == lenset)
7758 break;
7759 }
6de9cd9a
DN
7760 }
7761
7762 mpz_set_ui (result->value.integer, index);
7763 return result;
7764}
7765
5d723e54
FXC
7766
7767gfc_expr *
edf1eac2 7768gfc_simplify_xor (gfc_expr *x, gfc_expr *y)
5d723e54
FXC
7769{
7770 gfc_expr *result;
7771 int kind;
7772
7773 if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
7774 return NULL;
7775
7776 kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
b7e75771
JD
7777
7778 switch (x->ts.type)
5d723e54 7779 {
b7e75771
JD
7780 case BT_INTEGER:
7781 result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
7782 mpz_xor (result->value.integer, x->value.integer, y->value.integer);
7783 return range_check (result, "XOR");
7784
7785 case BT_LOGICAL:
7786 return gfc_get_logical_expr (kind, &x->where,
7787 (x->value.logical && !y->value.logical)
7788 || (!x->value.logical && y->value.logical));
5d723e54 7789
b7e75771
JD
7790 default:
7791 gcc_unreachable ();
7792 }
5d723e54
FXC
7793}
7794
7795
6de9cd9a
DN
7796/****************** Constant simplification *****************/
7797
7798/* Master function to convert one constant to another. While this is
7799 used as a simplification function, it requires the destination type
7800 and kind information which is supplied by a special case in
7801 do_simplify(). */
7802
7803gfc_expr *
edf1eac2 7804gfc_convert_constant (gfc_expr *e, bt type, int kind)
6de9cd9a
DN
7805{
7806 gfc_expr *g, *result, *(*f) (gfc_expr *, int);
b7e75771 7807 gfc_constructor *c;
6de9cd9a
DN
7808
7809 switch (e->ts.type)
7810 {
7811 case BT_INTEGER:
7812 switch (type)
7813 {
7814 case BT_INTEGER:
7815 f = gfc_int2int;
7816 break;
7817 case BT_REAL:
7818 f = gfc_int2real;
7819 break;
7820 case BT_COMPLEX:
7821 f = gfc_int2complex;
7822 break;
c3a29423
RS
7823 case BT_LOGICAL:
7824 f = gfc_int2log;
7825 break;
6de9cd9a
DN
7826 default:
7827 goto oops;
7828 }
7829 break;
7830
7831 case BT_REAL:
7832 switch (type)
7833 {
7834 case BT_INTEGER:
7835 f = gfc_real2int;
7836 break;
7837 case BT_REAL:
7838 f = gfc_real2real;
7839 break;
7840 case BT_COMPLEX:
7841 f = gfc_real2complex;
7842 break;
7843 default:
7844 goto oops;
7845 }
7846 break;
7847
7848 case BT_COMPLEX:
7849 switch (type)
7850 {
7851 case BT_INTEGER:
7852 f = gfc_complex2int;
7853 break;
7854 case BT_REAL:
7855 f = gfc_complex2real;
7856 break;
7857 case BT_COMPLEX:
7858 f = gfc_complex2complex;
7859 break;
7860
7861 default:
7862 goto oops;
7863 }
7864 break;
7865
7866 case BT_LOGICAL:
c3a29423
RS
7867 switch (type)
7868 {
7869 case BT_INTEGER:
7870 f = gfc_log2int;
7871 break;
7872 case BT_LOGICAL:
7873 f = gfc_log2log;
7874 break;
7875 default:
7876 goto oops;
7877 }
6de9cd9a
DN
7878 break;
7879
d3642f89
FW
7880 case BT_HOLLERITH:
7881 switch (type)
7882 {
7883 case BT_INTEGER:
7884 f = gfc_hollerith2int;
7885 break;
7886
7887 case BT_REAL:
7888 f = gfc_hollerith2real;
7889 break;
7890
7891 case BT_COMPLEX:
7892 f = gfc_hollerith2complex;
7893 break;
7894
7895 case BT_CHARACTER:
7896 f = gfc_hollerith2character;
7897 break;
7898
7899 case BT_LOGICAL:
7900 f = gfc_hollerith2logical;
7901 break;
7902
7903 default:
7904 goto oops;
7905 }
7906 break;
7907
b01fff48
TK
7908 case BT_CHARACTER:
7909 if (type == BT_CHARACTER)
7910 f = gfc_character2character;
7911 else
7912 goto oops;
7913 break;
7914
6de9cd9a
DN
7915 default:
7916 oops:
7917 gfc_internal_error ("gfc_convert_constant(): Unexpected type");
7918 }
7919
7920 result = NULL;
7921
7922 switch (e->expr_type)
7923 {
7924 case EXPR_CONSTANT:
7925 result = f (e, kind);
7926 if (result == NULL)
7927 return &gfc_bad_expr;
7928 break;
7929
7930 case EXPR_ARRAY:
7931 if (!gfc_is_constant_expr (e))
7932 break;
7933
b7e75771
JD
7934 result = gfc_get_array_expr (type, kind, &e->where);
7935 result->shape = gfc_copy_shape (e->shape, e->rank);
7936 result->rank = e->rank;
6de9cd9a 7937
b7e75771
JD
7938 for (c = gfc_constructor_first (e->value.constructor);
7939 c; c = gfc_constructor_next (c))
6de9cd9a 7940 {
b7e75771 7941 gfc_expr *tmp;
6de9cd9a 7942 if (c->iterator == NULL)
b7e75771 7943 tmp = f (c->expr, kind);
6de9cd9a
DN
7944 else
7945 {
7946 g = gfc_convert_constant (c->expr, type, kind);
7947 if (g == &gfc_bad_expr)
b7e75771
JD
7948 {
7949 gfc_free_expr (result);
7950 return g;
7951 }
7952 tmp = g;
6de9cd9a
DN
7953 }
7954
b7e75771 7955 if (tmp == NULL)
6de9cd9a 7956 {
b7e75771 7957 gfc_free_expr (result);
6de9cd9a
DN
7958 return NULL;
7959 }
b7e75771
JD
7960
7961 gfc_constructor_append_expr (&result->value.constructor,
7962 tmp, &c->where);
6de9cd9a
DN
7963 }
7964
6de9cd9a
DN
7965 break;
7966
7967 default:
7968 break;
7969 }
7970
7971 return result;
7972}
d393bbd7
FXC
7973
7974
7975/* Function for converting character constants. */
7976gfc_expr *
7977gfc_convert_char_constant (gfc_expr *e, bt type ATTRIBUTE_UNUSED, int kind)
7978{
7979 gfc_expr *result;
7980 int i;
7981
7982 if (!gfc_is_constant_expr (e))
7983 return NULL;
7984
691da334
FXC
7985 if (e->expr_type == EXPR_CONSTANT)
7986 {
7987 /* Simple case of a scalar. */
b7e75771 7988 result = gfc_get_constant_expr (BT_CHARACTER, kind, &e->where);
691da334 7989 if (result == NULL)
d393bbd7 7990 return &gfc_bad_expr;
d393bbd7 7991
691da334
FXC
7992 result->value.character.length = e->value.character.length;
7993 result->value.character.string
7994 = gfc_get_wide_string (e->value.character.length + 1);
7995 memcpy (result->value.character.string, e->value.character.string,
7996 (e->value.character.length + 1) * sizeof (gfc_char_t));
7997
7998 /* Check we only have values representable in the destination kind. */
7999 for (i = 0; i < result->value.character.length; i++)
8000 if (!gfc_check_character_range (result->value.character.string[i],
8001 kind))
8002 {
a4d9b221 8003 gfc_error ("Character %qs in string at %L cannot be converted "
691da334
FXC
8004 "into character kind %d",
8005 gfc_print_wide_char (result->value.character.string[i]),
8006 &e->where, kind);
47109217 8007 gfc_free_expr (result);
691da334
FXC
8008 return &gfc_bad_expr;
8009 }
8010
8011 return result;
8012 }
8013 else if (e->expr_type == EXPR_ARRAY)
8014 {
8015 /* For an array constructor, we convert each constructor element. */
b7e75771 8016 gfc_constructor *c;
691da334 8017
b7e75771
JD
8018 result = gfc_get_array_expr (type, kind, &e->where);
8019 result->shape = gfc_copy_shape (e->shape, e->rank);
8020 result->rank = e->rank;
8021 result->ts.u.cl = e->ts.u.cl;
691da334 8022
b7e75771
JD
8023 for (c = gfc_constructor_first (e->value.constructor);
8024 c; c = gfc_constructor_next (c))
8025 {
8026 gfc_expr *tmp = gfc_convert_char_constant (c->expr, type, kind);
8027 if (tmp == &gfc_bad_expr)
691da334 8028 {
b7e75771 8029 gfc_free_expr (result);
691da334
FXC
8030 return &gfc_bad_expr;
8031 }
8032
b7e75771 8033 if (tmp == NULL)
691da334 8034 {
b7e75771 8035 gfc_free_expr (result);
691da334
FXC
8036 return NULL;
8037 }
691da334 8038
b7e75771
JD
8039 gfc_constructor_append_expr (&result->value.constructor,
8040 tmp, &c->where);
8041 }
691da334
FXC
8042
8043 return result;
8044 }
8045 else
8046 return NULL;
d393bbd7 8047}
d000aa67
TB
8048
8049
8050gfc_expr *
8051gfc_simplify_compiler_options (void)
8052{
41804a5b
TB
8053 char *str;
8054 gfc_expr *result;
8055
8056 str = gfc_get_option_string ();
8057 result = gfc_get_character_expr (gfc_default_character_kind,
8058 &gfc_current_locus, str, strlen (str));
cede9502 8059 free (str);
41804a5b 8060 return result;
d000aa67
TB
8061}
8062
8063
8064gfc_expr *
8065gfc_simplify_compiler_version (void)
8066{
41804a5b
TB
8067 char *buffer;
8068 size_t len;
8069
ed17fc41
SK
8070 len = strlen ("GCC version ") + strlen (version_string);
8071 buffer = XALLOCAVEC (char, len + 1);
8072 snprintf (buffer, len + 1, "GCC version %s", version_string);
d000aa67 8073 return gfc_get_character_expr (gfc_default_character_kind,
41804a5b 8074 &gfc_current_locus, buffer, len);
d000aa67 8075}
0e360db9
FXC
8076
8077/* Simplification routines for intrinsics of IEEE modules. */
8078
8079gfc_expr *
8080simplify_ieee_selected_real_kind (gfc_expr *expr)
8081{
741b52b5
SK
8082 gfc_actual_arglist *arg;
8083 gfc_expr *p = NULL, *q = NULL, *rdx = NULL;
8084
8085 arg = expr->value.function.actual;
8086 p = arg->expr;
8087 if (arg->next)
8088 {
8089 q = arg->next->expr;
8090 if (arg->next->next)
8091 rdx = arg->next->next->expr;
8092 }
0e360db9
FXC
8093
8094 /* Currently, if IEEE is supported and this module is built, it means
8095 all our floating-point types conform to IEEE. Hence, we simply handle
8096 IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND. */
8097 return gfc_simplify_selected_real_kind (p, q, rdx);
8098}
8099
8100gfc_expr *
8101simplify_ieee_support (gfc_expr *expr)
8102{
8103 /* We consider that if the IEEE modules are loaded, we have full support
8104 for flags, halting and rounding, which are the three functions
8105 (IEEE_SUPPORT_{FLAG,HALTING,ROUNDING}) allowed in constant
8106 expressions. One day, we will need libgfortran to detect support and
8107 communicate it back to us, allowing for partial support. */
8108
8109 return gfc_get_logical_expr (gfc_default_logical_kind, &expr->where,
8110 true);
8111}
8112
8113bool
8114matches_ieee_function_name (gfc_symbol *sym, const char *name)
8115{
8116 int n = strlen(name);
8117
8118 if (!strncmp(sym->name, name, n))
8119 return true;
8120
8121 /* If a generic was used and renamed, we need more work to find out.
8122 Compare the specific name. */
8123 if (sym->generic && !strncmp(sym->generic->sym->name, name, n))
8124 return true;
8125
8126 return false;
8127}
8128
8129gfc_expr *
8130gfc_simplify_ieee_functions (gfc_expr *expr)
8131{
8132 gfc_symbol* sym = expr->symtree->n.sym;
8133
8134 if (matches_ieee_function_name(sym, "ieee_selected_real_kind"))
8135 return simplify_ieee_selected_real_kind (expr);
8136 else if (matches_ieee_function_name(sym, "ieee_support_flag")
8137 || matches_ieee_function_name(sym, "ieee_support_halting")
8138 || matches_ieee_function_name(sym, "ieee_support_rounding"))
8139 return simplify_ieee_support (expr);
8140 else
8141 return NULL;
8142}