functions.c
// Add instructions that read the FP or GP offset, determine if the type can fit
// in a register, and if not, jmp to the stack read label fetch_from_stack.
Add instructions that read the FP or GP offset, determine if the type can fit
in a register, and if not, jmp to the stack read label fetch_from_stack.
Add instructions that read the FP or GP offset determine if the type can fit in a register and if not jmp to the stack read label fetch_from_stack .
static Tac *add_function_va_arg_in_register_check(Function *function, Tac *ir, Type *type, Value *va_list, int gp_count, int fp_count, Value *fetch_from_stack, Value **result_gp_fp_offset) {
    Type *gp_fp_offset_type = new_type(TYPE_INT);
    gp_fp_offset_type->is_unsigned = 1;
    int gp_fp_offset_offset = gp_count ? 0 : 4; 
    Value *gp_fp_offset;
    ir = read_from_va_list(function, ir, va_list, gp_fp_offset_type, gp_fp_offset_type, gp_fp_offset_offset, &gp_fp_offset);
    Value *gp_fp_offset_ge_result = new_value();
    gp_fp_offset_ge_result->type = new_type(TYPE_INT);
    gp_fp_offset_ge_result->type->is_unsigned = 1;
    gp_fp_offset_ge_result->vreg = ++function->vreg_count;
    int last_offset = gp_count ? 48 - gp_count * 8 : 176 - fp_count * 16;
    Value *last_offset_value = new_integral_constant(TYPE_INT, last_offset);
    last_offset_value->type->is_unsigned = 1;
    ir = insert_instruction_after_from_operation(ir, IR_GT, gp_fp_offset_ge_result, gp_fp_offset, last_offset_value);
    ir = insert_instruction_after_from_operation(ir, IR_JNZ, 0, gp_fp_offset_ge_result, fetch_from_stack);
    *result_gp_fp_offset = gp_fp_offset;
    return ir;
}
static Tac * add_function_va_arg_in_register_check ( Function * function , Tac * ir , Type * type , Value * va_list , int gp_count , int fp_count , Value * fetch_from_stack , Value * * result_gp_fp_offset ) { Type * gp_fp_offset_type = new_type ( TYPE_INT ) ; gp_fp_offset_type -> is_unsigned = 1 ; int gp_fp_offset_offset = gp_count ? 0 : 4 ; Value * gp_fp_offset ; ir = read_from_va_list ( function , ir , va_list , gp_fp_offset_type , gp_fp_offset_type , gp_fp_offset_offset , & gp_fp_offset ) ; Value * gp_fp_offset_ge_result = new_value ( ) ; gp_fp_offset_ge_result -> type = new_type ( TYPE_INT ) ; gp_fp_offset_ge_result -> type -> is_unsigned = 1 ; gp_fp_offset_ge_result -> vreg = ++ function -> vreg_count ; int last_offset = gp_count ? 48 - gp_count * 8 : 176 - fp_count * 16 ; Value * last_offset_value = new_integral_constant ( TYPE_INT , last_offset ) ; last_offset_value -> type -> is_unsigned = 1 ; ir = insert_instruction_after_from_operation ( ir , IR_GT , gp_fp_offset_ge_result , gp_fp_offset , last_offset_value ) ; ir = insert_instruction_after_from_operation ( ir , IR_JNZ , 0 , gp_fp_offset_ge_result , fetch_from_stack ) ; * result_gp_fp_offset = gp_fp_offset ; return ir ; }
Add instructions that read the FP or GP offset, determine if the type can fit
in a register, and if not, jmp to the stack read label fetch_from_stack.
Add instructions that read the FP or GP offset determine if the type can fit in a register and if not jmp to the stack read label fetch_from_stack .
// Read gp_offset or fp_offset into gp_fp_offset register // gp_offset or fp_offset // Check if gp_fp_offset >= 48, and if so jump to the stack fetching code // Compare and jump to stack code if the arg doesn't fit in the register save area