functions.c
// This implements the reverse of make_int_struct_or_union_arg_move_instructions
// This is also used for moving struct/unions into function return value registers
This implements the reverse of make_int_struct_or_union_arg_move_instructions
This is also used for moving struct/unions into function return value registers
This implements the reverse of make_int_struct_or_union_arg_move_instructions This is also used for moving struct / unions into function return value registers
static int make_int_struct_or_union_move_from_register_to_stack_instructions(
        Function *function, Tac *ir, Type *type, FunctionParamLocation* pl,
        int register_index, int stack_index, RegisterSet *register_set, int param_register_vreg) {
    if (debug_function_param_mapping)
        printf("Adding param move from int register %d size %d to stack_index %d, offset %d\n", register_index, pl->stru_size, stack_index, pl->stru_offset);
    if (!param_register_vreg) param_register_vreg = ++function->vreg_count;
    Value *shift_register = new_value();
    shift_register->vreg = param_register_vreg;
    int live_range_preg = register_set->int_registers[register_index];
    shift_register->live_range_preg = live_range_preg;
    int size = pl->stru_size;
    int offset = 0;
    for (int i = 3; i >= 0; i--) {
        int size_unit = 1 << i;
        if (size_unit > size) continue;
        Value *dst = new_value();
        dst->type = new_type(TYPE_CHAR + i);
        dst->type->is_unsigned = 1;
        dst->is_lvalue = 1;
        dst->stack_index = stack_index;
        dst->offset = pl->stru_offset + offset;
        shift_register = dup_value(shift_register);
        shift_register->type = new_type(TYPE_CHAR + i);
        shift_register->type->is_unsigned = 1;
        insert_instruction_from_operation(ir, IR_MOVE, dst, shift_register, 0, 1);
        size -= size_unit;
        offset += size_unit;
        if (size == 0) break;
        shift_register = dup_value(shift_register);
        shift_register->type = new_type(TYPE_LONG);
        Value *new_shift_register = dup_value(shift_register);
        new_shift_register->live_range_preg = 0;
        insert_instruction_from_operation(ir, IR_BSHR, new_shift_register, shift_register, new_integral_constant(TYPE_LONG, size_unit * 8), 1);
        shift_register = new_shift_register;
    }
    return live_range_preg;
}
static int make_int_struct_or_union_move_from_register_to_stack_instructions ( Function * function , Tac * ir , Type * type , FunctionParamLocation * pl , int register_index , int stack_index , RegisterSet * register_set , int param_register_vreg ) { if ( debug_function_param_mapping ) printf ( " \n " , register_index , pl -> stru_size , stack_index , pl -> stru_offset ) ; if ( ! param_register_vreg ) param_register_vreg = ++ function -> vreg_count ; Value * shift_register = new_value ( ) ; shift_register -> vreg = param_register_vreg ; int live_range_preg = register_set -> int_registers [ register_index ] ; shift_register -> live_range_preg = live_range_preg ; int size = pl -> stru_size ; int offset = 0 ; for ( int i = 3 ; i >= 0 ; i -- ) { int size_unit = 1 << i ; if ( size_unit > size ) continue ; Value * dst = new_value ( ) ; dst -> type = new_type ( TYPE_CHAR + i ) ; dst -> type -> is_unsigned = 1 ; dst -> is_lvalue = 1 ; dst -> stack_index = stack_index ; dst -> offset = pl -> stru_offset + offset ; shift_register = dup_value ( shift_register ) ; shift_register -> type = new_type ( TYPE_CHAR + i ) ; shift_register -> type -> is_unsigned = 1 ; insert_instruction_from_operation ( ir , IR_MOVE , dst , shift_register , 0 , 1 ) ; size -= size_unit ; offset += size_unit ; if ( size == 0 ) break ; shift_register = dup_value ( shift_register ) ; shift_register -> type = new_type ( TYPE_LONG ) ; Value * new_shift_register = dup_value ( shift_register ) ; new_shift_register -> live_range_preg = 0 ; insert_instruction_from_operation ( ir , IR_BSHR , new_shift_register , shift_register , new_integral_constant ( TYPE_LONG , size_unit * 8 ) , 1 ) ; shift_register = new_shift_register ; } return live_range_preg ; }
This implements the reverse of make_int_struct_or_union_arg_move_instructions
This is also used for moving struct/unions into function return value registers
This implements the reverse of make_int_struct_or_union_arg_move_instructions This is also used for moving struct / unions into function return value registers
// Make shift register // Make dst on stack // Shift the register over size_unit * 8 bytes