We now support -msoft-float.
[cparser] / ast2firm.c
index 2b47167..d1cf59a 100644 (file)
@@ -44,7 +44,7 @@
 #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"
@@ -81,7 +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;
 
 static const entity_t     *current_function_entity;
 static ir_node            *current_function_name;
@@ -182,6 +181,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);
@@ -192,7 +200,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) {
@@ -201,13 +209,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);
@@ -229,26 +236,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)
@@ -536,21 +523,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);
        }
 }
 
@@ -616,7 +602,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);
@@ -627,7 +613,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);
@@ -747,9 +738,6 @@ ir_type *get_ir_type(type_t *type)
        case TYPE_ENUM:
                firm_type = create_enum_type(&type->enumt);
                break;
-       case TYPE_BITFIELD:
-               firm_type = create_bitfield_type(&type->bitfield);
-               break;
 
        case TYPE_TYPEOF:
        case TYPE_TYPEDEF:
@@ -1207,12 +1195,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; }
                }
@@ -1296,6 +1284,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 {
@@ -1830,10 +1820,16 @@ static ir_node *process_builtin_call(const call_expression_t *call)
        case bk_gnu_builtin_ffs:
                 return gen_unary_builtin(ir_bk_ffs,      call->arguments->expression, function_type, dbgi);
        case bk_gnu_builtin_clz:
+       case bk_gnu_builtin_clzl:
+       case bk_gnu_builtin_clzll:
                 return gen_unary_builtin(ir_bk_clz,      call->arguments->expression, function_type, dbgi);
        case bk_gnu_builtin_ctz:
+       case bk_gnu_builtin_ctzl:
+       case bk_gnu_builtin_ctzll:
                 return gen_unary_builtin(ir_bk_ctz,      call->arguments->expression, function_type, dbgi);
        case bk_gnu_builtin_popcount:
+       case bk_gnu_builtin_popcountl:
+       case bk_gnu_builtin_popcountll:
        case bk_ms__popcount:
                 return gen_unary_builtin(ir_bk_popcount, call->arguments->expression, function_type, dbgi);
        case bk_gnu_builtin_parity:
@@ -2147,9 +2143,8 @@ 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));
-
+       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);
@@ -2179,44 +2174,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);
-       ir_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);
-       ir_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 */
@@ -2267,7 +2269,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;
@@ -2320,7 +2322,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 {
@@ -3103,6 +3105,14 @@ static ir_tarval *fold_constant_to_tarval(const expression_t *expression)
        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)
@@ -3221,11 +3231,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);
        }
 
@@ -3307,7 +3316,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;
@@ -3581,7 +3589,6 @@ 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;
        }
@@ -4032,15 +4039,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 && expr->base.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);
@@ -4375,13 +4373,8 @@ static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi,
        }
 
        if (is_constant_initializer(initializer) == EXPR_CLASS_VARIABLE) {
-               bool old_initializer_use_bitfield_basetype
-                       = initializer_use_bitfield_basetype;
-               initializer_use_bitfield_basetype = true;
                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;