functions.c
// Add instructions to read a vararg from the register save area
Add instructions to read a vararg from the register save area
Add instructions to read a vararg from the register save area
static Tac *add_function_va_arg_register_save_area_read(Function *function, Tac *ir, Type *type, Value *va_list, int gp_count, int fp_count, Value *gp_fp_offset, Value *dst) {
    Value *register_save_area;
    ir = read_from_va_list(function, ir, va_list, make_pointer_to_void(), make_pointer(dst->type), 16, &register_save_area);
    Value *ptr = new_value();
    ptr->type = make_pointer(dst->type);
    ptr->vreg = ++function->vreg_count;
    ir = insert_instruction_after_from_operation(ir, IR_ADD, ptr, register_save_area, gp_fp_offset);
    if (type->type == TYPE_STRUCT_OR_UNION) {
        Value *memcpy_ptr = dup_value(ptr);
        memcpy_ptr->is_lvalue = 1;
        int size = va_arg_size(type);
        int splay_offsets = fp_count > 0; 
        ir = add_memory_copy_with_registers(function, ir, dst, memcpy_ptr, size, splay_offsets);
    }
    else
        ir = insert_instruction_after_from_operation(ir, IR_INDIRECT, dst, ptr, 0);
    Value *new_gp_fp_offset = dup_value(gp_fp_offset);
    new_gp_fp_offset->vreg = ++function->vreg_count;
    Value *size = new_integral_constant(TYPE_INT, gp_count * 8 + fp_count * 16);
    size->type->is_unsigned = 1;
    ir = insert_instruction_after_from_operation(ir, IR_ADD, new_gp_fp_offset, gp_fp_offset, size);
    int offset = gp_count ? 0 : 4; 
    ir = write_to_va_list(function, ir, va_list, new_gp_fp_offset, offset);
    return ir;
}
static Tac * add_function_va_arg_register_save_area_read ( Function * function , Tac * ir , Type * type , Value * va_list , int gp_count , int fp_count , Value * gp_fp_offset , Value * dst ) { Value * register_save_area ; ir = read_from_va_list ( function , ir , va_list , make_pointer_to_void ( ) , make_pointer ( dst -> type ) , 16 , & register_save_area ) ; Value * ptr = new_value ( ) ; ptr -> type = make_pointer ( dst -> type ) ; ptr -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_ADD , ptr , register_save_area , gp_fp_offset ) ; if ( type -> type == TYPE_STRUCT_OR_UNION ) { Value * memcpy_ptr = dup_value ( ptr ) ; memcpy_ptr -> is_lvalue = 1 ; int size = va_arg_size ( type ) ; int splay_offsets = fp_count > 0 ; ir = add_memory_copy_with_registers ( function , ir , dst , memcpy_ptr , size , splay_offsets ) ; } else ir = insert_instruction_after_from_operation ( ir , IR_INDIRECT , dst , ptr , 0 ) ; Value * new_gp_fp_offset = dup_value ( gp_fp_offset ) ; new_gp_fp_offset -> vreg = ++ function -> vreg_count ; Value * size = new_integral_constant ( TYPE_INT , gp_count * 8 + fp_count * 16 ) ; size -> type -> is_unsigned = 1 ; ir = insert_instruction_after_from_operation ( ir , IR_ADD , new_gp_fp_offset , gp_fp_offset , size ) ; int offset = gp_count ? 0 : 4 ; ir = write_to_va_list ( function , ir , va_list , new_gp_fp_offset , offset ) ; return ir ; }
Add instructions to read a vararg from the register save area
Add instructions to read a vararg from the register save area
// Read register_save_area into register_save_area register // Add gp_fp_offset to register_save_area // Copy memory for struct/union // Splay offsets if it's an SSE struct // Read a scalar value from a pointer // Add 8 or 16 to gp_fp_offset register // Write new gp offset back to va_list // gp_offset or fp_offset