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