diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-03-31 23:09:14 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-03-31 23:09:14 +0300 |
| commit | 59148d666a78d671198d56caabe7fe4d7fb3fee1 (patch) | |
| tree | 4c54666dca7090fd8d4f898160afe080ed0f1fa6 /src/abi.c | |
| parent | 1dcaa90d8b706118235bc74a0f2cbdcb836d29bb (diff) | |
| download | qbt-59148d666a78d671198d56caabe7fe4d7fb3fee1.tar.gz qbt-59148d666a78d671198d56caabe7fe4d7fb3fee1.zip | |
produce some very limited assembly output
+ Several subsystems missing critical features, but enough to do some
basic things like calling procedures, printing to screen and doing loops
Diffstat (limited to 'src/abi.c')
| -rw-r--r-- | src/abi.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/abi.c b/src/abi.c new file mode 100644 index 0000000..cb92190 --- /dev/null +++ b/src/abi.c @@ -0,0 +1,96 @@ +#include <assert.h> +#include <stdlib.h> +#include <qbt/abi.h> + +static const int64_t ar_map[] = { + RA0, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA8, RA9, + RA10, RA11, RA12, RA13, RA14, RA15, RA16, RA17, RA18, RA19, + RA20, RA21, RA22, RA23, RA24 +}; + +static struct val nth_ar(int64_t nth) +{ + return reg_val(ar_map[nth]); +} + +static struct insn rewrite_param(struct insn n) +{ + assert(n.type == PARAM); + assert(n.in[1].class == IMM); + int64_t nth_param = n.in[1].v; + assert(nth_param >= 0 && nth_param < 25 + && "stack argument passing not yet supported"); + + return insn_create(MOVE, I27, n.out, nth_ar(nth_param), noclass()); +} + +static struct insn rewrite_retval(struct insn n) +{ + assert(n.type == RETVAL); + assert(n.in[1].class == IMM); + int64_t nth_retval = n.in[1].v; + assert(nth_retval >= 0 && nth_retval < 25); + return insn_create(MOVE, I27, n.out, nth_ar(nth_retval), noclass()); +} + +static struct insn rewrite_arg(struct insn n) +{ + assert(n.type == ARG); + assert(n.in[1].class == IMM); + int64_t nth_arg = n.in[1].v; + assert(nth_arg >= 0 && nth_arg < 25); + + if (n.in[0].class == TMP || n.in[0].class == REG) + return insn_create(MOVE, I27, nth_ar(nth_arg), n.in[0], noclass()); + else if (n.in[0].class == IMM || n.in[0].class == REF) + return insn_create(COPY, I27, nth_ar(nth_arg), n.in[0], noclass()); + + assert("illegal arg type"); + abort(); +} + +static struct insn rewrite_retarg(struct insn n) +{ + assert(n.type == RETARG); + assert(n.in[1].class == IMM); + int64_t nth_arg = n.in[1].v; + assert(nth_arg >= 0 && nth_arg < 25); + + if (n.in[0].class == TMP || n.in[0].class == REG) + return insn_create(MOVE, I27, nth_ar(nth_arg), n.in[0], noclass()); + else if (n.in[0].class == IMM || n.in[0].class == REF) + return insn_create(COPY, I27, nth_ar(nth_arg), n.in[0], noclass()); + + assert("illegal retval type"); + abort(); +} + +void abi0(struct fn *f) +{ + foreach_blk(bi, f->blks) { + struct blk *b = blk_at(f->blks, bi); + foreach_insn(i, b->insns) { + struct insn n = insn_at(b->insns, i); + if (n.type == PARAM) { + struct insn p = rewrite_param(n); + insn_at(b->insns, i) = p; + } + + else if (n.type == RETVAL) { + struct insn r = rewrite_retval(n); + insn_at(b->insns, i) = r; + } + + else if (n.type == ARG) { + struct insn a = rewrite_arg(n); + insn_at(b->insns, i) = a; + } + + else if (n.type == RETARG) { + struct insn a = rewrite_retarg(n); + insn_at(b->insns, i) = a; + } + } + } +} + |
