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. */
50 gfc_build_const (tree type
, tree intval
)
55 switch (TREE_CODE (type
))
58 val
= convert (type
, intval
);
62 val
= build_real_from_int_cst (type
, intval
);
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
);
78 gfc_build_string_const (int length
, const char *s
)
83 str
= build_string (length
, s
);
84 len
= build_int_2 (length
, 0);
86 build_array_type (gfc_character1_type_node
,
87 build_range_type (gfc_strlen_type_node
,
88 integer_one_node
, len
));
92 /* Return a string constant with the given length. Used for static
93 initializers. The constant will be padded or truncated to match
97 gfc_conv_string_init (tree length
, gfc_expr
* expr
)
104 assert (expr
->expr_type
== EXPR_CONSTANT
);
105 assert (expr
->ts
.type
== BT_CHARACTER
&& expr
->ts
.kind
== 1);
106 assert (INTEGER_CST_P (length
));
107 assert (TREE_INT_CST_HIGH (length
) == 0);
109 len
= TREE_INT_CST_LOW (length
);
110 slen
= expr
->value
.character
.length
;
114 s
= gfc_getmem (len
);
115 memcpy (s
, expr
->value
.character
.string
, slen
);
116 memset (&s
[slen
], ' ', len
- slen
);
117 str
= gfc_build_string_const (len
, s
);
121 str
= gfc_build_string_const (len
, expr
->value
.character
.string
);
127 /* Create a tree node for the string length if it is constant. */
130 gfc_conv_const_charlen (gfc_charlen
* cl
)
132 if (cl
->backend_decl
)
135 if (cl
->length
&& cl
->length
->expr_type
== EXPR_CONSTANT
)
137 cl
->backend_decl
= gfc_conv_mpz_to_tree (cl
->length
->value
.integer
,
138 cl
->length
->ts
.kind
);
143 gfc_init_constants (void)
147 for (n
= 0; n
<= GFC_MAX_DIMENSIONS
; n
++)
149 gfc_rank_cst
[n
] = build_int_2 (n
, 0);
150 TREE_TYPE (gfc_rank_cst
[n
]) = gfc_array_index_type
;
153 gfc_strconst_bounds
= gfc_build_string_const (21, "Array bound mismatch");
156 gfc_build_string_const (30, "Array reference out of bounds");
158 gfc_strconst_wrong_return
=
159 gfc_build_string_const (32, "Incorrect function return value");
161 gfc_strconst_current_filename
=
162 gfc_build_string_const (strlen (gfc_option
.source
) + 1,
166 #define BITS_PER_HOST_WIDE_INT (8 * sizeof (HOST_WIDE_INT))
167 /* Converts a GMP integer into a backend tree node. */
169 gfc_conv_mpz_to_tree (mpz_t i
, int kind
)
174 unsigned HOST_WIDE_INT low
;
181 /* TODO: could be wrong if sizeof(HOST_WIDE_INT) |= SIZEOF (int). */
182 if (mpz_fits_slong_p (i
))
184 val
= mpz_get_si (i
);
185 res
= build_int_2 (val
, (val
< 0) ? (HOST_WIDE_INT
)-1 : 0);
186 TREE_TYPE (res
) = gfc_get_int_type (kind
);
190 n
= mpz_sizeinbase (i
, 16);
192 q
= gfc_getmem (n
+ 2);
198 p
= mpz_get_str (q
, 16, i
);
210 if (n
>= '0' && n
<= '9')
212 else if (n
>= 'a' && n
<= 'z')
214 else if (n
>= 'A' && n
<= 'Z')
219 assert (n
>= 0 && n
< 16);
220 high
= (high
<< 4) + (low
>> (BITS_PER_HOST_WIDE_INT
- 4));
221 low
= (low
<< 4) + n
;
223 res
= build_int_2 (low
, high
);
224 TREE_TYPE (res
) = gfc_get_int_type (kind
);
226 res
= fold (build1 (NEGATE_EXPR
, TREE_TYPE (res
), res
));
234 /* Converts a real constant into backend form. Uses an intermediate string
237 gfc_conv_mpf_to_tree (mpf_t f
, int kind
)
247 for (n
= 0; gfc_real_kinds
[n
].kind
!= 0; n
++)
249 if (gfc_real_kinds
[n
].kind
== kind
)
252 assert (gfc_real_kinds
[n
].kind
);
254 assert (gfc_real_kinds
[n
].radix
== 2);
256 n
= MAX (abs (gfc_real_kinds
[n
].min_exponent
),
257 abs (gfc_real_kinds
[n
].max_exponent
));
259 edigits
= 2 + (int) (log (n
) / log (gfc_real_kinds
[n
].radix
));
269 p
= mpf_get_str (NULL
, &exp
, 10, 0, f
);
271 /* We also have one minus sign, "e", "." and a null terminator. */
272 q
= (char *) gfc_getmem (strlen (p
) + edigits
+ 4);
278 strcpy (&q
[2], &p
[1]);
288 sprintf (&q
[strlen (q
)], "%d", (int) exp
);
295 type
= gfc_get_real_type (kind
);
296 res
= build_real (type
, REAL_VALUE_ATOF (q
, TYPE_MODE (type
)));
304 /* Translate any literal constant to a tree. Constants never have
305 pre or post chains. Character literal constants are special
306 special because they have a value and a length, so they cannot be
307 returned as a single tree. It is up to the caller to set the
308 length somewhere if necessary.
310 Returns the translated constant, or aborts if it gets a type it
314 gfc_conv_constant_to_tree (gfc_expr
* expr
)
316 assert (expr
->expr_type
== EXPR_CONSTANT
);
318 switch (expr
->ts
.type
)
321 return gfc_conv_mpz_to_tree (expr
->value
.integer
, expr
->ts
.kind
);
324 return gfc_conv_mpf_to_tree (expr
->value
.real
, expr
->ts
.kind
);
327 return build_int_2 (expr
->value
.logical
, 0);
331 tree real
= gfc_conv_mpf_to_tree (expr
->value
.complex.r
,
333 tree imag
= gfc_conv_mpf_to_tree (expr
->value
.complex.i
,
336 return build_complex (NULL_TREE
, real
, imag
);
340 return gfc_build_string_const (expr
->value
.character
.length
,
341 expr
->value
.character
.string
);
344 fatal_error ("gfc_conv_constant_to_tree(): invalid type: %s",
345 gfc_typename (&expr
->ts
));
350 /* Like gfc_conv_contrant_to_tree, but for a simplified expression.
351 We can handle character literal constants here as well. */
354 gfc_conv_constant (gfc_se
* se
, gfc_expr
* expr
)
356 assert (expr
->expr_type
== EXPR_CONSTANT
);
360 assert (se
->ss
!= gfc_ss_terminator
);
361 assert (se
->ss
->type
== GFC_SS_SCALAR
);
362 assert (se
->ss
->expr
== expr
);
364 se
->expr
= se
->ss
->data
.scalar
.expr
;
365 se
->string_length
= se
->ss
->data
.scalar
.string_length
;
366 gfc_advance_se_ss_chain (se
);
370 /* Translate the constant and put it in the simplifier structure. */
371 se
->expr
= gfc_conv_constant_to_tree (expr
);
373 /* If this is a CHARACTER string, set it's length in the simplifier
375 if (expr
->ts
.type
== BT_CHARACTER
)
376 se
->string_length
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (se
->expr
)));