ir.c
// The arguments are pushed onto the stack right to left, but the ABI requries
// the seventh arg and later to be pushed in reverse order. Easiest is to flip
// all args backwards, so they are pushed left to right.
The arguments are pushed onto the stack right to left, but the ABI requries
the seventh arg and later to be pushed in reverse order. Easiest is to flip
all args backwards, so they are pushed left to right.
The arguments are pushed onto the stack right to left but the ABI requries the seventh arg and later to be pushed in reverse order . Easiest is to flip all args backwards so they are pushed left to right .
void reverse_function_argument_order(Function *function) {
    const int MAX_ARGS = 256;
    typedef struct tac_interval {
        Tac *start;
        Tac *end;
    } TacInterval;
    int function_call_count = make_function_call_count(function);
    TacInterval *function_args;
    function_args = malloc(sizeof(TacInterval) * function_call_count * MAX_ARGS);
    int *arg_counts = malloc(sizeof(int) * function_call_count);
    memset(arg_counts, 0, sizeof(int) * function_call_count);
    Tac **calls = malloc(sizeof(Tac *) * function_call_count);
    memset(calls, 0, sizeof(int) * function_call_count);
    Tac **call_starts = malloc(sizeof(Tac *) * function_call_count);
    memset(call_starts, 0, sizeof(int) * function_call_count);
    ir = function->ir;
    Tac *tac = function->ir;
    while (tac) {
        if (tac->operation == IR_START_CALL) {
            int func = tac->src1->int_value;
            TacInterval *args = &(function_args[func * MAX_ARGS]);
            call_starts[func] = tac;
            tac = tac->next;
            args[arg_counts[func]].start = tac;
        }
        else if (tac->operation == IR_END_CALL) {
            int func = tac->src1->int_value;
            calls[func] = tac->prev;
            tac = tac->next;
        }
        else if (tac->operation == IR_ARG) {
            int func = tac->src1->int_value;
            TacInterval *args = &(function_args[func * MAX_ARGS]);
            args[arg_counts[func]].end = tac;
            tac = tac->next;
            if (tac->operation == IR_ARG_STACK_PADDING) {
                args[arg_counts[func]].end = tac;
                tac = tac->next;
            }
            arg_counts[func]++;
            if (tac->operation != IR_END_CALL) args[arg_counts[func]].start = tac;
        }
        else
            tac = tac->next;
    }
    for (int i = 0; i < function_call_count; i++) {
        TacInterval *args = &(function_args[i * MAX_ARGS]);
        int arg_count = arg_counts[i];
        Tac *call = calls[i];
        Tac *call_start = call_starts[i];
        if (arg_count > 1) {
            call_start->next = args[arg_count - 1].start;
            args[arg_count - 1].start->prev = call_start;
            args[0].end->next = call;
            call->prev = args[0].end;
            for (int j = 0; j < arg_count; j++) {
                if (j < arg_count - 1) {
                    args[j + 1].end->next = args[j].start;
                    args[j].start->prev = args[j + 1].end;
                }
            }
        }
    }
    free(function_args);
}
void reverse_function_argument_order ( Function * function ) { const int MAX_ARGS = 256 ; typedef struct tac_interval { Tac * start ; Tac * end ; } TacInterval ; int function_call_count = make_function_call_count ( function ) ; TacInterval * function_args ; function_args = malloc ( sizeof ( TacInterval ) * function_call_count * MAX_ARGS ) ; int * arg_counts = malloc ( sizeof ( int ) * function_call_count ) ; memset ( arg_counts , 0 , sizeof ( int ) * function_call_count ) ; Tac * * calls = malloc ( sizeof ( Tac * ) * function_call_count ) ; memset ( calls , 0 , sizeof ( int ) * function_call_count ) ; Tac * * call_starts = malloc ( sizeof ( Tac * ) * function_call_count ) ; memset ( call_starts , 0 , sizeof ( int ) * function_call_count ) ; ir = function -> ir ; Tac * tac = function -> ir ; while ( tac ) { if ( tac -> operation == IR_START_CALL ) { int func = tac -> src1 -> int_value ; TacInterval * args = & ( function_args [ func * MAX_ARGS ] ) ; call_starts [ func ] = tac ; tac = tac -> next ; args [ arg_counts [ func ] ] . start = tac ; } else if ( tac -> operation == IR_END_CALL ) { int func = tac -> src1 -> int_value ; calls [ func ] = tac -> prev ; tac = tac -> next ; } else if ( tac -> operation == IR_ARG ) { int func = tac -> src1 -> int_value ; TacInterval * args = & ( function_args [ func * MAX_ARGS ] ) ; args [ arg_counts [ func ] ] . end = tac ; tac = tac -> next ; if ( tac -> operation == IR_ARG_STACK_PADDING ) { args [ arg_counts [ func ] ] . end = tac ; tac = tac -> next ; } arg_counts [ func ] ++ ; if ( tac -> operation != IR_END_CALL ) args [ arg_counts [ func ] ] . start = tac ; } else tac = tac -> next ; } for ( int i = 0 ; i < function_call_count ; i ++ ) { TacInterval * args = & ( function_args [ i * MAX_ARGS ] ) ; int arg_count = arg_counts [ i ] ; Tac * call = calls [ i ] ; Tac * call_start = call_starts [ i ] ; if ( arg_count > 1 ) { call_start -> next = args [ arg_count - 1 ] . start ; args [ arg_count - 1 ] . start -> prev = call_start ; args [ 0 ] . end -> next = call ; call -> prev = args [ 0 ] . end ; for ( int j = 0 ; j < arg_count ; j ++ ) { if ( j < arg_count - 1 ) { args [ j + 1 ] . end -> next = args [ j ] . start ; args [ j ] . start -> prev = args [ j + 1 ] . end ; } } } } free ( function_args ) ; }
The arguments are pushed onto the stack right to left, but the ABI requries
the seventh arg and later to be pushed in reverse order.
The arguments are pushed onto the stack right to left but the ABI requries the seventh arg and later to be pushed in reverse order .
// Need to count this IR's function_call_count // First index, function_id, second index arg_id // Collect function call details in one pass through the IR // Reverse the args for each function call // Rearrange args backwards from this IR // cs -> p0.start -> p0.end -> p1.start -> p1.end -> cs.end // cs -> p0.start -> p0.end -> p1.start -> p1.end -> p2.start -> p2.end -> cs.end