commit: 813a8460859200afaca250be1417c8236b8eb96a
parent b745c9ac807d104abf083f46608fb964bcc12ade
Author: Michael Forney <mforney@mforney.org>
Date: Thu, 16 May 2019 23:11:01 -0700
qbe: Update to latest git and apply some patches
Diffstat:
10 files changed, 365 insertions(+), 1 deletion(-)
diff --git a/.gitmodules b/.gitmodules
@@ -197,6 +197,7 @@
[submodule "pkg/qbe/src"]
path = pkg/qbe/src
url = git://c9x.me/qbe.git
+ ignore = all
[submodule "pkg/samurai/src"]
path = pkg/samurai/src
url = https://github.com/michaelforney/samurai
diff --git a/pkg/qbe/patch/0001-load-Error-out-when-there-are-too-many-phi-args.patch b/pkg/qbe/patch/0001-load-Error-out-when-there-are-too-many-phi-args.patch
@@ -0,0 +1,25 @@
+From f7bd663aa19c84da21d5f6c15ca50daa9862ad9a Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sun, 21 Apr 2019 12:55:53 -0700
+Subject: [PATCH] load: Error out when there are too many phi args
+
+---
+ load.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/load.c b/load.c
+index 8e2dd64..9894000 100644
+--- a/load.c
++++ b/load.c
+@@ -330,6 +330,8 @@ def(Slice sl, bits msk, Blk *b, Ins *i, Loc *il)
+ p->to = r;
+ p->cls = sl.cls;
+ p->narg = b->npred;
++ if (b->npred >= NPred)
++ die("def, too many phi args (%u)", b->npred);
+ for (np=0; np<b->npred; ++np) {
+ bp = b->pred[np];
+ if (!bp->s2
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0002-Use-dynamic-array-for-phi-arguments.patch b/pkg/qbe/patch/0002-Use-dynamic-array-for-phi-arguments.patch
@@ -0,0 +1,125 @@
+From 3415d1f4dc68092819faf1744bfab556e338649b Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sun, 21 Apr 2019 13:37:32 -0700
+Subject: [PATCH] Use dynamic array for phi arguments
+
+---
+ all.h | 4 ++--
+ amd64/sysv.c | 8 ++++++--
+ arm64/abi.c | 8 ++++++--
+ load.c | 4 ++--
+ parse.c | 2 ++
+ ssa.c | 6 ++++--
+ 6 files changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/all.h b/all.h
+index 59eefe1..fba93b1 100644
+--- a/all.h
++++ b/all.h
+@@ -206,8 +206,8 @@ struct Ins {
+
+ struct Phi {
+ Ref to;
+- Ref arg[NPred];
+- Blk *blk[NPred];
++ Ref *arg;
++ Blk **blk;
+ uint narg;
+ int cls;
+ Phi *link;
+diff --git a/amd64/sysv.c b/amd64/sysv.c
+index ea9b2d2..286300a 100644
+--- a/amd64/sysv.c
++++ b/amd64/sysv.c
+@@ -590,9 +590,13 @@ selvaarg(Fn *fn, Blk *b, Ins *i)
+ *b0->phi = (Phi){
+ .cls = Kl, .to = loc,
+ .narg = 2,
+- .blk = {bstk, breg},
+- .arg = {lstk, lreg},
++ .blk = vnew(2, sizeof b0->phi->blk[0], Pfn),
++ .arg = vnew(2, sizeof b0->phi->arg[0], Pfn),
+ };
++ b0->phi->blk[0] = bstk;
++ b0->phi->blk[1] = breg;
++ b0->phi->arg[0] = lstk;
++ b0->phi->arg[1] = lreg;
+ r0 = newtmp("abi", Kl, fn);
+ r1 = newtmp("abi", Kw, fn);
+ b->jmp.type = Jjnz;
+diff --git a/arm64/abi.c b/arm64/abi.c
+index 8bc9c20..f5b605a 100644
+--- a/arm64/abi.c
++++ b/arm64/abi.c
+@@ -583,9 +583,13 @@ selvaarg(Fn *fn, Blk *b, Ins *i)
+ *b0->phi = (Phi){
+ .cls = Kl, .to = loc,
+ .narg = 2,
+- .blk = {bstk, breg},
+- .arg = {lstk, lreg},
++ .blk = vnew(2, sizeof b0->phi->blk[0], Pfn),
++ .arg = vnew(2, sizeof b0->phi->arg[0], Pfn),
+ };
++ b0->phi->blk[0] = bstk;
++ b0->phi->blk[1] = breg;
++ b0->phi->arg[0] = lstk;
++ b0->phi->arg[1] = lreg;
+ r0 = newtmp("abi", Kl, fn);
+ r1 = newtmp("abi", Kw, fn);
+ b->jmp.type = Jjnz;
+diff --git a/load.c b/load.c
+index 9894000..ae9cfcf 100644
+--- a/load.c
++++ b/load.c
+@@ -330,8 +330,8 @@ def(Slice sl, bits msk, Blk *b, Ins *i, Loc *il)
+ p->to = r;
+ p->cls = sl.cls;
+ p->narg = b->npred;
+- if (b->npred >= NPred)
+- die("def, too many phi args (%u)", b->npred);
++ p->arg = vnew(p->narg, sizeof p->arg[0], Pfn);
++ p->blk = vnew(p->narg, sizeof p->blk[0], Pfn);
+ for (np=0; np<b->npred; ++np) {
+ bp = b->pred[np];
+ if (!bp->s2
+diff --git a/parse.c b/parse.c
+index c4c1fe6..95bcf45 100644
+--- a/parse.c
++++ b/parse.c
+@@ -673,7 +673,9 @@ Ins:
+ phi = alloc(sizeof *phi);
+ phi->to = r;
+ phi->cls = k;
++ phi->arg = vnew(i, sizeof arg[0], Pfn);
+ memcpy(phi->arg, arg, i * sizeof arg[0]);
++ phi->blk = vnew(i, sizeof blk[0], Pfn);
+ memcpy(phi->blk, blk, i * sizeof blk[0]);
+ phi->narg = i;
+ *plink = phi;
+diff --git a/ssa.c b/ssa.c
+index c098438..2de02d1 100644
+--- a/ssa.c
++++ b/ssa.c
+@@ -181,6 +181,8 @@ phiins(Fn *fn)
+ p->cls = k;
+ p->to = TMP(t);
+ p->link = a->phi;
++ p->arg = vnew(0, sizeof p->arg[0], Pfn);
++ p->blk = vnew(0, sizeof p->blk[0], Pfn);
+ a->phi = p;
+ if (!bshas(defs, a->id))
+ if (!bshas(u, a->id)) {
+@@ -294,8 +296,8 @@ renblk(Blk *b, Name **stk, Fn *fn)
+ t = p->to.val;
+ if ((t=fn->tmp[t].visit)) {
+ m = p->narg++;
+- if (m == NPred)
+- die("renblk, too many phi args");
++ vgrow(&p->arg, p->narg);
++ vgrow(&p->blk, p->narg);
+ p->arg[m] = getstk(t, b, stk);
+ p->blk[m] = b;
+ }
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0003-Restore-NPred-to-its-previous-value.patch b/pkg/qbe/patch/0003-Restore-NPred-to-its-previous-value.patch
@@ -0,0 +1,27 @@
+From 6ea7a634070bb7a0312fcd6abd00b45cf7dd46f1 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sun, 21 Apr 2019 13:43:27 -0700
+Subject: [PATCH] Restore NPred to its previous value
+
+This now only limits the number of arguments when parsing the input SSA,
+which is usually a small fixed size (depending on the frontend).
+---
+ all.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/all.h b/all.h
+index fba93b1..5f67e81 100644
+--- a/all.h
++++ b/all.h
+@@ -32,7 +32,7 @@ typedef struct Target Target;
+
+ enum {
+ NString = 64,
+- NPred = 127,
++ NPred = 63,
+ NIns = 1 << 20,
+ NAlign = 3,
+ NField = 32,
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0004-arm64-Handle-slots.patch b/pkg/qbe/patch/0004-arm64-Handle-slots.patch
@@ -0,0 +1,36 @@
+From c8849e9c7b382f92326434a6522a26829a6e20f8 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Wed, 8 May 2019 18:29:28 -0700
+Subject: [PATCH] arm64: Handle slots
+
+---
+ arm64/emit.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/arm64/emit.c b/arm64/emit.c
+index 59e1aae..9cc4a64 100644
+--- a/arm64/emit.c
++++ b/arm64/emit.c
+@@ -220,8 +220,17 @@ emitf(char *s, Ins *i, E *e)
+ c = *s++;
+ assert(c == '0' || c == '1');
+ r = i->arg[c - '0'];
+- assert(isreg(r) && "TODO emit non reg addresses");
+- fprintf(e->f, "[%s]", rname(r.val, Kl));
++ switch (rtype(r)) {
++ default:
++ die("TODO emit non reg addresses");
++ case RTmp:
++ assert(isreg(r));
++ fprintf(e->f, "[%s]", rname(r.val, Kl));
++ break;
++ case RSlot:
++ fprintf(e->f, "[sp, %"PRIu64"]", slot(r.val, e));
++ break;
++ }
+ break;
+ }
+ }
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0005-arm64-Make-sure-SP-stays-aligned-by-16.patch b/pkg/qbe/patch/0005-arm64-Make-sure-SP-stays-aligned-by-16.patch
@@ -0,0 +1,36 @@
+From 036fef96ea7005996ea0f802d5629ddae3673da6 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Wed, 8 May 2019 19:05:57 -0700
+Subject: [PATCH] arm64: Make sure SP stays aligned by 16
+
+According to the ARMv8 overview document
+
+ However if SP is used as the base register then the value of the stack
+ pointer prior to adding any offset must be quadword (16 byte) aligned,
+ or else a stack alignment exception will be generated.
+
+This manifests as a bus error on my system.
+
+To resolve this, just save registers two at a time with stp.
+---
+ arm64/emit.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arm64/emit.c b/arm64/emit.c
+index 9cc4a64..e7effef 100644
+--- a/arm64/emit.c
++++ b/arm64/emit.c
+@@ -387,8 +387,8 @@ arm64_emitfn(Fn *fn, FILE *out)
+ if (e->fn->vararg) {
+ for (n=7; n>=0; n--)
+ fprintf(e->f, "\tstr\tq%d, [sp, -16]!\n", n);
+- for (n=7; n>=0; n--)
+- fprintf(e->f, "\tstr\tx%d, [sp, -8]!\n", n);
++ for (n=7; n>=0; n -= 2)
++ fprintf(e->f, "\tstp\tx%d, x%d, [sp, -16]!\n", n-1, n);
+ }
+
+ if (e->frame + 16 <= 512)
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0006-arm64-Handle-slots-in-Ocopy-operands.patch b/pkg/qbe/patch/0006-arm64-Handle-slots-in-Ocopy-operands.patch
@@ -0,0 +1,56 @@
+From 86ce810ec5463f41d001b543288bd43dda79eebd Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Thu, 9 May 2019 23:32:15 -0700
+Subject: [PATCH] arm64: Handle slots in Ocopy operands
+
+---
+ arm64/emit.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+diff --git a/arm64/emit.c b/arm64/emit.c
+index e7effef..adae233 100644
+--- a/arm64/emit.c
++++ b/arm64/emit.c
+@@ -218,8 +218,8 @@ emitf(char *s, Ins *i, E *e)
+ break;
+ case 'M':
+ c = *s++;
+- assert(c == '0' || c == '1');
+- r = i->arg[c - '0'];
++ assert(c == '0' || c == '1' || c == '=');
++ r = c == '=' ? i->to : i->arg[c - '0'];
+ switch (rtype(r)) {
+ default:
+ die("TODO emit non reg addresses");
+@@ -305,9 +305,26 @@ emitins(Ins *i, E *e)
+ case Ocopy:
+ if (req(i->to, i->arg[0]))
+ break;
+- if (rtype(i->arg[0]) != RCon)
++ if (rtype(i->to) == RSlot) {
++ if (rtype(i->arg[0]) == RSlot) {
++ emitf("ldr %?, %M0\n\tstr %?, %M=", i, e);
++ } else {
++ assert(isreg(i->arg[0]));
++ emitf("str %0, %M=", i, e);
++ }
++ break;
++ }
++ 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);
++ break;
++ case RSlot:
++ emitf("ldr %=, %M0", i, e);
++ break;
++ default:
+ goto Table;
+- loadcon(&e->fn->con[i->arg[0].val], i->to.val, i->cls, e->f);
++ }
+ break;
+ case Oaddr:
+ assert(rtype(i->arg[0]) == RSlot);
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0007-arm64-Prevent-stack-clobber-when-passing-structures-.patch b/pkg/qbe/patch/0007-arm64-Prevent-stack-clobber-when-passing-structures-.patch
@@ -0,0 +1,33 @@
+From ffd2585ef162a6dcc42011a33bd69687048ab4a8 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Sat, 11 May 2019 19:38:13 -0700
+Subject: [PATCH] arm64: Prevent stack clobber when passing structures < 8
+ bytes
+
+---
+ arm64/abi.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arm64/abi.c b/arm64/abi.c
+index f5b605a..4e80db2 100644
+--- a/arm64/abi.c
++++ b/arm64/abi.c
+@@ -308,12 +308,14 @@ stkblob(Ref r, Class *c, Fn *fn, Insl **ilp)
+ {
+ Insl *il;
+ int al;
++ uint64_t sz;
+
+ il = alloc(sizeof *il);
+ al = c->t->align - 2; /* NAlign == 3 */
+ if (al < 0)
+ al = 0;
+- il->i = (Ins){Oalloc+al, Kl, r, {getcon(c->t->size, fn)}};
++ sz = c->class & Cptr ? c->t->size : c->size;
++ il->i = (Ins){Oalloc+al, Kl, r, {getcon(sz, fn)}};
+ il->link = *ilp;
+ *ilp = il;
+ }
+--
+2.21.0
+
diff --git a/pkg/qbe/patch/0008-rega-Fix-allocation-of-multiple-temporaries-to-the-s.patch b/pkg/qbe/patch/0008-rega-Fix-allocation-of-multiple-temporaries-to-the-s.patch
@@ -0,0 +1,25 @@
+From 325cae726ecea5d332e8f4c68bc572069ff5e249 Mon Sep 17 00:00:00 2001
+From: Michael Forney <mforney@mforney.org>
+Date: Thu, 16 May 2019 15:21:26 -0700
+Subject: [PATCH] rega: Fix allocation of multiple temporaries to the same
+ register
+
+---
+ rega.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/rega.c b/rega.c
+index ba405e5..7547293 100644
+--- a/rega.c
++++ b/rega.c
+@@ -605,6 +605,7 @@ rega(Fn *fn)
+ if (x > 0 && !bshas(m->b, x)) {
+ pmadd(TMP(x), TMP(r), tmp[t].cls);
+ m->r[j] = x;
++ bsset(m->b, x);
+ }
+ }
+ curi = &insb[NIns];
+--
+2.21.0
+
diff --git a/pkg/qbe/ver b/pkg/qbe/ver
@@ -1 +1 @@
-ff4e5aab2c r0
+acc3af4733 r0