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:
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 */