functions.c
// Generate code to read a vararg from either the register save area or the stack
Generate code to read a vararg from either the register save area or the stack
Generate code to read a vararg from either the register save area or the stack
static void process_function_va_arg(Function *function, Tac *ir) {
    Value *va_list = ir->src1;
    Value *dst = ir->dst;
    Type *type = dst->type;
    ir->operation = IR_NOP;
    ir->src1 = 0;
    ir->dst = 0;
    if (type->type == TYPE_LONG_DOUBLE) {
        ir = add_function_va_arg_stack_read(function, ir, type, va_list, dst);
        return;
    }
    int gp_count = 0; 
    int fp_count = 0; 
    if (type->type == TYPE_STRUCT_OR_UNION) {
        FunctionParamAllocation *fpa = init_function_param_allocaton("vararg struct");
        add_function_param_to_allocation(fpa, type);
        FunctionParamLocations *fpl = &(fpa->params[0]);
        if (fpl->locations[0].stack_offset != -1) {
            ir = add_function_va_arg_stack_read(function, ir, type, va_list, dst);
            return;
        }
        else if (fpl->locations[0].int_register != -1)
            gp_count = fpl->count;
        else
            fp_count = fpl->count;
    }
    else {
        gp_count = is_integer_type(type) || is_pointer_type(type);
        fp_count = !gp_count;
    }
    Value *ldone = new_label_dst();
    Value *fetch_from_stack = new_label_dst();
    Value *gp_fp_offset;
    ir = add_function_va_arg_in_register_check(function, ir, type, va_list, gp_count, fp_count, fetch_from_stack, &gp_fp_offset);
    ir = add_function_va_arg_register_save_area_read(function, ir, type, va_list, gp_count, fp_count, gp_fp_offset, dst);
    ir = insert_instruction_after_from_operation(ir, IR_JMP, 0, ldone, 0);
    ir = insert_instruction_after_from_operation(ir, IR_NOP, 0, 0, 0);
    ir->label = fetch_from_stack->label;
    ir = add_function_va_arg_stack_read(function, ir, type, va_list, dst);
    ir = insert_instruction_after_from_operation(ir, IR_NOP, 0, 0, 0);
    ir->label = ldone->label;
}
static void process_function_va_arg ( Function * function , Tac * ir ) { Value * va_list = ir -> src1 ; Value * dst = ir -> dst ; Type * type = dst -> type ; ir -> operation = IR_NOP ; ir -> src1 = 0 ; ir -> dst = 0 ; if ( type -> type == TYPE_LONG_DOUBLE ) { ir = add_function_va_arg_stack_read ( function , ir , type , va_list , dst ) ; return ; } int gp_count = 0 ; int fp_count = 0 ; if ( type -> type == TYPE_STRUCT_OR_UNION ) { FunctionParamAllocation * fpa = init_function_param_allocaton ( " " ) ; add_function_param_to_allocation ( fpa , type ) ; FunctionParamLocations * fpl = & ( fpa -> params [ 0 ] ) ; if ( fpl -> locations [ 0 ] . stack_offset != -1 ) { ir = add_function_va_arg_stack_read ( function , ir , type , va_list , dst ) ; return ; } else if ( fpl -> locations [ 0 ] . int_register != -1 ) gp_count = fpl -> count ; else fp_count = fpl -> count ; } else { gp_count = is_integer_type ( type ) || is_pointer_type ( type ) ; fp_count = ! gp_count ; } Value * ldone = new_label_dst ( ) ; Value * fetch_from_stack = new_label_dst ( ) ; Value * gp_fp_offset ; ir = add_function_va_arg_in_register_check ( function , ir , type , va_list , gp_count , fp_count , fetch_from_stack , & gp_fp_offset ) ; ir = add_function_va_arg_register_save_area_read ( function , ir , type , va_list , gp_count , fp_count , gp_fp_offset , dst ) ; ir = insert_instruction_after_from_operation ( ir , IR_JMP , 0 , ldone , 0 ) ; ir = insert_instruction_after_from_operation ( ir , IR_NOP , 0 , 0 , 0 ) ; ir -> label = fetch_from_stack -> label ; ir = add_function_va_arg_stack_read ( function , ir , type , va_list , dst ) ; ir = insert_instruction_after_from_operation ( ir , IR_NOP , 0 , 0 , 0 ) ; ir -> label = ldone -> label ; }
Generate code to read a vararg from either the register save area or the stack
Generate code to read a vararg from either the register save area or the stack
// Determine how many gp and fp registers are needed // Integer registers // SSE registers // It's on the stack // The arg can be in registers. Although it might end up on the stack // if registers have run out. // A scalar arg is either in int (gp) or sse (fp) registers // Check if the arg is in the register save area or on stack // Read from register save area & jump to the done label // Add fetch_from_stack label // Read from stack // Add done label