functions.c
// Add a move for a function return value. If it's a long double, a load can be done,
// otherwise, either rax or xmm0 must hold the result.
Add a move for a function return value. If it's a long double, a load can be done,
otherwise, either rax or xmm0 must hold the result.
Add a move for a function return value . If it ' s a long double a load can be done otherwise either rax or xmm0 must hold the result .
void add_function_return_moves(Function *function, char *identifier) {
    for (Tac *ir = function->ir; ir; ir = ir->next) {
        if ((ir->operation == IR_RETURN && !ir->src1) || ir->operation != IR_RETURN) continue;
        if (ir->src1->type->type == TYPE_LONG_DOUBLE) {
            insert_instruction_from_operation(ir, IR_LOAD_LONG_DOUBLE, 0, ir->src1, 0, 1);
            ir->operation = IR_RETURN;
            ir->dst = 0;
            ir->src1 = 0;
            ir->src2 = 0;
        }
        else if (ir->src1->type->type == TYPE_STRUCT_OR_UNION)
            add_function_return_moves_for_struct_or_union(function, ir, identifier);
        else {
            int is_sse = is_sse_floating_point_type(function->return_type);
            int live_range_preg = is_sse ? LIVE_RANGE_PREG_XMM00_INDEX : LIVE_RANGE_PREG_RAX_INDEX;
            ir->src1->preferred_live_range_preg_index = live_range_preg;
            ir->dst = new_value();
            ir->dst->type = dup_type(function->return_type);
            if (ir->dst->type->type == TYPE_ENUM) ir->dst->type = new_type(TYPE_INT);
            ir->dst->vreg = ++function->vreg_count;
            ir->dst->live_range_preg = live_range_preg;
            ir->src1->preferred_live_range_preg_index = live_range_preg;
            insert_instruction_from_operation(ir, IR_MOVE, ir->dst, ir->src1, 0, 1);
            ir->operation = IR_RETURN;
            ir->dst = 0;
            ir->src1 = 0;
            ir->src2 = 0;
        }
        ir->src1 = 0;
    }
}
void add_function_return_moves ( Function * function , char * identifier ) { for ( Tac * ir = function -> ir ; ir ; ir = ir -> next ) { if ( ( ir -> operation == IR_RETURN && ! ir -> src1 ) || ir -> operation != IR_RETURN ) continue ; if ( ir -> src1 -> type -> type == TYPE_LONG_DOUBLE ) { insert_instruction_from_operation ( ir , IR_LOAD_LONG_DOUBLE , 0 , ir -> src1 , 0 , 1 ) ; ir -> operation = IR_RETURN ; ir -> dst = 0 ; ir -> src1 = 0 ; ir -> src2 = 0 ; } else if ( ir -> src1 -> type -> type == TYPE_STRUCT_OR_UNION ) add_function_return_moves_for_struct_or_union ( function , ir , identifier ) ; else { int is_sse = is_sse_floating_point_type ( function -> return_type ) ; int live_range_preg = is_sse ? LIVE_RANGE_PREG_XMM00_INDEX : LIVE_RANGE_PREG_RAX_INDEX ; ir -> src1 -> preferred_live_range_preg_index = live_range_preg ; ir -> dst = new_value ( ) ; ir -> dst -> type = dup_type ( function -> return_type ) ; if ( ir -> dst -> type -> type == TYPE_ENUM ) ir -> dst -> type = new_type ( TYPE_INT ) ; ir -> dst -> vreg = ++ function -> vreg_count ; ir -> dst -> live_range_preg = live_range_preg ; ir -> src1 -> preferred_live_range_preg_index = live_range_preg ; insert_instruction_from_operation ( ir , IR_MOVE , ir -> dst , ir -> src1 , 0 , 1 ) ; ir -> operation = IR_RETURN ; ir -> dst = 0 ; ir -> src1 = 0 ; ir -> src2 = 0 ; } ir -> src1 = 0 ; } }
Add a move for a function return value.
Add a move for a function return value .
// Implicit else, operation == IR_RETURN & ir-src1 has a value