* @date 04.11.2005
* @version $Id$
*/
-#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
#include "begnuas.h"
".section\t.bss",
".section\t.tbss,\"awT\",@nobits",
".section\t.ctors,\"aw\",@progbits",
+ ".section\t.dtors,\"aw\",@progbits",
NULL, /* no cstring section */
NULL,
NULL
".section\t.bss",
".section\t.tbss,\"awT\",@nobits",
".section\t.ctors,\"aw\",@progbits",
+ ".section\t.dtors,\"aw\",@progbits",
NULL,
NULL,
NULL
".section\t.bss",
".section\t.tbss,\"awT\",@nobits",
".section\t.ctors,\"aw\",@progbits",
+ ".section\t.dtors,\"aw\",@progbits",
NULL,
NULL,
NULL
".data",
NULL, /* TLS is not supported on Mach-O */
".mod_init_func",
+ NULL, /* TODO: how is this called? */
".cstring",
".section\t__IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5",
".section\t__IMPORT,__pointers,non_lazy_symbol_pointers"
case GAS_FLAVOUR_MINGW:
be_emit_cstring("\t.def\t");
be_emit_string(name);
- be_emit_cstring(";\t.scl\t2;\t.type\t32;\t.endef\n");
+ if (get_entity_visibility(entity) == visibility_external_visible) {
+ be_emit_cstring(";\t.scl\t2;\t.type\t32;\t.endef\n");
+ } else {
+ be_emit_cstring(";\t.scl\t3;\t.type\t32;\t.endef\n");
+ }
be_emit_write_line();
break;
case GAS_FLAVOUR_MACH_O:
return;
case 12:
- be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x%02x", get_tarval_sub_bits(tv, 11),
- get_tarval_sub_bits(tv, 10), get_tarval_sub_bits(tv, 9),
- get_tarval_sub_bits(tv, 8), get_tarval_sub_bits(tv, 7),
- get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5),
- get_tarval_sub_bits(tv, 4), get_tarval_sub_bits(tv, 3),
- get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1),
- get_tarval_sub_bits(tv, 0));
+ /* Beware: Mixed endian output! One little endian number emitted as
+ * three longs. Each long initializer is written in big endian. */
+ be_emit_irprintf(
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x\n"
+ "\t.long\t0x%02x%02x%02x%02x",
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0),
+ get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+ get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+ get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
+ get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8)
+ );
return;
case 16:
- be_emit_irprintf("0x%02x%02x%02x%02x%02x%02x%02x%02x"
- "%02x%02x%02x%02x%02x%02x%02x%02x",
+ be_emit_irprintf(
+ "\t.long\t0x%02x%02x%02x%02x0x%02x%02x%02x%02x0x%02x%02x%02x%02x0x%02x%02x%02x%02x",
get_tarval_sub_bits(tv, 15), get_tarval_sub_bits(tv, 16),
get_tarval_sub_bits(tv, 13), get_tarval_sub_bits(tv, 12),
get_tarval_sub_bits(tv, 11), get_tarval_sub_bits(tv, 10),
- get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
- get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
- get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
- get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
- get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
+ get_tarval_sub_bits(tv, 9), get_tarval_sub_bits(tv, 8),
+ get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6),
+ get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4),
+ get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2),
+ get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0)
+ );
return;
}
- panic("Can't dump a tarval with %d bytes\n", bytes);
+ panic("Can't dump a tarval with %d bytes", bytes);
}
/**
* Return the label prefix for labeled blocks.
*/
-const char *be_gas_label_prefix(void) {
+const char *be_gas_block_label_prefix(void) {
return ".LG";
}
+/**
+ * Return the label prefix for labeled instructions.
+ */
+const char *be_gas_insn_label_prefix(void) {
+ return ".LE";
+}
+
/**
* Dump a label.
*/
static void dump_label(ir_label_t label) {
- be_emit_irprintf("%s%ld", be_gas_label_prefix(), label);
+ be_emit_irprintf("%s%lu", be_gas_block_label_prefix(), label);
}
/**
init = skip_Id(init);
switch (get_irn_opcode(init)) {
-#if 0
case iro_Cast:
do_dump_atomic_init(env, get_Cast_op(init));
return;
case iro_Conv:
do_dump_atomic_init(env, get_Conv_op(init));
return;
-#endif
case iro_Const:
tv = get_Const_tarval(init);
}
return;
- case iro_Add:
- if (!mode_is_int(mode) && !mode_is_reference(mode)) {
- panic("Constant must be int or pointer for '+' to work");
- }
- do_dump_atomic_init(env, get_Add_left(init));
- be_emit_cstring(" + ");
- do_dump_atomic_init(env, get_Add_right(init));
- return;
-
- case iro_Sub:
- if (!mode_is_int(mode) && !mode_is_reference(mode)) {
- panic("Constant must be int or pointer for '-' to work");
- }
- do_dump_atomic_init(env, get_Sub_left(init));
- be_emit_cstring(" - ");
- do_dump_atomic_init(env, get_Sub_right(init));
- return;
-
- case iro_Mul:
- if (!mode_is_int(mode) && !mode_is_reference(mode)) {
- panic("Constant must be int or pointer for '*' to work");
- }
- do_dump_atomic_init(env, get_Mul_left(init));
- be_emit_cstring(" * ");
- do_dump_atomic_init(env, get_Mul_right(init));
- return;
+ case iro_Add:
+ if (!mode_is_int(mode) && !mode_is_reference(mode)) {
+ panic("Constant must be int or pointer for '+' to work");
+ }
+ do_dump_atomic_init(env, get_Add_left(init));
+ be_emit_cstring(" + ");
+ do_dump_atomic_init(env, get_Add_right(init));
+ return;
- default:
- assert(0 && "dump_atomic_init(): unknown IR-node");
+ case iro_Sub:
+ if (!mode_is_int(mode) && !mode_is_reference(mode)) {
+ panic("Constant must be int or pointer for '-' to work");
+ }
+ do_dump_atomic_init(env, get_Sub_left(init));
+ be_emit_cstring(" - ");
+ do_dump_atomic_init(env, get_Sub_right(init));
+ return;
+
+ case iro_Mul:
+ if (!mode_is_int(mode) && !mode_is_reference(mode)) {
+ panic("Constant must be int or pointer for '*' to work");
+ }
+ do_dump_atomic_init(env, get_Mul_left(init));
+ be_emit_cstring(" * ");
+ do_dump_atomic_init(env, get_Mul_right(init));
+ return;
+
+ default:
+ panic("dump_atomic_init(): unsupported IR-node %+F", init);
}
}
break;
default:
- panic("Try to dump a type with %u bytes\n", (unsigned) size);
+ panic("Try to dump a type with %u bytes", (unsigned)size);
}
}
static void dump_string_cst(ir_entity *ent)
{
int i, len;
+ int output_len;
ir_type *type;
int type_size;
int remaining_space;
- len = get_compound_ent_n_values(ent);
+ len = get_compound_ent_n_values(ent);
+ output_len = len;
if (be_gas_flavour == GAS_FLAVOUR_MACH_O) {
be_emit_cstring("\t.ascii \"");
} else {
be_emit_cstring("\t.string \"");
- len -= 1;
+ output_len -= 1;
}
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < output_len; ++i) {
ir_node *irn;
int c;
remaining_space = type_size - len;
assert(remaining_space >= 0);
if(remaining_space > 0) {
- be_emit_irprintf("\t.skip\t%d\n", remaining_space);
+ be_emit_irprintf("\t.space\t%d\n", remaining_space);
}
}
panic("bitfield initializer is compound");
}
if (tv == NULL) {
- panic("Couldn't get numeric value for bitfield initializer\n");
+ panic("Couldn't get numeric value for bitfield initializer");
}
+ tv = tarval_convert_to(tv, get_type_mode(type));
/* normalize offset */
vals += offset_bits >> 3;
* In the worst case, every initializer allocates one byte.
* Moreover, initializer might be big, do not allocate on stack.
*/
- vals = xcalloc(size, sizeof(vals[0]));
+ vals = XMALLOCNZ(normal_or_bitfield, size);
#ifndef NDEBUG
glob_vals = vals;
/* a gap */
if (space > 0) {
- be_emit_irprintf("\t.skip\t%d\n", space);
+ be_emit_irprintf("\t.space\t%d\n", space);
be_emit_write_line();
}
}
* In the worst case, every initializer allocates one byte.
* Moreover, initializer might be big, do not allocate on stack.
*/
- vals = xcalloc(last_ofs, sizeof(vals[0]));
+ vals = XMALLOCNZ(normal_or_bitfield, last_ofs);
/* collect the values and store them at the offsets */
for (i = 0; i < n; ++i) {
tarval *tv = get_atomic_init_tv(value);
unsigned char curr_bits, last_bits = 0;
if (tv == NULL) {
- panic("Couldn't get numeric value for bitfield initializer '%s'\n",
+ panic("Couldn't get numeric value for bitfield initializer '%s'",
get_entity_ld_name(ent));
}
/* normalize offset */
/* a gap */
if (space > 0) {
- be_emit_irprintf("\t.skip\t%d\n", space);
+ be_emit_irprintf("\t.space\t%d\n", space);
be_emit_write_line();
}
}
if (!is_po2(alignment))
panic("alignment not a power of 2");
- be_emit_irprintf(".p2align\t%u\n", log2_floor(alignment));
+ be_emit_irprintf("\t.p2align\t%u\n", log2_floor(alignment));
be_emit_write_line();
}
emit_align(align);
}
+ if (visibility != visibility_external_allocated && !emit_as_common
+ && be_gas_flavour == GAS_FLAVOUR_ELF) {
+ be_emit_cstring("\t.type\t");
+ be_emit_ident(ld_ident);
+ be_emit_cstring(", @object\n\t.size\t");
+ be_emit_ident(ld_ident);
+ be_emit_irprintf(", %u\n", get_type_size_bytes(type));
+ }
+
if (!emit_as_common) {
be_emit_ident(ld_ident);
be_emit_cstring(":\n");
be_emit_write_line();
break;
}
- } else if (section == GAS_SECTION_PIC_TRAMPOLINES) {
+ } else if (section == GAS_SECTION_PIC_TRAMPOLINES
+ || section == GAS_SECTION_PIC_SYMBOLS) {
if (be_gas_flavour == GAS_FLAVOUR_MACH_O) {
be_emit_cstring("\t.indirect_symbol ");
be_emit_ident(get_entity_ident(ent));
be_emit_char('\n');
be_emit_write_line();
- be_emit_cstring("\thlt ; hlt ; hlt ; hlt ; hlt\n");
- be_emit_write_line();
+ if (section == GAS_SECTION_PIC_TRAMPOLINES) {
+ be_emit_cstring("\thlt ; hlt ; hlt ; hlt ; hlt\n");
+ be_emit_write_line();
+ } else {
+ assert(section == GAS_SECTION_PIC_SYMBOLS);
+ be_emit_cstring("\t.long 0\n");
+ be_emit_write_line();
+ }
} else {
panic("PIC trampolines not yet supported in this gas mode");
}
dump_compound_init(env, ent);
break;
default:
- assert(0);
+ panic("Unimplemented type kind in dump_global()");
}
}
}
be_gas_dump_globals(get_glob_type(), &env, only_emit_marked_entities);
env.section = GAS_SECTION_TLS;
be_gas_dump_globals(get_tls_type(), &env, only_emit_marked_entities);
- env.section = GAS_SECTION_CTOR;
- be_gas_dump_globals(get_constructors_type(), &env,
+ env.section = GAS_SECTION_CONSTRUCTORS;
+ be_gas_dump_globals(get_segment_type(IR_SEGMENT_CONSTRUCTORS), &env,
only_emit_marked_entities);
+ env.section = GAS_SECTION_DESTRUCTORS;
+ be_gas_dump_globals(get_segment_type(IR_SEGMENT_DESTRUCTORS), &env,
+ only_emit_marked_entities);
+
env.section = GAS_SECTION_PIC_SYMBOLS;
be_gas_dump_globals(main_env->pic_symbols_type, &env,
only_emit_marked_entities);