besched: Change sched_foreach_from(sched_next(x), y) to sched_foreach_after(x, y).
[libfirm] / ir / be / begnuas.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief       Dumps global variables and constants as gas assembler.
9  * @author      Christian Wuerdig, Matthias Braun
10  * @date        04.11.2005
11  */
12 #include "config.h"
13
14 #include "begnuas.h"
15
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <assert.h>
20
21 #include "obst.h"
22 #include "tv.h"
23 #include "irnode.h"
24 #include "irprog.h"
25 #include "entity_t.h"
26 #include "error.h"
27 #include "util.h"
28 #include "execfreq.h"
29
30 #include "be_t.h"
31 #include "bearch.h"
32 #include "beemitter.h"
33 #include "bedwarf.h"
34
35 /** by default, we generate assembler code for the Linux gas */
36 object_file_format_t  be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF;
37 elf_variant_t         be_gas_elf_variant        = ELF_VARIANT_NORMAL;
38 bool                  be_gas_emit_types         = true;
39 char                  be_gas_elf_type_char      = '@';
40
41 static be_gas_section_t current_section = (be_gas_section_t) -1;
42 static pmap            *block_numbers;
43 static unsigned         next_block_nr;
44
45 /**
46  * An environment containing all needed dumper data.
47  * Currently we create the file completely in memory first, then
48  * write it to the disk. This is an artifact from the old C-generating backend
49  * and even there NOT needed. So we might change it in the future.
50  */
51 typedef struct be_gas_decl_env {
52         be_gas_section_t     section;
53         const be_main_env_t *main_env;
54 } be_gas_decl_env_t;
55
56 static void emit_section_macho(be_gas_section_t section)
57 {
58         be_gas_section_t  base  = section & GAS_SECTION_TYPE_MASK;
59         be_gas_section_t  flags = section & ~GAS_SECTION_TYPE_MASK;
60         const char       *name;
61
62         if (current_section == section)
63                 return;
64         current_section = section;
65
66         /* shortforms */
67         if (flags == 0) {
68                 switch (base) {
69                 case GAS_SECTION_TEXT:            name = "text";          break;
70                 case GAS_SECTION_DATA:            name = "data";          break;
71                 case GAS_SECTION_RODATA:          name = "const";         break;
72                 case GAS_SECTION_BSS:             name = "data";          break;
73                 case GAS_SECTION_CONSTRUCTORS:    name = "mod_init_func"; break;
74                 case GAS_SECTION_DESTRUCTORS:     name = "mod_term_func"; break;
75                 case GAS_SECTION_PIC_TRAMPOLINES: name = "section\t__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5"; break;
76                 case GAS_SECTION_PIC_SYMBOLS:     name = "section\t__IMPORT,__pointers,non_lazy_symbol_pointers"; break;
77                 case GAS_SECTION_CSTRING:         name = "cstring";       break;
78                 case GAS_SECTION_DEBUG_INFO:      name = "section __DWARF,__debug_info,regular,debug"; break;
79                 case GAS_SECTION_DEBUG_ABBREV:    name = "section __DWARF,__debug_abbrev,regular,debug"; break;
80                 case GAS_SECTION_DEBUG_LINE:      name = "section __DWARF,__debug_line,regular,debug"; break;
81                 case GAS_SECTION_DEBUG_PUBNAMES:  name = "section __DWARF,__debug_pubnames,regular,debug"; break;
82                 case GAS_SECTION_DEBUG_FRAME:     name = "section __DWARF,__debug_frame,regular,debug"; break;
83                 default: panic("unsupported scetion type 0x%X", section);
84                 }
85         } else if (flags & GAS_SECTION_FLAG_COMDAT) {
86                 switch (base) {
87                 case GAS_SECTION_TEXT:            name = "section __TEXT,__textcoal_nt,coalesced,pure_instructions"; break;
88                 case GAS_SECTION_BSS:
89                 case GAS_SECTION_DATA:            name = "section __DATA,__datacoal_nt,coalesced"; break;
90                 case GAS_SECTION_RODATA:          name = "section __TEXT,__const_coal,coalesced"; break;
91                 case GAS_SECTION_CSTRING:         name = "section __TEXT,__const_coal,coalesced"; break;
92                 default: panic("unsupported scetion type 0x%X", section);
93                 }
94         } else if (flags & GAS_SECTION_FLAG_TLS) {
95                 panic("thread local storage not supported on macho (section 0x%X)", section);
96         } else {
97                 panic("unsupported section type 0x%X", section);
98         }
99         be_emit_irprintf("\t.%s\n", name);
100         be_emit_write_line();
101 }
102
103 static void emit_section_sparc(be_gas_section_t section, const ir_entity *entity)
104 {
105         be_gas_section_t base = section & GAS_SECTION_TYPE_MASK;
106         be_gas_section_t flags = section & ~GAS_SECTION_TYPE_MASK;
107         static const char *const basename[GAS_SECTION_LAST+1] = {
108                 "text",
109                 "data",
110                 "rodata",
111                 "bss",
112                 "ctors",
113                 "dtors",
114                 NULL, /* cstring */
115                 NULL, /* pic trampolines */
116                 NULL, /* pic symbols */
117                 "debug_info",
118                 "debug_abbrev",
119                 "debug_line",
120                 "debug_pubnames"
121                 "debug_frame",
122         };
123
124         if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
125                 return;
126         current_section = section;
127
128         be_emit_cstring("\t.section\t\".");
129
130         /* Part1: section-name */
131         if (flags & GAS_SECTION_FLAG_TLS)
132                 be_emit_char('t');
133         assert(base < (be_gas_section_t)ARRAY_SIZE(basename));
134         be_emit_string(basename[base]);
135
136         if (flags & GAS_SECTION_FLAG_COMDAT) {
137                 be_emit_char('.');
138                 be_gas_emit_entity(entity);
139         }
140         be_emit_char('"');
141
142         /* for the simple sections we're done here */
143         if (flags == 0)
144                 goto end;
145
146         be_emit_cstring(",#alloc");
147
148         switch (base) {
149         case GAS_SECTION_TEXT: be_emit_cstring(",#execinstr"); break;
150         case GAS_SECTION_DATA:
151         case GAS_SECTION_BSS:  be_emit_cstring(",#write"); break;
152         default:
153                 /* nothing */
154                 break;
155         }
156         if (flags & GAS_SECTION_FLAG_TLS) {
157                 be_emit_cstring(",#tls");
158         }
159
160 end:
161         be_emit_char('\n');
162         be_emit_write_line();
163 }
164
165 static void emit_section(be_gas_section_t section, const ir_entity *entity)
166 {
167         be_gas_section_t base = section & GAS_SECTION_TYPE_MASK;
168         be_gas_section_t flags = section & ~GAS_SECTION_TYPE_MASK;
169         const char *f;
170         static const struct {
171                 const char *name;
172                 const char *type;
173                 const char *flags;
174         } sectioninfos[GAS_SECTION_LAST+1] = {
175                 { "text",           "progbits", "ax" },
176                 { "data",           "progbits", "aw" },
177                 { "rodata",         "progbits", "a"  },
178                 { "bss",            "nobits",   "aw" },
179                 { "ctors",          "progbits", "aw" },
180                 { "dtors",          "progbits", "aw" },
181                 { NULL,             NULL,       NULL }, /* cstring */
182                 { NULL,             NULL,       NULL }, /* pic trampolines */
183                 { NULL,             NULL,       NULL }, /* pic symbols */
184                 { "debug_info",     "progbits", ""   },
185                 { "debug_abbrev",   "progbits", ""   },
186                 { "debug_line",     "progbits", ""   },
187                 { "debug_pubnames", "progbits", ""   },
188                 { "debug_frame",    "progbits", ""   },
189         };
190
191         if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
192                 emit_section_macho(section);
193                 return;
194         } else if(be_gas_elf_variant == ELF_VARIANT_SPARC) {
195                 emit_section_sparc(section, entity);
196                 return;
197         }
198
199         if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
200                 return;
201         current_section = section;
202
203         /* shortforms */
204         if (flags == 0) {
205                 switch (base) {
206                 case GAS_SECTION_TEXT:
207                         be_emit_cstring("\t.text\n");
208                         be_emit_write_line();
209                         return;
210                 case GAS_SECTION_DATA:
211                         be_emit_cstring("\t.data\n");
212                         be_emit_write_line();
213                         return;
214                 case GAS_SECTION_RODATA:
215                         be_emit_cstring("\t.section\t.rodata\n");
216                         be_emit_write_line();
217                         return;
218                 case GAS_SECTION_BSS:
219                         be_emit_cstring("\t.bss\n");
220                         be_emit_write_line();
221                         return;
222                 default:
223                         break;
224                 }
225         }
226
227         assert(base < (be_gas_section_t) ARRAY_SIZE(sectioninfos));
228         be_emit_cstring("\t.section\t.");
229         /* section name */
230         if (flags & GAS_SECTION_FLAG_TLS)
231                 be_emit_char('t');
232         be_emit_string(sectioninfos[base].name);
233         if (flags & GAS_SECTION_FLAG_COMDAT) {
234                 be_emit_char('.');
235                 be_gas_emit_entity(entity);
236         }
237
238         /* section flags */
239         be_emit_cstring(",\"");
240         for (f = sectioninfos[base].flags; *f != '\0'; ++f) {
241                 be_emit_char(*f);
242         }
243         if (flags & GAS_SECTION_FLAG_TLS)
244                 be_emit_char('T');
245         if (flags & GAS_SECTION_FLAG_COMDAT)
246                 be_emit_char('G');
247
248         /* section type */
249         if (be_gas_object_file_format != OBJECT_FILE_FORMAT_COFF) {
250                 be_emit_cstring("\",");
251                 be_emit_char(be_gas_elf_type_char);
252                 be_emit_string(sectioninfos[base].type);
253         }
254
255         if (flags & GAS_SECTION_FLAG_COMDAT) {
256                 be_emit_char(',');
257                 be_gas_emit_entity(entity);
258                 be_emit_cstring(",comdat");
259         }
260         be_emit_char('\n');
261         be_emit_write_line();
262 }
263
264
265
266 void be_gas_emit_switch_section(be_gas_section_t section)
267 {
268         /* you have to produce a switch_section call with entity manually
269          * for comdat sections */
270         assert( !(section & GAS_SECTION_FLAG_COMDAT));
271
272         emit_section(section, NULL);
273 }
274
275 static ir_tarval *get_initializer_tarval(const ir_initializer_t *initializer)
276 {
277         if (initializer->kind == IR_INITIALIZER_TARVAL)
278                 return initializer->tarval.value;
279         if (initializer->kind == IR_INITIALIZER_CONST) {
280                 ir_node *node = initializer->consti.value;
281                 if (is_Const(node)) {
282                         return get_Const_tarval(node);
283                 }
284         }
285         return get_tarval_undefined();
286 }
287
288 static bool initializer_is_string_const(const ir_initializer_t *initializer)
289 {
290         size_t i, len;
291         bool found_printable = false;
292
293         if (initializer->kind != IR_INITIALIZER_COMPOUND)
294                 return false;
295
296         len = initializer->compound.n_initializers;
297         if (len < 1)
298                 return false;
299         for (i = 0; i < len; ++i) {
300                 int               c;
301                 ir_tarval        *tv;
302                 ir_mode          *mode;
303                 ir_initializer_t *sub_initializer
304                         = initializer->compound.initializers[i];
305
306                 tv = get_initializer_tarval(sub_initializer);
307                 if (!tarval_is_constant(tv))
308                         return false;
309
310                 mode = get_tarval_mode(tv);
311                 if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
312                         return false;
313
314                 c = get_tarval_long(tv);
315                 if (isgraph(c) || isspace(c))
316                         found_printable = true;
317                 else if (c != 0)
318                         return false;
319
320                 if (i == len - 1 && c != '\0')
321                         return false;
322         }
323
324         return found_printable;
325 }
326
327 static bool initializer_is_null(const ir_initializer_t *initializer)
328 {
329         switch (initializer->kind) {
330         case IR_INITIALIZER_NULL:
331                 return true;
332         case IR_INITIALIZER_TARVAL: {
333                 ir_tarval *tv = initializer->tarval.value;
334                 return tarval_is_null(tv);
335         }
336         case IR_INITIALIZER_CONST: {
337                 ir_node *value = initializer->consti.value;
338                 if (!is_Const(value))
339                         return false;
340                 return is_Const_null(value);
341         }
342         case IR_INITIALIZER_COMPOUND: {
343                 size_t i;
344                 for (i = 0; i < initializer->compound.n_initializers; ++i) {
345                         ir_initializer_t *subinitializer
346                                 = initializer->compound.initializers[i];
347                         if (!initializer_is_null(subinitializer))
348                                 return false;
349                 }
350                 return true;
351         }
352         }
353         panic("invalid initializer in initializer_is_null");
354 }
355
356 /**
357  * Determine if an entity is a string constant
358  * @param ent The entity
359  * @return 1 if it is a string constant, 0 otherwise
360  */
361 static int entity_is_string_const(const ir_entity *ent)
362 {
363         ir_type *type, *element_type;
364         ir_mode *mode;
365
366         type = get_entity_type(ent);
367
368         /* if it's an array */
369         if (!is_Array_type(type))
370                 return 0;
371
372         element_type = get_array_element_type(type);
373
374         /* and the array's element type is primitive */
375         if (!is_Primitive_type(element_type))
376                 return 0;
377
378         /* and the mode of the element type is an int of
379          * the same size as the byte mode */
380         mode = get_type_mode(element_type);
381         if (!mode_is_int(mode) || get_mode_size_bits(mode) != 8)
382                 return 0;
383
384         if (ent->initializer != NULL) {
385                 return initializer_is_string_const(ent->initializer);
386         }
387
388         return 0;
389 }
390
391 static bool entity_is_null(const ir_entity *entity)
392 {
393         ir_initializer_t *initializer = get_entity_initializer(entity);
394         return initializer == NULL || initializer_is_null(initializer);
395 }
396
397 static bool is_comdat(const ir_entity *entity)
398 {
399         ir_linkage linkage = get_entity_linkage(entity);
400         return (linkage & IR_LINKAGE_MERGE)
401                 && (linkage & IR_LINKAGE_GARBAGE_COLLECT);
402 }
403
404 static be_gas_section_t determine_basic_section(const ir_entity *entity)
405 {
406         ir_linkage linkage;
407
408         if (is_method_entity(entity))
409                 return GAS_SECTION_TEXT;
410
411         linkage = get_entity_linkage(entity);
412         if (linkage & IR_LINKAGE_CONSTANT) {
413                 /* mach-o is the only one with a cstring section */
414                 if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O
415                     && entity_is_string_const(entity))
416                         return GAS_SECTION_CSTRING;
417
418                 return GAS_SECTION_RODATA;
419         }
420         if (entity_is_null(entity))
421                 return GAS_SECTION_BSS;
422
423         return GAS_SECTION_DATA;
424 }
425
426 static be_gas_section_t determine_section(be_gas_decl_env_t *env,
427                                           const ir_entity *entity)
428 {
429         ir_type *owner = get_entity_owner(entity);
430
431         if (owner == get_segment_type(IR_SEGMENT_GLOBAL)) {
432                 be_gas_section_t section = determine_basic_section(entity);
433                 if (is_comdat(entity))
434                         section |= GAS_SECTION_FLAG_COMDAT;
435                 return section;
436         } else if (env != NULL && owner == env->main_env->pic_symbols_type) {
437                 return GAS_SECTION_PIC_SYMBOLS;
438         } else if (env != NULL && owner == env->main_env->pic_trampolines_type) {
439                 return GAS_SECTION_PIC_TRAMPOLINES;
440         } else if (owner == get_segment_type(IR_SEGMENT_CONSTRUCTORS)) {
441                 return GAS_SECTION_CONSTRUCTORS;
442         } else if (owner == get_segment_type(IR_SEGMENT_DESTRUCTORS)) {
443                 return GAS_SECTION_DESTRUCTORS;
444         } else if (owner == get_segment_type(IR_SEGMENT_THREAD_LOCAL)) {
445                 be_gas_section_t section = determine_basic_section(entity);
446                 if (is_comdat(entity))
447                         section |= GAS_SECTION_FLAG_COMDAT;
448
449                 return section | GAS_SECTION_FLAG_TLS;
450         }
451
452         /* the java frontend keeps some functions inside classes */
453         if (is_Class_type(owner)) {
454                 return determine_basic_section(entity);
455         }
456
457         panic("Couldn't determine section for %+F?!?", entity);
458 }
459
460 static void emit_weak(const ir_entity *entity)
461 {
462         if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
463                 be_emit_cstring("\t.weak_reference ");
464         } else {
465                 be_emit_cstring("\t.weak ");
466         }
467         be_gas_emit_entity(entity);
468         be_emit_char('\n');
469         be_emit_write_line();
470 }
471
472 static void emit_visibility(const ir_entity *entity)
473 {
474         ir_linkage const linkage = get_entity_linkage(entity);
475
476         if (linkage & IR_LINKAGE_WEAK) {
477                 emit_weak(entity);
478                 /* Note: .weak seems to imply .globl so no need to output .globl */
479         } else if (get_entity_visibility(entity) == ir_visibility_external
480                    && entity_has_definition(entity)) {
481                 be_emit_cstring("\t.globl ");
482                 be_gas_emit_entity(entity);
483                 be_emit_char('\n');
484                 be_emit_write_line();
485         }
486
487         if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O
488                         && (linkage & IR_LINKAGE_HIDDEN_USER)
489                         && get_entity_ld_name(entity)[0] != '\0') {
490                 be_emit_cstring("\t.no_dead_strip ");
491                 be_gas_emit_entity(entity);
492                 be_emit_char('\n');
493                 be_emit_write_line();
494         }
495 }
496
497 void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment, const parameter_dbg_info_t *parameter_infos)
498 {
499         be_gas_section_t section;
500
501         be_dwarf_method_before(entity, parameter_infos);
502
503         section = determine_section(NULL, entity);
504         emit_section(section, entity);
505
506         /* write the begin line (makes the life easier for scripts parsing the
507          * assembler) */
508         if (be_options.verbose_asm) {
509                 be_emit_cstring("# -- Begin  ");
510                 be_gas_emit_entity(entity);
511                 be_emit_char('\n');
512                 be_emit_write_line();
513         }
514
515         if (po2alignment > 0) {
516                 const char *fill_byte = "";
517                 unsigned    maximum_skip = (1 << po2alignment) - 1;
518                 /* gcc fills space between function with 0x90... */
519                 if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
520                         fill_byte = "0x90";
521                 }
522                 be_emit_cstring("\t.p2align ");
523                 be_emit_irprintf("%u,%s,%u\n", po2alignment, fill_byte, maximum_skip);
524                 be_emit_write_line();
525         }
526         emit_visibility(entity);
527
528         switch (be_gas_object_file_format) {
529         case OBJECT_FILE_FORMAT_ELF:
530                 be_emit_cstring("\t.type\t");
531                 be_gas_emit_entity(entity);
532                 be_emit_cstring(", ");
533                 be_emit_char(be_gas_elf_type_char);
534                 be_emit_cstring("function\n");
535                 be_emit_write_line();
536                 break;
537         case OBJECT_FILE_FORMAT_COFF:
538                 be_emit_cstring("\t.def\t");
539                 be_gas_emit_entity(entity);
540                 be_emit_cstring(";");
541                 if (get_entity_visibility(entity) == ir_visibility_local) {
542                         be_emit_cstring("\t.scl\t3;");
543                 } else {
544                         be_emit_cstring("\t.scl\t2;");
545                 }
546                 be_emit_cstring("\t.type\t32;\t.endef\n");
547                 be_emit_write_line();
548                 break;
549         case OBJECT_FILE_FORMAT_MACH_O:
550                 break;
551         }
552         be_gas_emit_entity(entity);
553         be_emit_cstring(":\n");
554         be_emit_write_line();
555
556         be_dwarf_method_begin();
557 }
558
559 void be_gas_emit_function_epilog(const ir_entity *entity)
560 {
561         be_dwarf_method_end();
562
563         if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF) {
564                 be_emit_cstring("\t.size\t");
565                 be_gas_emit_entity(entity);
566                 be_emit_cstring(", .-");
567                 be_gas_emit_entity(entity);
568                 be_emit_char('\n');
569                 be_emit_write_line();
570         }
571
572         if (be_options.verbose_asm) {
573                 be_emit_cstring("# -- End  ");
574                 be_gas_emit_entity(entity);
575                 be_emit_char('\n');
576                 be_emit_write_line();
577         }
578
579         be_emit_char('\n');
580         be_emit_write_line();
581
582         next_block_nr += 199;
583         next_block_nr -= next_block_nr % 100;
584 }
585
586 /**
587  * Output a tarval.
588  *
589  * @param tv     the tarval
590  * @param bytes  the width of the tarvals value in bytes
591  */
592 static void emit_arith_tarval(ir_tarval *tv, unsigned bytes)
593 {
594         switch (bytes) {
595         case 1:
596                 be_emit_irprintf("0x%02x", get_tarval_sub_bits(tv, 0));
597                 return;
598
599         case 2:
600                 be_emit_irprintf("0x%02x%02x",
601                         get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
602                 return;
603
604         case 4:
605                 be_emit_irprintf("0x%02x%02x%02x%02x",
606                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
607                         get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
608                 return;
609
610         case 8:
611                 be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x",
612                         get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
613                         get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
614                         get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
615                         get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
616                 return;
617         }
618
619         panic("Can't dump a tarval with %d bytes", bytes);
620 }
621
622 /**
623  * Return the label prefix for labeled instructions.
624  */
625 const char *be_gas_insn_label_prefix(void)
626 {
627         return ".LE";
628 }
629
630 /**
631  * Dump an atomic value.
632  *
633  * @param env   the gas output environment
634  * @param init  a node representing the atomic value (on the const code irg)
635  */
636 static void emit_init_expression(be_gas_decl_env_t *env, ir_node *init)
637 {
638         ir_mode *mode = get_irn_mode(init);
639         int bytes     = get_mode_size_bytes(mode);
640         ir_tarval *tv;
641         ir_entity *ent;
642
643         init = skip_Id(init);
644
645         switch (get_irn_opcode(init)) {
646         case iro_Conv:
647                 emit_init_expression(env, get_Conv_op(init));
648                 return;
649
650         case iro_Const:
651                 tv = get_Const_tarval(init);
652
653                 /* it's an arithmetic value */
654                 emit_arith_tarval(tv, bytes);
655                 return;
656
657         case iro_SymConst:
658                 switch (get_SymConst_kind(init)) {
659                 case symconst_addr_ent:
660                         ent = get_SymConst_entity(init);
661                         be_gas_emit_entity(ent);
662                         break;
663
664                 case symconst_ofs_ent:
665                         ent = get_SymConst_entity(init);
666                         be_emit_irprintf("%d", get_entity_offset(ent));
667                         break;
668
669                 case symconst_type_size:
670                         be_emit_irprintf("%u", get_type_size_bytes(get_SymConst_type(init)));
671                         break;
672
673                 case symconst_type_align:
674                         be_emit_irprintf("%u", get_type_alignment_bytes(get_SymConst_type(init)));
675                         break;
676
677                 case symconst_enum_const:
678                         tv = get_enumeration_value(get_SymConst_enum(init));
679                         emit_arith_tarval(tv, bytes);
680                         break;
681
682                 default:
683                         assert(!"emit_atomic_init(): don't know how to init from this SymConst");
684                 }
685                 return;
686
687         case iro_Add:
688                 if (!mode_is_int(mode) && !mode_is_reference(mode)) {
689                         panic("Constant must be int or pointer for '+' to work");
690                 }
691                 emit_init_expression(env, get_Add_left(init));
692                 be_emit_cstring(" + ");
693                 emit_init_expression(env, get_Add_right(init));
694                 return;
695
696         case iro_Sub:
697                 if (!mode_is_int(mode) && !mode_is_reference(mode)) {
698                         panic("Constant must be int or pointer for '-' to work");
699                 }
700                 emit_init_expression(env, get_Sub_left(init));
701                 be_emit_cstring(" - ");
702                 emit_init_expression(env, get_Sub_right(init));
703                 return;
704
705         case iro_Mul:
706                 if (!mode_is_int(mode) && !mode_is_reference(mode)) {
707                         panic("Constant must be int or pointer for '*' to work");
708                 }
709                 emit_init_expression(env, get_Mul_left(init));
710                 be_emit_cstring(" * ");
711                 emit_init_expression(env, get_Mul_right(init));
712                 return;
713
714         case iro_Unknown:
715                 be_emit_cstring("0");
716                 return;
717
718         default:
719                 panic("unsupported IR-node %+F", init);
720         }
721 }
722
723 /**
724  * Dumps the type for given size (.byte, .long, ...)
725  *
726  * @param size  the size in bytes
727  */
728 static void emit_size_type(size_t size)
729 {
730         switch (size) {
731         case 1: be_emit_cstring("\t.byte\t");  break;
732         case 2: be_emit_cstring("\t.short\t"); break;
733         case 4: be_emit_cstring("\t.long\t");  break;
734         case 8: be_emit_cstring("\t.quad\t");  break;
735
736         default:
737                 panic("Try to dump a type with %u bytes", (unsigned)size);
738         }
739 }
740
741 static void emit_string_char(int c)
742 {
743         switch (c) {
744         case '"' : be_emit_cstring("\\\""); break;
745         case '\n': be_emit_cstring("\\n"); break;
746         case '\r': be_emit_cstring("\\r"); break;
747         case '\t': be_emit_cstring("\\t"); break;
748         case '\\': be_emit_cstring("\\\\"); break;
749         default  :
750                 if (isprint(c))
751                         be_emit_char(c);
752                 else
753                         be_emit_irprintf("\\%03o", c);
754                 break;
755         }
756 }
757
758 static size_t emit_string_initializer(const ir_initializer_t *initializer)
759 {
760         be_emit_cstring("\t.asciz \"");
761
762         size_t len = initializer->compound.n_initializers;
763         for (size_t i = 0; i < len-1; ++i) {
764                 const ir_initializer_t *sub_initializer
765                         = get_initializer_compound_value(initializer, i);
766
767                 ir_tarval *tv = get_initializer_tarval(sub_initializer);
768                 int        c  = get_tarval_long(tv);
769                 emit_string_char(c);
770         }
771         be_emit_cstring("\"\n");
772         be_emit_write_line();
773
774         return initializer->compound.n_initializers;
775 }
776
777 void be_gas_emit_cstring(const char *string)
778 {
779         be_emit_cstring("\t.asciz \"");
780         for (const char *c = string; *c != '\0'; ++c) {
781                 emit_string_char(*c);
782         }
783         be_emit_cstring("\"\n");
784         be_emit_write_line();
785 }
786
787 typedef enum normal_or_bitfield_kind {
788         NORMAL = 0,
789         TARVAL,
790         STRING,
791         BITFIELD
792 } normal_or_bitfield_kind;
793
794 typedef struct {
795         normal_or_bitfield_kind kind;
796         ir_type                *type;
797         union {
798                 ir_node                *value;
799                 ir_tarval              *tarval;
800                 unsigned char           bf_val;
801                 const ir_initializer_t *string;
802         } v;
803 } normal_or_bitfield;
804
805 static size_t get_initializer_size(const ir_initializer_t *initializer,
806                                    ir_type *type)
807 {
808         switch (get_initializer_kind(initializer)) {
809         case IR_INITIALIZER_TARVAL:
810                 assert(get_tarval_mode(get_initializer_tarval_value(initializer)) == get_type_mode(type));
811                 return get_type_size_bytes(type);
812         case IR_INITIALIZER_CONST:
813         case IR_INITIALIZER_NULL:
814                 return get_type_size_bytes(type);
815         case IR_INITIALIZER_COMPOUND:
816                 if (is_Array_type(type)) {
817                         if (is_array_variable_size(type)) {
818                                 ir_type   *element_type = get_array_element_type(type);
819                                 unsigned   element_size = get_type_size_bytes(element_type);
820                                 unsigned   element_align
821                                         = get_type_alignment_bytes(element_type);
822                                 unsigned   misalign     = element_size % element_align;
823                                 size_t     n_inits
824                                         = get_initializer_compound_n_entries(initializer);
825                                 element_size += element_align - misalign;
826                                 return n_inits * element_size;
827                         } else {
828                                 return get_type_size_bytes(type);
829                         }
830                 } else {
831                         assert(is_compound_type(type));
832                         size_t size = get_type_size_bytes(type);
833                         if (is_compound_variable_size(type)) {
834                                 /* last initializer has to be an array of variable size */
835                                 size_t l = get_initializer_compound_n_entries(initializer)-1;
836                                 const ir_initializer_t *last
837                                         = get_initializer_compound_value(initializer, l);
838                                 const ir_entity *last_ent  = get_compound_member(type, l);
839                                 ir_type         *last_type = get_entity_type(last_ent);
840                                 assert(is_array_variable_size(last_type));
841                                 size += get_initializer_size(last, last_type);
842                         }
843                         return size;
844                 }
845         }
846
847         panic("found invalid initializer");
848 }
849
850 #ifndef NDEBUG
851 static normal_or_bitfield *glob_vals;
852 static size_t              max_vals;
853 #endif
854
855 static void emit_bitfield(normal_or_bitfield *vals, size_t offset_bits,
856                           const ir_initializer_t *initializer, ir_type *type)
857 {
858         static const size_t BITS_PER_BYTE = 8;
859         ir_mode   *mode      = get_type_mode(type);
860         ir_tarval *tv        = NULL;
861         int        value_len;
862         size_t     bit_offset;
863         size_t     end;
864         bool       big_endian = be_get_backend_param()->byte_order_big_endian;
865
866         switch (get_initializer_kind(initializer)) {
867         case IR_INITIALIZER_NULL:
868                 return;
869         case IR_INITIALIZER_TARVAL:
870                 tv = get_initializer_tarval_value(initializer);
871                 break;
872         case IR_INITIALIZER_CONST: {
873                 ir_node *node = get_initializer_const_value(initializer);
874                 if (!is_Const(node)) {
875                         panic("bitfield initializer not a Const node");
876                 }
877                 tv = get_Const_tarval(node);
878                 break;
879         }
880         case IR_INITIALIZER_COMPOUND:
881                 panic("bitfield initializer is compound");
882         }
883         if (tv == NULL) {
884                 panic("Couldn't get numeric value for bitfield initializer");
885         }
886         tv = tarval_convert_to(tv, get_type_mode(type));
887
888         value_len  = get_type_size_bytes(get_primitive_base_type(type));
889         bit_offset = 0;
890         end        = get_mode_size_bits(mode);
891         while (bit_offset < end) {
892                 size_t        src_offset      = bit_offset / BITS_PER_BYTE;
893                 size_t        src_offset_bits = bit_offset % BITS_PER_BYTE;
894                 size_t        dst_offset      = (bit_offset+offset_bits) / BITS_PER_BYTE;
895                 size_t        dst_offset_bits = (bit_offset+offset_bits) % BITS_PER_BYTE;
896                 size_t        src_bits_len    = end-bit_offset;
897                 size_t        dst_bits_len    = BITS_PER_BYTE-dst_offset_bits;
898                 unsigned char curr_bits;
899                 normal_or_bitfield *val;
900                 if (src_bits_len > dst_bits_len)
901                         src_bits_len = dst_bits_len;
902
903                 if (big_endian) {
904                         val = &vals[value_len - dst_offset - 1];
905                 } else {
906                         val = &vals[dst_offset];
907                 }
908
909                 assert((val-glob_vals) < (ptrdiff_t) max_vals);
910                 assert(val->kind == BITFIELD ||
911                                 (val->kind == NORMAL && val->v.value == NULL));
912                 val->kind  = BITFIELD;
913                 curr_bits  = get_tarval_sub_bits(tv, src_offset);
914                 curr_bits  = curr_bits >> src_offset_bits;
915                 if (src_offset_bits + src_bits_len > 8) {
916                         unsigned next_bits = get_tarval_sub_bits(tv, src_offset+1);
917                         curr_bits |= next_bits << (8 - src_offset_bits);
918                 }
919                 curr_bits &= (1 << src_bits_len) - 1;
920                 val->v.bf_val |= curr_bits << dst_offset_bits;
921
922                 bit_offset += dst_bits_len;
923         }
924 }
925
926 static void emit_ir_initializer(normal_or_bitfield *vals,
927                                 const ir_initializer_t *initializer,
928                                 ir_type *type)
929 {
930         assert((size_t) (vals - glob_vals) <= max_vals);
931
932         if (initializer_is_string_const(initializer)) {
933                 assert(vals->kind != BITFIELD);
934                 vals->kind     = STRING;
935                 vals->v.string = initializer;
936                 return;
937         }
938
939         switch (get_initializer_kind(initializer)) {
940         case IR_INITIALIZER_NULL:
941                 return;
942         case IR_INITIALIZER_TARVAL: {
943                 size_t i;
944
945                 assert(vals->kind != BITFIELD);
946                 vals->kind     = TARVAL;
947                 vals->type     = type;
948                 vals->v.tarval = get_initializer_tarval_value(initializer);
949                 assert(get_type_mode(type) == get_tarval_mode(vals->v.tarval));
950                 for (i = 1; i < get_type_size_bytes(type); ++i) {
951                         vals[i].kind    = NORMAL;
952                         vals[i].type    = NULL;
953                         vals[i].v.value = NULL;
954                 }
955                 return;
956         }
957         case IR_INITIALIZER_CONST: {
958                 size_t i;
959
960                 assert(vals->kind != BITFIELD);
961                 vals->kind    = NORMAL;
962                 vals->type    = type;
963                 vals->v.value = get_initializer_const_value(initializer);
964                 for (i = 1; i < get_type_size_bytes(type); ++i) {
965                         vals[i].kind    = NORMAL;
966                         vals[i].type    = NULL;
967                         vals[i].v.value = NULL;
968                 }
969                 return;
970         }
971         case IR_INITIALIZER_COMPOUND: {
972                 size_t i = 0;
973                 size_t n = get_initializer_compound_n_entries(initializer);
974
975                 if (is_Array_type(type)) {
976                         ir_type *element_type = get_array_element_type(type);
977                         size_t   skip         = get_type_size_bytes(element_type);
978                         size_t   alignment    = get_type_alignment_bytes(element_type);
979                         size_t   misalign     = skip % alignment;
980                         if (misalign != 0) {
981                                 skip += alignment - misalign;
982                         }
983
984                         for (i = 0; i < n; ++i) {
985                                 ir_initializer_t *sub_initializer
986                                         = get_initializer_compound_value(initializer, i);
987
988                                 emit_ir_initializer(vals, sub_initializer, element_type);
989
990                                 vals += skip;
991                         }
992                 } else {
993                         size_t n_members, i;
994                         assert(is_compound_type(type));
995                         n_members = get_compound_n_members(type);
996                         for (i = 0; i < n_members; ++i) {
997                                 ir_entity        *member    = get_compound_member(type, i);
998                                 size_t            offset    = get_entity_offset(member);
999                                 ir_type          *subtype   = get_entity_type(member);
1000                                 ir_mode          *mode      = get_type_mode(subtype);
1001                                 ir_initializer_t *sub_initializer;
1002
1003                                 assert(i < get_initializer_compound_n_entries(initializer));
1004                                 sub_initializer
1005                                         = get_initializer_compound_value(initializer, i);
1006
1007                                 if (mode != NULL) {
1008                                         size_t offset_bits
1009                                                 = get_entity_offset_bits_remainder(member);
1010
1011                                         if (is_Primitive_type(subtype)
1012                                                         && get_primitive_base_type(subtype) != NULL) {
1013                                                 emit_bitfield(&vals[offset], offset_bits,
1014                                                               sub_initializer, subtype);
1015                                                 continue;
1016                                         } else {
1017                                                 assert(offset_bits == 0);
1018                                         }
1019                                 }
1020
1021                                 emit_ir_initializer(&vals[offset], sub_initializer, subtype);
1022                         }
1023                 }
1024
1025                 return;
1026         }
1027         }
1028         panic("invalid ir_initializer kind found");
1029 }
1030
1031 static void emit_tarval_data(ir_type *type, ir_tarval *tv)
1032 {
1033         size_t size = get_type_size_bytes(type);
1034         if (size == 12) {
1035                 /* this should be an x86 extended float */
1036                 assert(be_get_backend_param()->byte_order_big_endian == 0);
1037
1038                 /* Beware: Mixed endian output!  One little endian number emitted as
1039                  * three longs.  Each long initializer is written in big endian. */
1040                 be_emit_irprintf(
1041                         "\t.long\t0x%02x%02x%02x%02x\n"
1042                         "\t.long\t0x%02x%02x%02x%02x\n"
1043                         "\t.long\t0x%02x%02x%02x%02x\n",
1044                         get_tarval_sub_bits(tv,  3), get_tarval_sub_bits(tv,  2),
1045                         get_tarval_sub_bits(tv,  1), get_tarval_sub_bits(tv,  0),
1046                         get_tarval_sub_bits(tv,  7), get_tarval_sub_bits(tv,  6),
1047                         get_tarval_sub_bits(tv,  5), get_tarval_sub_bits(tv,  4),
1048                         get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
1049                         get_tarval_sub_bits(tv,  9), get_tarval_sub_bits(tv,  8)
1050                 );
1051                 be_emit_write_line();
1052         } else if (size == 16) {
1053                 if (be_get_backend_param()->byte_order_big_endian) {
1054                         be_emit_irprintf(
1055                                 "\t.long\t0x%02x%02x%02x%02x\n"
1056                                 "\t.long\t0x%02x%02x%02x%02x\n"
1057                                 "\t.long\t0x%02x%02x%02x%02x\n"
1058                                 "\t.long\t0x%02x%02x%02x%02x\n",
1059                                 get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
1060                                 get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
1061                                 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
1062                                 get_tarval_sub_bits(tv,  9), get_tarval_sub_bits(tv,  8),
1063                                 get_tarval_sub_bits(tv,  7), get_tarval_sub_bits(tv,  6),
1064                                 get_tarval_sub_bits(tv,  5), get_tarval_sub_bits(tv,  4),
1065                                 get_tarval_sub_bits(tv,  3), get_tarval_sub_bits(tv,  2),
1066                                 get_tarval_sub_bits(tv,  1), get_tarval_sub_bits(tv,  0)
1067                         );
1068                 } else {
1069                         /* Beware: Mixed endian output! One little endian number emitted as
1070                          * three longs.  Each long initializer is written in big endian. */
1071                         be_emit_irprintf(
1072                                 "\t.long\t0x%02x%02x%02x%02x\n"
1073                                 "\t.long\t0x%02x%02x%02x%02x\n"
1074                                 "\t.long\t0x%02x%02x%02x%02x\n"
1075                                 "\t.long\t0x%02x%02x%02x%02x\n",
1076                                 get_tarval_sub_bits(tv,  3), get_tarval_sub_bits(tv,  2),
1077                                 get_tarval_sub_bits(tv,  1), get_tarval_sub_bits(tv,  0),
1078                                 get_tarval_sub_bits(tv,  7), get_tarval_sub_bits(tv,  6),
1079                                 get_tarval_sub_bits(tv,  5), get_tarval_sub_bits(tv,  4),
1080                                 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
1081                                 get_tarval_sub_bits(tv,  9), get_tarval_sub_bits(tv,  8),
1082                                 get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
1083                                 get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12)
1084                         );
1085                 }
1086                 be_emit_write_line();
1087                 return;
1088         } else {
1089                 /* default case */
1090                 emit_size_type(size);
1091                 emit_arith_tarval(tv, size);
1092                 be_emit_char('\n');
1093                 be_emit_write_line();
1094         }
1095 }
1096
1097 /**
1098  * Emit an atomic value.
1099  *
1100  * @param env   the gas output environment
1101  * @param init  a node representing the atomic value (on the const code irg)
1102  */
1103 static void emit_node_data(be_gas_decl_env_t *env, ir_node *init, ir_type *type)
1104 {
1105         size_t size = get_type_size_bytes(type);
1106         if (size == 12 || size == 16) {
1107                 ir_tarval *tv;
1108                 if (!is_Const(init)) {
1109                         panic("12/16byte initializers only support Const nodes yet");
1110                 }
1111                 tv = get_Const_tarval(init);
1112                 emit_tarval_data(type, tv);
1113                 return;
1114         }
1115
1116         emit_size_type(size);
1117         emit_init_expression(env, init);
1118         be_emit_char('\n');
1119         be_emit_write_line();
1120 }
1121
1122 static void emit_initializer(be_gas_decl_env_t *env, const ir_entity *entity)
1123 {
1124         const ir_initializer_t *initializer = entity->initializer;
1125         ir_type                *type;
1126         normal_or_bitfield     *vals;
1127         size_t                  size;
1128         size_t                  k;
1129
1130         if (initializer_is_string_const(initializer)) {
1131                 emit_string_initializer(initializer);
1132                 return;
1133         }
1134
1135         type = get_entity_type(entity);
1136         size = get_initializer_size(initializer, type);
1137
1138         if (size == 0)
1139                 return;
1140
1141         /*
1142          * In the worst case, every initializer allocates one byte.
1143          * Moreover, initializer might be big, do not allocate on stack.
1144          */
1145         vals = XMALLOCNZ(normal_or_bitfield, size);
1146
1147 #ifndef NDEBUG
1148         glob_vals = vals;
1149         max_vals  = size;
1150 #endif
1151
1152         emit_ir_initializer(vals, initializer, type);
1153
1154         /* now write values sorted */
1155         for (k = 0; k < size; ) {
1156                 int                     space     = 0;
1157                 normal_or_bitfield_kind kind      = vals[k].kind;
1158                 int                     elem_size;
1159                 switch (kind) {
1160                 case NORMAL:
1161                         if (vals[k].v.value != NULL) {
1162                                 emit_node_data(env, vals[k].v.value, vals[k].type);
1163                                 elem_size = get_type_size_bytes(vals[k].type);
1164                         } else {
1165                                 elem_size = 0;
1166                         }
1167                         break;
1168                 case TARVAL:
1169                         emit_tarval_data(vals[k].type, vals[k].v.tarval);
1170                         elem_size = get_type_size_bytes(vals[k].type);
1171                         break;
1172                 case STRING:
1173                         elem_size = emit_string_initializer(vals[k].v.string);
1174                         break;
1175                 case BITFIELD:
1176                         be_emit_irprintf("\t.byte\t%d\n", vals[k].v.bf_val);
1177                         be_emit_write_line();
1178                         elem_size = 1;
1179                         break;
1180                 default:
1181                         panic("internal compiler error (invalid normal_or_bitfield_kind");
1182                 }
1183
1184                 k += elem_size;
1185                 while (k < size && vals[k].kind == NORMAL && vals[k].v.value == NULL) {
1186                         ++space;
1187                         ++k;
1188                 }
1189
1190                 /* a gap */
1191                 if (space > 0) {
1192                         be_emit_irprintf("\t.space\t%d, 0\n", space);
1193                         be_emit_write_line();
1194                 }
1195         }
1196         xfree(vals);
1197 }
1198
1199 static void emit_align(unsigned p2alignment)
1200 {
1201         be_emit_irprintf("\t.p2align\t%u\n", log2_floor(p2alignment));
1202         be_emit_write_line();
1203 }
1204
1205 static unsigned get_effective_entity_alignment(const ir_entity *entity)
1206 {
1207         unsigned alignment = get_entity_alignment(entity);
1208         if (alignment == 0) {
1209                 ir_type *type = get_entity_type(entity);
1210                 alignment     = get_type_alignment_bytes(type);
1211         }
1212         return alignment;
1213 }
1214
1215 static void emit_common(const ir_entity *entity)
1216 {
1217         unsigned size      = get_type_size_bytes(get_entity_type(entity));
1218         unsigned alignment = get_effective_entity_alignment(entity);
1219
1220         if (get_entity_linkage(entity) & IR_LINKAGE_WEAK) {
1221                 emit_weak(entity);
1222         }
1223
1224         switch (be_gas_object_file_format) {
1225         case OBJECT_FILE_FORMAT_MACH_O:
1226                 be_emit_cstring("\t.comm ");
1227                 be_gas_emit_entity(entity);
1228                 be_emit_irprintf(",%u,%u\n", size, log2_floor(alignment));
1229                 be_emit_write_line();
1230                 return;
1231         case OBJECT_FILE_FORMAT_ELF:
1232                 be_emit_cstring("\t.comm ");
1233                 be_gas_emit_entity(entity);
1234                 be_emit_irprintf(",%u,%u\n", size, alignment);
1235                 be_emit_write_line();
1236                 return;
1237         case OBJECT_FILE_FORMAT_COFF:
1238                 be_emit_cstring("\t.comm ");
1239                 be_gas_emit_entity(entity);
1240                 be_emit_irprintf(",%u # %u\n", size, alignment);
1241                 be_emit_write_line();
1242                 return;
1243         }
1244         panic("invalid object file format");
1245 }
1246
1247 static void emit_local_common(const ir_entity *entity)
1248 {
1249         unsigned size      = get_type_size_bytes(get_entity_type(entity));
1250         unsigned alignment = get_effective_entity_alignment(entity);
1251
1252         if (get_entity_linkage(entity) & IR_LINKAGE_WEAK) {
1253                 emit_weak(entity);
1254         }
1255
1256         switch (be_gas_object_file_format) {
1257         case OBJECT_FILE_FORMAT_MACH_O:
1258                 be_emit_cstring("\t.lcomm ");
1259                 be_gas_emit_entity(entity);
1260                 be_emit_irprintf(",%u,%u\n", size, log2_floor(alignment));
1261                 be_emit_write_line();
1262                 return;
1263         case OBJECT_FILE_FORMAT_ELF:
1264                 be_emit_cstring("\t.local ");
1265                 be_gas_emit_entity(entity);
1266                 be_emit_cstring("\n");
1267                 be_emit_write_line();
1268                 be_emit_cstring("\t.comm ");
1269                 be_gas_emit_entity(entity);
1270                 be_emit_irprintf(",%u,%u\n", size, alignment);
1271                 be_emit_write_line();
1272                 return;
1273         case OBJECT_FILE_FORMAT_COFF:
1274                 be_emit_cstring("\t.lcomm ");
1275                 be_gas_emit_entity(entity);
1276                 be_emit_irprintf(",%u # %u\n", size, alignment);
1277                 be_emit_write_line();
1278                 return;
1279         }
1280         panic("invalid object file format");
1281 }
1282
1283 static void emit_indirect_symbol(const ir_entity *entity, be_gas_section_t section)
1284 {
1285         /* we can only do PIC code on macho so far */
1286         assert(be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O);
1287
1288         be_gas_emit_entity(entity);
1289         be_emit_cstring(":\n");
1290         be_emit_write_line();
1291         be_emit_irprintf("\t.indirect_symbol %I\n", get_entity_ident(entity));
1292         be_emit_write_line();
1293         if (section == GAS_SECTION_PIC_TRAMPOLINES) {
1294                 be_emit_cstring("\thlt ; hlt ; hlt ; hlt ; hlt\n");
1295                 be_emit_write_line();
1296         } else {
1297                 assert(section == GAS_SECTION_PIC_SYMBOLS);
1298                 be_emit_cstring("\t.long 0\n");
1299                 be_emit_write_line();
1300         }
1301 }
1302
1303 char const *be_gas_get_private_prefix(void)
1304 {
1305         return be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O ? "L" : ".L";
1306 }
1307
1308 void be_gas_emit_entity(const ir_entity *entity)
1309 {
1310         if (entity->type == get_code_type()) {
1311                 ir_label_t label = get_entity_label(entity);
1312                 be_emit_irprintf("%s_%lu", be_gas_get_private_prefix(), label);
1313                 return;
1314         }
1315
1316         if (get_entity_visibility(entity) == ir_visibility_private) {
1317                 be_emit_string(be_gas_get_private_prefix());
1318         }
1319         be_emit_irprintf("%I", get_entity_ld_ident(entity));
1320 }
1321
1322 void be_gas_emit_block_name(const ir_node *block)
1323 {
1324         ir_entity *entity = get_Block_entity(block);
1325         if (entity != NULL) {
1326                 be_gas_emit_entity(entity);
1327         } else {
1328                 void *nr_val = pmap_get(void, block_numbers, block);
1329                 int   nr;
1330                 if (nr_val == NULL) {
1331                         nr = next_block_nr++;
1332                         pmap_insert(block_numbers, block, INT_TO_PTR(nr+1));
1333                 } else {
1334                         nr = PTR_TO_INT(nr_val)-1;
1335                 }
1336                 be_emit_irprintf("%s%d", be_gas_get_private_prefix(), nr);
1337         }
1338 }
1339
1340 void be_gas_begin_block(const ir_node *block, bool needs_label)
1341 {
1342         if (needs_label) {
1343                 be_gas_emit_block_name(block);
1344                 be_emit_char(':');
1345         } else {
1346                 if (!be_options.verbose_asm)
1347                         return;
1348                 be_emit_cstring("/*");
1349                 be_gas_emit_block_name(block);
1350                 be_emit_cstring(":*/");
1351         }
1352
1353         if (be_options.verbose_asm) {
1354                 be_emit_pad_comment();
1355                 be_emit_irprintf("/* %+F preds:", block);
1356
1357                 int arity = get_irn_arity(block);
1358                 if (arity == 0) {
1359                         be_emit_cstring(" none");
1360                 } else {
1361                         int i;
1362                         for (i = 0; i < arity; ++i) {
1363                                 ir_node *predblock = get_Block_cfgpred_block(block, i);
1364                                 be_emit_char(' ');
1365                                 be_gas_emit_block_name(predblock);
1366                         }
1367                 }
1368                 be_emit_irprintf(", freq: %.3f */", get_block_execfreq(block));
1369         }
1370         be_emit_char('\n');
1371         be_emit_write_line();
1372 }
1373
1374 /**
1375  * Dump a global entity.
1376  *
1377  * @param env  the gas output environment
1378  * @param ent  the entity to be dumped
1379  */
1380 static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity)
1381 {
1382         ir_type          *type       = get_entity_type(entity);
1383         ident            *ld_ident   = get_entity_ld_ident(entity);
1384         unsigned          alignment  = get_effective_entity_alignment(entity);
1385         be_gas_section_t  section    = determine_section(env, entity);
1386         ir_visibility     visibility = get_entity_visibility(entity);
1387         ir_linkage        linkage    = get_entity_linkage(entity);
1388
1389         /* Block labels are already emitted in the code. */
1390         if (type == get_code_type())
1391                 return;
1392
1393         /* we already emitted all methods with graphs in other functions like
1394          * be_gas_emit_function_prolog(). All others don't need to be emitted.
1395          */
1396         if (is_Method_type(type) && section != GAS_SECTION_PIC_TRAMPOLINES) {
1397                 return;
1398         }
1399
1400         be_dwarf_variable(entity);
1401
1402         if (section == GAS_SECTION_BSS) {
1403                 switch (visibility) {
1404                 case ir_visibility_local:
1405                 case ir_visibility_private:
1406                         emit_local_common(entity);
1407                         return;
1408                 case ir_visibility_external:
1409                         if (linkage & IR_LINKAGE_MERGE) {
1410                                 emit_common(entity);
1411                                 return;
1412                         }
1413                         break;
1414                 }
1415         }
1416
1417         emit_visibility(entity);
1418
1419         if (!is_po2(alignment))
1420                 panic("alignment not a power of 2");
1421
1422         emit_section(section, entity);
1423
1424         if (section == GAS_SECTION_PIC_TRAMPOLINES
1425                         || section == GAS_SECTION_PIC_SYMBOLS) {
1426                 emit_indirect_symbol(entity, section);
1427                 return;
1428         }
1429
1430         /* nothing left to do without an initializer */
1431         if (!entity_has_definition(entity))
1432                 return;
1433
1434         /* alignment */
1435         if (alignment > 1) {
1436                 emit_align(alignment);
1437         }
1438         if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF
1439                         && be_gas_emit_types
1440                         && visibility != ir_visibility_private) {
1441                 be_emit_cstring("\t.type\t");
1442                 be_gas_emit_entity(entity);
1443                 be_emit_cstring(", ");
1444                 be_emit_char(be_gas_elf_type_char);
1445                 be_emit_cstring("object\n\t.size\t");\
1446                 be_gas_emit_entity(entity);
1447                 be_emit_irprintf(", %u\n", get_type_size_bytes(type));
1448         }
1449
1450         if (get_id_str(ld_ident)[0] != '\0') {
1451                 be_gas_emit_entity(entity);
1452                 be_emit_cstring(":\n");
1453                 be_emit_write_line();
1454         }
1455
1456         if (entity_is_null(entity)) {
1457                 /* we should use .space for stuff in the bss segment */
1458                 unsigned size = get_type_size_bytes(type);
1459                 if (size > 0) {
1460                         be_emit_irprintf("\t.space %u, 0\n", get_type_size_bytes(type));
1461                         be_emit_write_line();
1462                 }
1463         } else {
1464                 assert(entity->initializer != NULL);
1465                 emit_initializer(env, entity);
1466         }
1467 }
1468
1469 /**
1470  * Dumps declarations of global variables and the initialization code.
1471  *
1472  * @param gt                a global like type, either the global or the TLS one
1473  * @param env               an environment
1474  */
1475 static void be_gas_emit_globals(ir_type *gt, be_gas_decl_env_t *env)
1476 {
1477         size_t i, n = get_compound_n_members(gt);
1478
1479         for (i = 0; i < n; i++) {
1480                 ir_entity *ent = get_compound_member(gt, i);
1481                 emit_global(env, ent);
1482         }
1483 }
1484
1485 /* Generate all entities. */
1486 static void emit_global_decls(const be_main_env_t *main_env)
1487 {
1488         be_gas_decl_env_t env;
1489         memset(&env, 0, sizeof(env));
1490
1491         /* dump global type */
1492         env.main_env = main_env;
1493         env.section  = (be_gas_section_t) -1;
1494
1495         be_gas_emit_globals(get_glob_type(), &env);
1496         be_gas_emit_globals(get_tls_type(), &env);
1497         be_gas_emit_globals(get_segment_type(IR_SEGMENT_CONSTRUCTORS), &env);
1498         be_gas_emit_globals(get_segment_type(IR_SEGMENT_DESTRUCTORS), &env);
1499         be_gas_emit_globals(main_env->pic_symbols_type, &env);
1500         be_gas_emit_globals(main_env->pic_trampolines_type, &env);
1501
1502         /**
1503          * ".subsections_via_symbols marks object files which are OK to divide
1504          * their section contents into individual blocks".
1505          * From my understanding this means no label points in the middle of an
1506          * object which we want to address as a whole. Firm code should be fine
1507          * with this.
1508          */
1509         if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
1510                 be_emit_cstring("\t.subsections_via_symbols\n");
1511                 be_emit_write_line();
1512         }
1513 }
1514
1515 void be_emit_jump_table(const ir_node *node, const ir_switch_table *table,
1516                         ir_entity *entity, get_cfop_target_func get_cfop_target)
1517 {
1518         unsigned        n_outs    = arch_get_irn_n_outs(node);
1519         const ir_node **targets   = XMALLOCNZ(const ir_node*, n_outs);
1520         size_t          n_entries = ir_switch_table_get_n_entries(table);
1521         unsigned long   length    = 0;
1522         size_t          e;
1523         unsigned        i;
1524         const ir_node **labels;
1525
1526         /* go over all proj's and collect their jump targets */
1527         foreach_out_edge(node, edge) {
1528                 ir_node *proj   = get_edge_src_irn(edge);
1529                 long     pn     = get_Proj_proj(proj);
1530                 ir_node *target = get_cfop_target(proj);
1531                 assert(targets[pn] == NULL);
1532                 targets[pn] = target;
1533         }
1534
1535         /* go over table to determine max value (note that we normalized the
1536          * ranges so that the minimum is 0) */
1537         for (e = 0; e < n_entries; ++e) {
1538                 const ir_switch_table_entry *entry
1539                         = ir_switch_table_get_entry_const(table, e);
1540                 ir_tarval *max = entry->max;
1541                 unsigned long val;
1542                 if (entry->pn == 0)
1543                         continue;
1544                 if (!tarval_is_long(max))
1545                         panic("switch case overflow (%+F)", node);
1546                 val = (unsigned long) get_tarval_long(max);
1547                 if (val > length) {
1548                         length = val;
1549                 }
1550         }
1551
1552         /* the 16000 isn't a real limit of the architecture. But should protect us
1553          * from seamingly endless compiler runs */
1554         if (length > 16000) {
1555                 /* switch lowerer should have broken this monster to pieces... */
1556                 panic("too large switch encountered (%+F)", node);
1557         }
1558         ++length;
1559
1560         labels = XMALLOCNZ(const ir_node*, length);
1561         for (e = 0; e < n_entries; ++e) {
1562                 const ir_switch_table_entry *entry
1563                         = ir_switch_table_get_entry_const(table, e);
1564                 ir_tarval     *min    = entry->min;
1565                 ir_tarval     *max    = entry->max;
1566                 const ir_node *target = targets[entry->pn];
1567                 assert(entry->pn < (long)n_outs);
1568                 if (min == max) {
1569                         unsigned long val = (unsigned long)get_tarval_long(max);
1570                         labels[val] = target;
1571                 } else {
1572                         unsigned long min_val;
1573                         unsigned long max_val;
1574                         unsigned long i;
1575                         if (!tarval_is_long(min))
1576                                 panic("switch case overflow (%+F)", node);
1577                         min_val = (unsigned long)get_tarval_long(min);
1578                         max_val = (unsigned long)get_tarval_long(max);
1579                         assert(min_val <= max_val);
1580                         for (i = min_val; i <= max_val; ++i) {
1581                                 labels[i] = target;
1582                         }
1583                 }
1584         }
1585
1586         /* emit table */
1587         if (entity != NULL) {
1588                 be_gas_emit_switch_section(GAS_SECTION_RODATA);
1589                 be_emit_cstring("\t.align 4\n");
1590                 be_gas_emit_entity(entity);
1591                 be_emit_cstring(":\n");
1592         }
1593
1594         for (i = 0; i < length; ++i) {
1595                 const ir_node *block = labels[i];
1596                 if (block == NULL)
1597                         block = targets[0];
1598                 be_emit_cstring("\t.long ");
1599                 be_gas_emit_block_name(block);
1600                 be_emit_char('\n');
1601                 be_emit_write_line();
1602         }
1603
1604         if (entity != NULL)
1605                 be_gas_emit_switch_section(GAS_SECTION_TEXT);
1606
1607         xfree(labels);
1608         xfree(targets);
1609 }
1610
1611 static void emit_global_asms(void)
1612 {
1613         size_t n = get_irp_n_asms();
1614         size_t i;
1615
1616         be_gas_emit_switch_section(GAS_SECTION_TEXT);
1617         for (i = 0; i < n; ++i) {
1618                 ident *asmtext = get_irp_asm(i);
1619
1620                 be_emit_cstring("#APP\n");
1621                 be_emit_write_line();
1622                 be_emit_irprintf("%I\n", asmtext);
1623                 be_emit_write_line();
1624                 be_emit_cstring("#NO_APP\n");
1625                 be_emit_write_line();
1626         }
1627 }
1628
1629 void be_gas_begin_compilation_unit(const be_main_env_t *env)
1630 {
1631         be_dwarf_open();
1632         be_dwarf_unit_begin(env->cup_name);
1633
1634         block_numbers = pmap_create();
1635         next_block_nr = 0;
1636
1637         emit_global_asms();
1638 }
1639
1640 void be_gas_end_compilation_unit(const be_main_env_t *env)
1641 {
1642         emit_global_decls(env);
1643
1644         pmap_destroy(block_numbers);
1645
1646         be_dwarf_unit_end();
1647         be_dwarf_close();
1648 }