_ALL = 0xFF
} lang_features_t;
-/* the current C mode/dialect */
+/** the current C mode/dialect */
extern unsigned int c_mode;
-/* the 'machine size', 16, 32 or 64 bit */
+/** the 'machine size', 16, 32 or 64 bit */
extern unsigned int machine_size;
-/* true if the char type is signed */
+/** byte-order: true = big-endian, false = little-endian */
+extern bool byte_order_big_endian;
+
+/** true if the char type is signed */
extern bool char_is_signed;
-/* true for strict language checking. */
+/** true for strict language checking. */
extern bool strict_mode;
-/* atomic type of wchar_t */
+/** atomic type of wchar_t */
extern atomic_type_kind_t wchar_atomic_kind;
#endif
#endif
#endif
-/** The current c mode/dialect. */
-unsigned int c_mode = _C89 | _ANSI | _C99 | _GNUC;
-
-/** The 'machine size', 16, 32 or 64 bit, 32bit is the default. */
-unsigned int machine_size = 32;
-
-/** true if the char type is signed. */
-bool char_is_signed = true;
-
-/** true for strict language checking. */
-bool strict_mode = false;
-
-/** use builtins for some libc functions */
-bool use_builtins = false;
-
-/** we have extern function with const attribute. */
-bool have_const_functions = false;
-
-atomic_type_kind_t wchar_atomic_kind = ATOMIC_TYPE_INT;
+unsigned int c_mode = _C89 | _ANSI | _C99 | _GNUC;
+unsigned int machine_size = 32;
+bool byte_order_big_endian = false;
+bool char_is_signed = true;
+bool strict_mode = false;
+bool use_builtins = false;
+bool have_const_functions = false;
+atomic_type_kind_t wchar_atomic_kind = ATOMIC_TYPE_INT;
/* to switch on printing of implicit casts */
extern bool print_implicit_casts;
c_mode &= ~features_off;
gen_firm_init();
+ byte_order_big_endian = be_get_backend_param()->byte_order_big_endian;
init_symbol_table();
init_types();
init_typehash();
return identify_new_type(type);
}
+static entity_t *pack_bitfield_members_big_endian(il_size_t *struct_offset,
+ il_alignment_t *struct_alignment, bool packed, entity_t *first)
+{
+ type_t *current_base_type = NULL;
+ il_size_t offset = *struct_offset;
+ il_alignment_t alignment = *struct_alignment;
+ size_t bit_offset = 0;
+
+ if (packed)
+ panic("packed bitfields on big-endian arch not supported yet");
+
+ entity_t *member;
+ for (member = first; member != NULL; member = member->base.next) {
+ if (member->kind != ENTITY_COMPOUND_MEMBER)
+ continue;
+
+ type_t *type = member->declaration.type;
+ if (type->kind != TYPE_BITFIELD)
+ break;
+
+ size_t bit_size = type->bitfield.bit_size;
+ type_t *base_type = skip_typeref(type->bitfield.base_type);
+
+ /* see if we need to start a new "bucket" */
+ if (base_type != current_base_type || bit_size > bit_offset) {
+ if (current_base_type != NULL)
+ offset += get_type_size(current_base_type);
+
+ current_base_type = base_type;
+ il_alignment_t base_alignment = get_type_alignment(base_type);
+ il_alignment_t alignment_mask = base_alignment-1;
+ if (base_alignment > alignment)
+ alignment = base_alignment;
+ offset = (offset + base_alignment-1) & ~alignment_mask;
+ bit_offset = get_type_size(base_type) * BITS_PER_BYTE;
+ assert(bit_offset >= bit_size);
+ }
+
+ bit_offset -= bit_size;
+ member->compound_member.offset = offset;
+ member->compound_member.bit_offset = bit_offset;
+ }
+
+ if (current_base_type != NULL)
+ offset += get_type_size(current_base_type);
+
+ *struct_offset = offset;
+ *struct_alignment = alignment;
+ return member;
+}
+
static entity_t *pack_bitfield_members(il_size_t *struct_offset,
il_alignment_t *struct_alignment,
bool packed, entity_t *first)
entity_t *member;
for (member = first; member != NULL; member = member->base.next) {
if (member->kind != ENTITY_COMPOUND_MEMBER)
- break;
+ continue;
type_t *type = member->declaration.type;
if (type->kind != TYPE_BITFIELD)
*struct_offset = offset;
*struct_alignment = alignment;
-
return member;
}
}
if (skipped->kind == TYPE_BITFIELD) {
- entry = pack_bitfield_members(&offset, &alignment,
- compound->packed, entry);
+ if (byte_order_big_endian) {
+ entry = pack_bitfield_members_big_endian(&offset, &alignment,
+ compound->packed,
+ entry);
+ } else {
+ entry = pack_bitfield_members(&offset, &alignment,
+ compound->packed, entry);
+ }
continue;
}