2 * Dumps global variables and constants as gas assembler.
3 * @author Christian Wuerdig, Matthias Braun
27 #include "beemitter.h"
28 #include "be_dbgout.h"
30 typedef struct obstack obstack_t;
32 /** by default, we generate assembler code for the Linux gas */
33 be_gas_flavour_t be_gas_flavour = GAS_FLAVOUR_NORMAL;
35 static const char* get_section_name(be_gas_section_t section) {
36 static const char *text[GAS_FLAVOUR_MAX][GAS_SECTION_MAX] = {
42 ".section\t.tbss,\"awT\",@nobits",
43 ".section\t.ctors,\"aw\",@progbits"
48 ".section .rdata,\"dr\"",
50 ".section\t.tbss,\"awT\",@nobits",
51 ".section\t.ctors,\"aw\",@progbits"
55 assert(be_gas_flavour >= 0 && be_gas_flavour < GAS_FLAVOUR_MAX);
56 assert(section >= 0 && section < GAS_SECTION_MAX);
57 return text[be_gas_flavour][section];
60 void be_gas_emit_switch_section(be_emit_env_t *env, be_gas_section_t section) {
61 be_emit_char(env, '\t');
62 be_emit_string(env, get_section_name(section));
63 be_emit_char(env, '\n');
64 be_emit_write_line(env);
67 typedef struct _ia32_decl_env {
68 obstack_t *rodata_obst;
72 const be_main_env_t *main_env;
76 /************************************************************************/
81 static void dump_arith_tarval(obstack_t *obst, tarval *tv, int bytes)
86 obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
90 obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
94 obstack_printf(obst, "0x%02x%02x%02x%02x",
95 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
99 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
100 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
101 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
109 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x"
110 "%02x%02x%02x%02x%02x%02x%02x%02x",
111 get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
112 get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
113 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
114 get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
115 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
116 get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
117 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
118 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
123 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
129 * Return the tarval of an atomic initializer.
131 static tarval *get_atomic_init_tv(ir_node *init)
134 ir_mode *mode = get_irn_mode(init);
136 switch (get_irn_opcode(init)) {
139 init = get_Cast_op(init);
143 init = get_Conv_op(init);
147 return get_Const_tarval(init);
150 switch (get_SymConst_kind(init)) {
151 case symconst_ofs_ent:
152 return new_tarval_from_long(get_entity_offset(get_SymConst_entity(init)), mode);
154 case symconst_type_size:
155 return new_tarval_from_long(get_type_size_bytes(get_SymConst_type(init)), mode);
157 case symconst_type_align:
158 return new_tarval_from_long(get_type_alignment_bytes(get_SymConst_type(init)), mode);
160 case symconst_enum_const:
161 return get_enumeration_value(get_SymConst_enum(init));
174 * dump an atomic value
176 static void do_dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
179 ir_mode *mode = get_irn_mode(init);
180 int bytes = get_mode_size_bytes(mode);
184 switch (get_irn_opcode(init)) {
187 do_dump_atomic_init(env, obst, get_Cast_op(init));
191 do_dump_atomic_init(env, obst, get_Conv_op(init));
195 tv = get_Const_tarval(init);
197 /* it's a arithmetic value */
198 dump_arith_tarval(obst, tv, bytes);
202 switch (get_SymConst_kind(init)) {
203 case symconst_addr_name:
204 obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
207 case symconst_addr_ent:
208 ent = get_SymConst_entity(init);
209 if(!entity_visited(ent)) {
210 waitq_put(env->worklist, ent);
211 mark_entity_visited(ent);
213 obstack_printf(obst, "%s", get_entity_ld_name(ent));
216 case symconst_ofs_ent:
217 ent = get_SymConst_entity(init);
218 #if 0 /* not needed, is it? */
219 if(!entity_visited(ent)) {
220 waitq_put(env->worklist, ent);
221 mark_entity_visited(ent);
224 obstack_printf(obst, "%d", get_entity_offset(ent));
227 case symconst_type_size:
228 obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
231 case symconst_type_align:
232 obstack_printf(obst, "%d", get_type_alignment_bytes(get_SymConst_type(init)));
235 case symconst_enum_const:
236 tv = get_enumeration_value(get_SymConst_enum(init));
237 dump_arith_tarval(obst, tv, bytes);
241 assert(!"dump_atomic_init(): don't know how to init from this SymConst");
246 do_dump_atomic_init(env, obst, get_Add_left(init));
247 obstack_printf(obst, " + ");
248 do_dump_atomic_init(env, obst, get_Add_right(init));
252 do_dump_atomic_init(env, obst, get_Sub_left(init));
253 obstack_printf(obst, " - ");
254 do_dump_atomic_init(env, obst, get_Sub_right(init));
258 do_dump_atomic_init(env, obst, get_Mul_left(init));
259 obstack_printf(obst, " * ");
260 do_dump_atomic_init(env, obst, get_Mul_right(init));
264 assert(0 && "dump_atomic_init(): unknown IR-node");
269 * dumps the type for given size (.byte, .long, ...)
271 static void dump_size_type(obstack_t *obst, int size) {
275 obstack_printf(obst, "\t.byte\t");
279 obstack_printf(obst, "\t.value\t");
283 obstack_printf(obst, "\t.long\t");
287 obstack_printf(obst, "\t.quad\t");
292 /* handled in arith */
296 obstack_printf(obst, "\t.octa\t");
300 fprintf(stderr, "Try to dump a type with %d bytes\n", size);
306 * dump an atomic value to an obstack
308 static void dump_atomic_init(ia32_decl_env_t *env, obstack_t *obst,
311 ir_mode *mode = get_irn_mode(init);
312 int bytes = get_mode_size_bytes(mode);
314 dump_size_type(obst, bytes);
315 do_dump_atomic_init(env, obst, init);
316 obstack_printf(obst, "\n");
319 /************************************************************************/
320 /* Routines to dump global variables */
321 /************************************************************************/
324 * Determine if an entity is a string constant
325 * @param ent The entity
326 * @return 1 if it is a string constant, 0 otherwise
328 static int ent_is_string_const(ir_entity *ent)
330 ir_type *type, *element_type;
334 type = get_entity_type(ent);
336 /* if it's an array */
337 if (!is_Array_type(type))
340 element_type = get_array_element_type(type);
342 /* and the array's element type is primitive */
343 if (!is_Primitive_type(element_type))
346 /* and the mode of the element type is an int of
347 * the same size as the byte mode */
348 mode = get_type_mode(element_type);
349 if (!mode_is_int(mode)
350 || get_mode_size_bits(mode) != get_mode_size_bits(mode_Bs))
353 /* if it contains only printable chars and a 0 at the end */
354 n = get_compound_ent_n_values(ent);
355 for (i = 0; i < n; ++i) {
356 ir_node *irn = get_compound_ent_value(ent, i);
357 if(get_irn_opcode(irn) != iro_Const)
360 c = (int) get_tarval_long(get_Const_tarval(irn));
362 if((i < n - 1 && !(isgraph(c) || isspace(c)))
363 || (i == n - 1 && c != '\0'))
367 /* then we can emit it as a string constant */
372 * Dump a string constant.
373 * No checks are made!!
374 * @param obst The obst to dump on.
375 * @param ent The entity to dump.
377 static void dump_string_cst(obstack_t *obst, ir_entity *ent)
381 obstack_printf(obst, "\t.string \"");
382 n = get_compound_ent_n_values(ent);
384 for (i = 0; i < n-1; ++i) {
388 irn = get_compound_ent_value(ent, i);
389 c = (int) get_tarval_long(get_Const_tarval(irn));
392 case '"' : obstack_printf(obst, "\\\""); break;
393 case '\n': obstack_printf(obst, "\\n"); break;
394 case '\r': obstack_printf(obst, "\\r"); break;
395 case '\t': obstack_printf(obst, "\\t"); break;
396 case '\\': obstack_printf(obst, "\\\\"); break;
399 obstack_printf(obst, "%c", c);
401 obstack_printf(obst, "\\%o", c);
405 obstack_printf(obst, "\"\n");
408 static void dump_array_init(ia32_decl_env_t *env, obstack_t *obst,
411 const ir_type *ty = get_entity_type(ent);
416 /* potential spare values should be already included! */
417 for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
418 ir_entity *step = get_compound_ent_value_member(ent, i);
419 ir_type *stype = get_entity_type(step);
421 if (get_type_mode(stype)) {
422 int align = (get_type_alignment_bits(stype) + 7) >> 3;
423 int n = size % align;
426 obstack_printf(obst, "\t.zero\t%d\n", align - n);
430 dump_atomic_init(env, obst, get_compound_ent_value(ent, i));
431 size += get_type_size_bytes(stype);
433 filler = get_type_size_bytes(ty) - size;
436 obstack_printf(obst, "\t.skip\t%d\n", filler);
439 enum normal_or_bitfield_kind {
445 enum normal_or_bitfield_kind kind;
448 unsigned char bf_val;
450 } normal_or_bitfield;
453 * Dump an initializer for a compound entity.
455 static void dump_compound_init(ia32_decl_env_t *env, obstack_t *obst,
458 normal_or_bitfield *vals;
459 int i, j, n = get_compound_ent_n_values(ent);
462 /* Find the initializer size. Sorrily gcc support a nasty feature:
463 The last field of a compound may be a flexible array. This allows
464 initializers bigger than the type size. */
465 last_ofs = get_type_size_bytes(get_entity_type(ent));
466 for (i = 0; i < n; ++i) {
467 int offset = get_compound_ent_value_offset_bytes(ent, i);
468 int bits_remainder = get_compound_ent_value_offset_bit_remainder(ent, i);
469 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
470 int path_len = get_compound_graph_path_length(path);
471 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
472 int value_len = get_type_size_bits(get_entity_type(last_ent));
474 offset += (value_len + bits_remainder + 7) >> 3;
476 if (offset > last_ofs) {
482 * In the worst case, every initializer allocates one byte.
483 * Moreover, initializer might be big, do not allocate on stack.
485 vals = xcalloc(last_ofs, sizeof(vals[0]));
487 /* collect the values and store them at the offsets */
488 for (i = 0; i < n; ++i) {
489 const compound_graph_path *path = get_compound_ent_value_path(ent, i);
490 int path_len = get_compound_graph_path_length(path);
491 int offset = get_compound_ent_value_offset_bytes(ent, i);
492 int offset_bits = get_compound_ent_value_offset_bit_remainder(ent, i);
493 ir_node *value = get_compound_ent_value(ent, i);
494 ir_entity *last_ent = get_compound_graph_path_node(path, path_len - 1);
495 int value_len = get_type_size_bits(get_entity_type(last_ent));
497 assert(offset_bits >= 0);
499 if (offset_bits != 0 ||
500 (value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
501 tarval *shift, *shifted;
502 tarval *tv = get_atomic_init_tv(value);
504 panic("Couldn't get numeric value for bitfield initializer '%s'\n",
505 get_entity_ld_name(ent));
507 tv = tarval_convert_to(tv, mode_Lu);
508 shift = new_tarval_from_long(offset_bits, mode_Is);
509 shifted = tarval_shl(tv, shift);
510 if (shifted == tarval_bad || shifted == tarval_undefined) {
511 panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
512 get_entity_ld_name(ent));
515 for (j = 0; value_len > 0; ++j) {
516 assert(offset + j < last_ofs);
517 assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
518 vals[offset + j].kind = BITFIELD;
519 vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
520 value_len -= 8 - offset_bits;
524 assert(offset < last_ofs);
525 assert(vals[offset].kind == NORMAL);
526 assert(vals[offset].v.value == NULL);
527 vals[offset].v.value = value;
531 /* now write them sorted */
532 for (i = 0; i < last_ofs; ) {
533 int space = 0, skip = 0;
534 if (vals[i].kind == NORMAL) {
535 if(vals[i].v.value != NULL) {
536 dump_atomic_init(env, obst, vals[i].v.value);
537 skip = get_mode_size_bytes(get_irn_mode(vals[i].v.value)) - 1;
542 assert(vals[i].kind == BITFIELD);
543 obstack_printf(obst, "\t.byte\t%d\n", vals[i].v.bf_val);
548 while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
557 obstack_printf(obst, "\t.skip\t%d\n", space);
563 * Dump a global entity.
565 static void dump_global(ia32_decl_env_t *env, ir_entity *ent, int emit_commons)
568 ir_type *type = get_entity_type(ent);
569 const char *ld_name = get_entity_ld_name(ent);
570 ir_variability variability = get_entity_variability(ent);
571 ir_visibility visibility = get_entity_visibility(ent);
572 int align = get_type_alignment_bytes(type);
573 int emit_as_common = 0;
575 obst = env->data_obst;
576 if (is_Method_type(type)) {
577 if (get_method_img_section(ent) == section_constructors) {
578 obst = env->ctor_obst;
579 obstack_printf(obst, ".balign\t%d\n", align);
580 dump_size_type(obst, align);
581 obstack_printf(obst, "%s\n", ld_name);
584 } else if (variability == variability_constant) {
585 /* a constant entity, put it on the rdata */
586 obst = env->rodata_obst;
587 } else if (variability == variability_uninitialized) {
588 /* uninitialized entity put it in bss segment */
589 obst = env->bss_obst;
590 if(emit_commons && visibility != visibility_local)
594 be_dbg_variable(env->main_env->db_handle, obst, ent);
596 /* global or not global */
597 if (visibility == visibility_external_visible && !emit_as_common) {
598 obstack_printf(obst, ".global\t%s\n", ld_name);
599 } else if(visibility == visibility_external_allocated) {
600 obstack_printf(obst, ".global\t%s\n", ld_name);
601 /* we can return now... */
605 if (align > 1 && !emit_as_common) {
606 obstack_printf(obst, ".balign\t%d\n", align);
609 if (!emit_as_common) {
610 obstack_printf(obst, "%s:\n", ld_name);
613 if (variability == variability_uninitialized) {
615 obstack_printf(obst, "\t.comm %s,%d,%d\n",
616 ld_name, get_type_size_bytes(type), align);
618 obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
620 } else if (is_atomic_type(type)) {
621 dump_atomic_init(env, obst, get_atomic_ent_value(ent));
622 } else if (ent_is_string_const(ent)) {
623 dump_string_cst(obst, ent);
624 } else if (is_Array_type(type)) {
625 dump_array_init(env, obst, ent);
626 } else if (is_compound_type(type)) {
627 dump_compound_init(env, obst, ent);
629 assert(0 && "unsupported type");
634 * Dumps declarations of global variables and the initialization code.
636 static void ia32_dump_globals(ir_type *gt, ia32_decl_env_t *env,
637 int emit_commons, int only_emit_marked)
639 int i, n = get_compound_n_members(gt);
640 waitq *worklist = new_waitq();
642 if(only_emit_marked) {
643 for (i = 0; i < n; i++) {
644 ir_entity *ent = get_compound_member(gt, i);
645 if(entity_visited(ent) ||
646 get_entity_visibility(ent) != visibility_external_allocated) {
647 waitq_put(worklist, ent);
648 mark_entity_visited(ent);
652 inc_master_type_visited();
653 for (i = 0; i < n; i++) {
654 ir_entity *ent = get_compound_member(gt, i);
655 mark_entity_visited(ent);
656 waitq_put(worklist, ent);
660 env->worklist = worklist;
662 while(!waitq_empty(worklist)) {
663 ir_entity *ent = waitq_get(worklist);
665 dump_global(env, ent, emit_commons);
669 env->worklist = NULL;
672 /************************************************************************/
674 void be_gas_emit_decls(be_emit_env_t *emit, const be_main_env_t *main_env,
675 int only_emit_marked_entities)
678 obstack_t rodata, data, bss, ctor;
682 /* dump the global type */
683 obstack_init(&rodata);
688 env.rodata_obst = &rodata;
689 env.data_obst = &data;
691 env.ctor_obst = &ctor;
692 env.main_env = main_env;
694 ia32_dump_globals(get_glob_type(), &env, 1, only_emit_marked_entities);
696 size = obstack_object_size(&data);
697 cp = obstack_finish(&data);
699 be_gas_emit_switch_section(emit, GAS_SECTION_DATA);
700 be_emit_string_len(emit, cp, size);
701 be_emit_write_line(emit);
704 size = obstack_object_size(&rodata);
705 cp = obstack_finish(&rodata);
707 be_gas_emit_switch_section(emit, GAS_SECTION_RODATA);
708 be_emit_string_len(emit, cp, size);
709 be_emit_write_line(emit);
712 size = obstack_object_size(&bss);
713 cp = obstack_finish(&bss);
715 be_gas_emit_switch_section(emit, GAS_SECTION_COMMON);
716 be_emit_string_len(emit, cp, size);
717 be_emit_write_line(emit);
720 size = obstack_object_size(&ctor);
721 cp = obstack_finish(&ctor);
723 be_gas_emit_switch_section(emit, GAS_SECTION_CTOR);
724 be_emit_string_len(emit, cp, size);
725 be_emit_write_line(emit);
728 obstack_free(&rodata, NULL);
729 obstack_free(&data, NULL);
730 obstack_free(&bss, NULL);
731 obstack_free(&ctor, NULL);
733 /* dump the Thread Local Storage */
736 env.rodata_obst = &data;
737 env.data_obst = &data;
738 env.bss_obst = &data;
739 env.ctor_obst = NULL;
741 ia32_dump_globals(get_tls_type(), &env, 0, only_emit_marked_entities);
743 size = obstack_object_size(&data);
744 cp = obstack_finish(&data);
746 be_gas_emit_switch_section(emit, GAS_SECTION_TLS);
747 be_emit_cstring(emit, ".balign\t32\n");
748 be_emit_write_line(emit);
749 be_emit_string_len(emit, cp, size);
750 be_emit_write_line(emit);
753 obstack_free(&data, NULL);