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
emit_section_macho(be_gas_section_t section)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 } else if (flags & GAS_SECTION_FLAG_COMDAT) {
99 switch (base) {
100 case GAS_SECTION_TEXT: name = "section __TEXT,__textcoal_nt,coalesced,pure_instructions"; break;
101 case GAS_SECTION_BSS:
102 case GAS_SECTION_DATA: name = "section __DATA,__datacoal_nt,coalesced"; break;
103 case GAS_SECTION_RODATA: name = "section __TEXT,__const_coal,coalesced"; break;
104 case GAS_SECTION_CSTRING: name = "section __TEXT,__const_coal,coalesced"; break;
105 default: panic("unsupported scetion type 0x%X", section);
106 }
107 } else if (flags & GAS_SECTION_FLAG_TLS) {
108 panic("thread local storage not supported on macho (section 0x%X)", section);
109 } else {
110 panic("unsupported section type 0x%X", section);
111 }
112 be_emit_irprintf("\t.%s\n", name);
113 be_emit_write_line();
114 }
115
emit_section_sparc(be_gas_section_t section,const ir_entity * entity)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
emit_section(be_gas_section_t section,const ir_entity * entity)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
be_gas_emit_switch_section(be_gas_section_t section)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
get_initializer_tarval(const ir_initializer_t * initializer)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
initializer_is_string_const(const ir_initializer_t * initializer)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
initializer_is_null(const ir_initializer_t * initializer)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 */
entity_is_string_const(const ir_entity * ent)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
entity_is_null(const ir_entity * entity)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
is_comdat(const ir_entity * entity)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
determine_basic_section(const ir_entity * entity)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
determine_section(be_gas_decl_env_t * env,const ir_entity * entity)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
emit_weak(const ir_entity * entity)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
emit_visibility(const ir_entity * entity)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
be_gas_emit_function_prolog(const ir_entity * entity,unsigned po2alignment,const parameter_dbg_info_t * parameter_infos)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
be_gas_emit_function_epilog(const ir_entity * entity)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 += 199;
596 next_block_nr -= next_block_nr % 100;
597 }
598
599 /**
600 * Output a tarval.
601 *
602 * @param tv the tarval
603 * @param bytes the width of the tarvals value in bytes
604 */
emit_arith_tarval(ir_tarval * tv,unsigned bytes)605 static void emit_arith_tarval(ir_tarval *tv, unsigned bytes)
606 {
607 switch (bytes) {
608 case 1:
609 be_emit_irprintf("0x%02x", get_tarval_sub_bits(tv, 0));
610 return;
611
612 case 2:
613 be_emit_irprintf("0x%02x%02x",
614 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
615 return;
616
617 case 4:
618 be_emit_irprintf("0x%02x%02x%02x%02x",
619 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
620 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
621 return;
622
623 case 8:
624 be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x",
625 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
626 get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
627 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
628 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
629 return;
630 }
631
632 panic("Can't dump a tarval with %d bytes", bytes);
633 }
634
635 /**
636 * Return the label prefix for labeled instructions.
637 */
be_gas_insn_label_prefix(void)638 const char *be_gas_insn_label_prefix(void)
639 {
640 return ".LE";
641 }
642
643 /**
644 * Dump an atomic value.
645 *
646 * @param env the gas output environment
647 * @param init a node representing the atomic value (on the const code irg)
648 */
emit_init_expression(be_gas_decl_env_t * env,ir_node * init)649 static void emit_init_expression(be_gas_decl_env_t *env, ir_node *init)
650 {
651 ir_mode *mode = get_irn_mode(init);
652 int bytes = get_mode_size_bytes(mode);
653 ir_tarval *tv;
654 ir_entity *ent;
655
656 init = skip_Id(init);
657
658 switch (get_irn_opcode(init)) {
659 case iro_Cast:
660 emit_init_expression(env, get_Cast_op(init));
661 return;
662
663 case iro_Conv:
664 emit_init_expression(env, get_Conv_op(init));
665 return;
666
667 case iro_Const:
668 tv = get_Const_tarval(init);
669
670 /* it's an arithmetic value */
671 emit_arith_tarval(tv, bytes);
672 return;
673
674 case iro_SymConst:
675 switch (get_SymConst_kind(init)) {
676 case symconst_addr_ent:
677 ent = get_SymConst_entity(init);
678 be_gas_emit_entity(ent);
679 break;
680
681 case symconst_ofs_ent:
682 ent = get_SymConst_entity(init);
683 be_emit_irprintf("%d", get_entity_offset(ent));
684 break;
685
686 case symconst_type_size:
687 be_emit_irprintf("%u", get_type_size_bytes(get_SymConst_type(init)));
688 break;
689
690 case symconst_type_align:
691 be_emit_irprintf("%u", get_type_alignment_bytes(get_SymConst_type(init)));
692 break;
693
694 case symconst_enum_const:
695 tv = get_enumeration_value(get_SymConst_enum(init));
696 emit_arith_tarval(tv, bytes);
697 break;
698
699 default:
700 assert(!"emit_atomic_init(): don't know how to init from this SymConst");
701 }
702 return;
703
704 case iro_Add:
705 if (!mode_is_int(mode) && !mode_is_reference(mode)) {
706 panic("Constant must be int or pointer for '+' to work");
707 }
708 emit_init_expression(env, get_Add_left(init));
709 be_emit_cstring(" + ");
710 emit_init_expression(env, get_Add_right(init));
711 return;
712
713 case iro_Sub:
714 if (!mode_is_int(mode) && !mode_is_reference(mode)) {
715 panic("Constant must be int or pointer for '-' to work");
716 }
717 emit_init_expression(env, get_Sub_left(init));
718 be_emit_cstring(" - ");
719 emit_init_expression(env, get_Sub_right(init));
720 return;
721
722 case iro_Mul:
723 if (!mode_is_int(mode) && !mode_is_reference(mode)) {
724 panic("Constant must be int or pointer for '*' to work");
725 }
726 emit_init_expression(env, get_Mul_left(init));
727 be_emit_cstring(" * ");
728 emit_init_expression(env, get_Mul_right(init));
729 return;
730
731 case iro_Unknown:
732 be_emit_cstring("0");
733 return;
734
735 default:
736 panic("unsupported IR-node %+F", init);
737 }
738 }
739
740 /**
741 * Dumps the type for given size (.byte, .long, ...)
742 *
743 * @param size the size in bytes
744 */
emit_size_type(size_t size)745 static void emit_size_type(size_t size)
746 {
747 switch (size) {
748 case 1: be_emit_cstring("\t.byte\t"); break;
749 case 2: be_emit_cstring("\t.short\t"); break;
750 case 4: be_emit_cstring("\t.long\t"); break;
751 case 8: be_emit_cstring("\t.quad\t"); break;
752
753 default:
754 panic("Try to dump a type with %u bytes", (unsigned)size);
755 }
756 }
757
emit_string_char(int c)758 static void emit_string_char(int c)
759 {
760 switch (c) {
761 case '"' : be_emit_cstring("\\\""); break;
762 case '\n': be_emit_cstring("\\n"); break;
763 case '\r': be_emit_cstring("\\r"); break;
764 case '\t': be_emit_cstring("\\t"); break;
765 case '\\': be_emit_cstring("\\\\"); break;
766 default :
767 if (isprint(c))
768 be_emit_char(c);
769 else
770 be_emit_irprintf("\\%03o", c);
771 break;
772 }
773 }
774
emit_string_initializer(const ir_initializer_t * initializer)775 static size_t emit_string_initializer(const ir_initializer_t *initializer)
776 {
777 be_emit_cstring("\t.asciz \"");
778
779 size_t len = initializer->compound.n_initializers;
780 for (size_t i = 0; i < len-1; ++i) {
781 const ir_initializer_t *sub_initializer
782 = get_initializer_compound_value(initializer, i);
783
784 ir_tarval *tv = get_initializer_tarval(sub_initializer);
785 int c = get_tarval_long(tv);
786 emit_string_char(c);
787 }
788 be_emit_cstring("\"\n");
789 be_emit_write_line();
790
791 return initializer->compound.n_initializers;
792 }
793
be_gas_emit_cstring(const char * string)794 void be_gas_emit_cstring(const char *string)
795 {
796 be_emit_cstring("\t.asciz \"");
797 for (const char *c = string; *c != '\0'; ++c) {
798 emit_string_char(*c);
799 }
800 be_emit_cstring("\"\n");
801 be_emit_write_line();
802 }
803
804 typedef enum normal_or_bitfield_kind {
805 NORMAL = 0,
806 TARVAL,
807 STRING,
808 BITFIELD
809 } normal_or_bitfield_kind;
810
811 typedef struct {
812 normal_or_bitfield_kind kind;
813 ir_type *type;
814 union {
815 ir_node *value;
816 ir_tarval *tarval;
817 unsigned char bf_val;
818 const ir_initializer_t *string;
819 } v;
820 } normal_or_bitfield;
821
get_initializer_size(const ir_initializer_t * initializer,ir_type * type)822 static size_t get_initializer_size(const ir_initializer_t *initializer,
823 ir_type *type)
824 {
825 switch (get_initializer_kind(initializer)) {
826 case IR_INITIALIZER_TARVAL:
827 assert(get_tarval_mode(get_initializer_tarval_value(initializer)) == get_type_mode(type));
828 return get_type_size_bytes(type);
829 case IR_INITIALIZER_CONST:
830 case IR_INITIALIZER_NULL:
831 return get_type_size_bytes(type);
832 case IR_INITIALIZER_COMPOUND:
833 if (is_Array_type(type)) {
834 if (is_array_variable_size(type)) {
835 ir_type *element_type = get_array_element_type(type);
836 unsigned element_size = get_type_size_bytes(element_type);
837 unsigned element_align
838 = get_type_alignment_bytes(element_type);
839 unsigned misalign = element_size % element_align;
840 size_t n_inits
841 = get_initializer_compound_n_entries(initializer);
842 element_size += element_align - misalign;
843 return n_inits * element_size;
844 } else {
845 return get_type_size_bytes(type);
846 }
847 } else {
848 assert(is_compound_type(type));
849 size_t size = get_type_size_bytes(type);
850 if (is_compound_variable_size(type)) {
851 /* last initializer has to be an array of variable size */
852 size_t l = get_initializer_compound_n_entries(initializer)-1;
853 const ir_initializer_t *last
854 = get_initializer_compound_value(initializer, l);
855 const ir_entity *last_ent = get_compound_member(type, l);
856 ir_type *last_type = get_entity_type(last_ent);
857 assert(is_array_variable_size(last_type));
858 size += get_initializer_size(last, last_type);
859 }
860 return size;
861 }
862 }
863
864 panic("found invalid initializer");
865 }
866
867 #ifndef NDEBUG
868 static normal_or_bitfield *glob_vals;
869 static size_t max_vals;
870 #endif
871
emit_bitfield(normal_or_bitfield * vals,size_t offset_bits,const ir_initializer_t * initializer,ir_type * type)872 static void emit_bitfield(normal_or_bitfield *vals, size_t offset_bits,
873 const ir_initializer_t *initializer, ir_type *type)
874 {
875 static const size_t BITS_PER_BYTE = 8;
876 ir_mode *mode = get_type_mode(type);
877 ir_tarval *tv = NULL;
878 int value_len;
879 size_t bit_offset;
880 size_t end;
881 bool big_endian = be_get_backend_param()->byte_order_big_endian;
882
883 switch (get_initializer_kind(initializer)) {
884 case IR_INITIALIZER_NULL:
885 return;
886 case IR_INITIALIZER_TARVAL:
887 tv = get_initializer_tarval_value(initializer);
888 break;
889 case IR_INITIALIZER_CONST: {
890 ir_node *node = get_initializer_const_value(initializer);
891 if (!is_Const(node)) {
892 panic("bitfield initializer not a Const node");
893 }
894 tv = get_Const_tarval(node);
895 break;
896 }
897 case IR_INITIALIZER_COMPOUND:
898 panic("bitfield initializer is compound");
899 }
900 if (tv == NULL) {
901 panic("Couldn't get numeric value for bitfield initializer");
902 }
903 tv = tarval_convert_to(tv, get_type_mode(type));
904
905 value_len = get_type_size_bytes(get_primitive_base_type(type));
906 bit_offset = 0;
907 end = get_mode_size_bits(mode);
908 while (bit_offset < end) {
909 size_t src_offset = bit_offset / BITS_PER_BYTE;
910 size_t src_offset_bits = bit_offset % BITS_PER_BYTE;
911 size_t dst_offset = (bit_offset+offset_bits) / BITS_PER_BYTE;
912 size_t dst_offset_bits = (bit_offset+offset_bits) % BITS_PER_BYTE;
913 size_t src_bits_len = end-bit_offset;
914 size_t dst_bits_len = BITS_PER_BYTE-dst_offset_bits;
915 unsigned char curr_bits;
916 normal_or_bitfield *val;
917 if (src_bits_len > dst_bits_len)
918 src_bits_len = dst_bits_len;
919
920 if (big_endian) {
921 val = &vals[value_len - dst_offset - 1];
922 } else {
923 val = &vals[dst_offset];
924 }
925
926 assert((val-glob_vals) < (ptrdiff_t) max_vals);
927 assert(val->kind == BITFIELD ||
928 (val->kind == NORMAL && val->v.value == NULL));
929 val->kind = BITFIELD;
930 curr_bits = get_tarval_sub_bits(tv, src_offset);
931 curr_bits = curr_bits >> src_offset_bits;
932 if (src_offset_bits + src_bits_len > 8) {
933 unsigned next_bits = get_tarval_sub_bits(tv, src_offset+1);
934 curr_bits |= next_bits << (8 - src_offset_bits);
935 }
936 curr_bits &= (1 << src_bits_len) - 1;
937 val->v.bf_val |= curr_bits << dst_offset_bits;
938
939 bit_offset += dst_bits_len;
940 }
941 }
942
emit_ir_initializer(normal_or_bitfield * vals,const ir_initializer_t * initializer,ir_type * type)943 static void emit_ir_initializer(normal_or_bitfield *vals,
944 const ir_initializer_t *initializer,
945 ir_type *type)
946 {
947 assert((size_t) (vals - glob_vals) <= max_vals);
948
949 if (initializer_is_string_const(initializer)) {
950 assert(vals->kind != BITFIELD);
951 vals->kind = STRING;
952 vals->v.string = initializer;
953 return;
954 }
955
956 switch (get_initializer_kind(initializer)) {
957 case IR_INITIALIZER_NULL:
958 return;
959 case IR_INITIALIZER_TARVAL: {
960 size_t i;
961
962 assert(vals->kind != BITFIELD);
963 vals->kind = TARVAL;
964 vals->type = type;
965 vals->v.tarval = get_initializer_tarval_value(initializer);
966 assert(get_type_mode(type) == get_tarval_mode(vals->v.tarval));
967 for (i = 1; i < get_type_size_bytes(type); ++i) {
968 vals[i].kind = NORMAL;
969 vals[i].type = NULL;
970 vals[i].v.value = NULL;
971 }
972 return;
973 }
974 case IR_INITIALIZER_CONST: {
975 size_t i;
976
977 assert(vals->kind != BITFIELD);
978 vals->kind = NORMAL;
979 vals->type = type;
980 vals->v.value = get_initializer_const_value(initializer);
981 for (i = 1; i < get_type_size_bytes(type); ++i) {
982 vals[i].kind = NORMAL;
983 vals[i].type = NULL;
984 vals[i].v.value = NULL;
985 }
986 return;
987 }
988 case IR_INITIALIZER_COMPOUND: {
989 size_t i = 0;
990 size_t n = get_initializer_compound_n_entries(initializer);
991
992 if (is_Array_type(type)) {
993 ir_type *element_type = get_array_element_type(type);
994 size_t skip = get_type_size_bytes(element_type);
995 size_t alignment = get_type_alignment_bytes(element_type);
996 size_t misalign = skip % alignment;
997 if (misalign != 0) {
998 skip += alignment - misalign;
999 }
1000
1001 for (i = 0; i < n; ++i) {
1002 ir_initializer_t *sub_initializer
1003 = get_initializer_compound_value(initializer, i);
1004
1005 emit_ir_initializer(vals, sub_initializer, element_type);
1006
1007 vals += skip;
1008 }
1009 } else {
1010 size_t n_members, i;
1011 assert(is_compound_type(type));
1012 n_members = get_compound_n_members(type);
1013 for (i = 0; i < n_members; ++i) {
1014 ir_entity *member = get_compound_member(type, i);
1015 size_t offset = get_entity_offset(member);
1016 ir_type *subtype = get_entity_type(member);
1017 ir_mode *mode = get_type_mode(subtype);
1018 ir_initializer_t *sub_initializer;
1019
1020 assert(i < get_initializer_compound_n_entries(initializer));
1021 sub_initializer
1022 = get_initializer_compound_value(initializer, i);
1023
1024 if (mode != NULL) {
1025 size_t offset_bits
1026 = get_entity_offset_bits_remainder(member);
1027
1028 if (is_Primitive_type(subtype)
1029 && get_primitive_base_type(subtype) != NULL) {
1030 emit_bitfield(&vals[offset], offset_bits,
1031 sub_initializer, subtype);
1032 continue;
1033 } else {
1034 assert(offset_bits == 0);
1035 }
1036 }
1037
1038 emit_ir_initializer(&vals[offset], sub_initializer, subtype);
1039 }
1040 }
1041
1042 return;
1043 }
1044 }
1045 panic("invalid ir_initializer kind found");
1046 }
1047
emit_tarval_data(ir_type * type,ir_tarval * tv)1048 static void emit_tarval_data(ir_type *type, ir_tarval *tv)
1049 {
1050 size_t size = get_type_size_bytes(type);
1051 if (size == 12) {
1052 /* this should be an x86 extended float */
1053 assert(be_get_backend_param()->byte_order_big_endian == 0);
1054
1055 /* Beware: Mixed endian output! One little endian number emitted as
1056 * three longs. Each long initializer is written in big endian. */
1057 be_emit_irprintf(
1058 "\t.long\t0x%02x%02x%02x%02x\n"
1059 "\t.long\t0x%02x%02x%02x%02x\n"
1060 "\t.long\t0x%02x%02x%02x%02x\n",
1061 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
1062 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
1063 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
1064 get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
1065 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
1066 get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8)
1067 );
1068 be_emit_write_line();
1069 } else if (size == 16) {
1070 if (be_get_backend_param()->byte_order_big_endian) {
1071 be_emit_irprintf(
1072 "\t.long\t0x%02x%02x%02x%02x\n"
1073 "\t.long\t0x%02x%02x%02x%02x\n"
1074 "\t.long\t0x%02x%02x%02x%02x\n"
1075 "\t.long\t0x%02x%02x%02x%02x\n",
1076 get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
1077 get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
1078 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
1079 get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
1080 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
1081 get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
1082 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
1083 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0)
1084 );
1085 } else {
1086 /* Beware: Mixed endian output! One little endian number emitted as
1087 * three longs. Each long initializer is written in big endian. */
1088 be_emit_irprintf(
1089 "\t.long\t0x%02x%02x%02x%02x\n"
1090 "\t.long\t0x%02x%02x%02x%02x\n"
1091 "\t.long\t0x%02x%02x%02x%02x\n"
1092 "\t.long\t0x%02x%02x%02x%02x\n",
1093 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
1094 get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
1095 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
1096 get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
1097 get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
1098 get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
1099 get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 14),
1100 get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12)
1101 );
1102 }
1103 be_emit_write_line();
1104 return;
1105 } else {
1106 /* default case */
1107 emit_size_type(size);
1108 emit_arith_tarval(tv, size);
1109 be_emit_char('\n');
1110 be_emit_write_line();
1111 }
1112 }
1113
1114 /**
1115 * Emit an atomic value.
1116 *
1117 * @param env the gas output environment
1118 * @param init a node representing the atomic value (on the const code irg)
1119 */
emit_node_data(be_gas_decl_env_t * env,ir_node * init,ir_type * type)1120 static void emit_node_data(be_gas_decl_env_t *env, ir_node *init, ir_type *type)
1121 {
1122 size_t size = get_type_size_bytes(type);
1123 if (size == 12 || size == 16) {
1124 ir_tarval *tv;
1125 if (!is_Const(init)) {
1126 panic("12/16byte initializers only support Const nodes yet");
1127 }
1128 tv = get_Const_tarval(init);
1129 emit_tarval_data(type, tv);
1130 return;
1131 }
1132
1133 emit_size_type(size);
1134 emit_init_expression(env, init);
1135 be_emit_char('\n');
1136 be_emit_write_line();
1137 }
1138
emit_initializer(be_gas_decl_env_t * env,const ir_entity * entity)1139 static void emit_initializer(be_gas_decl_env_t *env, const ir_entity *entity)
1140 {
1141 const ir_initializer_t *initializer = entity->initializer;
1142 ir_type *type;
1143 normal_or_bitfield *vals;
1144 size_t size;
1145 size_t k;
1146
1147 if (initializer_is_string_const(initializer)) {
1148 emit_string_initializer(initializer);
1149 return;
1150 }
1151
1152 type = get_entity_type(entity);
1153 size = get_initializer_size(initializer, type);
1154
1155 if (size == 0)
1156 return;
1157
1158 /*
1159 * In the worst case, every initializer allocates one byte.
1160 * Moreover, initializer might be big, do not allocate on stack.
1161 */
1162 vals = XMALLOCNZ(normal_or_bitfield, size);
1163
1164 #ifndef NDEBUG
1165 glob_vals = vals;
1166 max_vals = size;
1167 #endif
1168
1169 emit_ir_initializer(vals, initializer, type);
1170
1171 /* now write values sorted */
1172 for (k = 0; k < size; ) {
1173 int space = 0;
1174 normal_or_bitfield_kind kind = vals[k].kind;
1175 int elem_size;
1176 switch (kind) {
1177 case NORMAL:
1178 if (vals[k].v.value != NULL) {
1179 emit_node_data(env, vals[k].v.value, vals[k].type);
1180 elem_size = get_type_size_bytes(vals[k].type);
1181 } else {
1182 elem_size = 0;
1183 }
1184 break;
1185 case TARVAL:
1186 emit_tarval_data(vals[k].type, vals[k].v.tarval);
1187 elem_size = get_type_size_bytes(vals[k].type);
1188 break;
1189 case STRING:
1190 elem_size = emit_string_initializer(vals[k].v.string);
1191 break;
1192 case BITFIELD:
1193 be_emit_irprintf("\t.byte\t%d\n", vals[k].v.bf_val);
1194 be_emit_write_line();
1195 elem_size = 1;
1196 break;
1197 default:
1198 panic("internal compiler error (invalid normal_or_bitfield_kind");
1199 }
1200
1201 k += elem_size;
1202 while (k < size && vals[k].kind == NORMAL && vals[k].v.value == NULL) {
1203 ++space;
1204 ++k;
1205 }
1206
1207 /* a gap */
1208 if (space > 0) {
1209 be_emit_irprintf("\t.space\t%d, 0\n", space);
1210 be_emit_write_line();
1211 }
1212 }
1213 xfree(vals);
1214 }
1215
emit_align(unsigned p2alignment)1216 static void emit_align(unsigned p2alignment)
1217 {
1218 be_emit_irprintf("\t.p2align\t%u\n", log2_floor(p2alignment));
1219 be_emit_write_line();
1220 }
1221
get_effective_entity_alignment(const ir_entity * entity)1222 static unsigned get_effective_entity_alignment(const ir_entity *entity)
1223 {
1224 unsigned alignment = get_entity_alignment(entity);
1225 if (alignment == 0) {
1226 ir_type *type = get_entity_type(entity);
1227 alignment = get_type_alignment_bytes(type);
1228 }
1229 return alignment;
1230 }
1231
emit_common(const ir_entity * entity)1232 static void emit_common(const ir_entity *entity)
1233 {
1234 unsigned size = get_type_size_bytes(get_entity_type(entity));
1235 unsigned alignment = get_effective_entity_alignment(entity);
1236
1237 if (get_entity_linkage(entity) & IR_LINKAGE_WEAK) {
1238 emit_weak(entity);
1239 }
1240
1241 switch (be_gas_object_file_format) {
1242 case OBJECT_FILE_FORMAT_MACH_O:
1243 be_emit_cstring("\t.comm ");
1244 be_gas_emit_entity(entity);
1245 be_emit_irprintf(",%u,%u\n", size, log2_floor(alignment));
1246 be_emit_write_line();
1247 return;
1248 case OBJECT_FILE_FORMAT_ELF:
1249 be_emit_cstring("\t.comm ");
1250 be_gas_emit_entity(entity);
1251 be_emit_irprintf(",%u,%u\n", size, alignment);
1252 be_emit_write_line();
1253 return;
1254 case OBJECT_FILE_FORMAT_COFF:
1255 be_emit_cstring("\t.comm ");
1256 be_gas_emit_entity(entity);
1257 be_emit_irprintf(",%u # %u\n", size, alignment);
1258 be_emit_write_line();
1259 return;
1260 }
1261 panic("invalid object file format");
1262 }
1263
emit_local_common(const ir_entity * entity)1264 static void emit_local_common(const ir_entity *entity)
1265 {
1266 unsigned size = get_type_size_bytes(get_entity_type(entity));
1267 unsigned alignment = get_effective_entity_alignment(entity);
1268
1269 if (get_entity_linkage(entity) & IR_LINKAGE_WEAK) {
1270 emit_weak(entity);
1271 }
1272
1273 switch (be_gas_object_file_format) {
1274 case OBJECT_FILE_FORMAT_MACH_O:
1275 be_emit_cstring("\t.lcomm ");
1276 be_gas_emit_entity(entity);
1277 be_emit_irprintf(",%u,%u\n", size, log2_floor(alignment));
1278 be_emit_write_line();
1279 return;
1280 case OBJECT_FILE_FORMAT_ELF:
1281 be_emit_cstring("\t.local ");
1282 be_gas_emit_entity(entity);
1283 be_emit_cstring("\n");
1284 be_emit_write_line();
1285 be_emit_cstring("\t.comm ");
1286 be_gas_emit_entity(entity);
1287 be_emit_irprintf(",%u,%u\n", size, alignment);
1288 be_emit_write_line();
1289 return;
1290 case OBJECT_FILE_FORMAT_COFF:
1291 be_emit_cstring("\t.lcomm ");
1292 be_gas_emit_entity(entity);
1293 be_emit_irprintf(",%u # %u\n", size, alignment);
1294 be_emit_write_line();
1295 return;
1296 }
1297 panic("invalid object file format");
1298 }
1299
emit_indirect_symbol(const ir_entity * entity,be_gas_section_t section)1300 static void emit_indirect_symbol(const ir_entity *entity, be_gas_section_t section)
1301 {
1302 /* we can only do PIC code on macho so far */
1303 assert(be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O);
1304
1305 be_gas_emit_entity(entity);
1306 be_emit_cstring(":\n");
1307 be_emit_write_line();
1308 be_emit_irprintf("\t.indirect_symbol %I\n", get_entity_ident(entity));
1309 be_emit_write_line();
1310 if (section == GAS_SECTION_PIC_TRAMPOLINES) {
1311 be_emit_cstring("\thlt ; hlt ; hlt ; hlt ; hlt\n");
1312 be_emit_write_line();
1313 } else {
1314 assert(section == GAS_SECTION_PIC_SYMBOLS);
1315 be_emit_cstring("\t.long 0\n");
1316 be_emit_write_line();
1317 }
1318 }
1319
be_gas_get_private_prefix(void)1320 char const *be_gas_get_private_prefix(void)
1321 {
1322 return be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O ? "L" : ".L";
1323 }
1324
be_gas_emit_entity(const ir_entity * entity)1325 void be_gas_emit_entity(const ir_entity *entity)
1326 {
1327 if (entity->type == get_code_type()) {
1328 ir_label_t label = get_entity_label(entity);
1329 be_emit_irprintf("%s_%lu", be_gas_get_private_prefix(), label);
1330 return;
1331 }
1332
1333 if (get_entity_visibility(entity) == ir_visibility_private) {
1334 be_emit_string(be_gas_get_private_prefix());
1335 }
1336 be_emit_irprintf("%I", get_entity_ld_ident(entity));
1337 }
1338
be_gas_emit_block_name(const ir_node * block)1339 void be_gas_emit_block_name(const ir_node *block)
1340 {
1341 ir_entity *entity = get_Block_entity(block);
1342 if (entity != NULL) {
1343 be_gas_emit_entity(entity);
1344 } else {
1345 void *nr_val = pmap_get(void, block_numbers, block);
1346 int nr;
1347 if (nr_val == NULL) {
1348 nr = next_block_nr++;
1349 pmap_insert(block_numbers, block, INT_TO_PTR(nr+1));
1350 } else {
1351 nr = PTR_TO_INT(nr_val)-1;
1352 }
1353 be_emit_irprintf("%s%d", be_gas_get_private_prefix(), nr);
1354 }
1355 }
1356
be_gas_begin_block(const ir_node * block,bool needs_label)1357 void be_gas_begin_block(const ir_node *block, bool needs_label)
1358 {
1359 if (needs_label) {
1360 be_gas_emit_block_name(block);
1361 be_emit_char(':');
1362 } else {
1363 if (!be_options.verbose_asm)
1364 return;
1365 be_emit_cstring("/*");
1366 be_gas_emit_block_name(block);
1367 be_emit_cstring(":*/");
1368 }
1369
1370 if (be_options.verbose_asm) {
1371 be_emit_pad_comment();
1372 be_emit_irprintf("/* %+F preds:", block);
1373
1374 int arity = get_irn_arity(block);
1375 if (arity == 0) {
1376 be_emit_cstring(" none");
1377 } else {
1378 int i;
1379 for (i = 0; i < arity; ++i) {
1380 ir_node *predblock = get_Block_cfgpred_block(block, i);
1381 be_emit_char(' ');
1382 be_gas_emit_block_name(predblock);
1383 }
1384 }
1385 be_emit_irprintf(", freq: %.3f */", get_block_execfreq(block));
1386 }
1387 be_emit_char('\n');
1388 be_emit_write_line();
1389 }
1390
1391 /**
1392 * Dump a global entity.
1393 *
1394 * @param env the gas output environment
1395 * @param ent the entity to be dumped
1396 */
emit_global(be_gas_decl_env_t * env,const ir_entity * entity)1397 static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity)
1398 {
1399 ir_type *type = get_entity_type(entity);
1400 ident *ld_ident = get_entity_ld_ident(entity);
1401 unsigned alignment = get_effective_entity_alignment(entity);
1402 be_gas_section_t section = determine_section(env, entity);
1403 ir_visibility visibility = get_entity_visibility(entity);
1404 ir_linkage linkage = get_entity_linkage(entity);
1405
1406 /* Block labels are already emitted in the code. */
1407 if (type == get_code_type())
1408 return;
1409
1410 /* we already emitted all methods with graphs in other functions like
1411 * be_gas_emit_function_prolog(). All others don't need to be emitted.
1412 */
1413 if (is_Method_type(type) && section != GAS_SECTION_PIC_TRAMPOLINES) {
1414 return;
1415 }
1416
1417 be_dwarf_variable(entity);
1418
1419 if (section == GAS_SECTION_BSS) {
1420 switch (visibility) {
1421 case ir_visibility_local:
1422 case ir_visibility_private:
1423 emit_local_common(entity);
1424 return;
1425 case ir_visibility_external:
1426 if (linkage & IR_LINKAGE_MERGE) {
1427 emit_common(entity);
1428 return;
1429 }
1430 break;
1431 }
1432 }
1433
1434 emit_visibility(entity);
1435
1436 if (!is_po2(alignment))
1437 panic("alignment not a power of 2");
1438
1439 emit_section(section, entity);
1440
1441 if (section == GAS_SECTION_PIC_TRAMPOLINES
1442 || section == GAS_SECTION_PIC_SYMBOLS) {
1443 emit_indirect_symbol(entity, section);
1444 return;
1445 }
1446
1447 /* nothing left to do without an initializer */
1448 if (!entity_has_definition(entity))
1449 return;
1450
1451 /* alignment */
1452 if (alignment > 1) {
1453 emit_align(alignment);
1454 }
1455 if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF
1456 && be_gas_emit_types
1457 && visibility != ir_visibility_private) {
1458 be_emit_cstring("\t.type\t");
1459 be_gas_emit_entity(entity);
1460 be_emit_cstring(", ");
1461 be_emit_char(be_gas_elf_type_char);
1462 be_emit_cstring("object\n\t.size\t");\
1463 be_gas_emit_entity(entity);
1464 be_emit_irprintf(", %u\n", get_type_size_bytes(type));
1465 }
1466
1467 if (get_id_str(ld_ident)[0] != '\0') {
1468 be_gas_emit_entity(entity);
1469 be_emit_cstring(":\n");
1470 be_emit_write_line();
1471 }
1472
1473 if (entity_is_null(entity)) {
1474 /* we should use .space for stuff in the bss segment */
1475 unsigned size = get_type_size_bytes(type);
1476 if (size > 0) {
1477 be_emit_irprintf("\t.space %u, 0\n", get_type_size_bytes(type));
1478 be_emit_write_line();
1479 }
1480 } else {
1481 assert(entity->initializer != NULL);
1482 emit_initializer(env, entity);
1483 }
1484 }
1485
1486 /**
1487 * Dumps declarations of global variables and the initialization code.
1488 *
1489 * @param gt a global like type, either the global or the TLS one
1490 * @param env an environment
1491 */
be_gas_emit_globals(ir_type * gt,be_gas_decl_env_t * env)1492 static void be_gas_emit_globals(ir_type *gt, be_gas_decl_env_t *env)
1493 {
1494 size_t i, n = get_compound_n_members(gt);
1495
1496 for (i = 0; i < n; i++) {
1497 ir_entity *ent = get_compound_member(gt, i);
1498 emit_global(env, ent);
1499 }
1500 }
1501
1502 /* Generate all entities. */
emit_global_decls(const be_main_env_t * main_env)1503 static void emit_global_decls(const be_main_env_t *main_env)
1504 {
1505 be_gas_decl_env_t env;
1506 memset(&env, 0, sizeof(env));
1507
1508 /* dump global type */
1509 env.main_env = main_env;
1510 env.section = (be_gas_section_t) -1;
1511
1512 be_gas_emit_globals(get_glob_type(), &env);
1513 be_gas_emit_globals(get_tls_type(), &env);
1514 be_gas_emit_globals(get_segment_type(IR_SEGMENT_CONSTRUCTORS), &env);
1515 be_gas_emit_globals(get_segment_type(IR_SEGMENT_DESTRUCTORS), &env);
1516 be_gas_emit_globals(main_env->pic_symbols_type, &env);
1517 be_gas_emit_globals(main_env->pic_trampolines_type, &env);
1518
1519 /**
1520 * ".subsections_via_symbols marks object files which are OK to divide
1521 * their section contents into individual blocks".
1522 * From my understanding this means no label points in the middle of an
1523 * object which we want to address as a whole. Firm code should be fine
1524 * with this.
1525 */
1526 if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
1527 be_emit_cstring("\t.subsections_via_symbols\n");
1528 be_emit_write_line();
1529 }
1530 }
1531
be_emit_jump_table(const ir_node * node,const ir_switch_table * table,ir_entity * entity,get_cfop_target_func get_cfop_target)1532 void be_emit_jump_table(const ir_node *node, const ir_switch_table *table,
1533 ir_entity *entity, get_cfop_target_func get_cfop_target)
1534 {
1535 unsigned n_outs = arch_get_irn_n_outs(node);
1536 const ir_node **targets = XMALLOCNZ(const ir_node*, n_outs);
1537 size_t n_entries = ir_switch_table_get_n_entries(table);
1538 unsigned long length = 0;
1539 size_t e;
1540 unsigned i;
1541 const ir_node **labels;
1542
1543 /* go over all proj's and collect their jump targets */
1544 foreach_out_edge(node, edge) {
1545 ir_node *proj = get_edge_src_irn(edge);
1546 long pn = get_Proj_proj(proj);
1547 ir_node *target = get_cfop_target(proj);
1548 assert(targets[pn] == NULL);
1549 targets[pn] = target;
1550 }
1551
1552 /* go over table to determine max value (note that we normalized the
1553 * ranges so that the minimum is 0) */
1554 for (e = 0; e < n_entries; ++e) {
1555 const ir_switch_table_entry *entry
1556 = ir_switch_table_get_entry_const(table, e);
1557 ir_tarval *max = entry->max;
1558 unsigned long val;
1559 if (entry->pn == 0)
1560 continue;
1561 if (!tarval_is_long(max))
1562 panic("switch case overflow (%+F)", node);
1563 val = (unsigned long) get_tarval_long(max);
1564 if (val > length) {
1565 length = val;
1566 }
1567 }
1568
1569 /* the 16000 isn't a real limit of the architecture. But should protect us
1570 * from seamingly endless compiler runs */
1571 if (length > 16000) {
1572 /* switch lowerer should have broken this monster to pieces... */
1573 panic("too large switch encountered (%+F)", node);
1574 }
1575 ++length;
1576
1577 labels = XMALLOCNZ(const ir_node*, length);
1578 for (e = 0; e < n_entries; ++e) {
1579 const ir_switch_table_entry *entry
1580 = ir_switch_table_get_entry_const(table, e);
1581 ir_tarval *min = entry->min;
1582 ir_tarval *max = entry->max;
1583 const ir_node *target = targets[entry->pn];
1584 assert(entry->pn < (long)n_outs);
1585 if (min == max) {
1586 unsigned long val = (unsigned long)get_tarval_long(max);
1587 labels[val] = target;
1588 } else {
1589 unsigned long min_val;
1590 unsigned long max_val;
1591 unsigned long i;
1592 if (!tarval_is_long(min))
1593 panic("switch case overflow (%+F)", node);
1594 min_val = (unsigned long)get_tarval_long(min);
1595 max_val = (unsigned long)get_tarval_long(max);
1596 assert(min_val <= max_val);
1597 for (i = min_val; i <= max_val; ++i) {
1598 labels[i] = target;
1599 }
1600 }
1601 }
1602
1603 /* emit table */
1604 if (entity != NULL) {
1605 be_gas_emit_switch_section(GAS_SECTION_RODATA);
1606 be_emit_cstring("\t.align 4\n");
1607 be_gas_emit_entity(entity);
1608 be_emit_cstring(":\n");
1609 }
1610
1611 for (i = 0; i < length; ++i) {
1612 const ir_node *block = labels[i];
1613 if (block == NULL)
1614 block = targets[0];
1615 be_emit_cstring("\t.long ");
1616 be_gas_emit_block_name(block);
1617 be_emit_char('\n');
1618 be_emit_write_line();
1619 }
1620
1621 if (entity != NULL)
1622 be_gas_emit_switch_section(GAS_SECTION_TEXT);
1623
1624 xfree(labels);
1625 xfree(targets);
1626 }
1627
emit_global_asms(void)1628 static void emit_global_asms(void)
1629 {
1630 size_t n = get_irp_n_asms();
1631 size_t i;
1632
1633 be_gas_emit_switch_section(GAS_SECTION_TEXT);
1634 for (i = 0; i < n; ++i) {
1635 ident *asmtext = get_irp_asm(i);
1636
1637 be_emit_cstring("#APP\n");
1638 be_emit_write_line();
1639 be_emit_irprintf("%I\n", asmtext);
1640 be_emit_write_line();
1641 be_emit_cstring("#NO_APP\n");
1642 be_emit_write_line();
1643 }
1644 }
1645
be_gas_begin_compilation_unit(const be_main_env_t * env)1646 void be_gas_begin_compilation_unit(const be_main_env_t *env)
1647 {
1648 be_dwarf_open();
1649 be_dwarf_unit_begin(env->cup_name);
1650
1651 block_numbers = pmap_create();
1652 next_block_nr = 0;
1653
1654 emit_global_asms();
1655 }
1656
be_gas_end_compilation_unit(const be_main_env_t * env)1657 void be_gas_end_compilation_unit(const be_main_env_t *env)
1658 {
1659 emit_global_decls(env);
1660
1661 pmap_destroy(block_numbers);
1662
1663 be_dwarf_unit_end();
1664 be_dwarf_close();
1665 }
1666