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