Adapted cparser to CopyB lowering changes.
[cparser] / ast2firm.c
index 0dfd8c5..d9cf3f5 100644 (file)
 #include "types.h"
 #include "type_hash.h"
 #include "mangle.h"
-#include "walk_statements.h"
+#include "walk.h"
 #include "warning.h"
 #include "printer.h"
 #include "entitymap_t.h"
 #include "driver/firm_opt.h"
-#include "driver/firm_cmdline.h"
 
 typedef struct trampoline_region trampoline_region;
 struct trampoline_region {
@@ -57,6 +56,8 @@ struct trampoline_region {
        ir_entity        *region;      /**< created region for the trampoline */
 };
 
+fp_model_t firm_fp_model = fp_model_precise;
+
 static const backend_params *be_params;
 
 static ir_type *ir_type_char;
@@ -80,9 +81,6 @@ static label_t  **all_labels;
 static entity_t **inner_functions;
 static ir_node   *ijmp_list;
 static bool       constant_folding;
-static bool       initializer_use_bitfield_basetype;
-
-extern bool       have_const_functions;
 
 static const entity_t     *current_function_entity;
 static ir_node            *current_function_name;
@@ -92,8 +90,8 @@ static ir_graph           *current_function;
 static translation_unit_t *current_translation_unit;
 static trampoline_region  *current_trampolines;
 static ir_type            *current_outer_frame;
-static ir_type            *current_outer_value_type;
 static ir_node            *current_static_link;
+static ir_entity          *current_vararg_entity;
 
 static entitymap_t  entitymap;
 
@@ -113,12 +111,6 @@ typedef enum declaration_kind_t {
 } declaration_kind_t;
 
 static ir_mode *get_ir_mode_storage(type_t *type);
-/*
- * get arithmetic mode for a type. This is different from get_ir_mode_storage,
- * int that it returns bigger modes for floating point on some platforms
- * (x87 internally does arithemtic with 80bits)
- */
-static ir_mode *get_ir_mode_arithmetic(type_t *type);
 
 static ir_type *get_ir_type_incomplete(type_t *type);
 
@@ -129,15 +121,13 @@ static void enqueue_inner_function(entity_t *entity)
        ARR_APP1(entity_t*, inner_functions, entity);
 }
 
-ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
+static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
 {
        const entity_t *entity = get_irg_loc_description(irg, pos);
 
        if (entity != NULL) {
-               warningf(&entity->base.source_position,
-                        "%s '%#T' might be used uninitialized",
-                        get_entity_kind_name(entity->kind),
-                        entity->declaration.type, entity->base.symbol);
+               source_position_t const *const pos = &entity->base.source_position;
+               warningf(WARN_UNINITIALIZED, pos, "'%N' might be used uninitialized", entity);
        }
        return new_r_Unknown(irg, mode);
 }
@@ -148,7 +138,7 @@ static const char *dbg_retrieve(const dbg_info *dbg, unsigned *line)
        if (pos == NULL)
                return NULL;
        if (line != NULL)
-               *line = pos->linenr;
+               *line = pos->lineno;
        return pos->input_name;
 }
 
@@ -172,6 +162,18 @@ static type_dbg_info *get_type_dbg_info_(const type_t *type)
        return (type_dbg_info*) type;
 }
 
+/* is the current block a reachable one? */
+static bool currently_reachable(void)
+{
+       ir_node *const block = get_cur_block();
+       return block != NULL && !is_Bad(block);
+}
+
+static void set_unreachable_now(void)
+{
+       set_cur_block(NULL);
+}
+
 static ir_mode *atomic_modes[ATOMIC_TYPE_LAST+1];
 
 static ir_mode *mode_int, *mode_uint;
@@ -180,6 +182,15 @@ static ir_node *_expression_to_firm(const expression_t *expression);
 static ir_node *expression_to_firm(const expression_t *expression);
 static void create_local_declaration(entity_t *entity);
 
+static unsigned decide_modulo_shift(unsigned type_size)
+{
+       if (architecture_modulo_shift == 0)
+               return 0;
+       if (type_size < architecture_modulo_shift)
+               return architecture_modulo_shift;
+       return type_size;
+}
+
 static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
 {
        unsigned flags = get_atomic_type_flags(kind);
@@ -190,7 +201,7 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
                ir_mode_sort    sort;
                unsigned        bit_size     = size * 8;
                bool            is_signed    = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0;
-               unsigned        modulo_shift;
+               unsigned        modulo_shift = 0;
                ir_mode_arithmetic arithmetic;
 
                if (flags & ATOMIC_TYPE_FLAG_INTEGER) {
@@ -199,13 +210,12 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
                                 bit_size);
                        sort         = irms_int_number;
                        arithmetic   = irma_twos_complement;
-                       modulo_shift = bit_size < machine_size ? machine_size : bit_size;
+                       modulo_shift = decide_modulo_shift(bit_size);
                } else {
                        assert(flags & ATOMIC_TYPE_FLAG_FLOAT);
                        snprintf(name, sizeof(name), "F%u", bit_size);
                        sort         = irms_float_number;
                        arithmetic   = irma_ieee754;
-                       modulo_shift = 0;
                }
                return new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
                                   modulo_shift);
@@ -227,26 +237,6 @@ static void init_atomic_modes(void)
 
        /* there's no real void type in firm */
        atomic_modes[ATOMIC_TYPE_VOID] = atomic_modes[ATOMIC_TYPE_CHAR];
-
-       /* initialize pointer modes */
-       char            name[64];
-       ir_mode_sort    sort         = irms_reference;
-       unsigned        bit_size     = machine_size;
-       bool            is_signed    = 0;
-       ir_mode_arithmetic arithmetic   = irma_twos_complement;
-       unsigned        modulo_shift
-               = bit_size < machine_size ? machine_size : bit_size;
-
-       snprintf(name, sizeof(name), "p%u", machine_size);
-       ir_mode *ptr_mode = new_ir_mode(name, sort, bit_size, is_signed, arithmetic,
-                                       modulo_shift);
-
-       set_reference_mode_signed_eq(ptr_mode, atomic_modes[get_intptr_kind()]);
-       set_reference_mode_unsigned_eq(ptr_mode, atomic_modes[get_uintptr_kind()]);
-
-       /* Hmm, pointers should be machine size */
-       set_modeP_data(ptr_mode);
-       set_modeP_code(ptr_mode);
 }
 
 ir_mode *get_atomic_mode(atomic_type_kind_t kind)
@@ -316,7 +306,7 @@ static ir_type *create_atomic_type(atomic_type_kind_t akind, const type_t *type)
 /**
  * Creates a Firm type for a complex type
  */
-static ir_type *create_complex_type(const complex_type_t *type)
+static ir_type *create_complex_type(const atomic_type_t *type)
 {
        atomic_type_kind_t  kind = type->akind;
        ir_mode            *mode = atomic_modes[kind];
@@ -331,9 +321,9 @@ static ir_type *create_complex_type(const complex_type_t *type)
 /**
  * Creates a Firm type for an imaginary type
  */
-static ir_type *create_imaginary_type(imaginary_type_t *type)
+static ir_type *create_imaginary_type(const atomic_type_t *type)
 {
-       return create_atomic_type(type->akind, (const type_t*) type);
+       return create_atomic_type(type->akind, (const type_t*)type);
 }
 
 /**
@@ -425,9 +415,9 @@ static ir_type *create_pointer_type(pointer_type_t *type)
        type_dbg_info *dbgi         = get_type_dbg_info_((const type_t*) type);
        type_t        *points_to    = type->points_to;
        ir_type       *ir_points_to = get_ir_type_incomplete(points_to);
-       ir_type       *ir_type      = new_d_type_pointer(ir_points_to, dbgi);
+       ir_type       *irtype       = new_d_type_pointer(ir_points_to, dbgi);
 
-       return ir_type;
+       return irtype;
 }
 
 static ir_type *create_reference_type(reference_type_t *type)
@@ -435,9 +425,9 @@ static ir_type *create_reference_type(reference_type_t *type)
        type_dbg_info *dbgi         = get_type_dbg_info_((const type_t*) type);
        type_t        *refers_to    = type->refers_to;
        ir_type       *ir_refers_to = get_ir_type_incomplete(refers_to);
-       ir_type       *ir_type      = new_d_type_pointer(ir_refers_to, dbgi);
+       ir_type       *irtype       = new_d_type_pointer(ir_refers_to, dbgi);
 
-       return ir_type;
+       return irtype;
 }
 
 static ir_type *create_array_type(array_type_t *type)
@@ -445,27 +435,27 @@ static ir_type *create_array_type(array_type_t *type)
        type_dbg_info *dbgi            = get_type_dbg_info_((const type_t*) type);
        type_t        *element_type    = type->element_type;
        ir_type       *ir_element_type = get_ir_type(element_type);
-       ir_type       *ir_type         = new_d_type_array(1, ir_element_type, dbgi);
+       ir_type       *irtype          = new_d_type_array(1, ir_element_type, dbgi);
 
        const int align = get_type_alignment_bytes(ir_element_type);
-       set_type_alignment_bytes(ir_type, align);
+       set_type_alignment_bytes(irtype, align);
 
        if (type->size_constant) {
                int n_elements = type->size;
 
-               set_array_bounds_int(ir_type, 0, 0, n_elements);
+               set_array_bounds_int(irtype, 0, 0, n_elements);
 
                size_t elemsize = get_type_size_bytes(ir_element_type);
                if (elemsize % align > 0) {
                        elemsize += align - (elemsize % align);
                }
-               set_type_size_bytes(ir_type, n_elements * elemsize);
+               set_type_size_bytes(irtype, n_elements * elemsize);
        } else {
-               set_array_lower_bound_int(ir_type, 0, 0);
+               set_array_lower_bound_int(irtype, 0, 0);
        }
-       set_type_state(ir_type, layout_fixed);
+       set_type_state(irtype, layout_fixed);
 
-       return ir_type;
+       return irtype;
 }
 
 /**
@@ -534,21 +524,20 @@ static ir_type *get_unsigned_int_type_for_bit_size(ir_type *base_tp,
        return res;
 }
 
-static ir_type *create_bitfield_type(bitfield_type_t *const type)
+static ir_type *create_bitfield_type(const entity_t *entity)
 {
-       type_t *base = skip_typeref(type->base_type);
+       assert(entity->kind == ENTITY_COMPOUND_MEMBER);
+       type_t *base = skip_typeref(entity->declaration.type);
        assert(base->kind == TYPE_ATOMIC || base->kind == TYPE_ENUM);
        ir_type *irbase = get_ir_type(base);
 
-       unsigned size = type->bit_size;
+       unsigned bit_size = entity->compound_member.bit_size;
 
        assert(!is_type_float(base));
        if (is_type_signed(base)) {
-               return get_signed_int_type_for_bit_size(irbase, size,
-                                                       (const type_t*) type);
+               return get_signed_int_type_for_bit_size(irbase, bit_size, base);
        } else {
-               return get_unsigned_int_type_for_bit_size(irbase, size,
-                                                         (const type_t*) type);
+               return get_unsigned_int_type_for_bit_size(irbase, bit_size, base);
        }
 }
 
@@ -571,10 +560,10 @@ static ir_type *create_compound_type(compound_type_t *type,
                return compound->irtype;
        }
 
-       symbol_t *symbol = compound->base.symbol;
+       symbol_t *type_symbol = compound->base.symbol;
        ident    *id;
-       if (symbol != NULL) {
-               id = new_id_from_str(symbol->string);
+       if (type_symbol != NULL) {
+               id = new_id_from_str(type_symbol->string);
        } else {
                if (is_union) {
                        id = id_unique("__anonymous_union.%u");
@@ -614,7 +603,7 @@ static ir_type *create_compound_type(compound_type_t *type,
                ident    *ident;
                if (symbol == NULL) {
                        /* anonymous bitfield member, skip */
-                       if (entry_type->kind == TYPE_BITFIELD)
+                       if (entry->compound_member.bitfield)
                                continue;
                        assert(entry_type->kind == TYPE_COMPOUND_STRUCT
                                        || entry_type->kind == TYPE_COMPOUND_UNION);
@@ -625,7 +614,12 @@ static ir_type *create_compound_type(compound_type_t *type,
 
                dbg_info *dbgi       = get_dbg_info(&entry->base.source_position);
 
-               ir_type   *entry_irtype = get_ir_type(entry_type);
+               ir_type *entry_irtype;
+               if (entry->compound_member.bitfield) {
+                       entry_irtype = create_bitfield_type(entry);
+               } else {
+                       entry_irtype = get_ir_type(entry_type);
+               }
                ir_entity *entity = new_d_entity(irtype, ident, entry_irtype, dbgi);
 
                set_entity_offset(entity, entry->compound_member.offset);
@@ -646,11 +640,11 @@ static ir_type *create_compound_type(compound_type_t *type,
 
 static ir_type *create_enum_type(enum_type_t *const type)
 {
-       type->base.firm_type = ir_type_int;
+       type->base.base.firm_type = ir_type_int;
 
-       ir_mode *const mode    = mode_int;
-       tarval  *const one     = get_mode_one(mode);
-       tarval  *      tv_next = get_mode_null(mode);
+       ir_mode   *const mode    = mode_int;
+       ir_tarval *const one     = get_mode_one(mode);
+       ir_tarval *      tv_next = get_mode_null(mode);
 
        bool constant_folding_old = constant_folding;
        constant_folding = true;
@@ -675,7 +669,7 @@ static ir_type *create_enum_type(enum_type_t *const type)
 
        constant_folding = constant_folding_old;
 
-       return create_atomic_type(type->akind, (const type_t*) type);
+       return create_atomic_type(type->base.akind, (const type_t*) type);
 }
 
 static ir_type *get_ir_type_incomplete(type_t *type)
@@ -719,10 +713,10 @@ ir_type *get_ir_type(type_t *type)
                firm_type = create_atomic_type(type->atomic.akind, type);
                break;
        case TYPE_COMPLEX:
-               firm_type = create_complex_type(&type->complex);
+               firm_type = create_complex_type(&type->atomic);
                break;
        case TYPE_IMAGINARY:
-               firm_type = create_imaginary_type(&type->imaginary);
+               firm_type = create_imaginary_type(&type->atomic);
                break;
        case TYPE_FUNCTION:
                firm_type = create_method_type(&type->function, false);
@@ -745,16 +739,9 @@ ir_type *get_ir_type(type_t *type)
        case TYPE_ENUM:
                firm_type = create_enum_type(&type->enumt);
                break;
-       case TYPE_BUILTIN:
-               firm_type = get_ir_type(type->builtin.real_type);
-               break;
-       case TYPE_BITFIELD:
-               firm_type = create_bitfield_type(&type->bitfield);
-               break;
 
        case TYPE_TYPEOF:
        case TYPE_TYPEDEF:
-       case TYPE_INVALID:
                break;
        }
        if (firm_type == NULL)
@@ -778,6 +765,11 @@ static ir_mode *get_ir_mode_storage(type_t *type)
        return mode;
 }
 
+/*
+ * get arithmetic mode for a type. This is different from get_ir_mode_storage,
+ * int that it returns bigger modes for floating point on some platforms
+ * (x87 internally does arithemtic with 80bits)
+ */
 static ir_mode *get_ir_mode_arithmetic(type_t *type)
 {
        ir_mode *mode = get_ir_mode_storage(type);
@@ -877,7 +869,12 @@ static const struct {
 
 static ident *rts_idents[lengthof(rts_data)];
 
-static ident* (*create_ld_ident)(entity_t*) = create_name_linux_elf;
+static create_ld_ident_func create_ld_ident = create_name_linux_elf;
+
+void set_create_ld_ident(ident *(*func)(entity_t*))
+{
+       create_ld_ident = func;
+}
 
 /**
  * Handle GNU attributes for entities
@@ -892,11 +889,10 @@ static void handle_decl_modifiers(ir_entity *irentity, entity_t *entity)
 
        if (is_method_entity(irentity)) {
                if (modifiers & DM_PURE) {
-                       set_entity_additional_property(irentity, mtp_property_pure);
+                       set_entity_additional_properties(irentity, mtp_property_pure);
                }
                if (modifiers & DM_CONST) {
-                       set_entity_additional_property(irentity, mtp_property_const);
-                       have_const_functions = true;
+                       add_entity_additional_properties(irentity, mtp_property_const);
                }
        }
        if (modifiers & DM_USED) {
@@ -933,15 +929,16 @@ static bool is_main(entity_t *entity)
 static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
 {
        assert(entity->kind == ENTITY_FUNCTION);
-       if (entity->function.irentity != NULL) {
+       if (entity->function.irentity != NULL)
                return entity->function.irentity;
-       }
 
-       entity_t *original_entity = entity;
-       if (entity->function.btk != bk_none) {
-               entity = get_builtin_replacement(entity);
-               if (entity == NULL)
-                       return NULL;
+       switch (entity->function.btk) {
+       case BUILTIN_NONE:
+       case BUILTIN_LIBC:
+       case BUILTIN_LIBC_CHECK:
+               break;
+       default:
+               return NULL;
        }
 
        if (is_main(entity)) {
@@ -983,7 +980,7 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
                nested_function = true;
 
        dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
-       irentity             = new_d_entity(owner_type, id, ir_type_method, dbgi);
+       irentity = new_d_entity(owner_type, id, ir_type_method, dbgi);
 
        ident *ld_id;
        if (nested_function)
@@ -1015,12 +1012,12 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
                }
        } else {
                /* nested functions are always local */
-               set_entity_visibility(irentity, ir_visibility_local);
+               set_entity_visibility(irentity, ir_visibility_local);
        }
 
        /* We should check for file scope here, but as long as we compile C only
           this is not needed. */
-       if (! firm_opt.freestanding && !has_body) {
+       if (!freestanding && !has_body) {
                /* check for a known runtime function */
                for (size_t i = 0; i < lengthof(rts_data); ++i) {
                        if (id != rts_idents[i])
@@ -1053,8 +1050,8 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
        entitymap_insert(&entitymap, symbol, irentity);
 
 entity_created:
-       original_entity->declaration.kind  = DECLARATION_KIND_FUNCTION;
-       original_entity->function.irentity = irentity;
+       entity->declaration.kind  = DECLARATION_KIND_FUNCTION;
+       entity->function.irentity = irentity;
 
        return irentity;
 }
@@ -1063,35 +1060,37 @@ entity_created:
  * Creates a SymConst for a given entity.
  *
  * @param dbgi    debug info
- * @param mode    the (reference) mode for the SymConst
  * @param entity  the entity
  */
-static ir_node *create_symconst(dbg_info *dbgi, ir_mode *mode,
-                                ir_entity *entity)
+static ir_node *create_symconst(dbg_info *dbgi, ir_entity *entity)
 {
        assert(entity != NULL);
        union symconst_symbol sym;
        sym.entity_p = entity;
-       return new_d_SymConst(dbgi, mode, sym, symconst_addr_ent);
+       return new_d_SymConst(dbgi, mode_P, sym, symconst_addr_ent);
 }
 
 static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
 {
        ir_mode *value_mode = get_irn_mode(value);
 
-       if (value_mode == dest_mode || is_Bad(value))
+       if (value_mode == dest_mode)
                return value;
 
        if (dest_mode == mode_b) {
                ir_node *zero = new_Const(get_mode_null(value_mode));
-               ir_node *cmp  = new_d_Cmp(dbgi, value, zero);
-               ir_node *proj = new_d_Proj(dbgi, cmp, mode_b, pn_Cmp_Lg);
-               return proj;
+               ir_node *cmp  = new_d_Cmp(dbgi, value, zero, ir_relation_less_greater);
+               return cmp;
        }
 
        return new_d_Conv(dbgi, value, dest_mode);
 }
 
+static ir_node *create_Const_from_bool(ir_mode *const mode, bool const v)
+{
+       return new_Const((v ? get_mode_one : get_mode_null)(mode));
+}
+
 /**
  * Creates a SymConst node representing a wide string literal.
  *
@@ -1123,14 +1122,14 @@ static ir_node *wide_string_literal_to_firm(
        const char              *p    = literal->value.begin;
        for (size_t i = 0; i < slen; ++i) {
                assert(p < literal->value.begin + literal->value.size);
-               utf32              v  = read_utf8_char(&p);
-               tarval           *tv  = new_tarval_from_long(v, mode);
+               utf32               = read_utf8_char(&p);
+               ir_tarval        *tv  = new_tarval_from_long(v, mode);
                ir_initializer_t *val = create_initializer_tarval(tv);
                set_initializer_compound_value(initializer, i, val);
        }
        set_entity_initializer(entity, initializer);
 
-       return create_symconst(dbgi, mode_P_data, entity);
+       return create_symconst(dbgi, entity);
 }
 
 /**
@@ -1167,13 +1166,13 @@ static ir_node *string_to_firm(const source_position_t *const src_pos,
 
        ir_initializer_t *initializer = create_initializer_compound(slen);
        for (size_t i = 0; i < slen; ++i) {
-               tarval           *tv  = new_tarval_from_long(string[i], mode);
+               ir_tarval        *tv  = new_tarval_from_long(string[i], mode);
                ir_initializer_t *val = create_initializer_tarval(tv);
                set_initializer_compound_value(initializer, i, val);
        }
        set_entity_initializer(entity, initializer);
 
-       return create_symconst(dbgi, mode_P_data, entity);
+       return create_symconst(dbgi, entity);
 }
 
 static bool try_create_integer(literal_expression_t *literal,
@@ -1185,8 +1184,8 @@ static bool try_create_integer(literal_expression_t *literal,
        assert(type->kind == TYPE_ATOMIC);
        atomic_type_kind_t akind = type->atomic.akind;
 
-       ir_mode *mode = atomic_modes[akind];
-       tarval  *tv   = new_integer_tarval_from_str(string, size, 1, base, mode);
+       ir_mode   *mode = atomic_modes[akind];
+       ir_tarval *tv   = new_integer_tarval_from_str(string, size, 1, base, mode);
        if (tv == tarval_bad)
                return false;
 
@@ -1197,12 +1196,12 @@ static bool try_create_integer(literal_expression_t *literal,
 
 static void create_integer_tarval(literal_expression_t *literal)
 {
-       unsigned  us     = 0;
-       unsigned  ls     = 0;
-       symbol_t *suffix = literal->suffix;
+       unsigned        us     = 0;
+       unsigned        ls     = 0;
+       const string_t *suffix = &literal->suffix;
        /* parse suffix */
-       if (suffix != NULL) {
-               for (const char *c = suffix->string; *c != '\0'; ++c) {
+       if (suffix->size > 0) {
+               for (const char *c = suffix->begin; *c != '\0'; ++c) {
                        if (*c == 'u' || *c == 'U') { ++us; }
                        if (*c == 'l' || *c == 'L') { ++ls; }
                }
@@ -1273,7 +1272,7 @@ static ir_node *literal_to_firm(const literal_expression_t *literal)
        ir_mode    *mode   = get_ir_mode_storage(type);
        const char *string = literal->value.begin;
        size_t      size   = literal->value.size;
-       tarval     *tv;
+       ir_tarval  *tv;
 
        switch (literal->base.kind) {
        case EXPR_LITERAL_WIDE_CHARACTER: {
@@ -1286,6 +1285,8 @@ static ir_node *literal_to_firm(const literal_expression_t *literal)
        }
        case EXPR_LITERAL_CHARACTER: {
                long long int v;
+               bool char_is_signed
+                       = get_atomic_type_flags(ATOMIC_TYPE_CHAR) & ATOMIC_TYPE_FLAG_SIGNED;
                if (size == 1 && char_is_signed) {
                        v = (signed char)string[0];
                } else {
@@ -1413,7 +1414,7 @@ static ir_node *create_trampoline(dbg_info *dbgi, ir_mode *mode,
        assert(entity != NULL);
        ir_node *in[3];
        in[0] = get_trampoline_region(dbgi, entity);
-       in[1] = create_symconst(dbgi, mode, entity);
+       in[1] = create_symconst(dbgi, entity);
        in[2] = get_irg_frame(current_ir_graph);
 
        ir_node *irn = new_d_Builtin(dbgi, get_store(), 3, in, ir_bk_inner_trampoline, get_unknown_type());
@@ -1478,25 +1479,6 @@ static ir_node *do_strict_conv(dbg_info *dbgi, ir_node *node)
        return new_d_strictConv(dbgi, node, mode);
 }
 
-/**
- * Returns the address of a global variable.
- *
- * @param dbgi      debug info
- * @param variable  the variable
- */
-static ir_node *get_global_var_address(dbg_info *const dbgi,
-                                       const variable_t *const variable)
-{
-       ir_entity *const irentity = variable->v.entity;
-       if (variable->thread_local) {
-               ir_node *const no_mem = new_NoMem();
-               ir_node *const tls    = get_irg_tls(current_ir_graph);
-               return new_d_simpleSel(dbgi, no_mem, tls, irentity);
-       } else {
-               return create_symconst(dbgi, mode_P_data, irentity);
-       }
-}
-
 /**
  * Returns the correct base address depending on whether it is a parameter or a
  * normal local variable.
@@ -1505,7 +1487,7 @@ static ir_node *get_local_frame(ir_entity *const ent)
 {
        ir_graph      *const irg   = current_ir_graph;
        const ir_type *const owner = get_entity_owner(ent);
-       if (owner == current_outer_frame || owner == current_outer_value_type) {
+       if (owner == current_outer_frame) {
                assert(current_static_link != NULL);
                return current_static_link;
        } else {
@@ -1547,20 +1529,19 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        /* make sure the type is constructed */
        (void) get_ir_type(type);
 
-       if (entity->kind == ENTITY_FUNCTION && entity->function.btk != bk_none) {
+       if (entity->kind == ENTITY_FUNCTION
+           && entity->function.btk != BUILTIN_NONE) {
                ir_entity *irentity = get_function_entity(entity, NULL);
                /* for gcc compatibility we have to produce (dummy) addresses for some
                 * builtins which don't have entities */
                if (irentity == NULL) {
-                       if (warning.other) {
-                               warningf(&ref->base.source_position,
-                                               "taking address of builtin '%Y'",
-                                               ref->entity->base.symbol);
-                       }
+                       source_position_t const *const pos = &ref->base.source_position;
+                       symbol_t          const *const sym = ref->entity->base.symbol;
+                       warningf(WARN_OTHER, pos, "taking address of builtin '%Y'", sym);
 
                        /* simply create a NULL pointer */
                        ir_mode  *mode = get_ir_mode_arithmetic(type_void_ptr);
-                       ir_node  *res  = new_Const_long(mode, 0);
+                       ir_node  *res  = new_Const(get_mode_null(mode));
 
                        return res;
                }
@@ -1581,14 +1562,13 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
                return create_conv(NULL, value, get_ir_mode_arithmetic(type));
        }
        case DECLARATION_KIND_FUNCTION: {
-               ir_mode *const mode = get_ir_mode_storage(type);
-               return create_symconst(dbgi, mode, entity->function.irentity);
+               return create_symconst(dbgi, entity->function.irentity);
        }
        case DECLARATION_KIND_INNER_FUNCTION: {
                ir_mode *const mode = get_ir_mode_storage(type);
                if (!entity->function.goto_to_outer && !entity->function.need_closure) {
                        /* inner function not using the closure */
-                       return create_symconst(dbgi, mode, entity->function.irentity);
+                       return create_symconst(dbgi, entity->function.irentity);
                } else {
                        /* need trampoline here */
                        return create_trampoline(dbgi, mode, entity->function.irentity);
@@ -1596,7 +1576,7 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        }
        case DECLARATION_KIND_GLOBAL_VARIABLE: {
                const variable_t *variable = &entity->variable;
-               ir_node *const addr = get_global_var_address(dbgi, variable);
+               ir_node *const addr = create_symconst(dbgi, variable->v.entity);
                return deref_address(dbgi, variable->base.type, addr);
        }
 
@@ -1638,7 +1618,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                 * as an indicator for no real address) */
                return NULL;
        case DECLARATION_KIND_GLOBAL_VARIABLE: {
-               ir_node *const addr = get_global_var_address(dbgi, &entity->variable);
+               ir_node *const addr = create_symconst(dbgi, entity->variable.v.entity);
                return addr;
        }
        case DECLARATION_KIND_LOCAL_VARIABLE_ENTITY: {
@@ -1660,9 +1640,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                return entity->variable.v.vla_base;
 
        case DECLARATION_KIND_FUNCTION: {
-               type_t  *const type = skip_typeref(entity->declaration.type);
-               ir_mode *const mode = get_ir_mode_storage(type);
-               return create_symconst(dbgi, mode, entity->function.irentity);
+               return create_symconst(dbgi, entity->function.irentity);
        }
 
        case DECLARATION_KIND_INNER_FUNCTION: {
@@ -1670,7 +1648,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                ir_mode *const mode = get_ir_mode_storage(type);
                if (!entity->function.goto_to_outer && !entity->function.need_closure) {
                        /* inner function not using the closure */
-                       return create_symconst(dbgi, mode, entity->function.irentity);
+                       return create_symconst(dbgi, entity->function.irentity);
                } else {
                        /* need trampoline here */
                        return create_trampoline(dbgi, mode, entity->function.irentity);
@@ -1684,72 +1662,6 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        panic("reference to declaration with unknown type found");
 }
 
-/**
- * Generate an unary builtin.
- *
- * @param kind           the builtin kind to generate
- * @param op             the operand
- * @param function_type  the function type for the GNU builtin routine
- * @param db             debug info
- */
-static ir_node *gen_unary_builtin(ir_builtin_kind kind, expression_t *op, type_t *function_type, dbg_info *db)
-{
-       ir_node *in[1];
-       in[0] = expression_to_firm(op);
-
-       ir_type *tp  = get_ir_type(function_type);
-       ir_type *res = get_method_res_type(tp, 0);
-       ir_node *irn = new_d_Builtin(db, get_irg_no_mem(current_ir_graph), 1, in, kind, tp);
-       set_irn_pinned(irn, op_pin_state_floats);
-       return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
-}
-
-/**
- * Generate a pinned unary builtin.
- *
- * @param kind           the builtin kind to generate
- * @param op             the operand
- * @param function_type  the function type for the GNU builtin routine
- * @param db             debug info
- */
-static ir_node *gen_unary_builtin_pinned(ir_builtin_kind kind, expression_t *op,
-                                         type_t *function_type, dbg_info *db)
-{
-       ir_node *in[1];
-       in[0] = expression_to_firm(op);
-
-       ir_type *tp  = get_ir_type(function_type);
-       ir_type *res = get_method_res_type(tp, 0);
-       ir_node *mem = get_store();
-       ir_node *irn = new_d_Builtin(db, mem, 1, in, kind, tp);
-       set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-       return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
-}
-
-/**
- * Generate an binary-void-return builtin.
- *
- * @param kind           the builtin kind to generate
- * @param op1            the first operand
- * @param op2            the second operand
- * @param function_type  the function type for the GNU builtin routine
- * @param db             debug info
- */
-static ir_node *gen_binary_builtin_mem(ir_builtin_kind kind, expression_t *op1,
-                                       expression_t *op2, type_t *function_type,
-                                                                          dbg_info *db)
-{
-       ir_node *in[2];
-       in[0] = expression_to_firm(op1);
-       in[1] = expression_to_firm(op2);
-
-       ir_type *tp  = get_ir_type(function_type);
-       ir_node *mem = get_store();
-       ir_node *irn = new_d_Builtin(db, mem, 2, in, kind, tp);
-       set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-       return NULL;
-}
-
 /**
  * Transform calls to builtin functions.
  */
@@ -1760,16 +1672,15 @@ static ir_node *process_builtin_call(const call_expression_t *call)
        assert(call->function->kind == EXPR_REFERENCE);
        reference_expression_t *builtin = &call->function->reference;
 
-       type_t *type = skip_typeref(builtin->base.type);
-       assert(is_type_pointer(type));
+       type_t *expr_type = skip_typeref(builtin->base.type);
+       assert(is_type_pointer(expr_type));
 
-       type_t   *function_type = skip_typeref(type->pointer.points_to);
+       type_t *function_type = skip_typeref(expr_type->pointer.points_to);
 
        switch (builtin->entity->function.btk) {
-       case bk_gnu_builtin_alloca: {
-               if (call->arguments == NULL || call->arguments->next != NULL) {
-                       panic("invalid number of parameters on __builtin_alloca");
-               }
+       case BUILTIN_NONE:
+               break;
+       case BUILTIN_ALLOCA: {
                expression_t *argument = call->arguments->expression;
                ir_node      *size     = expression_to_firm(argument);
 
@@ -1782,136 +1693,49 @@ static ir_node *process_builtin_call(const call_expression_t *call)
 
                return res;
        }
-
-       case bk_gnu_builtin_huge_val:
-       case bk_gnu_builtin_huge_valf:
-       case bk_gnu_builtin_huge_vall:
-       case bk_gnu_builtin_inf:
-       case bk_gnu_builtin_inff:
-       case bk_gnu_builtin_infl: {
-               type_t  *type = function_type->function.return_type;
-               ir_mode *mode = get_ir_mode_arithmetic(type);
-               tarval  *tv   = get_mode_infinite(mode);
-               ir_node *res  = new_d_Const(dbgi, tv);
-               return   res;
-       }
-       case bk_gnu_builtin_nan:
-       case bk_gnu_builtin_nanf:
-       case bk_gnu_builtin_nanl: {
+       case BUILTIN_INF: {
+               type_t    *type = function_type->function.return_type;
+               ir_mode   *mode = get_ir_mode_arithmetic(type);
+               ir_tarval *tv   = get_mode_infinite(mode);
+               ir_node   *res  = new_d_Const(dbgi, tv);
+               return res;
+       }
+       case BUILTIN_NAN: {
                /* Ignore string for now... */
                assert(is_type_function(function_type));
-               type_t  *type = function_type->function.return_type;
-               ir_mode *mode = get_ir_mode_arithmetic(type);
-               tarval  *tv   = get_mode_NAN(mode);
-               ir_node *res  = new_d_Const(dbgi, tv);
+               type_t    *type = function_type->function.return_type;
+               ir_mode   *mode = get_ir_mode_arithmetic(type);
+               ir_tarval *tv   = get_mode_NAN(mode);
+               ir_node   *res  = new_d_Const(dbgi, tv);
                return res;
        }
-       case bk_gnu_builtin_expect: {
+       case BUILTIN_EXPECT: {
                expression_t *argument = call->arguments->expression;
                return _expression_to_firm(argument);
        }
-       case bk_gnu_builtin_va_end:
+       case BUILTIN_VA_END:
                /* evaluate the argument of va_end for its side effects */
                _expression_to_firm(call->arguments->expression);
                return NULL;
-       case bk_gnu_builtin_frame_address: {
-               expression_t *const expression = call->arguments->expression;
-               bool val = fold_constant_to_bool(expression);
-               if (!val) {
-                       /* the nice case */
-                       return get_irg_frame(current_ir_graph);
-               } else {
-                       /* get the argument */
-                       ir_node *in[2];
-
-                       in[0] = expression_to_firm(expression);
-                       in[1] = get_irg_frame(current_ir_graph);
-                       ir_type *tp  = get_ir_type(function_type);
-                       ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_frame_address, tp);
-                       return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
-               }
-       }
-       case bk_gnu_builtin_return_address: {
-
-               expression_t *const expression = call->arguments->expression;
-               ir_node *in[2];
-
-               in[0] = expression_to_firm(expression);
-               in[1] = get_irg_frame(current_ir_graph);
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp);
-               return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
-       }
-       case bk_gnu_builtin_ffs:
-                return gen_unary_builtin(ir_bk_ffs,      call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_clz:
-                return gen_unary_builtin(ir_bk_clz,      call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_ctz:
-                return gen_unary_builtin(ir_bk_ctz,      call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_popcount:
-       case bk_ms__popcount:
-                return gen_unary_builtin(ir_bk_popcount, call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_parity:
-                return gen_unary_builtin(ir_bk_parity,   call->arguments->expression, function_type, dbgi);
-       case bk_gnu_builtin_prefetch: {
-               call_argument_t *const args = call->arguments;
-               expression_t *const addr    = args->expression;
-               ir_node *in[3];
-
-               in[0] = _expression_to_firm(addr);
-               if (args->next != NULL) {
-                       expression_t *const rw = args->next->expression;
-
-                       in[1] = _expression_to_firm(rw);
-
-                       if (args->next->next != NULL) {
-                               expression_t *const locality = args->next->next->expression;
-
-                               in[2] = expression_to_firm(locality);
-                       } else {
-                               in[2] = new_Const_long(mode_int, 3);
-                       }
-               } else {
-                       in[1] = new_Const_long(mode_int, 0);
-                       in[2] = new_Const_long(mode_int, 3);
-               }
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), 3, in, ir_bk_prefetch, tp);
-               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-               return NULL;
-       }
-       case bk_gnu_builtin_trap:
-       case bk_ms__ud2:
-       {
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), 0, NULL, ir_bk_trap, tp);
-               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-               return NULL;
-       }
-       case bk_ms__debugbreak: {
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), 0, NULL, ir_bk_debugbreak, tp);
-               set_store(new_Proj(irn, mode_M, pn_Builtin_M));
-               return NULL;
-       }
-       case bk_ms_ReturnAddress: {
-               ir_node *in[2];
-
-               in[0] = new_Const_long(mode_int, 0);
-               in[1] = get_irg_frame(current_ir_graph);
-               ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp);
-               return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
-       }
-       case bk_ms_rotl:
-       case bk_ms_rotl64: {
+       case BUILTIN_OBJECT_SIZE: {
+               /* determine value of "type" */
+               expression_t *type_expression = call->arguments->next->expression;
+               long          type_val        = fold_constant_to_int(type_expression);
+               type_t       *type            = function_type->function.return_type;
+               ir_mode      *mode            = get_ir_mode_arithmetic(type);
+               /* just produce a "I don't know" result */
+               ir_tarval    *result          = type_val & 2 ? get_mode_null(mode) :
+                                               get_mode_minus_one(mode);
+
+               return new_d_Const(dbgi, result);
+       }
+       case BUILTIN_ROTL: {
                ir_node *val  = expression_to_firm(call->arguments->expression);
                ir_node *shf  = expression_to_firm(call->arguments->next->expression);
                ir_mode *mode = get_irn_mode(val);
                return new_d_Rotl(dbgi, val, create_conv(dbgi, shf, mode_uint), mode);
        }
-       case bk_ms_rotr:
-       case bk_ms_rotr64: {
+       case BUILTIN_ROTR: {
                ir_node *val  = expression_to_firm(call->arguments->expression);
                ir_node *shf  = expression_to_firm(call->arguments->next->expression);
                ir_mode *mode = get_irn_mode(val);
@@ -1919,22 +1743,13 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                ir_node *sub  = new_d_Sub(dbgi, c, create_conv(dbgi, shf, mode_uint), mode_uint);
                return new_d_Rotl(dbgi, val, sub, mode);
        }
-       case bk_ms_byteswap_ushort:
-       case bk_ms_byteswap_ulong:
-       case bk_ms_byteswap_uint64:
-               return gen_unary_builtin(ir_bk_bswap, call->arguments->expression, function_type, dbgi);
-       case bk_ms__inbyte:
-       case bk_ms__inword:
-       case bk_ms__indword:
-               return gen_unary_builtin_pinned(ir_bk_inport, call->arguments->expression, function_type, dbgi);
-       case bk_ms__outbyte:
-       case bk_ms__outword:
-       case bk_ms__outdword:
-               return gen_binary_builtin_mem(ir_bk_outport, call->arguments->expression,
-                       call->arguments->next->expression, function_type, dbgi);
-       default:
-               panic("unsupported builtin found");
+       case BUILTIN_FIRM:
+               break;
+       case BUILTIN_LIBC:
+       case BUILTIN_LIBC_CHECK:
+               panic("builtin did not produce an entity");
        }
+       panic("invalid builtin found");
 }
 
 /**
@@ -1947,42 +1762,29 @@ static ir_node *process_builtin_call(const call_expression_t *call)
 static ir_node *call_expression_to_firm(const call_expression_t *const call)
 {
        dbg_info *const dbgi = get_dbg_info(&call->base.source_position);
-       assert(get_cur_block() != NULL);
+       assert(currently_reachable());
 
-       expression_t *function = call->function;
+       expression_t   *function = call->function;
+       ir_node        *callee   = NULL;
+       bool            firm_builtin = false;
+       ir_builtin_kind firm_builtin_kind = ir_bk_trap;
        if (function->kind == EXPR_REFERENCE) {
                const reference_expression_t *ref    = &function->reference;
                entity_t                     *entity = ref->entity;
 
                if (entity->kind == ENTITY_FUNCTION) {
-                       ir_entity *irentity = entity->function.irentity;
-                       if (irentity == NULL)
-                               irentity = get_function_entity(entity, NULL);
-
-                       if (irentity == NULL && entity->function.btk != bk_none) {
+                       builtin_kind_t builtin = entity->function.btk;
+                       if (builtin == BUILTIN_FIRM) {
+                               firm_builtin = true;
+                               firm_builtin_kind = entity->function.b.firm_builtin_kind;
+                       } else if (builtin != BUILTIN_NONE && builtin != BUILTIN_LIBC
+                                  && builtin != BUILTIN_LIBC_CHECK) {
                                return process_builtin_call(call);
                        }
-
-                       if (irentity == rts_entities[rts_alloca]) {
-                               /* handle alloca() call */
-                               expression_t *argument = call->arguments->expression;
-                               ir_node      *size     = expression_to_firm(argument);
-                               ir_mode      *mode     = get_ir_mode_arithmetic(type_size_t);
-
-                               size = create_conv(dbgi, size, mode);
-
-                               ir_node  *store  = get_store();
-                               ir_node  *alloca = new_d_Alloc(dbgi, store, size,
-                                                              firm_unknown_type, stack_alloc);
-                               ir_node  *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M);
-                               set_store(proj_m);
-                               ir_node  *res    = new_Proj(alloca, mode_P_data, pn_Alloc_res);
-
-                               return res;
-                       }
                }
        }
-       ir_node *callee = expression_to_firm(function);
+       if (!firm_builtin)
+               callee = expression_to_firm(function);
 
        type_t *type = skip_typeref(function->base.type);
        assert(is_type_pointer(type));
@@ -1991,7 +1793,7 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
        assert(is_type_function(points_to));
        function_type_t *function_type = &points_to->function;
 
-       int      n_parameters = 0;
+       int      n_parameters    = 0;
        ir_type *ir_method_type  = get_ir_type((type_t*) function_type);
        ir_type *new_method_type = NULL;
        if (function_type->variadic || function_type->unspecified_parameters) {
@@ -2034,8 +1836,8 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                expression_t *expression = argument->expression;
                ir_node      *arg_node   = expression_to_firm(expression);
 
-               type_t  *type = skip_typeref(expression->base.type);
-               if (!is_type_compound(type)) {
+               type_t *arg_type = skip_typeref(expression->base.type);
+               if (!is_type_compound(arg_type)) {
                        ir_mode *mode = get_ir_mode_storage(expression->base.type);
                        arg_node      = create_conv(dbgi, arg_node, mode);
                        arg_node      = do_strict_conv(dbgi, arg_node);
@@ -2046,26 +1848,50 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                argument = argument->next;
        }
 
-       ir_node  *store = get_store();
-       ir_node  *node  = new_d_Call(dbgi, store, callee, n_parameters, in,
-                                    ir_method_type);
-       ir_node  *mem   = new_d_Proj(dbgi, node, mode_M, pn_Call_M);
-       set_store(mem);
+       ir_node *store;
+       if (function_type->modifiers & DM_CONST) {
+               store = get_irg_no_mem(current_ir_graph);
+       } else {
+               store = get_store();
+       }
 
+       ir_node *node;
        type_t  *return_type = skip_typeref(function_type->return_type);
        ir_node *result      = NULL;
+       if (firm_builtin) {
+               node = new_d_Builtin(dbgi, store, n_parameters, in, firm_builtin_kind,
+                                    ir_method_type);
+               if (! (function_type->modifiers & DM_CONST)) {
+                       ir_node *mem = new_Proj(node, mode_M, pn_Builtin_M);
+                       set_store(mem);
+               }
 
-       if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
-               ir_node *resproj = new_d_Proj(dbgi, node, mode_T, pn_Call_T_result);
-
-               if (is_type_scalar(return_type)) {
-                       ir_mode *mode       = get_ir_mode_storage(return_type);
-                       result              = new_d_Proj(dbgi, resproj, mode, 0);
+               if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+                       assert(is_type_scalar(return_type));
+                       ir_mode *mode = get_ir_mode_storage(return_type);
+                       result = new_Proj(node, mode, pn_Builtin_1_result);
                        ir_mode *mode_arith = get_ir_mode_arithmetic(return_type);
                        result              = create_conv(NULL, result, mode_arith);
-               } else {
-                       ir_mode *mode = mode_P_data;
-                       result        = new_d_Proj(dbgi, resproj, mode, 0);
+               }
+       } else {
+               node = new_d_Call(dbgi, store, callee, n_parameters, in, ir_method_type);
+               if (! (function_type->modifiers & DM_CONST)) {
+                       ir_node *mem = new_Proj(node, mode_M, pn_Call_M);
+                       set_store(mem);
+               }
+
+               if (!is_type_atomic(return_type, ATOMIC_TYPE_VOID)) {
+                       ir_node *resproj = new_Proj(node, mode_T, pn_Call_T_result);
+
+                       if (is_type_scalar(return_type)) {
+                               ir_mode *mode       = get_ir_mode_storage(return_type);
+                               result              = new_Proj(resproj, mode, 0);
+                               ir_mode *mode_arith = get_ir_mode_arithmetic(return_type);
+                               result              = create_conv(NULL, result, mode_arith);
+                       } else {
+                               ir_mode *mode = mode_P_data;
+                               result        = new_Proj(resproj, mode, 0);
+                       }
                }
        }
 
@@ -2115,10 +1941,10 @@ static void assign_value(dbg_info *dbgi, ir_node *addr, type_t *type,
        }
 }
 
-static tarval *create_bitfield_mask(ir_mode *mode, int offset, int size)
+static ir_tarval *create_bitfield_mask(ir_mode *mode, int offset, int size)
 {
-       tarval *all_one   = get_mode_all_one(mode);
-       int     mode_size = get_mode_size_bits(mode);
+       ir_tarval *all_one   = get_mode_all_one(mode);
+       int        mode_size = get_mode_size_bits(mode);
 
        assert(offset >= 0);
        assert(size   >= 0);
@@ -2127,12 +1953,12 @@ static tarval *create_bitfield_mask(ir_mode *mode, int offset, int size)
                return all_one;
        }
 
-       long    shiftr    = get_mode_size_bits(mode) - size;
-       long    shiftl    = offset;
-       tarval *tv_shiftr = new_tarval_from_long(shiftr, mode_uint);
-       tarval *tv_shiftl = new_tarval_from_long(shiftl, mode_uint);
-       tarval *mask0     = tarval_shr(all_one, tv_shiftr);
-       tarval *mask1     = tarval_shl(mask0, tv_shiftl);
+       long       shiftr    = get_mode_size_bits(mode) - size;
+       long       shiftl    = offset;
+       ir_tarval *tv_shiftr = new_tarval_from_long(shiftr, mode_uint);
+       ir_tarval *tv_shiftl = new_tarval_from_long(shiftl, mode_uint);
+       ir_tarval *mask0     = tarval_shr(all_one, tv_shiftr);
+       ir_tarval *mask1     = tarval_shl(mask0, tv_shiftl);
 
        return mask1;
 }
@@ -2148,26 +1974,25 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
        value = create_conv(dbgi, value, mode);
 
        /* kill upper bits of value and shift to right position */
-       int      bitoffset    = get_entity_offset_bits_remainder(entity);
-       int      bitsize      = get_mode_size_bits(get_type_mode(entity_type));
-
-       tarval  *mask            = create_bitfield_mask(mode, 0, bitsize);
-       ir_node *mask_node       = new_d_Const(dbgi, mask);
-       ir_node *value_masked    = new_d_And(dbgi, value, mask_node, mode);
-       tarval  *shiftl          = new_tarval_from_long(bitoffset, mode_uint);
-       ir_node *shiftcount      = new_d_Const(dbgi, shiftl);
-       ir_node *value_maskshift = new_d_Shl(dbgi, value_masked, shiftcount, mode);
+       int        bitoffset       = get_entity_offset_bits_remainder(entity);
+       int        bitsize         = get_mode_size_bits(get_type_mode(entity_type));
+       ir_tarval *mask            = create_bitfield_mask(mode, 0, bitsize);
+       ir_node   *mask_node       = new_d_Const(dbgi, mask);
+       ir_node   *value_masked    = new_d_And(dbgi, value, mask_node, mode);
+       ir_tarval *shiftl          = new_tarval_from_long(bitoffset, mode_uint);
+       ir_node   *shiftcount      = new_d_Const(dbgi, shiftl);
+       ir_node   *value_maskshift = new_d_Shl(dbgi, value_masked, shiftcount, mode);
 
        /* load current value */
-       ir_node  *mem             = get_store();
-       ir_node  *load            = new_d_Load(dbgi, mem, addr, mode,
-                                       set_volatile ? cons_volatile : cons_none);
-       ir_node  *load_mem        = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
-       ir_node  *load_res        = new_d_Proj(dbgi, load, mode, pn_Load_res);
-       tarval   *shift_mask      = create_bitfield_mask(mode, bitoffset, bitsize);
-       tarval   *inv_mask        = tarval_not(shift_mask);
-       ir_node  *inv_mask_node   = new_d_Const(dbgi, inv_mask);
-       ir_node  *load_res_masked = new_d_And(dbgi, load_res, inv_mask_node, mode);
+       ir_node   *mem             = get_store();
+       ir_node   *load            = new_d_Load(dbgi, mem, addr, mode,
+                                         set_volatile ? cons_volatile : cons_none);
+       ir_node   *load_mem        = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
+       ir_node   *load_res        = new_d_Proj(dbgi, load, mode, pn_Load_res);
+       ir_tarval *shift_mask      = create_bitfield_mask(mode, bitoffset, bitsize);
+       ir_tarval *inv_mask        = tarval_not(shift_mask);
+       ir_node   *inv_mask_node   = new_d_Const(dbgi, inv_mask);
+       ir_node   *load_res_masked = new_d_And(dbgi, load_res, inv_mask_node, mode);
 
        /* construct new value and store */
        ir_node *new_val   = new_d_Or(dbgi, load_res_masked, value_maskshift, mode);
@@ -2180,44 +2005,51 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
 }
 
 static ir_node *bitfield_extract_to_firm(const select_expression_t *expression,
-               ir_node *addr)
-{
-       dbg_info *dbgi     = get_dbg_info(&expression->base.source_position);
-       type_t   *type     = expression->base.type;
-       ir_mode  *mode     = get_ir_mode_storage(type);
-       ir_node  *mem      = get_store();
-       ir_node  *load     = new_d_Load(dbgi, mem, addr, mode, cons_none);
-       ir_node  *load_mem = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
-       ir_node  *load_res = new_d_Proj(dbgi, load, mode, pn_Load_res);
-
-       load_res           = create_conv(dbgi, load_res, mode_int);
+                                         ir_node *addr)
+{
+       dbg_info *dbgi      = get_dbg_info(&expression->base.source_position);
+       entity_t *entity    = expression->compound_entry;
+       type_t   *base_type = entity->declaration.type;
+       ir_mode  *mode      = get_ir_mode_storage(base_type);
+       ir_node  *mem       = get_store();
+       ir_node  *load      = new_d_Load(dbgi, mem, addr, mode, cons_none);
+       ir_node  *load_mem  = new_d_Proj(dbgi, load, mode_M, pn_Load_M);
+       ir_node  *load_res  = new_d_Proj(dbgi, load, mode, pn_Load_res);
+
+       ir_mode  *amode     = mode;
+       /* optimisation, since shifting in modes < machine_size is usually
+        * less efficient */
+       if (get_mode_size_bits(amode) < get_mode_size_bits(mode_uint)) {
+               amode = mode_uint;
+       }
+       unsigned amode_size = get_mode_size_bits(amode);
+       load_res = create_conv(dbgi, load_res, amode);
 
        set_store(load_mem);
 
        /* kill upper bits */
        assert(expression->compound_entry->kind == ENTITY_COMPOUND_MEMBER);
-       ir_entity *entity       = expression->compound_entry->compound_member.entity;
-       int        bitoffset    = get_entity_offset_bits_remainder(entity);
-       ir_type   *entity_type  = get_entity_type(entity);
-       int        bitsize      = get_mode_size_bits(get_type_mode(entity_type));
-       long       shift_bitsl  = machine_size - bitoffset - bitsize;
-       assert(shift_bitsl >= 0);
-       tarval    *tvl          = new_tarval_from_long(shift_bitsl, mode_uint);
-       ir_node   *countl       = new_d_Const(dbgi, tvl);
-       ir_node   *shiftl       = new_d_Shl(dbgi, load_res, countl, mode_int);
-
-       long       shift_bitsr  = bitoffset + shift_bitsl;
-       assert(shift_bitsr <= (long) machine_size);
-       tarval    *tvr          = new_tarval_from_long(shift_bitsr, mode_uint);
-       ir_node   *countr       = new_d_Const(dbgi, tvr);
+       int        bitoffset   = entity->compound_member.bit_offset;
+       int        bitsize     = entity->compound_member.bit_size;
+       unsigned   shift_bitsl = amode_size - bitoffset - bitsize;
+       ir_tarval *tvl         = new_tarval_from_long((long)shift_bitsl, mode_uint);
+       ir_node   *countl      = new_d_Const(dbgi, tvl);
+       ir_node   *shiftl      = new_d_Shl(dbgi, load_res, countl, amode);
+
+       unsigned   shift_bitsr = bitoffset + shift_bitsl;
+       assert(shift_bitsr <= amode_size);
+       ir_tarval *tvr         = new_tarval_from_long((long)shift_bitsr, mode_uint);
+       ir_node   *countr      = new_d_Const(dbgi, tvr);
        ir_node   *shiftr;
        if (mode_is_signed(mode)) {
-               shiftr = new_d_Shrs(dbgi, shiftl, countr, mode_int);
+               shiftr = new_d_Shrs(dbgi, shiftl, countr, amode);
        } else {
-               shiftr = new_d_Shr(dbgi, shiftl, countr, mode_int);
+               shiftr = new_d_Shr(dbgi, shiftl, countr, amode);
        }
 
-       return create_conv(dbgi, shiftr, mode);
+       type_t  *type    = expression->base.type;
+       ir_mode *resmode = get_ir_mode_arithmetic(type);
+       return create_conv(dbgi, shiftr, resmode);
 }
 
 /* make sure the selected compound type is constructed */
@@ -2268,7 +2100,7 @@ static ir_node *set_value_for_expression_addr(const expression_t *expression,
 
                entity_t *entity = select->compound_entry;
                assert(entity->kind == ENTITY_COMPOUND_MEMBER);
-               if (entity->declaration.type->kind == TYPE_BITFIELD) {
+               if (entity->compound_member.bitfield) {
                        ir_entity *irentity = entity->compound_member.entity;
                        bool       set_volatile
                                = select->base.type->base.qualifiers & TYPE_QUALIFIER_VOLATILE;
@@ -2321,7 +2153,7 @@ static ir_node *get_value_from_lvalue(const expression_t *expression,
 
        ir_node *value;
        if (expression->kind == EXPR_SELECT &&
-           expression->select.compound_entry->declaration.type->kind == TYPE_BITFIELD){
+           expression->select.compound_entry->compound_member.bitfield) {
            construct_select_compound(&expression->select);
                value = bitfield_extract_to_firm(&expression->select, addr);
        } else {
@@ -2391,22 +2223,21 @@ static bool is_local_variable(expression_t *expression)
        return entity->declaration.kind == DECLARATION_KIND_LOCAL_VARIABLE;
 }
 
-static pn_Cmp get_pnc(const expression_kind_t kind, type_t *const type)
+static ir_relation get_relation(const expression_kind_t kind)
 {
        switch(kind) {
-       case EXPR_BINARY_EQUAL:         return pn_Cmp_Eq;
-       case EXPR_BINARY_ISLESSGREATER: return pn_Cmp_Lg;
-       case EXPR_BINARY_NOTEQUAL:
-               return is_type_float(skip_typeref(type)) ? pn_Cmp_Ne : pn_Cmp_Lg;
+       case EXPR_BINARY_EQUAL:         return ir_relation_equal;
+       case EXPR_BINARY_ISLESSGREATER: return ir_relation_less_greater;
+       case EXPR_BINARY_NOTEQUAL:      return ir_relation_unordered_less_greater;
        case EXPR_BINARY_ISLESS:
-       case EXPR_BINARY_LESS:          return pn_Cmp_Lt;
+       case EXPR_BINARY_LESS:          return ir_relation_less;
        case EXPR_BINARY_ISLESSEQUAL:
-       case EXPR_BINARY_LESSEQUAL:     return pn_Cmp_Le;
+       case EXPR_BINARY_LESSEQUAL:     return ir_relation_less_equal;
        case EXPR_BINARY_ISGREATER:
-       case EXPR_BINARY_GREATER:       return pn_Cmp_Gt;
+       case EXPR_BINARY_GREATER:       return ir_relation_greater;
        case EXPR_BINARY_ISGREATEREQUAL:
-       case EXPR_BINARY_GREATEREQUAL:  return pn_Cmp_Ge;
-       case EXPR_BINARY_ISUNORDERED:   return pn_Cmp_Uo;
+       case EXPR_BINARY_GREATEREQUAL:  return ir_relation_greater_equal;
+       case EXPR_BINARY_ISUNORDERED:   return ir_relation_unordered;
 
        default:
                break;
@@ -2432,13 +2263,11 @@ static ir_node *handle_assume_compare(dbg_info *dbi,
        expression_t *op1 = expression->left;
        expression_t *op2 = expression->right;
        entity_t     *var2, *var = NULL;
-       ir_node      *res = NULL;
-       pn_Cmp        cmp_val;
-
-       cmp_val = get_pnc(expression->base.kind, op1->base.type);
+       ir_node      *res      = NULL;
+       ir_relation   relation = get_relation(expression->base.kind);
 
        if (is_local_variable(op1) && is_local_variable(op2)) {
-       var  = op1->reference.entity;
+               var  = op1->reference.entity;
            var2 = op2->reference.entity;
 
                type_t  *const type = skip_typeref(var->declaration.type);
@@ -2447,21 +2276,21 @@ static ir_node *handle_assume_compare(dbg_info *dbi,
                ir_node *const irn1 = get_value(var->variable.v.value_number, mode);
                ir_node *const irn2 = get_value(var2->variable.v.value_number, mode);
 
-               res = new_d_Confirm(dbi, irn2, irn1, get_inversed_pnc(cmp_val));
+               res = new_d_Confirm(dbi, irn2, irn1, get_inversed_relation(relation));
                set_value(var2->variable.v.value_number, res);
 
-               res = new_d_Confirm(dbi, irn1, irn2, cmp_val);
+               res = new_d_Confirm(dbi, irn1, irn2, relation);
                set_value(var->variable.v.value_number, res);
 
                return res;
        }
 
-       expression_t *con;
-       if (is_local_variable(op1) && is_constant_expression(op2)) {
+       expression_t *con = NULL;
+       if (is_local_variable(op1) && is_constant_expression(op2) == EXPR_CLASS_CONSTANT) {
                var = op1->reference.entity;
                con = op2;
-       } else if (is_constant_expression(op1) && is_local_variable(op2)) {
-               cmp_val = get_inversed_pnc(cmp_val);
+       } else if (is_constant_expression(op1) == EXPR_CLASS_CONSTANT && is_local_variable(op2)) {
+               relation = get_inversed_relation(relation);
                var = op2->reference.entity;
                con = op1;
        }
@@ -2471,7 +2300,7 @@ static ir_node *handle_assume_compare(dbg_info *dbi,
                ir_mode *const mode = get_ir_mode_storage(type);
 
                res = get_value(var->variable.v.value_number, mode);
-               res = new_d_Confirm(dbi, res, expression_to_firm(con), cmp_val);
+               res = new_d_Confirm(dbi, res, expression_to_firm(con), relation);
                set_value(var->variable.v.value_number, res);
        }
        return res;
@@ -2498,10 +2327,15 @@ static ir_node *handle_assume(dbg_info *dbi, const expression_t *expression)
        }
 }
 
-static ir_node *create_cast(dbg_info *dbgi,    ir_node *value_node,
+static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node,
                             type_t *from_type, type_t *type)
 {
        type = skip_typeref(type);
+       if (type == type_void) {
+               /* make sure firm type is constructed */
+               (void) get_ir_type(type);
+               return NULL;
+       }
        if (!is_type_scalar(type)) {
                /* make sure firm type is constructed */
                (void) get_ir_type(type);
@@ -2516,12 +2350,12 @@ static ir_node *create_cast(dbg_info *dbgi,     ir_node *value_node,
                const variable_t *to_var   = type->pointer.base_variable;
                if (from_var != to_var) {
                        if (from_var != NULL) {
-                               ir_node *const addr = get_global_var_address(dbgi, from_var);
+                               ir_node *const addr = create_symconst(dbgi, from_var->v.entity);
                                ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
                                value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
                        }
                        if (to_var != NULL) {
-                               ir_node *const addr = get_global_var_address(dbgi, to_var);
+                               ir_node *const addr = create_symconst(dbgi, to_var->v.entity);
                                ir_node *const base = deref_address(dbgi, to_var->base.type, addr);
                                value_node = new_d_Sub(dbgi, value_node, base, mode);
                        }
@@ -2579,7 +2413,7 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
                /* check for __based */
                const variable_t *const base_var = value_type->pointer.base_variable;
                if (base_var != NULL) {
-                       ir_node *const addr = get_global_var_address(dbgi, base_var);
+                       ir_node *const addr = create_symconst(dbgi, base_var->v.entity);
                        ir_node *const base = deref_address(dbgi, base_var->base.type, addr);
                        value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(value_type));
                }
@@ -2591,17 +2425,13 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
        case EXPR_UNARY_PREFIX_INCREMENT:
        case EXPR_UNARY_PREFIX_DECREMENT:
                return create_incdec(expression);
-       case EXPR_UNARY_CAST_IMPLICIT:
        case EXPR_UNARY_CAST: {
                ir_node *value_node = expression_to_firm(value);
                type_t  *from_type  = value->base.type;
                return create_cast(dbgi, value_node, from_type, type);
        }
        case EXPR_UNARY_ASSUME:
-               if (firm_opt.confirm)
-                       return handle_assume(dbgi, value);
-               else
-                       return NULL;
+               return handle_assume(dbgi, value);
 
        default:
                break;
@@ -2615,29 +2445,22 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
 static ir_node *produce_condition_result(const expression_t *expression,
                                          ir_mode *mode, dbg_info *dbgi)
 {
-       ir_node *cur_block = get_cur_block();
-
-       ir_node *one_block = new_immBlock();
-       set_cur_block(one_block);
-       ir_node *one       = new_Const(get_mode_one(mode));
-       ir_node *jmp_one   = new_d_Jmp(dbgi);
-
-       ir_node *zero_block = new_immBlock();
-       set_cur_block(zero_block);
-       ir_node *zero       = new_Const(get_mode_null(mode));
-       ir_node *jmp_zero   = new_d_Jmp(dbgi);
-
-       set_cur_block(cur_block);
+       ir_node *const one_block  = new_immBlock();
+       ir_node *const zero_block = new_immBlock();
        create_condition_evaluation(expression, one_block, zero_block);
        mature_immBlock(one_block);
        mature_immBlock(zero_block);
 
-       ir_node *in_cf[2] = { jmp_one, jmp_zero };
-       ir_node *block = new_Block(2, in_cf);
+       ir_node *const jmp_one  = new_rd_Jmp(dbgi, one_block);
+       ir_node *const jmp_zero = new_rd_Jmp(dbgi, zero_block);
+       ir_node *const in_cf[2] = { jmp_one, jmp_zero };
+       ir_node *const block    = new_Block(lengthof(in_cf), in_cf);
        set_cur_block(block);
 
-       ir_node *in[2] = { one, zero };
-       ir_node *val   = new_d_Phi(dbgi, 2, in, mode);
+       ir_node *const one   = new_Const(get_mode_one(mode));
+       ir_node *const zero  = new_Const(get_mode_null(mode));
+       ir_node *const in[2] = { one, zero };
+       ir_node *const val   = new_d_Phi(dbgi, lengthof(in), in, mode);
 
        return val;
 }
@@ -2670,7 +2493,7 @@ static ir_node *create_op(dbg_info *dbgi, const binary_expression_t *expression,
        case EXPR_BINARY_SHIFTRIGHT:
        case EXPR_BINARY_SHIFTLEFT_ASSIGN:
        case EXPR_BINARY_SHIFTRIGHT_ASSIGN:
-               mode  = get_irn_mode(left);
+               mode  = get_ir_mode_arithmetic(expression->base.type);
                right = create_conv(dbgi, right, mode_uint);
                break;
 
@@ -2748,15 +2571,9 @@ normal_node:
        case EXPR_BINARY_DIV:
        case EXPR_BINARY_DIV_ASSIGN: {
                ir_node *pin = new_Pin(new_NoMem());
-               ir_node *op;
-               ir_node *res;
-               if (mode_is_float(mode)) {
-                       op  = new_d_Quot(dbgi, pin, left, right, mode, op_pin_state_floats);
-                       res = new_d_Proj(dbgi, op, mode, pn_Quot_res);
-               } else {
-                       op  = new_d_Div(dbgi, pin, left, right, mode, op_pin_state_floats);
-                       res = new_d_Proj(dbgi, op, mode, pn_Div_res);
-               }
+               ir_node *op  = new_d_Div(dbgi, pin, left, right, mode,
+                                        op_pin_state_floats);
+               ir_node *res = new_d_Proj(dbgi, op, mode, pn_Div_res);
                return res;
        }
        case EXPR_BINARY_MOD:
@@ -2779,7 +2596,7 @@ static ir_node *create_lazy_op(const binary_expression_t *expression)
        type_t   *type = skip_typeref(expression->base.type);
        ir_mode  *mode = get_ir_mode_arithmetic(type);
 
-       if (is_constant_expression(expression->left)) {
+       if (is_constant_expression(expression->left) == EXPR_CLASS_CONSTANT) {
                bool val = fold_constant_to_bool(expression->left);
                expression_kind_t ekind = expression->base.kind;
                assert(ekind == EXPR_BINARY_LOGICAL_AND || ekind == EXPR_BINARY_LOGICAL_OR);
@@ -2793,11 +2610,9 @@ static ir_node *create_lazy_op(const binary_expression_t *expression)
                        }
                }
 
-               if (is_constant_expression(expression->right)) {
+               if (is_constant_expression(expression->right) == EXPR_CLASS_CONSTANT) {
                        bool valr = fold_constant_to_bool(expression->right);
-                       return valr ?
-                               new_Const(get_mode_one(mode)) :
-                               new_Const(get_mode_null(mode));
+                       return create_Const_from_bool(mode, valr);
                }
 
                return produce_condition_result(expression->right, mode, dbgi);
@@ -2849,13 +2664,12 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
        case EXPR_BINARY_ISLESSEQUAL:
        case EXPR_BINARY_ISLESSGREATER:
        case EXPR_BINARY_ISUNORDERED: {
-               dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
-               ir_node *left  = expression_to_firm(expression->left);
-               ir_node *right = expression_to_firm(expression->right);
-               ir_node *cmp   = new_d_Cmp(dbgi, left, right);
-               long     pnc   = get_pnc(kind, expression->left->base.type);
-               ir_node *proj  = new_d_Proj(dbgi, cmp, mode_b, pnc);
-               return proj;
+               dbg_info   *dbgi     = get_dbg_info(&expression->base.source_position);
+               ir_node    *left     = expression_to_firm(expression->left);
+               ir_node    *right    = expression_to_firm(expression->right);
+               ir_relation relation = get_relation(kind);
+               ir_node    *cmp      = new_d_Cmp(dbgi, left, right, relation);
+               return cmp;
        }
        case EXPR_BINARY_ASSIGN: {
                ir_node *addr  = expression_to_addr(expression->left);
@@ -2984,10 +2798,10 @@ static long get_offsetof_offset(const offsetof_expression_t *expression)
 
 static ir_node *offsetof_to_firm(const offsetof_expression_t *expression)
 {
-       ir_mode  *mode   = get_ir_mode_arithmetic(expression->base.type);
-       long      offset = get_offsetof_offset(expression);
-       tarval   *tv     = new_tarval_from_long(offset, mode);
-       dbg_info *dbgi   = get_dbg_info(&expression->base.source_position);
+       ir_mode   *mode   = get_ir_mode_arithmetic(expression->base.type);
+       long       offset = get_offsetof_offset(expression);
+       ir_tarval *tv     = new_tarval_from_long(offset, mode);
+       dbg_info  *dbgi   = get_dbg_info(&expression->base.source_position);
 
        return new_d_Const(dbgi, tv);
 }
@@ -3030,6 +2844,11 @@ static ir_node *sizeof_to_firm(const typeprop_expression_t *expression)
                        && expression->tp_expression != NULL) {
                expression_to_firm(expression->tp_expression);
        }
+       /* strange gnu extensions: sizeof(function) == 1 */
+       if (is_type_function(type)) {
+               ir_mode *mode = get_ir_mode_storage(type_size_t);
+               return new_Const(get_mode_one(mode));
+       }
 
        return get_type_size_node(type);
 }
@@ -3069,7 +2888,12 @@ static ir_node *alignof_to_firm(const typeprop_expression_t *expression)
        if (tp_expression != NULL) {
                entity_t *entity = get_expression_entity(tp_expression);
                if (entity != NULL) {
-                       alignment = get_cparser_entity_alignment(entity);
+                       if (entity->kind == ENTITY_FUNCTION) {
+                               /* a gnu-extension */
+                               alignment = 1;
+                       } else {
+                               alignment = get_cparser_entity_alignment(entity);
+                       }
                }
        }
 
@@ -3078,15 +2902,15 @@ static ir_node *alignof_to_firm(const typeprop_expression_t *expression)
                alignment = get_type_alignment(type);
        }
 
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
-       ir_mode  *mode = get_ir_mode_arithmetic(expression->base.type);
-       tarval   *tv   = new_tarval_from_long(alignment, mode);
+       dbg_info  *dbgi = get_dbg_info(&expression->base.source_position);
+       ir_mode   *mode = get_ir_mode_arithmetic(expression->base.type);
+       ir_tarval *tv   = new_tarval_from_long(alignment, mode);
        return new_d_Const(dbgi, tv);
 }
 
 static void init_ir_types(void);
 
-static tarval *fold_constant_to_tarval(const expression_t *expression)
+static ir_tarval *fold_constant_to_tarval(const expression_t *expression)
 {
        assert(is_type_valid(skip_typeref(expression->base.type)));
 
@@ -3095,7 +2919,7 @@ static tarval *fold_constant_to_tarval(const expression_t *expression)
 
        init_ir_types();
 
-       assert(is_constant_expression(expression));
+       assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT);
 
        ir_graph *old_current_ir_graph = current_ir_graph;
        current_ir_graph = get_const_code_irg();
@@ -3109,16 +2933,23 @@ static tarval *fold_constant_to_tarval(const expression_t *expression)
 
        constant_folding = constant_folding_old;
 
-       tarval *tv = get_Const_tarval(cnst);
-       return tv;
+       return get_Const_tarval(cnst);
+}
+
+/* this function is only used in parser.c, but it relies on libfirm functionality */
+bool constant_is_negative(const expression_t *expression)
+{
+       assert(is_constant_expression(expression) == EXPR_CLASS_CONSTANT);
+       ir_tarval *tv = fold_constant_to_tarval(expression);
+       return tarval_is_negative(tv);
 }
 
 long fold_constant_to_int(const expression_t *expression)
 {
-       if (expression->kind == EXPR_INVALID)
+       if (expression->kind == EXPR_ERROR)
                return 0;
 
-       tarval *tv = fold_constant_to_tarval(expression);
+       ir_tarval *tv = fold_constant_to_tarval(expression);
        if (!tarval_is_long(tv)) {
                panic("result of constant folding is not integer");
        }
@@ -3128,9 +2959,9 @@ long fold_constant_to_int(const expression_t *expression)
 
 bool fold_constant_to_bool(const expression_t *expression)
 {
-       if (expression->kind == EXPR_INVALID)
+       if (expression->kind == EXPR_ERROR)
                return false;
-       tarval *tv = fold_constant_to_tarval(expression);
+       ir_tarval *tv = fold_constant_to_tarval(expression);
        return !tarval_is_null(tv);
 }
 
@@ -3139,7 +2970,7 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
        dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
 
        /* first try to fold a constant condition */
-       if (is_constant_expression(expression->condition)) {
+       if (is_constant_expression(expression->condition) == EXPR_CLASS_CONSTANT) {
                bool val = fold_constant_to_bool(expression->condition);
                if (val) {
                        expression_t *true_expression = expression->true_expression;
@@ -3151,51 +2982,47 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
                }
        }
 
-       ir_node *cur_block   = get_cur_block();
+       ir_node *const true_block  = new_immBlock();
+       ir_node *const false_block = new_immBlock();
+       ir_node *const cond_expr   = create_condition_evaluation(expression->condition, true_block, false_block);
+       mature_immBlock(true_block);
+       mature_immBlock(false_block);
 
-       /* create the true block */
-       ir_node *true_block  = new_immBlock();
        set_cur_block(true_block);
+       ir_node *true_val;
+       if (expression->true_expression != NULL) {
+               true_val = expression_to_firm(expression->true_expression);
+       } else if (cond_expr != NULL && get_irn_mode(cond_expr) != mode_b) {
+               true_val = cond_expr;
+       } else {
+               /* Condition ended with a short circuit (&&, ||, !) operation or a
+                * comparison.  Generate a "1" as value for the true branch. */
+               true_val = new_Const(get_mode_one(mode_Is));
+       }
+       ir_node *const true_jmp = new_d_Jmp(dbgi);
 
-       ir_node *true_val = expression->true_expression != NULL ?
-               expression_to_firm(expression->true_expression) : NULL;
-       ir_node *true_jmp = new_Jmp();
-
-       /* create the false block */
-       ir_node *false_block = new_immBlock();
        set_cur_block(false_block);
-
-       ir_node *false_val = expression_to_firm(expression->false_expression);
-       ir_node *false_jmp = new_Jmp();
-
-       /* create the condition evaluation */
-       set_cur_block(cur_block);
-       ir_node *const cond_expr = create_condition_evaluation(expression->condition, true_block, false_block);
-       if (expression->true_expression == NULL) {
-               if (cond_expr != NULL && get_irn_mode(cond_expr) != mode_b) {
-                       true_val = cond_expr;
-               } else {
-                       /* Condition ended with a short circuit (&&, ||, !) operation or a
-                        * comparison.  Generate a "1" as value for the true branch. */
-                       true_val = new_Const(get_mode_one(mode_Is));
-               }
-       }
-       mature_immBlock(true_block);
-       mature_immBlock(false_block);
+       ir_node *const false_val = expression_to_firm(expression->false_expression);
+       ir_node *const false_jmp = new_d_Jmp(dbgi);
 
        /* create the common block */
-       ir_node *in_cf[2] = { true_jmp, false_jmp };
-       ir_node *block = new_Block(2, in_cf);
+       ir_node *const in_cf[2] = { true_jmp, false_jmp };
+       ir_node *const block    = new_Block(lengthof(in_cf), in_cf);
        set_cur_block(block);
 
        /* TODO improve static semantics, so either both or no values are NULL */
        if (true_val == NULL || false_val == NULL)
                return NULL;
 
-       ir_node *in[2] = { true_val, false_val };
-       ir_mode *mode  = get_irn_mode(true_val);
-       assert(get_irn_mode(false_val) == mode);
-       ir_node *val   = new_d_Phi(dbgi, 2, in, mode);
+       ir_node *const in[2] = { true_val, false_val };
+       type_t  *const type  = skip_typeref(expression->base.type);
+       ir_mode *mode;
+       if (is_type_compound(type)) {
+               mode = mode_P;
+       } else {
+               mode = get_ir_mode_arithmetic(type);
+       }
+       ir_node *const val   = new_d_Phi(dbgi, lengthof(in), in, mode);
 
        return val;
 }
@@ -3235,11 +3062,10 @@ static ir_node *select_to_firm(const select_expression_t *expression)
                        (const expression_t*) expression);
        type           = skip_typeref(type);
 
-       entity_t *entry      = expression->compound_entry;
+       entity_t *entry = expression->compound_entry;
        assert(entry->kind == ENTITY_COMPOUND_MEMBER);
-       type_t   *entry_type = skip_typeref(entry->declaration.type);
 
-       if (entry_type->kind == TYPE_BITFIELD) {
+       if (entry->compound_member.bitfield) {
                return bitfield_extract_to_firm(expression, addr);
        }
 
@@ -3321,7 +3147,6 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
 
                        case TYPE_COMPLEX:         tc = complex_type_class; goto make_const;
                        case TYPE_IMAGINARY:       tc = complex_type_class; goto make_const;
-                       case TYPE_BITFIELD:        tc = integer_type_class; goto make_const;
                        case TYPE_ARRAY:           /* gcc handles this as pointer */
                        case TYPE_FUNCTION:        /* gcc handles this as pointer */
                        case TYPE_POINTER:         tc = pointer_type_class; goto make_const;
@@ -3334,11 +3159,9 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
                        /* gcc classifies the referenced type */
                        case TYPE_REFERENCE: type = type->reference.refers_to; continue;
 
-                       case TYPE_BUILTIN:
                        /* typedef/typeof should be skipped already */
                        case TYPE_TYPEDEF:
                        case TYPE_TYPEOF:
-                       case TYPE_INVALID:
                        case TYPE_ERROR:
                                break;
                }
@@ -3346,8 +3169,8 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
        }
 
 make_const:;
-       dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
-       tarval   *const tv   = new_tarval_from_long(tc, mode_int);
+       dbg_info  *const dbgi = get_dbg_info(&expr->base.source_position);
+       ir_tarval *const tv   = new_tarval_from_long(tc, mode_int);
        return new_d_Const(dbgi, tv);
 }
 
@@ -3389,25 +3212,21 @@ static ir_node *statement_expression_to_firm(const statement_expression_t *expr)
 static ir_node *va_start_expression_to_firm(
        const va_start_expression_t *const expr)
 {
-       type_t    *const type        = current_function_entity->declaration.type;
-       ir_type   *const method_type = get_ir_type(type);
-       int        const n           = get_method_n_params(method_type) - 1;
-       ir_entity *const parm_ent    = get_method_value_param_ent(method_type, n);
-       ir_node   *const frame       = get_irg_frame(current_ir_graph);
-       dbg_info  *const dbgi        = get_dbg_info(&expr->base.source_position);
-       ir_node   *const no_mem      = new_NoMem();
-       ir_node   *const arg_sel     =
-               new_d_simpleSel(dbgi, no_mem, frame, parm_ent);
-
-       type_t    *const param_type  = expr->parameter->base.type;
-       ir_node   *const cnst        = get_type_size_node(param_type);
-       ir_mode   *const mode        = get_irn_mode(cnst);
-       ir_node   *const c1          = new_Const_long(mode, stack_param_align - 1);
-       ir_node   *const c2          = new_d_Add(dbgi, cnst, c1, mode);
-       ir_node   *const c3          = new_Const_long(mode, -(long)stack_param_align);
-       ir_node   *const c4          = new_d_And(dbgi, c2, c3, mode);
-       ir_node   *const add         = new_d_Add(dbgi, arg_sel, c4, mode_P_data);
-       set_value_for_expression(expr->ap, add);
+       ir_entity *param_ent = current_vararg_entity;
+       if (param_ent == NULL) {
+               size_t   const n           = IR_VA_START_PARAMETER_NUMBER;
+               ir_type *const frame_type  = get_irg_frame_type(current_ir_graph);
+               ir_type *const param_type  = get_unknown_type();
+               param_ent = new_parameter_entity(frame_type, n, param_type);
+               current_vararg_entity = param_ent;
+       }
+
+       ir_node  *const frame   = get_irg_frame(current_ir_graph);
+       dbg_info *const dbgi    = get_dbg_info(&expr->base.source_position);
+       ir_node  *const no_mem  = new_NoMem();
+       ir_node  *const arg_sel = new_d_simpleSel(dbgi, no_mem, frame, param_ent);
+
+       set_value_for_expression(expr->ap, arg_sel);
 
        return NULL;
 }
@@ -3477,15 +3296,9 @@ static ir_node *expression_to_addr(const expression_t *expression)
 static ir_node *builtin_constant_to_firm(
                const builtin_constant_expression_t *expression)
 {
-       ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
-       long     v;
-
-       if (is_constant_expression(expression->value)) {
-               v = 1;
-       } else {
-               v = 0;
-       }
-       return new_Const_long(mode, v);
+       ir_mode *const mode = get_ir_mode_arithmetic(expression->base.type);
+       bool     const v    = is_constant_expression(expression->value) == EXPR_CLASS_CONSTANT;
+       return create_Const_from_bool(mode, v);
 }
 
 static ir_node *builtin_types_compatible_to_firm(
@@ -3493,9 +3306,9 @@ static ir_node *builtin_types_compatible_to_firm(
 {
        type_t  *const left  = get_unqualified_type(skip_typeref(expression->left));
        type_t  *const right = get_unqualified_type(skip_typeref(expression->right));
-       long     const value = types_compatible(left, right) ? 1 : 0;
+       bool     const value = types_compatible(left, right);
        ir_mode *const mode  = get_ir_mode_arithmetic(expression->base.type);
-       return new_Const_long(mode, value);
+       return create_Const_from_bool(mode, value);
 }
 
 static ir_node *get_label_block(label_t *label)
@@ -3533,6 +3346,12 @@ static ir_node *label_address_to_firm(const label_address_expression_t *label)
        return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
 }
 
+static ir_node *error_to_firm(const expression_t *expression)
+{
+       ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
+       return new_Bad(mode);
+}
+
 /**
  * creates firm nodes for an expression. The difference between this function
  * and expression_to_firm is, that this version might produce mode_b nodes
@@ -3598,9 +3417,8 @@ static ir_node *_expression_to_firm(const expression_t *expression)
        case EXPR_LABEL_ADDRESS:
                return label_address_to_firm(&expression->label_address);
 
-       case EXPR_UNKNOWN:
-       case EXPR_INVALID:
-               break;
+       case EXPR_ERROR:
+               return error_to_firm(expression);
        }
        panic("invalid expression found");
 }
@@ -3618,7 +3436,7 @@ static bool is_builtin_expect(const expression_t *expression)
                return false;
        reference_expression_t *ref = &function->reference;
        if (ref->entity->kind         != ENTITY_FUNCTION ||
-           ref->entity->function.btk != bk_gnu_builtin_expect)
+           ref->entity->function.btk != BUILTIN_EXPECT)
                return false;
 
        return true;
@@ -3664,15 +3482,14 @@ static ir_node *expression_to_firm(const expression_t *expression)
                return res;
        }
 
-       if (is_constant_expression(expression)) {
+       if (is_constant_expression(expression) == EXPR_CLASS_CONSTANT) {
+               bool const constant_folding_old = constant_folding;
+               constant_folding = true;
                ir_node *res  = _expression_to_firm(expression);
+               constant_folding = constant_folding_old;
                ir_mode *mode = get_ir_mode_arithmetic(expression->base.type);
                assert(is_Const(res));
-               if (is_Const_null(res)) {
-                       return new_Const_long(mode, 0);
-               } else {
-                       return new_Const_long(mode, 1);
-               }
+               return create_Const_from_bool(mode, !is_Const_null(res));
        }
 
        /* we have to produce a 0/1 from the mode_b expression */
@@ -3734,15 +3551,9 @@ static ir_node *create_condition_evaluation(const expression_t *expression,
        /* set branch prediction info based on __builtin_expect */
        if (is_builtin_expect(expression) && is_Cond(cond)) {
                call_argument_t *argument = expression->call.arguments->next;
-               if (is_constant_expression(argument->expression)) {
-                       bool             cnst = fold_constant_to_bool(argument->expression);
-                       cond_jmp_predicate pred;
-
-                       if (cnst == false) {
-                               pred = COND_JMP_PRED_FALSE;
-                       } else {
-                               pred = COND_JMP_PRED_TRUE;
-                       }
+               if (is_constant_expression(argument->expression) == EXPR_CLASS_CONSTANT) {
+                       bool               const cnst = fold_constant_to_bool(argument->expression);
+                       cond_jmp_predicate const pred = cnst ? COND_JMP_PRED_TRUE : COND_JMP_PRED_FALSE;
                        set_Cond_jmp_pred(cond, pred);
                }
        }
@@ -3750,7 +3561,7 @@ static ir_node *create_condition_evaluation(const expression_t *expression,
        add_immBlock_pred(true_block, true_proj);
        add_immBlock_pred(false_block, false_proj);
 
-       set_cur_block(NULL);
+       set_unreachable_now();
        return cond_expr;
 }
 
@@ -4034,7 +3845,7 @@ static void advance_current_object(type_path_t *path)
 
        /* we're past the last member of the current sub-aggregate, try if we
         * can ascend in the type hierarchy and continue with another subobject */
-       size_t len = ARR_LEN(path->path);
+       size_t len = ARR_LEN(path->path);
 
        if (len > 1) {
                ascend_from_subtype(path);
@@ -4056,15 +3867,6 @@ static ir_initializer_t *create_ir_initializer_value(
        }
        type_t       *type = initializer->value->base.type;
        expression_t *expr = initializer->value;
-       if (initializer_use_bitfield_basetype) {
-               type_t *skipped = skip_typeref(type);
-               if (skipped->kind == TYPE_BITFIELD) {
-                       /* remove the bitfield cast... */
-                       assert(expr->kind == EXPR_UNARY_CAST_IMPLICIT);
-                       expr = expr->unary.value;
-                       type = skipped->bitfield.base_type;
-               }
-       }
        ir_node *value = expression_to_firm(expr);
        ir_mode *mode  = get_ir_mode_storage(type);
        value          = create_conv(NULL, value, mode);
@@ -4168,7 +3970,7 @@ static ir_initializer_t *create_ir_initializer_string(
                if (i < string_len)
                        c = string[i];
 
-               tarval           *tv = new_tarval_from_long(c, mode);
+               ir_tarval        *tv = new_tarval_from_long(c, mode);
                ir_initializer_t *char_initializer = create_initializer_tarval(tv);
 
                set_initializer_compound_value(irinitializer, i, char_initializer);
@@ -4194,7 +3996,7 @@ static ir_initializer_t *create_ir_initializer_wide_string(
                if (i < string_len) {
                        c = read_utf8_char(&p);
                }
-               tarval *tv = new_tarval_from_long(c, mode);
+               ir_tarval *tv = new_tarval_from_long(c, mode);
                ir_initializer_t *char_initializer = create_initializer_tarval(tv);
 
                set_initializer_compound_value(irinitializer, i, char_initializer);
@@ -4226,14 +4028,68 @@ static ir_initializer_t *create_ir_initializer(
        panic("unknown initializer");
 }
 
+/** ANSI C Â§6.7.8:21: If there are fewer initializers [..] than there
+ *  are elements [...] the remainder of the aggregate shall be initialized
+ *  implicitly the same as objects that have static storage duration. */
+static void create_dynamic_null_initializer(ir_entity *entity, dbg_info *dbgi,
+               ir_node *base_addr)
+{
+       /* for unions we must NOT do anything for null initializers */
+       ir_type *owner = get_entity_owner(entity);
+       if (is_Union_type(owner)) {
+               return;
+       }
+
+       ir_type *ent_type = get_entity_type(entity);
+       /* create sub-initializers for a compound type */
+       if (is_compound_type(ent_type)) {
+               unsigned n_members = get_compound_n_members(ent_type);
+               for (unsigned n = 0; n < n_members; ++n) {
+                       ir_entity *member = get_compound_member(ent_type, n);
+                       ir_node   *addr   = new_d_simpleSel(dbgi, new_NoMem(), base_addr,
+                                                               member);
+                       create_dynamic_null_initializer(member, dbgi, addr);
+               }
+               return;
+       }
+       if (is_Array_type(ent_type)) {
+               assert(has_array_upper_bound(ent_type, 0));
+               long n = get_array_upper_bound_int(ent_type, 0);
+               for (long i = 0; i < n; ++i) {
+                       ir_tarval *index_tv = new_tarval_from_long(i, mode_uint);
+                       ir_node   *cnst     = new_d_Const(dbgi, index_tv);
+                       ir_node   *in[1]    = { cnst };
+                       ir_entity *arrent   = get_array_element_entity(ent_type);
+                       ir_node   *addr     = new_d_Sel(dbgi, new_NoMem(), base_addr, 1, in,
+                                                       arrent);
+                       create_dynamic_null_initializer(arrent, dbgi, addr);
+               }
+               return;
+       }
+
+       ir_mode *value_mode = get_type_mode(ent_type);
+       ir_node *node       = new_Const(get_mode_null(value_mode));
+
+       /* is it a bitfield type? */
+       if (is_Primitive_type(ent_type) &&
+                       get_primitive_base_type(ent_type) != NULL) {
+               bitfield_store_to_firm(dbgi, entity, base_addr, node, false);
+               return;
+       }
+
+       ir_node *mem    = get_store();
+       ir_node *store  = new_d_Store(dbgi, mem, base_addr, node, cons_none);
+       ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
+       set_store(proj_m);
+}
+
 static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                ir_entity *entity, ir_type *type, dbg_info *dbgi, ir_node *base_addr)
 {
        switch(get_initializer_kind(initializer)) {
-       case IR_INITIALIZER_NULL: {
-               /* NULL is undefined for dynamic initializers */
+       case IR_INITIALIZER_NULL:
+               create_dynamic_null_initializer(entity, dbgi, base_addr);
                return;
-       }
        case IR_INITIALIZER_CONST: {
                ir_node *node     = get_initializer_const_value(initializer);
                ir_type *ent_type = get_entity_type(entity);
@@ -4253,9 +4109,9 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                return;
        }
        case IR_INITIALIZER_TARVAL: {
-               tarval  *tv       = get_initializer_tarval_value(initializer);
-               ir_node *cnst     = new_d_Const(dbgi, tv);
-               ir_type *ent_type = get_entity_type(entity);
+               ir_tarval *tv       = get_initializer_tarval_value(initializer);
+               ir_node   *cnst     = new_d_Const(dbgi, tv);
+               ir_type   *ent_type = get_entity_type(entity);
 
                /* is it a bitfield type? */
                if (is_Primitive_type(ent_type) &&
@@ -4290,7 +4146,7 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                        ir_type   *irtype;
                        ir_entity *sub_entity;
                        if (is_Array_type(type)) {
-                               tarval    *index_tv = new_tarval_from_long(i, mode_uint);
+                               ir_tarval *index_tv = new_tarval_from_long(i, mode_uint);
                                ir_node   *cnst     = new_d_Const(dbgi, index_tv);
                                ir_node   *in[1]    = { cnst };
                                irtype     = get_array_element_type(type);
@@ -4344,14 +4200,9 @@ static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi,
                return;
        }
 
-       if (!is_constant_initializer(initializer)) {
-               bool old_initializer_use_bitfield_basetype
-                       = initializer_use_bitfield_basetype;
-               initializer_use_bitfield_basetype = true;
+       if (is_constant_initializer(initializer) == EXPR_CLASS_VARIABLE) {
                ir_initializer_t *irinitializer
                        = create_ir_initializer(initializer, type);
-               initializer_use_bitfield_basetype
-                       = old_initializer_use_bitfield_basetype;
 
                create_dynamic_initializer(irinitializer, dbgi, entity);
                return;
@@ -4378,7 +4229,7 @@ static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi,
 
        set_entity_initializer(init_entity, irinitializer);
 
-       ir_node *const src_addr = create_symconst(dbgi, mode_P_data, init_entity);
+       ir_node *const src_addr = create_symconst(dbgi, init_entity);
        ir_node *const copyb    = new_d_CopyB(dbgi, memory, addr, src_addr, irtype);
 
        ir_node *const copyb_mem = new_Proj(copyb, mode_M, pn_CopyB_M);
@@ -4419,8 +4270,8 @@ static void create_variable_initializer(entity_t *entity)
 
                ir_node *value = expression_to_firm(initializer_value->value);
 
-               type_t  *type = initializer_value->value->base.type;
-               ir_mode *mode = get_ir_mode_storage(type);
+               type_t  *init_type = initializer_value->value->base.type;
+               ir_mode *mode      = get_ir_mode_storage(init_type);
                value = create_conv(dbgi, value, mode);
                value = do_strict_conv(dbgi, value);
 
@@ -4468,7 +4319,7 @@ static void allocate_variable_length_array(entity_t *entity)
 {
        assert(entity->kind == ENTITY_VARIABLE);
        assert(entity->variable.initializer == NULL);
-       assert(get_cur_block() != NULL);
+       assert(currently_reachable());
 
        dbg_info *dbgi      = get_dbg_info(&entity->base.source_position);
        type_t   *type      = entity->declaration.type;
@@ -4563,14 +4414,13 @@ static void create_local_static_variable(entity_t *entity)
 
 static void return_statement_to_firm(return_statement_t *statement)
 {
-       if (get_cur_block() == NULL)
+       if (!currently_reachable())
                return;
 
        dbg_info *dbgi        = get_dbg_info(&statement->base.source_position);
        type_t   *type        = current_function_entity->declaration.type;
        ir_type  *func_irtype = get_ir_type(type);
 
-
        ir_node *in[1];
        int      in_len;
        if (get_method_n_ress(func_irtype) > 0) {
@@ -4579,10 +4429,10 @@ static void return_statement_to_firm(return_statement_t *statement)
                if (statement->value != NULL) {
                        ir_node *node = expression_to_firm(statement->value);
                        if (!is_compound_type(res_type)) {
-                               type_t  *type = statement->value->base.type;
-                               ir_mode *mode = get_ir_mode_storage(type);
-                               node          = create_conv(dbgi, node, mode);
-                               node          = do_strict_conv(dbgi, node);
+                               type_t  *ret_value_type = statement->value->base.type;
+                               ir_mode *mode           = get_ir_mode_storage(ret_value_type);
+                               node                    = create_conv(dbgi, node, mode);
+                               node                    = do_strict_conv(dbgi, node);
                        }
                        in[0] = node;
                } else {
@@ -4609,12 +4459,12 @@ static void return_statement_to_firm(return_statement_t *statement)
        ir_node *end_block = get_irg_end_block(current_ir_graph);
        add_immBlock_pred(end_block, ret);
 
-       set_cur_block(NULL);
+       set_unreachable_now();
 }
 
 static ir_node *expression_statement_to_firm(expression_statement_t *statement)
 {
-       if (get_cur_block() == NULL)
+       if (!currently_reachable())
                return NULL;
 
        return expression_to_firm(statement->expression);
@@ -4647,7 +4497,7 @@ static ir_node *compound_statement_to_firm(compound_statement_t *compound)
 
 static void create_global_variable(entity_t *entity)
 {
-       ir_linkage    linkage    = 0;
+       ir_linkage    linkage    = IR_LINKAGE_DEFAULT;
        ir_visibility visibility = ir_visibility_default;
        ir_entity    *irentity;
        assert(entity->kind == ENTITY_VARIABLE);
@@ -4735,7 +4585,7 @@ static void initialize_local_declaration(entity_t *entity)
 
        // no need to emit code in dead blocks
        if (entity->declaration.storage_class != STORAGE_CLASS_STATIC
-                       && get_cur_block() == NULL)
+                       && !currently_reachable())
                return;
 
        switch ((declaration_kind_t) entity->declaration.kind) {
@@ -4789,145 +4639,125 @@ static void declaration_statement_to_firm(declaration_statement_t *statement)
 
 static void if_statement_to_firm(if_statement_t *statement)
 {
-       ir_node *cur_block = get_cur_block();
-
-       ir_node *fallthrough_block = NULL;
-
-       /* the true (blocks) */
-       ir_node *true_block = NULL;
-       if (statement->true_statement != NULL) {
-               true_block = new_immBlock();
-               set_cur_block(true_block);
-               statement_to_firm(statement->true_statement);
-               if (get_cur_block() != NULL) {
-                       ir_node *jmp = new_Jmp();
-                       if (fallthrough_block == NULL)
-                               fallthrough_block = new_immBlock();
-                       add_immBlock_pred(fallthrough_block, jmp);
-               }
+       /* Create the condition. */
+       ir_node *true_block  = NULL;
+       ir_node *false_block = NULL;
+       if (currently_reachable()) {
+               true_block  = new_immBlock();
+               false_block = new_immBlock();
+               create_condition_evaluation(statement->condition, true_block, false_block);
+               mature_immBlock(true_block);
        }
 
-       /* the false (blocks) */
-       ir_node *false_block = NULL;
+       /* Create the false statement.
+        * Handle false before true, so if no false statement is present, then the
+        * empty false block is reused as fallthrough block. */
+       ir_node *fallthrough_block = NULL;
        if (statement->false_statement != NULL) {
-               false_block = new_immBlock();
+               if (false_block != NULL) {
+                       mature_immBlock(false_block);
+               }
                set_cur_block(false_block);
-
                statement_to_firm(statement->false_statement);
-               if (get_cur_block() != NULL) {
-                       ir_node *jmp = new_Jmp();
-                       if (fallthrough_block == NULL)
-                               fallthrough_block = new_immBlock();
-                       add_immBlock_pred(fallthrough_block, jmp);
+               if (currently_reachable()) {
+                       fallthrough_block = new_immBlock();
+                       add_immBlock_pred(fallthrough_block, new_Jmp());
                }
+       } else {
+               fallthrough_block = false_block;
        }
 
-       /* create the condition */
-       if (cur_block != NULL) {
-               if (true_block == NULL || false_block == NULL) {
-                       if (fallthrough_block == NULL)
-                               fallthrough_block = new_immBlock();
-                       if (true_block == NULL)
-                               true_block = fallthrough_block;
-                       if (false_block == NULL)
-                               false_block = fallthrough_block;
+       /* Create the true statement. */
+       set_cur_block(true_block);
+       statement_to_firm(statement->true_statement);
+       if (currently_reachable()) {
+               if (fallthrough_block == NULL) {
+                       fallthrough_block = new_immBlock();
                }
-
-               set_cur_block(cur_block);
-               create_condition_evaluation(statement->condition, true_block,
-                                           false_block);
+               add_immBlock_pred(fallthrough_block, new_Jmp());
        }
 
-       mature_immBlock(true_block);
-       if (false_block != fallthrough_block && false_block != NULL) {
-               mature_immBlock(false_block);
-       }
+       /* Handle the block after the if-statement. */
        if (fallthrough_block != NULL) {
                mature_immBlock(fallthrough_block);
        }
-
        set_cur_block(fallthrough_block);
 }
 
+/* Create a jump node which jumps into target_block, if the current block is
+ * reachable. */
+static void jump_if_reachable(ir_node *const target_block)
+{
+       ir_node *const pred = currently_reachable() ? new_Jmp() : new_Bad(mode_X);
+       add_immBlock_pred(target_block, pred);
+}
+
 static void while_statement_to_firm(while_statement_t *statement)
 {
-       ir_node *jmp = NULL;
-       if (get_cur_block() != NULL) {
-               jmp = new_Jmp();
-       }
+       /* Create the header block */
+       ir_node *const header_block = new_immBlock();
+       jump_if_reachable(header_block);
+
+       /* Create the condition. */
+       ir_node      *      body_block;
+       ir_node      *      false_block;
+       expression_t *const cond = statement->condition;
+       if (is_constant_expression(cond) == EXPR_CLASS_CONSTANT &&
+                       fold_constant_to_bool(cond)) {
+               /* Shortcut for while (true). */
+               body_block  = header_block;
+               false_block = NULL;
 
-       /* create the header block */
-       ir_node *header_block = new_immBlock();
-       if (jmp != NULL) {
-               add_immBlock_pred(header_block, jmp);
+               keep_alive(header_block);
+               keep_all_memory(header_block);
+       } else {
+               body_block  = new_immBlock();
+               false_block = new_immBlock();
+
+               set_cur_block(header_block);
+               create_condition_evaluation(cond, body_block, false_block);
+               mature_immBlock(body_block);
        }
 
-       /* the loop body */
-       ir_node *old_continue_label = continue_label;
-       ir_node *old_break_label    = break_label;
-       continue_label              = header_block;
-       break_label                 = NULL;
+       ir_node *const old_continue_label = continue_label;
+       ir_node *const old_break_label    = break_label;
+       continue_label = header_block;
+       break_label    = false_block;
 
-       ir_node *body_block = new_immBlock();
+       /* Create the loop body. */
        set_cur_block(body_block);
        statement_to_firm(statement->body);
-       ir_node *false_block = break_label;
-
-       assert(continue_label == header_block);
-       continue_label = old_continue_label;
-       break_label    = old_break_label;
-
-       if (get_cur_block() != NULL) {
-               jmp = new_Jmp();
-               add_immBlock_pred(header_block, jmp);
-       }
-
-       /* shortcut for while(true) */
-       if (is_constant_expression(statement->condition)
-                       && fold_constant_to_bool(statement->condition) != 0) {
-               set_cur_block(header_block);
-               ir_node *header_jmp = new_Jmp();
-               add_immBlock_pred(body_block, header_jmp);
-
-               keep_alive(body_block);
-               keep_all_memory(body_block);
-               set_cur_block(body_block);
-       } else {
-               if (false_block == NULL) {
-                       false_block = new_immBlock();
-               }
-
-               /* create the condition */
-               set_cur_block(header_block);
-
-               create_condition_evaluation(statement->condition, body_block,
-                                           false_block);
-       }
+       jump_if_reachable(header_block);
 
-       mature_immBlock(body_block);
        mature_immBlock(header_block);
+       assert(false_block == NULL || false_block == break_label);
+       false_block = break_label;
        if (false_block != NULL) {
                mature_immBlock(false_block);
        }
-
        set_cur_block(false_block);
+
+       assert(continue_label == header_block);
+       continue_label = old_continue_label;
+       break_label    = old_break_label;
 }
 
-static void do_while_statement_to_firm(do_while_statement_t *statement)
+static ir_node *get_break_label(void)
 {
-       ir_node *jmp = NULL;
-       if (get_cur_block() != NULL) {
-               jmp = new_Jmp();
+       if (break_label == NULL) {
+               break_label = new_immBlock();
        }
+       return break_label;
+}
 
+static void do_while_statement_to_firm(do_while_statement_t *statement)
+{
        /* create the header block */
        ir_node *header_block = new_immBlock();
 
        /* the loop body */
        ir_node *body_block = new_immBlock();
-       if (jmp != NULL) {
-               add_immBlock_pred(body_block, jmp);
-       }
+       jump_if_reachable(body_block);
 
        ir_node *old_continue_label = continue_label;
        ir_node *old_break_label    = break_label;
@@ -4936,28 +4766,20 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
 
        set_cur_block(body_block);
        statement_to_firm(statement->body);
-       ir_node *false_block = break_label;
+       ir_node *const false_block = get_break_label();
 
        assert(continue_label == header_block);
        continue_label = old_continue_label;
        break_label    = old_break_label;
 
-       if (get_cur_block() != NULL) {
-               ir_node *body_jmp = new_Jmp();
-               add_immBlock_pred(header_block, body_jmp);
-               mature_immBlock(header_block);
-       }
-
-       if (false_block == NULL) {
-               false_block = new_immBlock();
-       }
+       jump_if_reachable(header_block);
 
        /* create the condition */
+       mature_immBlock(header_block);
        set_cur_block(header_block);
 
        create_condition_evaluation(statement->condition, body_block, false_block);
        mature_immBlock(body_block);
-       mature_immBlock(header_block);
        mature_immBlock(false_block);
 
        set_cur_block(false_block);
@@ -4965,8 +4787,6 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
 
 static void for_statement_to_firm(for_statement_t *statement)
 {
-       ir_node *jmp = NULL;
-
        /* create declarations */
        entity_t *entity = statement->scope.entities;
        for ( ; entity != NULL; entity = entity->base.next) {
@@ -4976,7 +4796,7 @@ static void for_statement_to_firm(for_statement_t *statement)
                create_local_declaration(entity);
        }
 
-       if (get_cur_block() != NULL) {
+       if (currently_reachable()) {
                entity = statement->scope.entities;
                for ( ; entity != NULL; entity = entity->base.next) {
                        if (!is_declaration(entity))
@@ -4988,95 +4808,80 @@ static void for_statement_to_firm(for_statement_t *statement)
                if (statement->initialisation != NULL) {
                        expression_to_firm(statement->initialisation);
                }
-
-               jmp = new_Jmp();
-       }
-
-
-       /* create the step block */
-       ir_node *const step_block = new_immBlock();
-       set_cur_block(step_block);
-       if (statement->step != NULL) {
-               expression_to_firm(statement->step);
        }
-       ir_node *const step_jmp = new_Jmp();
 
-       /* create the header block */
+       /* Create the header block */
        ir_node *const header_block = new_immBlock();
-       set_cur_block(header_block);
-       if (jmp != NULL) {
-               add_immBlock_pred(header_block, jmp);
-       }
-       add_immBlock_pred(header_block, step_jmp);
-
-       /* the false block */
-       ir_node *const false_block = new_immBlock();
+       jump_if_reachable(header_block);
 
-       /* the loop body */
+       /* Create the condition. */
        ir_node *body_block;
-       if (statement->body != NULL) {
-               ir_node *const old_continue_label = continue_label;
-               ir_node *const old_break_label    = break_label;
-               continue_label = step_block;
-               break_label    = false_block;
-
-               body_block = new_immBlock();
-               set_cur_block(body_block);
-               statement_to_firm(statement->body);
-
-               assert(continue_label == step_block);
-               assert(break_label    == false_block);
-               continue_label = old_continue_label;
-               break_label    = old_break_label;
-
-               if (get_cur_block() != NULL) {
-                       jmp = new_Jmp();
-                       add_immBlock_pred(step_block, jmp);
-               }
-       } else {
-               body_block = step_block;
-       }
-
-       /* create the condition */
-       set_cur_block(header_block);
+       ir_node *false_block;
        if (statement->condition != NULL) {
-               create_condition_evaluation(statement->condition, body_block,
-                                           false_block);
+               body_block  = new_immBlock();
+               false_block = new_immBlock();
+
+               set_cur_block(header_block);
+               create_condition_evaluation(statement->condition, body_block, false_block);
+               mature_immBlock(body_block);
        } else {
+               /* for-ever. */
+               body_block  = header_block;
+               false_block = NULL;
+
                keep_alive(header_block);
                keep_all_memory(header_block);
-               jmp = new_Jmp();
-               add_immBlock_pred(body_block, jmp);
        }
 
-       mature_immBlock(body_block);
-       mature_immBlock(false_block);
-       mature_immBlock(step_block);
-       mature_immBlock(header_block);
-       mature_immBlock(false_block);
+       /* Create the step block, if necessary. */
+       ir_node      *      step_block = header_block;
+       expression_t *const step       = statement->step;
+       if (step != NULL) {
+               step_block = new_immBlock();
+       }
+
+       ir_node *const old_continue_label = continue_label;
+       ir_node *const old_break_label    = break_label;
+       continue_label = step_block;
+       break_label    = false_block;
+
+       /* Create the loop body. */
+       set_cur_block(body_block);
+       statement_to_firm(statement->body);
+       jump_if_reachable(step_block);
 
+       /* Create the step code. */
+       if (step != NULL) {
+               mature_immBlock(step_block);
+               set_cur_block(step_block);
+               expression_to_firm(step);
+               jump_if_reachable(header_block);
+       }
+
+       mature_immBlock(header_block);
+       assert(false_block == NULL || false_block == break_label);
+       false_block = break_label;
+       if (false_block != NULL) {
+               mature_immBlock(false_block);
+       }
        set_cur_block(false_block);
+
+       assert(continue_label == step_block);
+       continue_label = old_continue_label;
+       break_label    = old_break_label;
 }
 
 static void create_jump_statement(const statement_t *statement,
                                   ir_node *target_block)
 {
-       if (get_cur_block() == NULL)
+       if (!currently_reachable())
                return;
 
        dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
        ir_node  *jump = new_d_Jmp(dbgi);
        add_immBlock_pred(target_block, jump);
 
-       set_cur_block(NULL);
-}
-
-static ir_node *get_break_label(void)
-{
-       if (break_label == NULL) {
-               break_label = new_immBlock();
-       }
-       return break_label;
+       set_unreachable_now();
 }
 
 static void switch_statement_to_firm(switch_statement_t *statement)
@@ -5085,13 +4890,13 @@ static void switch_statement_to_firm(switch_statement_t *statement)
        dbg_info *dbgi        = get_dbg_info(&statement->base.source_position);
        ir_node  *cond        = NULL;
 
-       if (get_cur_block() != NULL) {
+       if (currently_reachable()) {
                ir_node *expression = expression_to_firm(statement->expression);
                cond                = new_d_Cond(dbgi, expression);
                first_block         = get_cur_block();
        }
 
-       set_cur_block(NULL);
+       set_unreachable_now();
 
        ir_node *const old_switch_cond       = current_switch_cond;
        ir_node *const old_break_label       = break_label;
@@ -5103,8 +4908,8 @@ static void switch_statement_to_firm(switch_statement_t *statement)
        current_switch                       = statement;
 
        /* determine a free number for the default label */
-       unsigned long num_cases = 0;
-       long def_nr = 0;
+       unsigned long num_cases       = 0;
+       long          default_proj_nr = 0;
        for (case_label_statement_t *l = statement->first_case; l != NULL; l = l->next) {
                if (l->expression == NULL) {
                        /* default case */
@@ -5112,18 +4917,18 @@ static void switch_statement_to_firm(switch_statement_t *statement)
                }
                if (l->last_case >= l->first_case)
                        num_cases += l->last_case - l->first_case + 1;
-               if (l->last_case > def_nr)
-                       def_nr = l->last_case;
+               if (l->last_case > default_proj_nr)
+                       default_proj_nr = l->last_case;
        }
 
-       if (def_nr == INT_MAX) {
+       if (default_proj_nr == LONG_MAX) {
                /* Bad: an overflow will occur, we cannot be sure that the
                 * maximum + 1 is a free number. Scan the values a second
                 * time to find a free number.
                 */
                unsigned char *bits = xmalloc((num_cases + 7) >> 3);
 
-               memset(bits, 0, (num_cases + 7) >> 3);
+               memset(bits, 0, (num_cases + 7) >> 3);
                for (case_label_statement_t *l = statement->first_case; l != NULL; l = l->next) {
                        if (l->expression == NULL) {
                                /* default case */
@@ -5149,25 +4954,23 @@ static void switch_statement_to_firm(switch_statement_t *statement)
                                break;
 
                free(bits);
-               def_nr = i;
+               default_proj_nr = i;
        } else {
-               ++def_nr;
+               ++default_proj_nr;
        }
-       statement->default_proj_nr = def_nr;
-
-       if (statement->body != NULL) {
-               statement_to_firm(statement->body);
+       statement->default_proj_nr = default_proj_nr;
+       /* safety check: cond might already be folded to a Bad */
+       if (cond != NULL && is_Cond(cond)) {
+               set_Cond_default_proj(cond, default_proj_nr);
        }
 
-       if (get_cur_block() != NULL) {
-               ir_node *jmp = new_Jmp();
-               add_immBlock_pred(get_break_label(), jmp);
-       }
+       statement_to_firm(statement->body);
+
+       jump_if_reachable(get_break_label());
 
        if (!saw_default_label && first_block != NULL) {
                set_cur_block(first_block);
-               ir_node *const proj = new_d_defaultProj(dbgi, cond,
-                                                       statement->default_proj_nr);
+               ir_node *const proj = new_d_Proj(dbgi, cond, mode_X, default_proj_nr);
                add_immBlock_pred(get_break_label(), proj);
        }
 
@@ -5188,65 +4991,51 @@ static void case_label_to_firm(const case_label_statement_t *statement)
        if (statement->is_empty_range)
                return;
 
-       dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
-
-       ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
-
-       ir_node *proj;
        ir_node *block = new_immBlock();
+       /* Fallthrough from previous case */
+       jump_if_reachable(block);
 
        if (current_switch_cond != NULL) {
                set_cur_block(get_nodes_block(current_switch_cond));
+               dbg_info *const dbgi = get_dbg_info(&statement->base.source_position);
                if (statement->expression != NULL) {
                        long pn     = statement->first_case;
                        long end_pn = statement->last_case;
                        assert(pn <= end_pn);
                        /* create jumps for all cases in the given range */
                        do {
-                               proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
+                               ir_node *const proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
                                add_immBlock_pred(block, proj);
                        } while (pn++ < end_pn);
                } else {
                        saw_default_label = true;
-                       proj = new_d_defaultProj(dbgi, current_switch_cond,
-                                                                        current_switch->default_proj_nr);
-
+                       ir_node *const proj = new_d_Proj(dbgi, current_switch_cond, mode_X,
+                                                        current_switch->default_proj_nr);
                        add_immBlock_pred(block, proj);
                }
        }
 
-       if (fallthrough != NULL) {
-               add_immBlock_pred(block, fallthrough);
-       }
        mature_immBlock(block);
        set_cur_block(block);
 
-       if (statement->statement != NULL) {
-               statement_to_firm(statement->statement);
-       }
+       statement_to_firm(statement->statement);
 }
 
 static void label_to_firm(const label_statement_t *statement)
 {
        ir_node *block = get_label_block(statement->label);
-
-       if (get_cur_block() != NULL) {
-               ir_node *jmp = new_Jmp();
-               add_immBlock_pred(block, jmp);
-       }
+       jump_if_reachable(block);
 
        set_cur_block(block);
        keep_alive(block);
        keep_all_memory(block);
 
-       if (statement->statement != NULL) {
-               statement_to_firm(statement->statement);
-       }
+       statement_to_firm(statement->statement);
 }
 
 static void goto_to_firm(const goto_statement_t *statement)
 {
-       if (get_cur_block() == NULL)
+       if (!currently_reachable())
                return;
 
        if (statement->expression) {
@@ -5261,7 +5050,7 @@ static void goto_to_firm(const goto_statement_t *statement)
                ir_node *jmp   = new_Jmp();
                add_immBlock_pred(block, jmp);
        }
-       set_cur_block(NULL);
+       set_unreachable_now();
 }
 
 static void asm_statement_to_firm(const asm_statement_t *statement)
@@ -5324,20 +5113,19 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
                asm_constraint_flags_t asm_flags
                        = be_parse_asm_constraints(constraints);
 
-               if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
-                       warningf(&statement->base.source_position,
-                              "some constraints in '%s' are not supported", constraints);
-               }
-               if (asm_flags & ASM_CONSTRAINT_FLAG_INVALID) {
-                       errorf(&statement->base.source_position,
-                              "some constraints in '%s' are invalid", constraints);
-                       continue;
-               }
-               if (! (asm_flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE)) {
-                       errorf(&statement->base.source_position,
-                              "no write flag specified for output constraints '%s'",
-                              constraints);
-                       continue;
+               {
+                       source_position_t const *const pos = &statement->base.source_position;
+                       if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
+                               warningf(WARN_OTHER, pos, "some constraints in '%s' are not supported", constraints);
+                       }
+                       if (asm_flags & ASM_CONSTRAINT_FLAG_INVALID) {
+                               errorf(pos, "some constraints in '%s' are invalid", constraints);
+                               continue;
+                       }
+                       if (! (asm_flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE)) {
+                               errorf(pos, "no write flag specified for output constraints '%s'", constraints);
+                               continue;
+                       }
                }
 
                unsigned pos = next_pos++;
@@ -5507,13 +5295,14 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
        }
 }
 
-static void    ms_try_statement_to_firm(ms_try_statement_t *statement)
+static void ms_try_statement_to_firm(ms_try_statement_t *statement)
 {
        statement_to_firm(statement->try_statement);
-       warningf(&statement->base.source_position, "structured exception handling ignored");
+       source_position_t const *const pos = &statement->base.source_position;
+       warningf(WARN_OTHER, pos, "structured exception handling ignored");
 }
 
-static void    leave_statement_to_firm(leave_statement_t *statement)
+static void leave_statement_to_firm(leave_statement_t *statement)
 {
        errorf(&statement->base.source_position, "__leave not supported yet");
 }
@@ -5529,8 +5318,8 @@ static void statement_to_firm(statement_t *statement)
 #endif
 
        switch (statement->kind) {
-       case STATEMENT_INVALID:
-               panic("invalid statement found");
+       case STATEMENT_ERROR:
+               panic("error statement found");
        case STATEMENT_EMPTY:
                /* nothing */
                return;
@@ -5659,16 +5448,23 @@ static void initialize_function_parameters(entity_t *entity)
        assert(entity->kind == ENTITY_FUNCTION);
        ir_graph *irg             = current_ir_graph;
        ir_node  *args            = get_irg_args(irg);
-       ir_type  *function_irtype = get_ir_type(entity->declaration.type);
-       int      first_param_nr   = 0;
+       int       n               = 0;
+       ir_type  *function_irtype;
 
        if (entity->function.need_closure) {
                /* add an extra parameter for the static link */
                entity->function.static_link = new_r_Proj(args, mode_P_data, 0);
-               ++first_param_nr;
+               ++n;
+
+               /* Matze: IMO this is wrong, nested functions should have an own
+                * type and not rely on strange parameters... */
+               function_irtype = create_method_type(&entity->declaration.type->function, true);
+       } else {
+               function_irtype = get_ir_type(entity->declaration.type);
        }
 
-       int       n         = 0;
+
+
        entity_t *parameter = entity->function.parameters.entities;
        for ( ; parameter != NULL; parameter = parameter->base.next, ++n) {
                if (parameter->kind != ENTITY_PARAMETER)
@@ -5683,22 +5479,20 @@ static void initialize_function_parameters(entity_t *entity)
                        needs_entity = true;
                }
 
+               ir_type *param_irtype = get_method_param_type(function_irtype, n);
                if (needs_entity) {
-                       ir_entity *entity = get_method_value_param_ent(function_irtype, n);
-                       ident     *id     = new_id_from_str(parameter->base.symbol->string);
-                       set_entity_ident(entity, id);
-
+                       ir_type   *frame_type = get_irg_frame_type(irg);
+                       ir_entity *param
+                               = new_parameter_entity(frame_type, n, param_irtype);
                        parameter->declaration.kind
                                = DECLARATION_KIND_PARAMETER_ENTITY;
-                       parameter->parameter.v.entity = entity;
+                       parameter->parameter.v.entity = param;
                        continue;
                }
 
-               ir_type *param_irtype = get_method_param_type(function_irtype, n);
-               ir_mode *param_mode   = get_type_mode(param_irtype);
-
-               long     pn    = n + first_param_nr;
-               ir_node *value = new_r_Proj(args, param_mode, pn);
+               ir_mode *param_mode = get_type_mode(param_irtype);
+               long     pn         = n;
+               ir_node *value      = new_r_Proj(args, param_mode, pn);
 
                ir_mode *mode = get_ir_mode_storage(type);
                value = create_conv(NULL, value, mode);
@@ -5725,22 +5519,22 @@ static void handle_decl_modifier_irg(ir_graph_ptr irg,
 {
        if (decl_modifiers & DM_RETURNS_TWICE) {
                /* TRUE if the declaration includes __attribute__((returns_twice)) */
-               set_irg_additional_property(irg, mtp_property_returns_twice);
+               add_irg_additional_properties(irg, mtp_property_returns_twice);
        }
        if (decl_modifiers & DM_NORETURN) {
                /* TRUE if the declaration includes the Microsoft
                   __declspec(noreturn) specifier. */
-               set_irg_additional_property(irg, mtp_property_noreturn);
+               add_irg_additional_properties(irg, mtp_property_noreturn);
        }
        if (decl_modifiers & DM_NOTHROW) {
                /* TRUE if the declaration includes the Microsoft
                   __declspec(nothrow) specifier. */
-               set_irg_additional_property(irg, mtp_property_nothrow);
+               add_irg_additional_properties(irg, mtp_property_nothrow);
        }
        if (decl_modifiers & DM_NAKED) {
                /* TRUE if the declaration includes the Microsoft
                   __declspec(naked) specifier. */
-               set_irg_additional_property(irg, mtp_property_naked);
+               add_irg_additional_properties(irg, mtp_property_naked);
        }
        if (decl_modifiers & DM_FORCEINLINE) {
                /* TRUE if the declaration includes the
@@ -5768,11 +5562,11 @@ static void add_function_pointer(ir_type *segment, ir_entity *method,
        ir_entity *ptr          = new_entity(segment, ide, ptr_type);
        ir_graph  *irg          = get_const_code_irg();
        ir_node   *val          = new_rd_SymConst_addr_ent(NULL, irg, mode_P_code,
-                                                          method, NULL);
+                                                          method);
 
        set_entity_ld_ident(ptr, new_id_from_chars("", 0));
        set_entity_compiler_generated(ptr, 1);
-       set_entity_visibility(ptr, ir_visibility_local);
+       set_entity_visibility(ptr, ir_visibility_private);
        add_entity_linkage(ptr, IR_LINKAGE_CONSTANT|IR_LINKAGE_HIDDEN_USER);
        set_atomic_ent_value(ptr, val);
 }
@@ -5801,7 +5595,7 @@ static void create_function(entity_t *entity)
        if (entity->function.statement == NULL)
                return;
 
-       if (is_main(entity) && firm_opt.os_support == OS_SUPPORT_MINGW) {
+       if (is_main(entity) && enable_main_collect2_hack) {
                prepare_main_collect2(entity);
        }
 
@@ -5827,13 +5621,18 @@ static void create_function(entity_t *entity)
 
        int       n_local_vars = get_function_n_local_vars(entity);
        ir_graph *irg          = new_ir_graph(function_entity, n_local_vars);
+       current_ir_graph = irg;
 
        ir_graph *old_current_function = current_function;
        current_function = irg;
 
-       set_irg_fp_model(irg, firm_opt.fp_model);
+       ir_entity *const old_current_vararg_entity = current_vararg_entity;
+       current_vararg_entity = NULL;
+
+       set_irg_fp_model(irg, firm_fp_model);
        tarval_enable_fp_ops(1);
-       set_irn_dbg_info(get_irg_start_block(irg), get_entity_dbg_info(function_entity));
+       set_irn_dbg_info(get_irg_start_block(irg),
+                        get_entity_dbg_info(function_entity));
 
        ir_node *first_block = get_cur_block();
 
@@ -5851,7 +5650,7 @@ static void create_function(entity_t *entity)
        ir_node *end_block = get_irg_end_block(irg);
 
        /* do we have a return statement yet? */
-       if (get_cur_block() != NULL) {
+       if (currently_reachable()) {
                type_t *type = skip_typeref(entity->declaration.type);
                assert(is_type_function(type));
                const function_type_t *func_type   = &type->function;
@@ -5893,9 +5692,8 @@ static void create_function(entity_t *entity)
        if (has_computed_gotos) {
                /* if we have computed goto's in the function, we cannot inline it */
                if (get_irg_inline_property(irg) >= irg_inline_recomended) {
-                       warningf(&entity->base.source_position,
-                                "function '%Y' can never be inlined because it contains a computed goto",
-                                entity->base.symbol);
+                       source_position_t const *const pos = &entity->base.source_position;
+                       warningf(WARN_OTHER, pos, "'%N' can never be inlined because it contains a computed goto", entity);
                }
                set_irg_inline_property(irg, irg_inline_forbidden);
        }
@@ -5914,8 +5712,8 @@ static void create_function(entity_t *entity)
        int      align_all  = 4;
        int      offset     = 0;
        for (int i = 0; i < n; ++i) {
-               ir_entity *entity      = get_compound_member(frame_type, i);
-               ir_type   *entity_type = get_entity_type(entity);
+               ir_entity *member      = get_compound_member(frame_type, i);
+               ir_type   *entity_type = get_entity_type(member);
 
                int align = get_type_alignment_bytes(entity_type);
                if (align > align_all)
@@ -5928,14 +5726,15 @@ static void create_function(entity_t *entity)
                        }
                }
 
-               set_entity_offset(entity, offset);
+               set_entity_offset(member, offset);
                offset += get_type_size_bytes(entity_type);
        }
        set_type_size_bytes(frame_type, offset);
        set_type_alignment_bytes(frame_type, align_all);
 
-       irg_vrfy(irg);
-       current_function = old_current_function;
+       irg_verify(irg, VERIFY_ENFORCE_SSA);
+       current_vararg_entity = old_current_vararg_entity;
+       current_function      = old_current_function;
 
        if (current_trampolines != NULL) {
                DEL_ARR_F(current_trampolines);
@@ -5947,14 +5746,11 @@ static void create_function(entity_t *entity)
        if (inner != NULL) {
                ir_type *rem_outer_frame      = current_outer_frame;
                current_outer_frame           = get_irg_frame_type(current_ir_graph);
-               ir_type *rem_outer_value_type = current_outer_value_type;
-               current_outer_value_type      = get_irg_value_param_type(current_ir_graph);
                for (int i = ARR_LEN(inner) - 1; i >= 0; --i) {
                        create_function(inner[i]);
                }
                DEL_ARR_F(inner);
 
-               current_outer_value_type = rem_outer_value_type;
                current_outer_frame      = rem_outer_frame;
        }
 }
@@ -5968,7 +5764,7 @@ static void scope_to_firm(scope_t *scope)
                        continue;
 
                if (entity->kind == ENTITY_FUNCTION) {
-                       if (entity->function.btk != bk_none) {
+                       if (entity->function.btk != BUILTIN_NONE) {
                                /* builtins have no representation */
                                continue;
                        }
@@ -5987,7 +5783,7 @@ static void scope_to_firm(scope_t *scope)
                        continue;
 
                if (entity->kind == ENTITY_FUNCTION) {
-                       if (entity->function.btk != bk_none) {
+                       if (entity->function.btk != BUILTIN_NONE) {
                                /* builtins have no representation */
                                continue;
                        }
@@ -6009,21 +5805,6 @@ void init_ast2firm(void)
        ir_set_debug_retrieve(dbg_retrieve);
        ir_set_type_debug_retrieve(dbg_print_type_dbg_info);
 
-       /* OS option must be set to the backend */
-       switch (firm_opt.os_support) {
-       case OS_SUPPORT_MINGW:
-               create_ld_ident = create_name_win32;
-               break;
-       case OS_SUPPORT_LINUX:
-               create_ld_ident = create_name_linux_elf;
-               break;
-       case OS_SUPPORT_MACHO:
-               create_ld_ident = create_name_macho;
-               break;
-       default:
-               panic("unexpected OS support mode");
-       }
-
        /* create idents for all known runtime functions */
        for (size_t i = 0; i < lengthof(rts_data); ++i) {
                rts_idents[i] = new_id_from_str(rts_data[i].name);
@@ -6078,6 +5859,7 @@ void translation_unit_to_firm(translation_unit_t *unit)
 {
        /* initialize firm arithmetic */
        tarval_set_integer_overflow_mode(TV_OVERFLOW_WRAP);
+       ir_set_uninitialized_local_variable_func(uninitialized_local_var);
 
        /* just to be sure */
        continue_label           = NULL;