qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit f135a0b1fdfd22b0f32e5021ab4e486e681129a1
parent 8dddb971d923fa19dced39013e6d4a39676e065a
Author: Quentin Carbonneaux <quentin@c9x.me>
Date:   Thu,  1 Sep 2022 19:03:53 +0200

use direct bl calls on arm64

This generates tidier code and is pic
friendly because it lets the linker
trampoline calls to dynlinked libs.

Diffstat:
Marm64/emit.c | 16++++++++++++++--
Marm64/isel.c | 21+++++++++++++++++++++
2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/arm64/emit.c b/arm64/emit.c @@ -306,10 +306,11 @@ fixarg(Ref *pr, int sz, E *e) static void emitins(Ins *i, E *e) { - char *rn; + char *l, *p, *rn; uint64_t s; int o; Ref r; + Con *c; switch (i->op) { default: @@ -355,7 +356,8 @@ emitins(Ins *i, E *e) assert(isreg(i->to)); switch (rtype(i->arg[0])) { case RCon: - loadcon(&e->fn->con[i->arg[0].val], i->to.val, i->cls, e->f); + c = &e->fn->con[i->arg[0].val]; + loadcon(c, i->to.val, i->cls, e->f); break; case RSlot: i->op = Oload; @@ -386,6 +388,16 @@ emitins(Ins *i, E *e) rn, s & 0xFFFF, rn, s >> 16, rn, rn ); break; + case Ocall: + if (rtype(i->arg[0]) != RCon) + goto Table; + c = &e->fn->con[i->arg[0].val]; + if (c->type != CAddr || c->bits.i) + die("invalid call argument"); + l = str(c->label); + p = l[0] == '"' ? "" : T.assym; + fprintf(e->f, "\tbl\t%s%s\n", p, l); + break; case Osalloc: emitf("sub sp, sp, %0", i, e); if (!req(i->to, R)) diff --git a/arm64/isel.c b/arm64/isel.c @@ -156,6 +156,22 @@ selcmp(Ref arg[2], int k, Fn *fn) return swap; } +static int +callable(Ref r, Fn *fn) +{ + Con *c; + + if (rtype(r) == RTmp) + return 1; + if (rtype(r) == RCon) { + c = &fn->con[r.val]; + if (c->type == CAddr) + if (c->bits.i == 0) + return 1; + } + return 0; +} + static void sel(Ins i, Fn *fn) { @@ -178,6 +194,11 @@ sel(Ins i, Fn *fn) i0->op += cc; return; } + if (i.op == Ocall) + if (callable(i.arg[0], fn)) { + emiti(i); + return; + } if (i.op != Onop) { emiti(i); iarg = curi->arg; /* fixarg() can change curi */