PR target/16286
[official-gcc.git] / gcc / fortran / trans-const.c
blobc0572da043a76438579c95a088d4ab4fe1b9afcd
1 /* Translation of constants
2 Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
3 Contributed by Paul Brook
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 /* trans-const.c -- convert constant values */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tree.h"
28 #include <stdio.h>
29 #include "ggc.h"
30 #include "toplev.h"
31 #include "real.h"
32 #include <gmp.h>
33 #include <math.h>
34 #include "gfortran.h"
35 #include "trans.h"
36 #include "trans-const.h"
37 #include "trans-types.h"
39 /* String constants. */
40 tree gfc_strconst_bounds;
41 tree gfc_strconst_fault;
42 tree gfc_strconst_wrong_return;
43 tree gfc_strconst_current_filename;
45 tree gfc_rank_cst[GFC_MAX_DIMENSIONS + 1];
47 /* Build a constant with given type from an int_cst. */
49 tree
50 gfc_build_const (tree type, tree intval)
52 tree val;
53 tree zero;
55 switch (TREE_CODE (type))
57 case INTEGER_TYPE:
58 val = convert (type, intval);
59 break;
61 case REAL_TYPE:
62 val = build_real_from_int_cst (type, intval);
63 break;
65 case COMPLEX_TYPE:
66 val = build_real_from_int_cst (TREE_TYPE (type), intval);
67 zero = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
68 val = build_complex (type, val, zero);
69 break;
71 default:
72 gcc_unreachable ();
74 return val;
77 tree
78 gfc_build_string_const (int length, const char *s)
80 tree str;
81 tree len;
83 str = build_string (length, s);
84 len = build_int_cst (NULL_TREE, length);
85 TREE_TYPE (str) =
86 build_array_type (gfc_character1_type_node,
87 build_range_type (gfc_charlen_type_node,
88 integer_one_node, len));
89 return str;
92 /* Build a Fortran character constant from a zero-terminated string. */
94 tree
95 gfc_build_cstring_const (const char *s)
97 return gfc_build_string_const (strlen (s) + 1, s);
100 /* Return a string constant with the given length. Used for static
101 initializers. The constant will be padded or truncated to match
102 length. */
104 tree
105 gfc_conv_string_init (tree length, gfc_expr * expr)
107 char *s;
108 HOST_WIDE_INT len;
109 int slen;
110 tree str;
112 gcc_assert (expr->expr_type == EXPR_CONSTANT);
113 gcc_assert (expr->ts.type == BT_CHARACTER && expr->ts.kind == 1);
114 gcc_assert (INTEGER_CST_P (length));
115 gcc_assert (TREE_INT_CST_HIGH (length) == 0);
117 len = TREE_INT_CST_LOW (length);
118 slen = expr->value.character.length;
120 if (len > slen)
122 s = gfc_getmem (len);
123 memcpy (s, expr->value.character.string, slen);
124 memset (&s[slen], ' ', len - slen);
125 str = gfc_build_string_const (len, s);
126 gfc_free (s);
128 else
129 str = gfc_build_string_const (len, expr->value.character.string);
131 return str;
135 /* Create a tree node for the string length if it is constant. */
137 void
138 gfc_conv_const_charlen (gfc_charlen * cl)
140 if (cl->backend_decl)
141 return;
143 if (cl->length && cl->length->expr_type == EXPR_CONSTANT)
145 cl->backend_decl = gfc_conv_mpz_to_tree (cl->length->value.integer,
146 cl->length->ts.kind);
150 void
151 gfc_init_constants (void)
153 int n;
155 for (n = 0; n <= GFC_MAX_DIMENSIONS; n++)
156 gfc_rank_cst[n] = build_int_cst (gfc_array_index_type, n);
158 gfc_strconst_bounds = gfc_build_cstring_const ("Array bound mismatch");
160 gfc_strconst_fault =
161 gfc_build_cstring_const ("Array reference out of bounds");
163 gfc_strconst_wrong_return =
164 gfc_build_cstring_const ("Incorrect function return value");
166 gfc_strconst_current_filename =
167 gfc_build_cstring_const (gfc_option.source);
170 /* Converts a GMP integer into a backend tree node. */
171 tree
172 gfc_conv_mpz_to_tree (mpz_t i, int kind)
174 HOST_WIDE_INT high;
175 unsigned HOST_WIDE_INT low;
177 if (mpz_fits_slong_p (i))
179 /* Note that HOST_WIDE_INT is never smaller than long. */
180 low = mpz_get_si (i);
181 high = mpz_sgn (i) < 0 ? -1 : 0;
183 else
185 unsigned HOST_WIDE_INT words[2];
186 size_t count;
188 /* Since we know that the value is not zero (mpz_fits_slong_p),
189 we know that at one word will be written, but we don't know
190 about the second. It's quicker to zero the second word before
191 that conditionally clear it later. */
192 words[1] = 0;
194 /* Extract the absolute value into words. */
195 mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i);
197 /* We assume that all numbers are in range for its type, and that
198 we never create a type larger than 2*HWI, which is the largest
199 that the middle-end can handle. */
200 gcc_assert (count == 1 || count == 2);
202 low = words[0];
203 high = words[1];
205 /* Negate if necessary. */
206 if (mpz_sgn (i) < 0)
208 if (low == 0)
209 high = -high;
210 else
211 low = -low, high = ~high;
215 return build_int_cst_wide (gfc_get_int_type (kind), low, high);
218 /* Converts a real constant into backend form. Uses an intermediate string
219 representation. */
221 tree
222 gfc_conv_mpfr_to_tree (mpfr_t f, int kind)
224 tree res;
225 tree type;
226 mp_exp_t exp;
227 char *p;
228 char *q;
229 int n;
230 int edigits;
232 for (n = 0; gfc_real_kinds[n].kind != 0; n++)
234 if (gfc_real_kinds[n].kind == kind)
235 break;
237 gcc_assert (gfc_real_kinds[n].kind);
239 n = MAX (abs (gfc_real_kinds[n].min_exponent),
240 abs (gfc_real_kinds[n].max_exponent));
242 edigits = 1;
243 while (n > 0)
245 n = n / 10;
246 edigits += 3;
249 if (kind == gfc_default_double_kind)
250 p = mpfr_get_str (NULL, &exp, 10, 17, f, GFC_RND_MODE);
251 else
252 p = mpfr_get_str (NULL, &exp, 10, 8, f, GFC_RND_MODE);
255 /* We also have one minus sign, "e", "." and a null terminator. */
256 q = (char *) gfc_getmem (strlen (p) + edigits + 4);
258 if (p[0])
260 if (p[0] == '-')
262 strcpy (&q[2], &p[1]);
263 q[0] = '-';
264 q[1] = '.';
266 else
268 strcpy (&q[1], p);
269 q[0] = '.';
271 strcat (q, "e");
272 sprintf (&q[strlen (q)], "%d", (int) exp);
274 else
276 strcpy (q, "0");
279 type = gfc_get_real_type (kind);
280 res = build_real (type, REAL_VALUE_ATOF (q, TYPE_MODE (type)));
282 gfc_free (q);
283 gfc_free (p);
285 return res;
289 /* Translate any literal constant to a tree. Constants never have
290 pre or post chains. Character literal constants are special
291 special because they have a value and a length, so they cannot be
292 returned as a single tree. It is up to the caller to set the
293 length somewhere if necessary.
295 Returns the translated constant, or aborts if it gets a type it
296 can't handle. */
298 tree
299 gfc_conv_constant_to_tree (gfc_expr * expr)
301 gcc_assert (expr->expr_type == EXPR_CONSTANT);
303 switch (expr->ts.type)
305 case BT_INTEGER:
306 return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
308 case BT_REAL:
309 return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind);
311 case BT_LOGICAL:
312 return build_int_cst (NULL_TREE, expr->value.logical);
314 case BT_COMPLEX:
316 tree real = gfc_conv_mpfr_to_tree (expr->value.complex.r,
317 expr->ts.kind);
318 tree imag = gfc_conv_mpfr_to_tree (expr->value.complex.i,
319 expr->ts.kind);
321 return build_complex (NULL_TREE, real, imag);
324 case BT_CHARACTER:
325 return gfc_build_string_const (expr->value.character.length,
326 expr->value.character.string);
328 default:
329 fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
330 gfc_typename (&expr->ts));
335 /* Like gfc_conv_constant_to_tree, but for a simplified expression.
336 We can handle character literal constants here as well. */
338 void
339 gfc_conv_constant (gfc_se * se, gfc_expr * expr)
341 gcc_assert (expr->expr_type == EXPR_CONSTANT);
343 if (se->ss != NULL)
345 gcc_assert (se->ss != gfc_ss_terminator);
346 gcc_assert (se->ss->type == GFC_SS_SCALAR);
347 gcc_assert (se->ss->expr == expr);
349 se->expr = se->ss->data.scalar.expr;
350 se->string_length = se->ss->string_length;
351 gfc_advance_se_ss_chain (se);
352 return;
355 /* Translate the constant and put it in the simplifier structure. */
356 se->expr = gfc_conv_constant_to_tree (expr);
358 /* If this is a CHARACTER string, set its length in the simplifier
359 structure, too. */
360 if (expr->ts.type == BT_CHARACTER)
361 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));