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