Branch data Line data Source code
1 : : /* Simulate storage of variables into target memory.
2 : : Copyright (C) 2007-2024 Free Software Foundation, Inc.
3 : : Contributed by Paul Thomas and Brooks Moses
4 : :
5 : : This file is part of GCC.
6 : :
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 3, or (at your option) any later
10 : : version.
11 : :
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.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #include "config.h"
22 : : #include "system.h"
23 : : #include "coretypes.h"
24 : : #include "tree.h"
25 : : #include "gfortran.h"
26 : : #include "trans.h"
27 : : #include "fold-const.h"
28 : : #include "stor-layout.h"
29 : : #include "arith.h"
30 : : #include "constructor.h"
31 : : #include "trans-const.h"
32 : : #include "trans-types.h"
33 : : #include "target-memory.h"
34 : :
35 : : /* --------------------------------------------------------------- */
36 : : /* Calculate the size of an expression. */
37 : :
38 : :
39 : : static size_t
40 : 4272 : size_integer (int kind)
41 : : {
42 : 4272 : return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_int_type (kind)));
43 : : }
44 : :
45 : : static size_t
46 : 0 : size_unsigned (int kind)
47 : : {
48 : 0 : return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_unsigned_type (kind)));
49 : : }
50 : :
51 : : static size_t
52 : 4017 : size_float (int kind)
53 : : {
54 : 4017 : return GET_MODE_SIZE (SCALAR_FLOAT_TYPE_MODE (gfc_get_real_type (kind)));
55 : : }
56 : :
57 : :
58 : : static size_t
59 : 723 : size_complex (int kind)
60 : : {
61 : 0 : return 2 * size_float (kind);
62 : : }
63 : :
64 : :
65 : : static size_t
66 : 976 : size_logical (int kind)
67 : : {
68 : 976 : return GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (gfc_get_logical_type (kind)));
69 : : }
70 : :
71 : :
72 : : static size_t
73 : 286245 : size_character (gfc_charlen_t length, int kind)
74 : : {
75 : 286245 : int i = gfc_validate_kind (BT_CHARACTER, kind, false);
76 : 286245 : return length * gfc_character_kinds[i].bit_size / 8;
77 : : }
78 : :
79 : :
80 : : /* Return the size of a single element of the given expression.
81 : : Equivalent to gfc_target_expr_size for scalars. */
82 : :
83 : : bool
84 : 6458 : gfc_element_size (gfc_expr *e, size_t *siz)
85 : : {
86 : 6458 : tree type;
87 : :
88 : 6458 : switch (e->ts.type)
89 : : {
90 : 2464 : case BT_INTEGER:
91 : 2464 : *siz = size_integer (e->ts.kind);
92 : 2464 : return true;
93 : 0 : case BT_UNSIGNED:
94 : 0 : *siz = size_unsigned (e->ts.kind);
95 : 0 : return true;
96 : 1084 : case BT_REAL:
97 : 1084 : *siz = size_float (e->ts.kind);
98 : 1084 : return true;
99 : 723 : case BT_COMPLEX:
100 : 723 : *siz = size_complex (e->ts.kind);
101 : 723 : return true;
102 : 535 : case BT_LOGICAL:
103 : 535 : *siz = size_logical (e->ts.kind);
104 : 535 : return true;
105 : 1353 : case BT_CHARACTER:
106 : 1353 : if (e->expr_type == EXPR_CONSTANT)
107 : 786 : *siz = size_character (e->value.character.length, e->ts.kind);
108 : 567 : else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
109 : 535 : && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
110 : 535 : && e->ts.u.cl->length->ts.type == BT_INTEGER)
111 : : {
112 : 535 : HOST_WIDE_INT length;
113 : :
114 : 535 : gfc_extract_hwi (e->ts.u.cl->length, &length);
115 : 535 : *siz = size_character (length, e->ts.kind);
116 : 535 : }
117 : : else
118 : : {
119 : 32 : *siz = 0;
120 : 32 : return false;
121 : : }
122 : : return true;
123 : :
124 : 7 : case BT_HOLLERITH:
125 : 7 : *siz = e->representation.length;
126 : 7 : return true;
127 : 292 : case BT_DERIVED:
128 : 292 : case BT_CLASS:
129 : 292 : case BT_VOID:
130 : 292 : case BT_ASSUMED:
131 : 292 : case BT_PROCEDURE:
132 : 292 : {
133 : : /* Determine type size without clobbering the typespec for ISO C
134 : : binding types. */
135 : 292 : gfc_typespec ts;
136 : 292 : HOST_WIDE_INT size;
137 : 292 : ts = e->ts;
138 : 292 : type = gfc_typenode_for_spec (&ts);
139 : 292 : size = int_size_in_bytes (type);
140 : 292 : gcc_assert (size >= 0);
141 : 292 : *siz = size;
142 : : }
143 : 292 : return true;
144 : 0 : default:
145 : 0 : gfc_internal_error ("Invalid expression in gfc_element_size.");
146 : : *siz = 0;
147 : : return false;
148 : : }
149 : : }
150 : :
151 : :
152 : : /* Return the size of an expression in its target representation. */
153 : :
154 : : bool
155 : 4240 : gfc_target_expr_size (gfc_expr *e, size_t *size)
156 : : {
157 : 4240 : mpz_t tmp;
158 : 4240 : size_t asz, el_size;
159 : :
160 : 4240 : gcc_assert (e != NULL);
161 : :
162 : 4240 : *size = 0;
163 : 4240 : if (e->rank)
164 : : {
165 : 459 : if (gfc_array_size (e, &tmp))
166 : 459 : asz = mpz_get_ui (tmp);
167 : : else
168 : : return false;
169 : :
170 : 459 : mpz_clear (tmp);
171 : : }
172 : : else
173 : : asz = 1;
174 : :
175 : 4240 : if (!gfc_element_size (e, &el_size))
176 : : return false;
177 : 4239 : *size = asz * el_size;
178 : 4239 : return true;
179 : : }
180 : :
181 : :
182 : : /* The encode_* functions export a value into a buffer, and
183 : : return the number of bytes of the buffer that have been
184 : : used. */
185 : :
186 : : static unsigned HOST_WIDE_INT
187 : 282 : encode_array (gfc_expr *expr, unsigned char *buffer, size_t buffer_size)
188 : : {
189 : 282 : mpz_t array_size;
190 : 282 : int i;
191 : 282 : int ptr = 0;
192 : :
193 : 282 : gfc_constructor_base ctor = expr->value.constructor;
194 : :
195 : 282 : gfc_array_size (expr, &array_size);
196 : 1209 : for (i = 0; i < (int)mpz_get_ui (array_size); i++)
197 : : {
198 : 633 : ptr += gfc_target_encode_expr (gfc_constructor_lookup_expr (ctor, i),
199 : 633 : &buffer[ptr], buffer_size - ptr);
200 : : }
201 : :
202 : 282 : mpz_clear (array_size);
203 : 282 : return ptr;
204 : : }
205 : :
206 : :
207 : : static int
208 : 714 : encode_integer (int kind, mpz_t integer, unsigned char *buffer,
209 : : size_t buffer_size)
210 : : {
211 : 714 : return native_encode_expr (gfc_conv_mpz_to_tree (integer, kind),
212 : 714 : buffer, buffer_size);
213 : : }
214 : :
215 : :
216 : : static int
217 : 157 : encode_float (int kind, mpfr_t real, unsigned char *buffer, size_t buffer_size)
218 : : {
219 : 157 : return native_encode_expr (gfc_conv_mpfr_to_tree (real, kind, 0), buffer,
220 : 157 : buffer_size);
221 : : }
222 : :
223 : :
224 : : static int
225 : 18 : encode_complex (int kind, mpc_t cmplx,
226 : : unsigned char *buffer, size_t buffer_size)
227 : : {
228 : 18 : int size;
229 : 18 : size = encode_float (kind, mpc_realref (cmplx), &buffer[0], buffer_size);
230 : 36 : size += encode_float (kind, mpc_imagref (cmplx),
231 : 18 : &buffer[size], buffer_size - size);
232 : 18 : return size;
233 : : }
234 : :
235 : :
236 : : static int
237 : 63 : encode_logical (int kind, int logical, unsigned char *buffer, size_t buffer_size)
238 : : {
239 : 63 : return native_encode_expr (build_int_cst (gfc_get_logical_type (kind),
240 : : logical),
241 : 63 : buffer, buffer_size);
242 : : }
243 : :
244 : :
245 : : size_t
246 : 141457 : gfc_encode_character (int kind, size_t length, const gfc_char_t *string,
247 : : unsigned char *buffer, size_t buffer_size)
248 : : {
249 : 141457 : size_t elsize = size_character (1, kind);
250 : 141457 : tree type = gfc_get_char_type (kind);
251 : :
252 : 141457 : gcc_assert (buffer_size >= size_character (length, kind));
253 : :
254 : 2061551 : for (size_t i = 0; i < length; i++)
255 : 1920094 : native_encode_expr (build_int_cst (type, string[i]), &buffer[i*elsize],
256 : : elsize);
257 : :
258 : 141457 : return length;
259 : : }
260 : :
261 : :
262 : : static unsigned HOST_WIDE_INT
263 : 14 : encode_derived (gfc_expr *source, unsigned char *buffer, size_t buffer_size)
264 : : {
265 : 14 : gfc_constructor *c;
266 : 14 : gfc_component *cmp;
267 : 14 : int ptr;
268 : 14 : tree type;
269 : 14 : HOST_WIDE_INT size;
270 : :
271 : 14 : type = gfc_typenode_for_spec (&source->ts);
272 : :
273 : 14 : for (c = gfc_constructor_first (source->value.constructor),
274 : 14 : cmp = source->ts.u.derived->components;
275 : 34 : c;
276 : 20 : c = gfc_constructor_next (c), cmp = cmp->next)
277 : : {
278 : 20 : gcc_assert (cmp);
279 : 20 : if (!c->expr)
280 : 0 : continue;
281 : 20 : ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
282 : 20 : + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
283 : :
284 : 20 : if (c->expr->expr_type == EXPR_NULL)
285 : : {
286 : 1 : size = int_size_in_bytes (TREE_TYPE (cmp->backend_decl));
287 : 1 : gcc_assert (size >= 0);
288 : 1 : memset (&buffer[ptr], 0, size);
289 : : }
290 : : else
291 : 19 : gfc_target_encode_expr (c->expr, &buffer[ptr],
292 : 19 : buffer_size - ptr);
293 : : }
294 : :
295 : 14 : size = int_size_in_bytes (type);
296 : 14 : gcc_assert (size >= 0);
297 : 14 : return size;
298 : : }
299 : :
300 : :
301 : : /* Write a constant expression in binary form to a buffer. */
302 : : unsigned HOST_WIDE_INT
303 : 1856 : gfc_target_encode_expr (gfc_expr *source, unsigned char *buffer,
304 : : size_t buffer_size)
305 : : {
306 : 1856 : if (source == NULL)
307 : : return 0;
308 : :
309 : 1856 : if (source->expr_type == EXPR_ARRAY)
310 : 282 : return encode_array (source, buffer, buffer_size);
311 : :
312 : 1574 : gcc_assert (source->expr_type == EXPR_CONSTANT
313 : : || source->expr_type == EXPR_STRUCTURE
314 : : || source->expr_type == EXPR_SUBSTRING);
315 : :
316 : : /* If we already have a target-memory representation, we use that rather
317 : : than recreating one. */
318 : 1574 : if (source->representation.string)
319 : : {
320 : 144 : memcpy (buffer, source->representation.string,
321 : 144 : source->representation.length);
322 : 144 : return source->representation.length;
323 : : }
324 : :
325 : 1430 : switch (source->ts.type)
326 : : {
327 : 457 : case BT_INTEGER:
328 : 457 : return encode_integer (source->ts.kind, source->value.integer, buffer,
329 : 457 : buffer_size);
330 : 121 : case BT_REAL:
331 : 121 : return encode_float (source->ts.kind, source->value.real, buffer,
332 : 121 : buffer_size);
333 : 18 : case BT_COMPLEX:
334 : 18 : return encode_complex (source->ts.kind, source->value.complex,
335 : 18 : buffer, buffer_size);
336 : 63 : case BT_LOGICAL:
337 : 63 : return encode_logical (source->ts.kind, source->value.logical, buffer,
338 : 63 : buffer_size);
339 : 754 : case BT_CHARACTER:
340 : 754 : if (source->expr_type == EXPR_CONSTANT || source->ref == NULL)
341 : 724 : return gfc_encode_character (source->ts.kind,
342 : 724 : source->value.character.length,
343 : 724 : source->value.character.string,
344 : 724 : buffer, buffer_size);
345 : : else
346 : : {
347 : 30 : HOST_WIDE_INT start, end;
348 : :
349 : 30 : gcc_assert (source->expr_type == EXPR_SUBSTRING);
350 : 30 : gfc_extract_hwi (source->ref->u.ss.start, &start);
351 : 30 : gfc_extract_hwi (source->ref->u.ss.end, &end);
352 : 30 : return gfc_encode_character (source->ts.kind, MAX(end - start + 1, 0),
353 : 30 : &source->value.character.string[start-1],
354 : : buffer, buffer_size);
355 : : }
356 : :
357 : 17 : case BT_DERIVED:
358 : 17 : if (source->ts.u.derived->ts.f90_type == BT_VOID)
359 : : {
360 : 3 : gfc_constructor *c;
361 : 3 : gcc_assert (source->expr_type == EXPR_STRUCTURE);
362 : 3 : c = gfc_constructor_first (source->value.constructor);
363 : 3 : gcc_assert (c->expr->expr_type == EXPR_CONSTANT
364 : : && c->expr->ts.type == BT_INTEGER);
365 : 3 : return encode_integer (gfc_index_integer_kind, c->expr->value.integer,
366 : 3 : buffer, buffer_size);
367 : : }
368 : :
369 : 14 : return encode_derived (source, buffer, buffer_size);
370 : 0 : default:
371 : 0 : gfc_internal_error ("Invalid expression in gfc_target_encode_expr.");
372 : : return 0;
373 : : }
374 : : }
375 : :
376 : :
377 : : static size_t
378 : 335 : interpret_array (unsigned char *buffer, size_t buffer_size, gfc_expr *result,
379 : : bool convert_widechar)
380 : : {
381 : 335 : gfc_constructor_base base = NULL;
382 : 335 : size_t array_size = 1;
383 : 335 : size_t ptr = 0;
384 : :
385 : : /* Calculate array size from its shape and rank. */
386 : 335 : gcc_assert (result->rank > 0 && result->shape);
387 : :
388 : 670 : for (int i = 0; i < result->rank; i++)
389 : 370 : array_size *= mpz_get_ui (result->shape[i]);
390 : :
391 : : /* Iterate over array elements, producing constructors. */
392 : 1416 : for (size_t i = 0; i < array_size; i++)
393 : : {
394 : 1081 : gfc_expr *e = gfc_get_constant_expr (result->ts.type, result->ts.kind,
395 : : &result->where);
396 : 1081 : e->ts = result->ts;
397 : :
398 : 1081 : if (e->ts.type == BT_CHARACTER)
399 : 529 : e->value.character.length = result->value.character.length;
400 : :
401 : 1081 : gfc_constructor_append_expr (&base, e, &result->where);
402 : :
403 : 1081 : ptr += gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e,
404 : : convert_widechar);
405 : : }
406 : :
407 : 335 : result->value.constructor = base;
408 : 335 : return ptr;
409 : : }
410 : :
411 : :
412 : : int
413 : 1300 : gfc_interpret_integer (int kind, unsigned char *buffer, size_t buffer_size,
414 : : mpz_t integer)
415 : : {
416 : 1300 : mpz_init (integer);
417 : 1300 : gfc_conv_tree_to_mpz (integer,
418 : : native_interpret_expr (gfc_get_int_type (kind),
419 : : buffer, buffer_size));
420 : 1300 : return size_integer (kind);
421 : : }
422 : :
423 : :
424 : : int
425 : 1956 : gfc_interpret_float (int kind, unsigned char *buffer, size_t buffer_size,
426 : : mpfr_t real)
427 : : {
428 : 1956 : gfc_set_model_kind (kind);
429 : :
430 : 1956 : tree source = native_interpret_expr (gfc_get_real_type (kind), buffer,
431 : : buffer_size);
432 : 1956 : if (!source)
433 : : return 0;
434 : :
435 : 1956 : mpfr_init (real);
436 : 1956 : gfc_conv_tree_to_mpfr (real, source);
437 : 1956 : return size_float (kind);
438 : : }
439 : :
440 : :
441 : : int
442 : 512 : gfc_interpret_complex (int kind, unsigned char *buffer, size_t buffer_size,
443 : : mpc_t complex)
444 : : {
445 : 512 : int size;
446 : 1024 : size = gfc_interpret_float (kind, &buffer[0], buffer_size,
447 : 512 : mpc_realref (complex));
448 : 1024 : size += gfc_interpret_float (kind, &buffer[size], buffer_size - size,
449 : 512 : mpc_imagref (complex));
450 : 512 : return size;
451 : : }
452 : :
453 : :
454 : : int
455 : 441 : gfc_interpret_logical (int kind, unsigned char *buffer, size_t buffer_size,
456 : : int *logical)
457 : : {
458 : 441 : tree t = native_interpret_expr (gfc_get_logical_type (kind), buffer,
459 : : buffer_size);
460 : 441 : *logical = wi::to_wide (t) == 0 ? 0 : 1;
461 : 441 : return size_logical (kind);
462 : : }
463 : :
464 : :
465 : : size_t
466 : 783 : gfc_interpret_character (unsigned char *buffer, size_t buffer_size,
467 : : gfc_expr *result)
468 : : {
469 : 783 : if (result->ts.u.cl && result->ts.u.cl->length)
470 : 783 : result->value.character.length =
471 : 783 : gfc_mpz_get_hwi (result->ts.u.cl->length->value.integer);
472 : :
473 : 783 : gcc_assert (buffer_size >= size_character (result->value.character.length,
474 : : result->ts.kind));
475 : 1566 : result->value.character.string =
476 : 783 : gfc_get_wide_string (result->value.character.length + 1);
477 : :
478 : 783 : if (result->ts.kind == gfc_default_character_kind)
479 : 1169 : for (size_t i = 0; i < (size_t) result->value.character.length; i++)
480 : 830 : result->value.character.string[i] = (gfc_char_t) buffer[i];
481 : : else
482 : : {
483 : 444 : mpz_t integer;
484 : 444 : size_t bytes = size_character (1, result->ts.kind);
485 : 444 : mpz_init (integer);
486 : 444 : gcc_assert (bytes <= sizeof (unsigned long));
487 : :
488 : 1346 : for (size_t i = 0; i < (size_t) result->value.character.length; i++)
489 : : {
490 : 902 : gfc_conv_tree_to_mpz (integer,
491 : : native_interpret_expr (gfc_get_char_type (result->ts.kind),
492 : 902 : &buffer[bytes*i], buffer_size-bytes*i));
493 : 902 : result->value.character.string[i]
494 : 902 : = (gfc_char_t) mpz_get_ui (integer);
495 : : }
496 : :
497 : 444 : mpz_clear (integer);
498 : : }
499 : :
500 : 783 : result->value.character.string[result->value.character.length] = '\0';
501 : :
502 : 783 : return size_character (result->value.character.length, result->ts.kind);
503 : : }
504 : :
505 : :
506 : : int
507 : 41 : gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *result)
508 : : {
509 : 41 : gfc_component *cmp;
510 : 41 : int ptr;
511 : 41 : tree type;
512 : :
513 : : /* The attributes of the derived type need to be bolted to the floor. */
514 : 41 : result->expr_type = EXPR_STRUCTURE;
515 : :
516 : 41 : cmp = result->ts.u.derived->components;
517 : :
518 : 41 : if (result->ts.u.derived->from_intmod == INTMOD_ISO_C_BINDING
519 : 15 : && (result->ts.u.derived->intmod_sym_id == ISOCBINDING_PTR
520 : 1 : || result->ts.u.derived->intmod_sym_id == ISOCBINDING_FUNPTR))
521 : : {
522 : 15 : gfc_constructor *c;
523 : 15 : gfc_expr *e;
524 : : /* Needed as gfc_typenode_for_spec as gfc_typenode_for_spec
525 : : sets this to BT_INTEGER. */
526 : 15 : result->ts.type = BT_DERIVED;
527 : 15 : e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind, &result->where);
528 : 15 : c = gfc_constructor_append_expr (&result->value.constructor, e, NULL);
529 : 15 : c->n.component = cmp;
530 : 15 : gfc_target_interpret_expr (buffer, buffer_size, e, true);
531 : 15 : e->ts.is_iso_c = 1;
532 : 15 : return int_size_in_bytes (ptr_type_node);
533 : : }
534 : :
535 : 26 : type = gfc_typenode_for_spec (&result->ts);
536 : :
537 : : /* Run through the derived type components. */
538 : 73 : for (;cmp; cmp = cmp->next)
539 : : {
540 : 53 : gfc_constructor *c;
541 : 53 : gfc_expr *e = gfc_get_constant_expr (cmp->ts.type, cmp->ts.kind,
542 : : &result->where);
543 : 53 : e->ts = cmp->ts;
544 : :
545 : : /* Copy shape, if needed. */
546 : 53 : if (cmp->as && cmp->as->rank)
547 : : {
548 : 18 : int n;
549 : :
550 : 18 : if (cmp->as->type != AS_EXPLICIT)
551 : : return 0;
552 : :
553 : 12 : e->expr_type = EXPR_ARRAY;
554 : 12 : e->rank = cmp->as->rank;
555 : :
556 : 12 : e->shape = gfc_get_shape (e->rank);
557 : 24 : for (n = 0; n < e->rank; n++)
558 : : {
559 : 12 : mpz_init_set_ui (e->shape[n], 1);
560 : 12 : mpz_add (e->shape[n], e->shape[n],
561 : 12 : cmp->as->upper[n]->value.integer);
562 : 12 : mpz_sub (e->shape[n], e->shape[n],
563 : 12 : cmp->as->lower[n]->value.integer);
564 : : }
565 : : }
566 : :
567 : 47 : c = gfc_constructor_append_expr (&result->value.constructor, e, NULL);
568 : :
569 : : /* The constructor points to the component. */
570 : 47 : c->n.component = cmp;
571 : :
572 : : /* Calculate the offset, which consists of the FIELD_OFFSET in
573 : : bytes, which appears in multiples of DECL_OFFSET_ALIGN-bit-sized,
574 : : and additional bits of FIELD_BIT_OFFSET. The code assumes that all
575 : : sizes of the components are multiples of BITS_PER_UNIT,
576 : : i.e. there are, e.g., no bit fields. */
577 : :
578 : 47 : gcc_assert (cmp->backend_decl);
579 : 47 : ptr = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (cmp->backend_decl));
580 : 47 : gcc_assert (ptr % 8 == 0);
581 : 47 : ptr = ptr/8 + TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl));
582 : :
583 : 47 : gcc_assert (e->ts.type != BT_VOID || cmp->attr.caf_token);
584 : 47 : gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr, e, true);
585 : : }
586 : :
587 : 20 : return int_size_in_bytes (type);
588 : : }
589 : :
590 : :
591 : : /* Read a binary buffer to a constant expression. */
592 : : size_t
593 : 2156 : gfc_target_interpret_expr (unsigned char *buffer, size_t buffer_size,
594 : : gfc_expr *result, bool convert_widechar)
595 : : {
596 : 2156 : if (result->expr_type == EXPR_ARRAY)
597 : 335 : return interpret_array (buffer, buffer_size, result, convert_widechar);
598 : :
599 : 1821 : switch (result->ts.type)
600 : : {
601 : 735 : case BT_INTEGER:
602 : 1470 : result->representation.length =
603 : 1470 : gfc_interpret_integer (result->ts.kind, buffer, buffer_size,
604 : 735 : result->value.integer);
605 : 735 : break;
606 : :
607 : 164 : case BT_REAL:
608 : 328 : result->representation.length =
609 : 328 : gfc_interpret_float (result->ts.kind, buffer, buffer_size,
610 : 164 : result->value.real);
611 : 164 : break;
612 : :
613 : 37 : case BT_COMPLEX:
614 : 74 : result->representation.length =
615 : 74 : gfc_interpret_complex (result->ts.kind, buffer, buffer_size,
616 : 37 : result->value.complex);
617 : 37 : break;
618 : :
619 : 60 : case BT_LOGICAL:
620 : 120 : result->representation.length =
621 : 60 : gfc_interpret_logical (result->ts.kind, buffer, buffer_size,
622 : : &result->value.logical);
623 : 60 : break;
624 : :
625 : 783 : case BT_CHARACTER:
626 : 1566 : result->representation.length =
627 : 783 : gfc_interpret_character (buffer, buffer_size, result);
628 : 783 : break;
629 : :
630 : 0 : case BT_CLASS:
631 : 0 : result->ts = CLASS_DATA (result)->ts;
632 : : /* Fall through. */
633 : 41 : case BT_DERIVED:
634 : 82 : result->representation.length =
635 : 41 : gfc_interpret_derived (buffer, buffer_size, result);
636 : 41 : gcc_assert (result->representation.length >= 0);
637 : : break;
638 : :
639 : 1 : case BT_VOID:
640 : : /* This deals with caf_tokens. */
641 : 2 : result->representation.length =
642 : 2 : gfc_interpret_integer (result->ts.kind, buffer, buffer_size,
643 : 1 : result->value.integer);
644 : 1 : break;
645 : :
646 : 0 : default:
647 : 0 : gfc_internal_error ("Invalid expression in gfc_target_interpret_expr.");
648 : 1821 : break;
649 : : }
650 : :
651 : 1821 : if (result->ts.type == BT_CHARACTER && convert_widechar)
652 : 0 : result->representation.string
653 : 0 : = gfc_widechar_to_char (result->value.character.string,
654 : 0 : result->value.character.length);
655 : : else
656 : : {
657 : 3642 : result->representation.string =
658 : 1821 : XCNEWVEC (char, result->representation.length + 1);
659 : 1821 : memcpy (result->representation.string, buffer,
660 : 1821 : result->representation.length);
661 : 1821 : result->representation.string[result->representation.length] = '\0';
662 : : }
663 : :
664 : 1821 : return result->representation.length;
665 : : }
666 : :
667 : :
668 : : /* --------------------------------------------------------------- */
669 : : /* Two functions used by trans-common.cc to write overlapping
670 : : equivalence initializers to a buffer. This is added to the union
671 : : and the original initializers freed. */
672 : :
673 : :
674 : : /* Writes the values of a constant expression to a char buffer. If another
675 : : unequal initializer has already been written to the buffer, this is an
676 : : error. */
677 : :
678 : : static size_t
679 : 206 : expr_to_char (gfc_expr *e, locus *loc,
680 : : unsigned char *data, unsigned char *chk, size_t len)
681 : : {
682 : 206 : int i;
683 : 206 : int ptr;
684 : 206 : gfc_constructor *c;
685 : 206 : gfc_component *cmp;
686 : 206 : unsigned char *buffer;
687 : :
688 : 206 : if (e == NULL)
689 : : return 0;
690 : :
691 : : /* Take a derived type, one component at a time, using the offsets from the backend
692 : : declaration. */
693 : 206 : if (e->ts.type == BT_DERIVED)
694 : : {
695 : 15 : for (c = gfc_constructor_first (e->value.constructor),
696 : 15 : cmp = e->ts.u.derived->components;
697 : 54 : c; c = gfc_constructor_next (c), cmp = cmp->next)
698 : : {
699 : 39 : gcc_assert (cmp && cmp->backend_decl);
700 : 39 : if (!c->expr)
701 : 12 : continue;
702 : 27 : ptr = TREE_INT_CST_LOW(DECL_FIELD_OFFSET(cmp->backend_decl))
703 : 27 : + TREE_INT_CST_LOW(DECL_FIELD_BIT_OFFSET(cmp->backend_decl))/8;
704 : 27 : expr_to_char (c->expr, loc, &data[ptr], &chk[ptr], len);
705 : : }
706 : 15 : return len;
707 : : }
708 : :
709 : : /* Otherwise, use the target-memory machinery to write a bitwise image, appropriate
710 : : to the target, in a buffer and check off the initialized part of the buffer. */
711 : 191 : gfc_target_expr_size (e, &len);
712 : 191 : buffer = (unsigned char*)alloca (len);
713 : 191 : len = gfc_target_encode_expr (e, buffer, len);
714 : :
715 : 1009 : for (i = 0; i < (int)len; i++)
716 : : {
717 : 821 : if (chk[i] && (buffer[i] != data[i]))
718 : : {
719 : 3 : if (loc)
720 : 3 : gfc_error ("Overlapping unequal initializers in EQUIVALENCE "
721 : : "at %L", loc);
722 : : else
723 : 0 : gfc_error ("Overlapping unequal initializers in EQUIVALENCE "
724 : : "at %C");
725 : 3 : return 0;
726 : : }
727 : 818 : chk[i] = 0xFF;
728 : : }
729 : :
730 : 188 : memcpy (data, buffer, len);
731 : 188 : return len;
732 : : }
733 : :
734 : :
735 : : /* Writes the values from the equivalence initializers to a char* array
736 : : that will be written to the constructor to make the initializer for
737 : : the union declaration. */
738 : :
739 : : size_t
740 : 239 : gfc_merge_initializers (gfc_typespec ts, gfc_expr *e, locus *loc,
741 : : unsigned char *data,
742 : : unsigned char *chk, size_t length)
743 : : {
744 : 239 : size_t len = 0;
745 : 239 : gfc_constructor * c;
746 : :
747 : 239 : switch (e->expr_type)
748 : : {
749 : 179 : case EXPR_CONSTANT:
750 : 179 : case EXPR_STRUCTURE:
751 : 179 : len = expr_to_char (e, loc, &data[0], &chk[0], length);
752 : 179 : break;
753 : :
754 : 60 : case EXPR_ARRAY:
755 : 60 : for (c = gfc_constructor_first (e->value.constructor);
756 : 203 : c; c = gfc_constructor_next (c))
757 : : {
758 : 143 : size_t elt_size;
759 : :
760 : 143 : gfc_target_expr_size (c->expr, &elt_size);
761 : :
762 : 143 : if (mpz_cmp_si (c->offset, 0) != 0)
763 : 83 : len = elt_size * (size_t)mpz_get_si (c->offset);
764 : :
765 : 143 : len = len + gfc_merge_initializers (ts, c->expr, loc, &data[len],
766 : : &chk[len], length - len);
767 : : }
768 : : break;
769 : :
770 : : default:
771 : : return 0;
772 : : }
773 : :
774 : : return len;
775 : : }
776 : :
777 : :
778 : : /* Transfer the bitpattern of a (integer) BOZ to real or complex variables.
779 : : When successful, no BOZ or nothing to do, true is returned. */
780 : :
781 : : bool
782 : 254 : gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
783 : : {
784 : 254 : size_t buffer_size, boz_bit_size, ts_bit_size;
785 : 254 : int index;
786 : 254 : unsigned char *buffer;
787 : :
788 : 254 : if (expr->ts.type != BT_INTEGER)
789 : : return true;
790 : :
791 : : /* Don't convert BOZ to logical, character, derived etc. */
792 : 254 : gcc_assert (ts->type == BT_REAL);
793 : :
794 : 254 : buffer_size = size_float (ts->kind);
795 : 254 : ts_bit_size = buffer_size * 8;
796 : :
797 : : /* Convert BOZ to the smallest possible integer kind. */
798 : 254 : boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);
799 : :
800 : 254 : gcc_assert (boz_bit_size <= ts_bit_size);
801 : :
802 : 880 : for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
803 : 880 : if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
804 : : break;
805 : :
806 : 254 : expr->ts.kind = gfc_integer_kinds[index].kind;
807 : 254 : buffer_size = MAX (buffer_size, size_integer (expr->ts.kind));
808 : :
809 : 254 : buffer = (unsigned char*)alloca (buffer_size);
810 : 254 : encode_integer (expr->ts.kind, expr->value.integer, buffer, buffer_size);
811 : 254 : mpz_clear (expr->value.integer);
812 : :
813 : 254 : mpfr_init (expr->value.real);
814 : 254 : gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
815 : :
816 : 254 : expr->ts.type = ts->type;
817 : 254 : expr->ts.kind = ts->kind;
818 : :
819 : 254 : return true;
820 : : }
|