gen/
.clang-format
570 B
.gitignore
30 B
.gitsigners
112 B
LICENSE
1.1 KiB
Makefile
911 B
README
1.8 KiB
ast.c
5.0 KiB
ast.h
15.1 KiB
desugar.c
23.1 KiB
desugar.h
286 B
gen.c
108.5 KiB
gen.h
4.9 KiB
io.c
1.1 KiB
io.h
444 B
limits.h
1.3 KiB
module.c
10.0 KiB
module.h
2.2 KiB
options.c
1.4 KiB
options.h
472 B
parser.c
68.3 KiB
parser.h
942 B
radiance.c
3.7 KiB
ralloc.c
2.0 KiB
ralloc.h
1.1 KiB
resolver.c
109.7 KiB
resolver.h
5.6 KiB
riscv.c
12.0 KiB
riscv.h
12.0 KiB
scanner.c
10.2 KiB
scanner.h
3.2 KiB
strings.c
2.6 KiB
strings.h
407 B
symtab.c
5.7 KiB
symtab.h
4.6 KiB
types.h
1.0 KiB
util.h
1.5 KiB
ralloc.c
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 | } |