ir.c
// Save an integer to a bit field
Save an integer to a bit field
Save an integer to a bit field
static void add_save_bit_field(Function *function, Tac *ir) {
    int offset, bit_offset, bit_size;
    determine_bit_field_params(ir->dst, &offset, &bit_offset, &bit_size);
    Value *dst = dup_value(ir->dst);;
    Value *src1 = dup_value(ir->src1);
    ir->operation = IR_NOP;
    ir->dst = 0;
    ir->src1 = 0;
    ir->src2 = 0;
    src1->type->is_unsigned = 1;
    Value *loaded_src1 = new_value();
    loaded_src1->type = new_type(TYPE_INT);
    loaded_src1->type->is_unsigned = 1;
    loaded_src1->vreg = ++function->vreg_count;
    ir = insert_instruction_after_from_operation(ir, IR_MOVE, loaded_src1, src1, 0);
    Value *masked_src1 = dup_value(loaded_src1);
    masked_src1->vreg = ++function->vreg_count;
    unsigned int mask = bit_size == 32 ? -1 : (1 << bit_size) - 1;
    Value *mask_value = new_integral_constant(TYPE_INT, mask);
    mask_value->type->is_unsigned = 1;
    ir = insert_instruction_after_from_operation(ir, IR_BAND, masked_src1, loaded_src1, mask_value);
    Value *shifted_src1;
    if (bit_offset) {
        shifted_src1 = dup_value(masked_src1);
        shifted_src1->vreg = ++function->vreg_count;
        ir = insert_instruction_after_from_operation(ir, IR_BSHL, shifted_src1, masked_src1, new_integral_constant(TYPE_INT, bit_offset));
    }
    else
        shifted_src1 = masked_src1;
    Value *loaded_dst = new_value();
    loaded_dst->type = new_type(TYPE_INT);
    loaded_dst->type->is_unsigned = 1;
    loaded_dst->vreg = ++function->vreg_count;
    dst->type->is_unsigned = 1;
    dst->offset = offset;
    dst->bit_field_offset = 0;
    dst->bit_field_size = 0;
    if (dst->is_lvalue && dst->vreg) {
        Value *indirect_dst = dup_value(dst);
        indirect_dst->type = make_pointer(loaded_dst->type);
        indirect_dst->is_lvalue = 0;
        ir = insert_instruction_after_from_operation(ir, IR_INDIRECT, loaded_dst, indirect_dst, 0);
    } else
        ir = insert_instruction_after_from_operation(ir, IR_MOVE, loaded_dst, dst, 0);
    unsigned int inverted_shifted_mask = ~(mask << bit_offset);
    Value *masked_dst = dup_value(loaded_dst);
    masked_dst->vreg = ++function->vreg_count;
    Value *inverted_shifted_mask_value = new_integral_constant(TYPE_INT, inverted_shifted_mask);
    inverted_shifted_mask_value->type->is_unsigned = 1;
    ir = insert_instruction_after_from_operation(ir, IR_BAND, masked_dst, loaded_dst, inverted_shifted_mask_value);
    Value *orred_dst = dup_value(loaded_dst);
    orred_dst->vreg = ++function->vreg_count;
    ir = insert_instruction_after_from_operation(ir, IR_BOR, orred_dst, masked_dst, shifted_src1);
    ir = insert_instruction_after_from_operation(ir, IR_MOVE, dst, orred_dst, 0);
}
static void add_save_bit_field ( Function * function , Tac * ir ) { int offset , bit_offset , bit_size ; determine_bit_field_params ( ir -> dst , & offset , & bit_offset , & bit_size ) ; Value * dst = dup_value ( ir -> dst ) ; ; Value * src1 = dup_value ( ir -> src1 ) ; ir -> operation = IR_NOP ; ir -> dst = 0 ; ir -> src1 = 0 ; ir -> src2 = 0 ; src1 -> type -> is_unsigned = 1 ; Value * loaded_src1 = new_value ( ) ; loaded_src1 -> type = new_type ( TYPE_INT ) ; loaded_src1 -> type -> is_unsigned = 1 ; loaded_src1 -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_MOVE , loaded_src1 , src1 , 0 ) ; Value * masked_src1 = dup_value ( loaded_src1 ) ; masked_src1 -> vreg = ++ function -> vreg_count ; unsigned int mask = bit_size == 32 ? -1 : ( 1 << bit_size ) - 1 ; Value * mask_value = new_integral_constant ( TYPE_INT , mask ) ; mask_value -> type -> is_unsigned = 1 ; ir = insert_instruction_after_from_operation ( ir , IR_BAND , masked_src1 , loaded_src1 , mask_value ) ; Value * shifted_src1 ; if ( bit_offset ) { shifted_src1 = dup_value ( masked_src1 ) ; shifted_src1 -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_BSHL , shifted_src1 , masked_src1 , new_integral_constant ( TYPE_INT , bit_offset ) ) ; } else shifted_src1 = masked_src1 ; Value * loaded_dst = new_value ( ) ; loaded_dst -> type = new_type ( TYPE_INT ) ; loaded_dst -> type -> is_unsigned = 1 ; loaded_dst -> vreg = ++ function -> vreg_count ; dst -> type -> is_unsigned = 1 ; dst -> offset = offset ; dst -> bit_field_offset = 0 ; dst -> bit_field_size = 0 ; if ( dst -> is_lvalue && dst -> vreg ) { Value * indirect_dst = dup_value ( dst ) ; indirect_dst -> type = make_pointer ( loaded_dst -> type ) ; indirect_dst -> is_lvalue = 0 ; ir = insert_instruction_after_from_operation ( ir , IR_INDIRECT , loaded_dst , indirect_dst , 0 ) ; } else ir = insert_instruction_after_from_operation ( ir , IR_MOVE , loaded_dst , dst , 0 ) ; unsigned int inverted_shifted_mask = ~ ( mask << bit_offset ) ; Value * masked_dst = dup_value ( loaded_dst ) ; masked_dst -> vreg = ++ function -> vreg_count ; Value * inverted_shifted_mask_value = new_integral_constant ( TYPE_INT , inverted_shifted_mask ) ; inverted_shifted_mask_value -> type -> is_unsigned = 1 ; ir = insert_instruction_after_from_operation ( ir , IR_BAND , masked_dst , loaded_dst , inverted_shifted_mask_value ) ; Value * orred_dst = dup_value ( loaded_dst ) ; orred_dst -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_BOR , orred_dst , masked_dst , shifted_src1 ) ; ir = insert_instruction_after_from_operation ( ir , IR_MOVE , dst , orred_dst , 0 ) ; }
Save an integer to a bit field
Save an integer to a bit field
// Load the src into an unsigned integer // Set bits outside of the src value to zero // Shift the src over to the right spot // Load the dst // Make it a pointer and add an indirect instruction // Set the destination bits to zero on the loaded dst // Or two values // Store the result in dst