ralloc.c 2.0 KiB raw
1
/**
2
 * Register allocator.
3
 * Uses a simple stack-based algorithm.
4
 */
5
#include <stdio.h>
6
#include <stdlib.h>
7
8
#include "io.h"
9
#include "ralloc.h"
10
#include "riscv.h"
11
#include "types.h"
12
13
/* Order of temporary registers to allocate. */
14
const reg_t ralloc_regs[] = { A0, A1, A2, A3, A4, A5, A6, A7,
15
                              T0, T1, T2, T3, T4, T5, T6 };
16
17
ralloc_t ralloc(void) {
18
    return (ralloc_t){ .regs = { false } };
19
}
20
21
reg_t ralloc_next(ralloc_t *ra) {
22
    for (int i = 0; i < RALLOC_NREGS; i++) {
23
        if (!ra->regs[i]) {
24
            ra->regs[i] = true;
25
            return ralloc_regs[i];
26
        }
27
    }
28
    bail("out of registers");
29
}
30
31
reg_t ralloc_next_except(ralloc_t *ra, reg_t avoid) {
32
    for (int i = 0; i < RALLOC_NREGS; i++) {
33
        if (!ra->regs[i] && ralloc_regs[i] != avoid) {
34
            ra->regs[i] = true;
35
            return ralloc_regs[i];
36
        }
37
    }
38
    return ralloc_next(ra);
39
}
40
41
void ralloc_free(ralloc_t *ra, reg_t r) {
42
    for (int i = 0; i < RALLOC_NREGS; i++) {
43
        if (ralloc_regs[i] == r) {
44
            ra->regs[i] = false;
45
            break;
46
        }
47
    }
48
}
49
50
void ralloc_reserve(ralloc_t *ra, reg_t r) {
51
    for (int i = 0; i < RALLOC_NREGS; i++) {
52
        if (ralloc_regs[i] == r) {
53
            ra->regs[i] = true;
54
            break;
55
        }
56
    }
57
}
58
59
bool ralloc_is_free(ralloc_t *ra, reg_t r) {
60
    for (int i = 0; i < RALLOC_NREGS; i++) {
61
        if (ralloc_regs[i] == r) {
62
            return !ra->regs[i];
63
        }
64
    }
65
    return false;
66
}
67
68
void ralloc_free_all(ralloc_t *ra) {
69
    for (int i = 0; i < RALLOC_NREGS; i++) {
70
        ra->regs[i] = false;
71
    }
72
}
73
74
void ralloc_save(ralloc_t *ra, bool *reserved) {
75
    for (int i = 0; i < RALLOC_NREGS; i++) {
76
        if (ralloc_regs[i] != A0) {
77
            reserved[i] = ra->regs[i];
78
        }
79
    }
80
}
81
82
void ralloc_restore(ralloc_t *ra, bool *reserved) {
83
    for (int i = 0; i < RALLOC_NREGS; i++) {
84
        if (ralloc_regs[i] != A0) {
85
            ra->regs[i] = reserved[i];
86
        }
87
    }
88
}