+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);
+ 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 *mode_uint = atomic_modes[ATOMIC_TYPE_UINT];
+
+ 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);
+ unsigned bitoffset = entity->compound_member.bit_offset;
+ unsigned 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, amode);
+ } else {
+ shiftr = new_d_Shr(dbgi, shiftl, countr, amode);
+ }
+
+ 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 */
+static void construct_select_compound(const select_expression_t *expression)
+{
+ type_t *type = skip_typeref(expression->compound->base.type);
+ if (is_type_pointer(type)) {
+ type = type->pointer.points_to;
+ }
+ (void) get_ir_type(type);
+}
+
+static ir_node *set_value_for_expression_addr(const expression_t *expression,
+ ir_node *value, ir_node *addr)