}
}
+/**
+ * Return the label prefix for labeled blocks.
+ */
+const char *be_gas_label_prefix(void) {
+ return ".LG";
+}
+
+/**
+ * Dump a label.
+ */
+static void dump_label(obstack_t *obst, ir_label_t label) {
+ obstack_printf(obst, "%s%ld", be_gas_label_prefix(), label);
+}
+
/**
* Return the tarval of an atomic initializer.
*
- * @param init a node representing the initializer (on teh const code irg)
+ * @param init a node representing the initializer (on the const code irg)
*
* @return the tarval
*/
case symconst_enum_const:
return get_enumeration_value(get_SymConst_enum(init));
+ case symconst_label:
+ return NULL;
+
default:
return NULL;
}
ir_mode *mode = get_irn_mode(init);
int bytes = get_mode_size_bytes(mode);
tarval *tv;
+ ir_label_t label;
ir_entity *ent;
switch (get_irn_opcode(init)) {
case symconst_addr_ent:
ent = get_SymConst_entity(init);
- if(!entity_visited(ent)) {
+ if(!is_entity_backend_marked(ent)) {
waitq_put(env->worklist, ent);
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
}
obstack_printf(obst, "%s", get_entity_ld_name(ent));
break;
case symconst_ofs_ent:
ent = get_SymConst_entity(init);
#if 0 /* not needed, is it? */
- if(!entity_visited(ent)) {
+ if(!is_entity_backend_marked(ent)) {
waitq_put(env->worklist, ent);
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
}
#endif
obstack_printf(obst, "%d", get_entity_offset(ent));
dump_arith_tarval(obst, tv, bytes);
break;
+ case symconst_label:
+ label = get_SymConst_label(init);
+ dump_label(obst, label);
+ break;
+
default:
assert(!"dump_atomic_init(): don't know how to init from this SymConst");
}
}
}
-static void dump_array_init(be_gas_decl_env_t *env, obstack_t *obst,
- ir_entity *ent)
-{
- const ir_type *ty = get_entity_type(ent);
- int i;
- int filler;
- int size = 0;
-
- /* potential spare values should be already included! */
- for (i = 0; i < get_compound_ent_n_values(ent); ++i) {
- ir_entity *step = get_compound_ent_value_member(ent, i);
- ir_type *stype = get_entity_type(step);
-
- if (get_type_mode(stype)) {
- int align = (get_type_alignment_bits(stype) + 7) >> 3;
- int n = size % align;
-
- if (n > 0) {
- obstack_printf(obst, "\t.zero\t%d\n", align - n);
- size += align - n;
- }
- }
- dump_atomic_init(env, obst, get_compound_ent_value(ent, i));
- size += get_type_size_bytes(stype);
- }
- filler = get_type_size_bytes(ty) - size;
-
- if (filler > 0)
- obstack_printf(obst, "\t.skip\t%d\n", filler);
-}
-
enum normal_or_bitfield_kind {
NORMAL = 0,
BITFIELD
if (offset_bits != 0 ||
(value_len != 8 && value_len != 16 && value_len != 32 && value_len != 64)) {
- tarval *shift, *shifted;
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",
get_entity_ld_name(ent));
}
- tv = tarval_convert_to(tv, mode_Lu);
- shift = new_tarval_from_long(offset_bits, mode_Is);
- shifted = tarval_shl(tv, shift);
- if (shifted == tarval_bad || shifted == tarval_undefined) {
- panic("Couldn't shift numeric value for bitfield initializer '%s'\n",
- get_entity_ld_name(ent));
- }
+ /* normalize offset */
+ offset += offset_bits >> 3;
+ offset_bits &= 7;
- for (j = 0; value_len > 0; ++j) {
+ for (j = 0; value_len + offset_bits > 0; ++j) {
assert(offset + j < last_ofs);
assert(vals[offset + j].kind == BITFIELD || vals[offset + j].v.value == NULL);
vals[offset + j].kind = BITFIELD;
- vals[offset + j].v.bf_val |= get_tarval_sub_bits(shifted, j);
- value_len -= 8 - offset_bits;
- offset_bits = 0;
+ curr_bits = get_tarval_sub_bits(tv, j);
+ vals[offset + j].v.bf_val |= (last_bits >> (8 - offset_bits)) | (curr_bits << offset_bits);
+ value_len -= 8;
+ last_bits = curr_bits;
}
} else {
assert(offset < last_ofs);
}
++i;
- space = 0;
while (i < last_ofs && vals[i].kind == NORMAL && vals[i].v.value == NULL) {
++space;
++i;
obstack_t *obst;
ir_type *type = get_entity_type(ent);
const char *ld_name = get_entity_ld_name(ent);
- ir_variability variability = get_entity_variability(ent);
- ir_visibility visibility = get_entity_visibility(ent);
int align = get_type_alignment_bytes(type);
int emit_as_common = 0;
+ ir_variability variability;
+ ir_visibility visibility;
obst = env->data_obst;
if (is_Method_type(type)) {
obstack_printf(obst, "%s\n", ld_name);
}
return;
- } else if (variability == variability_constant) {
+ }
+
+ variability = get_entity_variability(ent);
+ visibility = get_entity_visibility(ent);
+ if (variability == variability_constant) {
/* a constant entity, put it on the rdata */
obst = env->rodata_obst;
} else if (variability == variability_uninitialized) {
/* uninitialized entity put it in bss segment */
obst = env->bss_obst;
- if(emit_commons && visibility != visibility_local)
+ if (emit_commons && visibility != visibility_local)
emit_as_common = 1;
}
} else {
obstack_printf(obst, "\t.zero %d\n", get_type_size_bytes(type));
}
- } else if (is_atomic_type(type)) {
- dump_atomic_init(env, obst, get_atomic_ent_value(ent));
- } else if (ent_is_string_const(ent)) {
- dump_string_cst(obst, ent);
- } else if (is_Array_type(type)) {
- dump_array_init(env, obst, ent);
- } else if (is_compound_type(type)) {
- dump_compound_init(env, obst, ent);
} else {
- assert(0 && "unsupported type");
+ if (is_atomic_entity(ent)) {
+ dump_atomic_init(env, obst, get_atomic_ent_value(ent));
+ } else {
+ /* sort_compound_ent_values(ent); */
+
+ switch (get_type_tpop_code(get_entity_type(ent))) {
+ case tpo_array:
+ if (ent_is_string_const(ent))
+ dump_string_cst(obst, ent);
+ else
+ dump_compound_init(env, obst, ent);
+ break;
+ case tpo_struct:
+ case tpo_class:
+ case tpo_union:
+ dump_compound_init(env, obst, ent);
+ break;
+ default:
+ assert(0);
+ }
+ }
}
}
if (is_entity_backend_marked(ent) ||
get_entity_visibility(ent) != visibility_external_allocated) {
waitq_put(worklist, ent);
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
}
}
} else {
- inc_master_type_visited();
for (i = 0; i < n; i++) {
ir_entity *ent = get_compound_member(gt, i);
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
waitq_put(worklist, ent);
}
}