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
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
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
22 /* trans-const.c -- convert constant values */
26 #include "coretypes.h"
37 #include "trans-const.h"
38 #include "trans-types.h"
40 /* String constants. */
41 tree gfc_strconst_bounds;
42 tree gfc_strconst_fault;
43 tree gfc_strconst_wrong_return;
44 tree gfc_strconst_current_filename;
46 tree gfc_rank_cst[GFC_MAX_DIMENSIONS + 1];
48 /* Build a constant with given type from an int_cst. */
51 gfc_build_const (tree type, tree intval)
56 switch (TREE_CODE (type))
59 val = convert (type, intval);
63 val = build_real_from_int_cst (type, intval);
67 val = build_real_from_int_cst (TREE_TYPE (type), intval);
68 zero = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);
69 val = build_complex (type, val, zero);
79 gfc_build_string_const (int length, const char *s)
84 str = build_string (length, s);
85 len = build_int_cst (NULL_TREE, length);
87 build_array_type (gfc_character1_type_node,
88 build_range_type (gfc_charlen_type_node,
89 integer_one_node, len));
93 /* Return a string constant with the given length. Used for static
94 initializers. The constant will be padded or truncated to match
98 gfc_conv_string_init (tree length, gfc_expr * expr)
105 assert (expr->expr_type == EXPR_CONSTANT);
106 assert (expr->ts.type == BT_CHARACTER && expr->ts.kind == 1);
107 assert (INTEGER_CST_P (length));
108 assert (TREE_INT_CST_HIGH (length) == 0);
110 len = TREE_INT_CST_LOW (length);
111 slen = expr->value.character.length;
115 s = gfc_getmem (len);
116 memcpy (s, expr->value.character.string, slen);
117 memset (&s[slen], ' ', len - slen);
118 str = gfc_build_string_const (len, s);
122 str = gfc_build_string_const (len, expr->value.character.string);
128 /* Create a tree node for the string length if it is constant. */
131 gfc_conv_const_charlen (gfc_charlen * cl)
133 if (cl->backend_decl)
136 if (cl->length && cl->length->expr_type == EXPR_CONSTANT)
138 cl->backend_decl = gfc_conv_mpz_to_tree (cl->length->value.integer,
139 cl->length->ts.kind);
144 gfc_init_constants (void)
148 for (n = 0; n <= GFC_MAX_DIMENSIONS; n++)
149 gfc_rank_cst[n] = build_int_cst (gfc_array_index_type, n);
151 gfc_strconst_bounds = gfc_build_string_const (21, "Array bound mismatch");
154 gfc_build_string_const (30, "Array reference out of bounds");
156 gfc_strconst_wrong_return =
157 gfc_build_string_const (32, "Incorrect function return value");
159 gfc_strconst_current_filename =
160 gfc_build_string_const (strlen (gfc_option.source) + 1,
164 /* Converts a GMP integer into a backend tree node. */
166 gfc_conv_mpz_to_tree (mpz_t i, int kind)
169 unsigned HOST_WIDE_INT low;
171 if (mpz_fits_slong_p (i))
173 /* Note that HOST_WIDE_INT is never smaller than long. */
174 low = mpz_get_si (i);
175 high = mpz_sgn (i) < 0 ? -1 : 0;
179 unsigned HOST_WIDE_INT words[2];
182 /* Since we know that the value is not zero (mpz_fits_slong_p),
183 we know that at one word will be written, but we don't know
184 about the second. It's quicker to zero the second word before
185 that conditionally clear it later. */
188 /* Extract the absolute value into words. */
189 mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i);
191 /* We assume that all numbers are in range for its type, and that
192 we never create a type larger than 2*HWI, which is the largest
193 that the middle-end can handle. */
194 assert (count == 1 || count == 2);
199 /* Negate if necessary. */
205 low = -low, high = ~high;
209 return build_int_cst_wide (gfc_get_int_type (kind), low, high);
212 /* Converts a real constant into backend form. Uses an intermediate string
216 gfc_conv_mpfr_to_tree (mpfr_t f, int kind)
226 for (n = 0; gfc_real_kinds[n].kind != 0; n++)
228 if (gfc_real_kinds[n].kind == kind)
231 assert (gfc_real_kinds[n].kind);
233 n = MAX (abs (gfc_real_kinds[n].min_exponent),
234 abs (gfc_real_kinds[n].max_exponent));
243 if (kind == gfc_default_double_kind)
244 p = mpfr_get_str (NULL, &exp, 10, 17, f, GFC_RND_MODE);
246 p = mpfr_get_str (NULL, &exp, 10, 8, f, GFC_RND_MODE);
249 /* We also have one minus sign, "e", "." and a null terminator. */
250 q = (char *) gfc_getmem (strlen (p) + edigits + 4);
256 strcpy (&q[2], &p[1]);
266 sprintf (&q[strlen (q)], "%d", (int) exp);
273 type = gfc_get_real_type (kind);
274 res = build_real (type, REAL_VALUE_ATOF (q, TYPE_MODE (type)));
283 /* Translate any literal constant to a tree. Constants never have
284 pre or post chains. Character literal constants are special
285 special because they have a value and a length, so they cannot be
286 returned as a single tree. It is up to the caller to set the
287 length somewhere if necessary.
289 Returns the translated constant, or aborts if it gets a type it
293 gfc_conv_constant_to_tree (gfc_expr * expr)
295 assert (expr->expr_type == EXPR_CONSTANT);
297 switch (expr->ts.type)
300 return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
303 return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind);
306 return build_int_cst (NULL_TREE, expr->value.logical);
310 tree real = gfc_conv_mpfr_to_tree (expr->value.complex.r,
312 tree imag = gfc_conv_mpfr_to_tree (expr->value.complex.i,
315 return build_complex (NULL_TREE, real, imag);
319 return gfc_build_string_const (expr->value.character.length,
320 expr->value.character.string);
323 fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
324 gfc_typename (&expr->ts));
329 /* Like gfc_conv_constant_to_tree, but for a simplified expression.
330 We can handle character literal constants here as well. */
333 gfc_conv_constant (gfc_se * se, gfc_expr * expr)
335 assert (expr->expr_type == EXPR_CONSTANT);
339 assert (se->ss != gfc_ss_terminator);
340 assert (se->ss->type == GFC_SS_SCALAR);
341 assert (se->ss->expr == expr);
343 se->expr = se->ss->data.scalar.expr;
344 se->string_length = se->ss->string_length;
345 gfc_advance_se_ss_chain (se);
349 /* Translate the constant and put it in the simplifier structure. */
350 se->expr = gfc_conv_constant_to_tree (expr);
352 /* If this is a CHARACTER string, set its length in the simplifier
354 if (expr->ts.type == BT_CHARACTER)
355 se->string_length = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se->expr)));