2 * Dumps global variables and constants as ia32 assembler.
3 * @author Christian Wuerdig
26 #include "ia32_emitter.h"
27 #include "ia32_gen_decls.h"
29 typedef struct obstack obstack_t;
31 typedef struct _ia32_decl_env {
32 obstack_t *rodata_obst;
36 const be_main_env_t *main_env;
39 /************************************************************************/
44 static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
49 obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
53 obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
57 obstack_printf(obst, "0x%02x%02x%02x%02x",
58 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
62 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
63 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
64 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
72 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
73 "%02x%02x%02x%02x%02x%02x%02x%02x",
74 get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
75 get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
76 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
77 get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
78 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
79 get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
80 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
81 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
86 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
92 * Return the tarval of an atomic initializer.
94 static tarval *get_atomic_init_tv(ir_node *init)
97 ir_mode *mode = get_irn_mode(init);
99 switch (get_irn_opcode(init)) {
102 init = get_Cast_op(init);
106 init = get_Conv_op(init);
110 return get_Const_tarval(init);
113 switch (get_SymConst_kind(init)) {
114 case symconst_ofs_ent:
115 return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
117 case symconst_type_size:
118 return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
120 case symconst_type_align:
121 return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
123 case symconst_enum_const:
124 return get_enumeration_value(get_SymConst_enum(init));
137 * dump an atomic value
139 static void do_dump_atomic_init(obstack_t *obst, ir_node *init)
141 ir_mode *mode = get_irn_mode(init);
142 int bytes = get_mode_size_bytes(mode);
145 switch (get_irn_opcode(init)) {
148 do_dump_atomic_init(obst, get_Cast_op(init));
152 do_dump_atomic_init(obst, get_Conv_op(init));
156 tv = get_Const_tarval(init);
158 /* it's a arithmetic value */
159 dump_arith_tarval(obst, tv, bytes);
163 switch (get_SymConst_kind(init)) {
164 case symconst_addr_name:
165 obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
168 case symconst_addr_ent:
169 obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
172 case symconst_ofs_ent:
173 obstack_printf(obst, "%d", get_entity_offset(get_SymConst_entity(init)));
176 case symconst_type_size:
177 obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
180 case symconst_type_align:
181 obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
184 case symconst_enum_const:
185 tv = get_enumeration_value(get_SymConst_enum(init));
186 dump_arith_tarval(obst, tv, bytes);
190 assert(!"dump_atomic_init(): don't know how to init from this SymConst");
195 do_dump_atomic_init(obst, get_Add_left(init));
196 obstack_printf(obst, " + ");
197 do_dump_atomic_init(obst, get_Add_right(init));
201 do_dump_atomic_init(obst, get_Sub_left(init));
202 obstack_printf(obst, " - ");
203 do_dump_atomic_init(obst, get_Sub_right(init));
207 do_dump_atomic_init(obst, get_Mul_left(init));
208 obstack_printf(obst, " * ");
209 do_dump_atomic_init(obst, get_Mul_right(init));
213 assert(0 && "dump_atomic_init(): unknown IR-node");
218 * dumps the type for given size (.byte, .long, ...)
220 static void dump_size_type(obstack_t *obst, int size) {
224 obstack_printf(obst, "\t.byte\t");
228 obstack_printf(obst, "\t.value\t");
232 obstack_printf(obst, "\t.long\t");
236 obstack_printf(obst, "\t.quad\t");
241 /* handled in arith */
245 obstack_printf(obst, "\t.octa\t");
249 fprintf(stderr, "Try to dump a type with %d bytes\n", size);
255 * dump an atomic value to an obstack
257 static void dump_atomic_init(obstack_t *obst, ir_node *init)
259 ir_mode *mode = get_irn_mode(init);
260 int bytes = get_mode_size_bytes(mode);
262 dump_size_type(obst, bytes);
263 do_dump_atomic_init(obst, init);
264 obstack_printf(obst, "\n");
267 /************************************************************************/
268 /* Routines to dump global variables */
269 /************************************************************************/
272 * Determine if an entity is a string constant
273 * @param ent The entity
274 * @return 1 if it is a string constant, 0 otherwise
276 static int ent_is_string_const(ir_entity *ent)
278 ir_type *type, *element_type;
282 type = get_entity_type(ent);
284 /* if it's an array */
285 if (!is_Array_type(type))
288 element_type = get_array_element_type(type);
290 /* and the array's element type is primitive */
291 if (!is_Primitive_type(element_type))
294 /* and the mode of the element type is an int of
295 * the same size as the byte mode */
296 mode = get_type_mode(element_type);
297 if (!mode_is_int(mode)
298 || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
301 /* if it contains only printable chars and a 0 at the end */
302 n = get_compound_ent_n_values(ent);
303 for (i = 0; i < n; ++i) {
304 ir_node *irn = get_compound_ent_value(ent, i);
305 if(get_irn_opcode(irn) != iro_Const)
308 c = (int) get_tarval_long(get_Const_tarval(irn));
310 if((i < n - 1 && !(isgraph(c) || isspace(c)))
311 || (i == n - 1 && c != '\0'))
315 /* then we can emit it as a string constant */
320 * Dump a string constant.
321 * No checks are made!!
322 * @param obst The obst to dump on.
323 * @param ent The entity to dump.
325 static void dump_string_cst(obstack_t *obst, ir_entity *ent)
329 obstack_printf(obst, "\t.string \"");
330 n = get_compound_ent_n_values(ent);
332 for (i = 0; i < n-1; ++i) {
336 irn = get_compound_ent_value(ent, i);
337 c = (int) get_tarval_long(get_Const_tarval(irn));
340 case '"' : obstack_printf(obst, "\\\""); break;
341 case '\n': obstack_printf(obst, "\\n"); break;
342 case '\r': obstack_printf(obst, "\\r"); break;
343 case '\t': obstack_printf(obst, "\\t"); break;
344 case '\\': obstack_printf(obst, "\\\\"); break;
347 obstack_printf(obst, "%c", c);
349 obstack_printf(obst, "\\%o", c);
353 obstack_printf(obst, "\"\n");
356 static void dump_array_init(obstack_t *obst, ir_entity *ent)
358 const ir_type *ty = get_entity_type(ent);
363 /* potential spare values should be already included! */
364 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
365 ir_entity *step = get_compound_ent_value_member(ent, i);
366 ir_type *stype = get_entity_type(step);
368 if (get_type_mode(stype)) {
369 int align = (get_type_alignment_bits(stype) + 7) >> 3;
370 int n = size % align;
373 obstack_printf(obst, "\t.zero\t%d\n", align - n);
377 dump_atomic_init(obst, get_compound_ent_value(ent, i));
378 size += get_type_size_bytes(stype);
380 filler = get_type_size_bytes(ty) - size;
383 obstack_printf(obst, "\t.skip\t%d\n", filler);
386 enum normal_or_bitfield_kind {
392 enum normal_or_bitfield_kind kind;
395 unsigned char bf_val;
397 } normal_or_bitfield;
400 * Dump an initializer for a compound entity.
402 static void dump_compound_init(obstack_t *obst, ir_entity *ent)
404 normal_or_bitfield *vals;
405 int i, j, n = get_compound_ent_n_values(ent);
408 /* Find the initializer size. Sorrily gcc support a nasty feature:
409 The last field of a compound may be a flexible array. This allows
410 initializers bigger than the type size. */
412 for (i = 0; i < n; ++i) {
413 int offset = get_compound_ent_value_offset_bytes(ent, i);
414 int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
415 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
416 int path_len = get_compound_graph_path_length(path);
417 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
418 int value_len = get_type_size_bits(get_entity_type(last_ent));
420 offset += (value_len + bits_remainder + 7) >> 3;
422 if (offset > last_ofs) {
428 * In the worst case, every initializer allocates one byte.
429 * Moreover, initializer might be big, do not allocate an stack.
431 vals = xcalloc(last_ofs, sizeof(vals[0]));
433 /* collect the values and store them at the offsets */
434 for (i = 0; i < n; ++i) {
435 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
436 int path_len = get_compound_graph_path_length(path);
437 int offset = get_compound_ent_value_offset_bytes(ent, i);
438 int offset_bits = get_compound_ent_value_offset_bit_remainder(ent, i);
439 ir_node *value = get_compound_ent_value(ent, i);
440 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
441 int value_len = get_type_size_bits(get_entity_type(last_ent));
443 assert(offset_bits >= 0);
445 if (offset_bits != 0 ||
446 (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
447 tarval *shift, *shifted;
448 tarval *tv = get_atomic_init_tv(value);
450 panic("Couldn't get numeric value for bitfield initializer '%s'\n",
451 get_entity_ld_name(ent));
453 tv = tarval_convert_to(tv, mode_Lu);
454 shift = new_tarval_from_long(offset_bits, mode_Is);
455 shifted = tarval_shl(tv, shift);
456 if (shifted == tarval_bad || shifted == tarval_undefined) {
457 panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
458 get_entity_ld_name(ent));
461 for (j = 0; value_len > 0; ++j) {
462 assert(offset + j < last_ofs);
463 assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
464 vals[offset + j].kind = BITFIELD;
465 vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
466 value_len -= 8 - offset_bits;
470 assert(offset < last_ofs);
471 assert(vals[offset].kind == NORMAL);
472 assert(vals[offset].v.value == NULL);
473 vals[offset].v.value = value;
477 /* now write them sorted */
478 for (i = 0; i < last_ofs; ) {
479 int space = 0, skip = 0;
480 if (vals[i].kind == NORMAL) {
481 if(vals[i].v.value != NULL) {
482 dump_atomic_init(obst, vals[i].v.value);
483 skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
488 assert(vals[i].kind == BITFIELD);
489 obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
494 while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
503 obstack_printf(obst, "\t.skip\t%d\n", space);
509 * Dump a global entity.
511 static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
514 ir_type *type = get_entity_type(ent);
515 const char *ld_name = get_entity_ld_name(ent);
516 ir_variability variability = get_entity_variability(ent);
517 ir_visibility visibility = get_entity_visibility(ent);
518 int align = get_type_alignment_bytes(type);
519 int emit_as_common = 0;
521 obst = env->data_obst;
522 if (is_Method_type(type)) {
523 if (get_method_img_section(ent) == section_constructors) {
524 obst = env->ctor_obst;
525 obstack_printf(obst, ".balign\t%d\n", align);
526 dump_size_type(obst, align);
527 obstack_printf(obst, "%s\n", ld_name);
530 } else if (variability == variability_constant) {
531 /* a constant entity, put it on the rdata */
532 obst = env->rodata_obst;
533 } else if (variability == variability_uninitialized) {
534 /* uninitialized entity put it in bss segment */
535 obst = env->bss_obst;
536 if(emit_commons && visibility != visibility_local)
540 be_dbg_variable(env->main_env->db_handle, obst, ent);
542 /* global or not global */
543 if (visibility == visibility_external_visible && !emit_as_common) {
544 obstack_printf(obst, ".global\t%s\n", ld_name);
545 } else if(visibility == visibility_external_allocated) {
546 obstack_printf(obst, ".global\t%s\n", ld_name);
547 /* we can return now... */
551 if (align > 1 && !emit_as_common) {
552 obstack_printf(obst, ".balign\t%d\n", align);
555 if (!emit_as_common) {
556 obstack_printf(obst, "%s:\n", ld_name);
559 if (variability == variability_uninitialized) {
561 obstack_printf(obst, "\t.comm %s,%d,%d\n",
562 ld_name, get_type_size_bytes(type), align);
564 obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
566 } else if (is_atomic_type(type)) {
567 dump_atomic_init(obst, get_atomic_ent_value(ent));
568 } else if (ent_is_string_const(ent)) {
569 dump_string_cst(obst, ent);
570 } else if (is_Array_type(type)) {
571 dump_array_init(obst, ent);
572 } else if (is_compound_type(type)) {
573 dump_compound_init(obst, ent);
575 assert(0 && "unsupported type");
580 * Dumps declarations of global variables and the initialization code.
582 static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env, int emit_commons)
584 int i, n = get_compound_n_members(gt);
586 for (i = 0; i < n; i++) {
587 ir_entity *ent = get_compound_member(gt, i);
588 dump_global(env, ent, emit_commons);
592 /************************************************************************/
594 void ia32_gen_decls(FILE *out, const be_main_env_t *main_env) {
596 obstack_t rodata, data, bss, ctor;
600 /* dump the global type */
601 obstack_init(&rodata);
605 if (main_env->options->opt_profile)
608 env.rodata_obst = &rodata;
609 env.data_obst = &data;
611 env.ctor_obst = main_env->options->opt_profile ? &ctor : NULL;
612 env.main_env = main_env;
614 ia32_dump_globals(get_glob_type(), &env, 1);
616 size = obstack_object_size(&data);
617 cp = obstack_finish(&data);
619 ia32_switch_section(out, SECTION_DATA);
620 fwrite(cp, 1, size, out);
623 size = obstack_object_size(&rodata);
624 cp = obstack_finish(&rodata);
626 ia32_switch_section(out, SECTION_RODATA);
627 fwrite(cp, 1, size, out);
630 size = obstack_object_size(&bss);
631 cp = obstack_finish(&bss);
633 ia32_switch_section(out, SECTION_COMMON);
634 fwrite(cp, 1, size, out);
637 if (main_env->options->opt_profile) {
638 size = obstack_object_size(&ctor);
639 cp = obstack_finish(&ctor);
641 ia32_switch_section(out, SECTION_CTOR);
642 fwrite(cp, 1, size, out);
644 obstack_free(&ctor, NULL);
647 obstack_free(&rodata, NULL);
648 obstack_free(&data, NULL);
649 obstack_free(&bss, NULL);
651 /* dump the Thread Local Storage */
654 env.rodata_obst = &data;
655 env.data_obst = &data;
656 env.bss_obst = &data;
657 env.ctor_obst = NULL;
659 ia32_dump_globals(get_tls_type(), &env, 0);
661 size = obstack_object_size(&data);
662 cp = obstack_finish(&data);
664 ia32_switch_section(out, SECTION_TLS);
665 fprintf(out, ".balign\t%d\n", 32);
666 fwrite(cp, 1, size, out);
669 obstack_free(&data, NULL);