functions.c
// Add instructions to read a vararg from the stack
Add instructions to read a vararg from the stack
Add instructions to read a vararg from the stack
static Tac *add_function_va_arg_stack_read(Function *function, Tac *ir, Type *type, Value *va_list, Value *dst) {
    int size = va_arg_size(type);
    Value *size_value = new_integral_constant(TYPE_INT, size);
    size_value->type->is_unsigned = 1;
    Value *overflow_arg_area;
    ir = read_from_va_list(function, ir, va_list, make_pointer_to_void(), make_pointer(dst->type), 8, &overflow_arg_area);
    if (type->type == TYPE_LONG_DOUBLE) {
        Value *long_overflow_arg_area = dup_value(overflow_arg_area);
        long_overflow_arg_area->type = new_type(TYPE_LONG);
        Value *tmp1 = dup_value(long_overflow_arg_area);
        tmp1->vreg = ++function->vreg_count;
        ir = insert_instruction_after_from_operation(ir, IR_ADD, tmp1, long_overflow_arg_area, new_integral_constant(TYPE_LONG, 15));
        Value *tmp2 = dup_value(long_overflow_arg_area);
        tmp2->vreg = ++function->vreg_count;
        ir = insert_instruction_after_from_operation(ir, IR_BAND, tmp2, tmp1, new_integral_constant(TYPE_LONG, ~15));
        overflow_arg_area = dup_value(tmp2);
        overflow_arg_area->type = make_pointer(dst->type);
    }
    if (type->type == TYPE_STRUCT_OR_UNION) {
        Value *memcpy_overflow_arg_area = dup_value(overflow_arg_area);
        memcpy_overflow_arg_area->is_lvalue = 1;
        ir = add_memory_copy(function, ir, dst, memcpy_overflow_arg_area, size);
    }
    else
        ir = insert_instruction_after_from_operation(ir, IR_INDIRECT, dst, overflow_arg_area, 0);
    Value *new_overflow_arg_area = dup_value(overflow_arg_area);
    new_overflow_arg_area->vreg = ++function->vreg_count;
    ir = insert_instruction_after_from_operation(ir, IR_ADD, new_overflow_arg_area, overflow_arg_area, size_value);
    ir = write_to_va_list(function, ir, va_list, new_overflow_arg_area, 8);
    return ir;
}
static Tac * add_function_va_arg_stack_read ( Function * function , Tac * ir , Type * type , Value * va_list , Value * dst ) { int size = va_arg_size ( type ) ; Value * size_value = new_integral_constant ( TYPE_INT , size ) ; size_value -> type -> is_unsigned = 1 ; Value * overflow_arg_area ; ir = read_from_va_list ( function , ir , va_list , make_pointer_to_void ( ) , make_pointer ( dst -> type ) , 8 , & overflow_arg_area ) ; if ( type -> type == TYPE_LONG_DOUBLE ) { Value * long_overflow_arg_area = dup_value ( overflow_arg_area ) ; long_overflow_arg_area -> type = new_type ( TYPE_LONG ) ; Value * tmp1 = dup_value ( long_overflow_arg_area ) ; tmp1 -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_ADD , tmp1 , long_overflow_arg_area , new_integral_constant ( TYPE_LONG , 15 ) ) ; Value * tmp2 = dup_value ( long_overflow_arg_area ) ; tmp2 -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_BAND , tmp2 , tmp1 , new_integral_constant ( TYPE_LONG , ~ 15 ) ) ; overflow_arg_area = dup_value ( tmp2 ) ; overflow_arg_area -> type = make_pointer ( dst -> type ) ; } if ( type -> type == TYPE_STRUCT_OR_UNION ) { Value * memcpy_overflow_arg_area = dup_value ( overflow_arg_area ) ; memcpy_overflow_arg_area -> is_lvalue = 1 ; ir = add_memory_copy ( function , ir , dst , memcpy_overflow_arg_area , size ) ; } else ir = insert_instruction_after_from_operation ( ir , IR_INDIRECT , dst , overflow_arg_area , 0 ) ; Value * new_overflow_arg_area = dup_value ( overflow_arg_area ) ; new_overflow_arg_area -> vreg = ++ function -> vreg_count ; ir = insert_instruction_after_from_operation ( ir , IR_ADD , new_overflow_arg_area , overflow_arg_area , size_value ) ; ir = write_to_va_list ( function , ir , va_list , new_overflow_arg_area , 8 ) ; return ir ; }
Add instructions to read a vararg from the stack
Add instructions to read a vararg from the stack
// Read overflow_arg_area into overflow_arg_area register // Align overflow arg area to 16 byte boundary, by adding 15 then anding with ~15 // Add 15 // Read arg from stack // Copy memory for struct/union // Read a scalar value from a pointer // Add 8 or 16 to overflow_arg_area register // Write new gp overflow_arg_area back to va_list // Value *final_gp_overflow_arg_area = dup_value(va_list); // final_gp_overflow_arg_area->type = make_pointer_to_void(); // final_gp_overflow_arg_area->offset = 8; // ir = insert_instruction_after_from_operation(ir, IR_MOVE, va_list, new_overflow_arg_area, 0);