summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--6/asm.h3
-rw-r--r--6/isel.c13
-rw-r--r--6/ra.c359
-rw-r--r--6/regs.def4
-rw-r--r--parse/util.c2
5 files changed, 290 insertions, 91 deletions
diff --git a/6/asm.h b/6/asm.h
index 6eebb0a..6e61bb1 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -123,11 +123,12 @@ struct Isel {
/* register allocator state */
Bitset *prepainted; /* locations that need to be a specific colour */
+ Bitset *initial; /* initial set of locations used by this fn */
size_t *gbits; /* igraph matrix repr */
Bitset **gadj; /* igraph adj set repr */
int *degree; /* degree of nodes */
- Loc **aliasmap; /* mapping of aliases */
+ Loc **aliasmap; /* mapping of aliases */
Loc **selstk;
size_t nselstk;
diff --git a/6/isel.c b/6/isel.c
index aa97bc0..78a3568 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -699,8 +699,8 @@ void iprintf(FILE *fd, Insn *insn)
if (insn->args[0]->mode != insn->args[1]->mode)
insn->args[0] = coreg(insn->args[0]->reg.colour, insn->args[1]->mode);
/* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
- return;
+ // if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ // return;
break;
default:
break;
@@ -781,7 +781,7 @@ static void prologue(Isel *s, size_t sz)
Loc *rsp;
Loc *rbp;
Loc *stksz;
- //size_t i;
+ size_t i;
rsp = locphysreg(Rrsp);
rbp = locphysreg(Rrbp);
@@ -790,14 +790,11 @@ static void prologue(Isel *s, size_t sz)
g(s, Ipush, rbp, NULL);
g(s, Imov, rsp, rbp, NULL);
g(s, Isub, stksz, rsp, NULL);
-#if 0
/* save registers */
for (i = 0; i < sizeof(savedregs)/sizeof(savedregs[0]); i++) {
s->calleesave[i] = locreg(ModeQ);
g(s, Imov, locphysreg(savedregs[i]), s->calleesave[i], NULL);
}
-#endif
-
s->stksz = stksz; /* need to update if we spill */
}
@@ -805,7 +802,7 @@ static void epilogue(Isel *s)
{
Loc *rsp, *rbp;
Loc *ret;
- //size_t i;
+ size_t i;
rsp = locphysreg(Rrsp);
rbp = locphysreg(Rrbp);
@@ -813,12 +810,10 @@ static void epilogue(Isel *s)
ret = loc(s, s->ret);
g(s, Imov, ret, coreg(Rax, ret->mode), NULL);
}
-#if 0
/* restore registers */
for (i = 0; i < Nsaved; i++)
g(s, Imov, s->calleesave[i], locphysreg(savedregs[i]), NULL);
/* leave function */
-#endif
g(s, Imov, rbp, rsp, NULL);
g(s, Ipop, rbp, NULL);
g(s, Iret, NULL);
diff --git a/6/ra.c b/6/ra.c
index 6373b7d..93f347f 100644
--- a/6/ra.c
+++ b/6/ra.c
@@ -18,7 +18,10 @@ struct Usemap {
int r[Maxarg + 1]; /* list of registers used implicitly by instruction */
};
+void wlprint(FILE *fd, char *name, Loc **wl, size_t nwl);
+static int moverelated(Isel *s, regid n);
static void printedge(FILE *fd, char *msg, size_t a, size_t b);
+static void check(Isel *s);
/* tables of uses/defs by instruction */
Usemap usetab[] = {
@@ -282,24 +285,71 @@ static void gbputedge(Isel *s, size_t u, size_t v)
i = (maxregid * u) + v;
j = (maxregid * v) + u;
- s->gbits[i/Sizetbits] |= 1ULL <<(i % Sizetbits);
- s->gbits[j/Sizetbits] |= 1ULL <<(j % Sizetbits);
+ s->gbits[i/Sizetbits] |= 1ULL << (i % Sizetbits);
+ s->gbits[j/Sizetbits] |= 1ULL << (j % Sizetbits);
assert(gbhasedge(s, u, v) && gbhasedge(s, v, u));
}
-static void addedge(Isel *s, size_t u, size_t v)
+static int wlhas(Loc **wl, size_t nwl, regid v, size_t *idx)
+{
+ size_t i;
+
+ for (i = 0; i < nwl; i++) {
+ if (wl[i]->reg.id == v) {
+ *idx = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * If we have an edge between two aliasing registers,
+ * we should not increment the degree, since that would
+ * be double counting.
+ */
+static int degreechange(Isel *s, regid u, regid v)
+{
+ regid phys, virt, r;
+ size_t i;
+
+ if (bshas(s->prepainted, u)) {
+ phys = u;
+ virt = v;
+ } else if (bshas(s->prepainted, v)) {
+ phys = v;
+ virt = u;
+ } else {
+ return 1;
+ }
+
+ for (i = 0; i < Nmode; i++) {
+ r = regmap[colourmap[phys]][i];
+ if (r != phys && gbhasedge(s, virt, regmap[colourmap[phys]][i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static void addedge(Isel *s, regid u, regid v)
{
if (u == v || gbhasedge(s, u, v))
return;
+ if (u == Rrbp || u == Rrsp || u == Rrip)
+ return;
+ if (v == Rrbp || v == Rrsp || v == Rrip)
+ return;
+
gbputedge(s, u, v);
gbputedge(s, v, u);
if (!bshas(s->prepainted, u)) {
bsput(s->gadj[u], v);
- s->degree[u]++;
+ s->degree[u] += degreechange(s, v, u);
}
if (!bshas(s->prepainted, v)) {
bsput(s->gadj[v], u);
- s->degree[v]++;
+ s->degree[v] += degreechange(s, u, v);
}
}
@@ -319,23 +369,29 @@ static void setup(Isel *s)
s->spilled = bsclear(s->spilled);
s->coalesced = bsclear(s->coalesced);
- /*
- s->wlspill = bsclear(s->wlspill);
- s->wlfreeze = bsclear(s->wlfreeze);
- s->wlsimp = bsclear(s->wlsimp);
- */
+ lfree(&s->wlspill, &s->nwlspill);
+ lfree(&s->wlfreeze, &s->nwlfreeze);
+ lfree(&s->wlsimp, &s->nwlsimp);
+
+ free(s->aliasmap);
+ free(s->degree);
+ free(s->rmoves);
+ free(s->nrmoves);
s->aliasmap = zalloc(maxregid * sizeof(size_t));
s->degree = zalloc(maxregid * sizeof(int));
s->rmoves = zalloc(maxregid * sizeof(Loc **));
s->nrmoves = zalloc(maxregid * sizeof(size_t));
+
+ for (i = 0; bsiter(s->prepainted, &i); i++)
+ s->degree[i] = 1<<16;
}
static void build(Isel *s)
{
regid u[Maxuse], d[Maxdef];
size_t nu, nd;
- size_t i, k;
+ size_t i, k, a;
ssize_t j;
Bitset *live;
Asmbb **bb;
@@ -354,12 +410,26 @@ static void build(Isel *s)
nu = uses(insn, u);
nd = defs(insn, d);
+ /* add these to the initial set */
+ for (k = 0; k < nu; k++)
+ bsput(s->initial, u[k]);
+ for (k = 0; k < nd; k++)
+ bsput(s->initial, d[k]);
+
/* moves get special treatment, since we don't want spurious
* edges between the src and dest */
+ //iprintf(stdout, insn);
if (ismove(insn)) {
/* live \= uses(i) */
- for (k = 0; k < nu; k++)
- bsdel(live, u[k]);
+ for (k = 0; k < nu; k++) {
+ /* remove all physical register aliases */
+ if (bshas(s->prepainted, u[k])) {
+ for (a = 0; a < Nmode; a++)
+ bsdel(live, regmap[colourmap[u[k]]][a]);
+ } else {
+ bsdel(live, u[k]);
+ }
+ }
for (k = 0; k < nu; k++)
lappend(&s->rmoves[u[k]], &s->nrmoves[u[k]], insn);
@@ -393,7 +463,6 @@ static int adjiter(Isel *s, regid n, regid *m)
goto next;
if (bshas(s->coalesced, r))
goto next;
- assert(r < maxregid);
*m = r;
return 1;
next:
@@ -416,14 +485,16 @@ static size_t nodemoves(Isel *s, regid n, Insn ***pil)
if (s->mactive[j] == s->rmoves[n][i]) {
if (pil)
lappend(pil, &count, s->rmoves[n][i]);
- continue;
+ else
+ count++;
}
}
for (j = 0; j < s->nwlmove; j++) {
if (s->wlmove[j] == s->rmoves[n][i]) {
if (pil)
lappend(pil, &count, s->rmoves[n][i]);
- continue;
+ else
+ count++;
}
}
}
@@ -439,7 +510,7 @@ static void mkworklist(Isel *s)
{
size_t i;
- for (i = 0; i < maxregid; i++) {
+ for (i = 0; bsiter(s->initial, &i); i++) {
if (bshas(s->prepainted, i))
continue;
else if (s->degree[i] >= K)
@@ -468,19 +539,28 @@ static void enablemove(Isel *s, regid n)
}
}
-static void decdegree(Isel *s, regid n)
+static void decdegree(Isel *s, regid m)
{
int d;
- regid m;
+ size_t idx;
+ regid n;
- assert(n < maxregid);
- d = s->degree[n];
- s->degree[n]--;
+ assert(m < maxregid);
+ d = s->degree[m];
+ s->degree[m]--;
if (d == K) {
- enablemove(s, n);
- for (m = 0; adjiter(s, n, &m); m++)
+ enablemove(s, m);
+ for (n = 0; adjiter(s, m, &n); n++)
enablemove(s, n);
+ if (!wlhas(s->wlspill, s->nwlspill, m, &idx))
+ die("%zd not in wlspill", m);
+ ldel(&s->wlspill, &s->nwlspill, idx);
+ if (moverelated(s, m)) {
+ lappend(&s->wlfreeze, &s->nwlfreeze, locmap[m]);
+ } else {
+ lappend(&s->wlsimp, &s->nwlsimp, locmap[m]);
+ }
}
}
@@ -489,10 +569,13 @@ static void simp(Isel *s)
Loc *l;
regid m;
+ check(s);
l = lpop(&s->wlsimp, &s->nwlsimp);
lappend(&s->selstk, &s->nselstk, l);
- for (m = 0; adjiter(s, l->reg.id, &m); m++)
+ for (m = 0; adjiter(s, l->reg.id, &m); m++) {
decdegree(s, m);
+ }
+ check(s);
}
static regid getalias(Isel *s, regid id)
@@ -505,6 +588,18 @@ static regid getalias(Isel *s, regid id)
return id;
}
+void whichwl(Isel *s, regid u)
+{
+ size_t x;
+
+ if (wlhas(s->wlsimp, s->nwlsimp, u, &x)) printf("%zd on simp\n", u);
+ if (wlhas(s->wlfreeze, s->nwlfreeze, u, &x)) printf("%zd on freeze\n", u);
+ if (wlhas(s->wlspill, s->nwlspill, u, &x)) printf("%zd on spill\n", u);
+ if (wlhas(s->selstk, s->nselstk, u, &x)) printf("%zd on select stack\n", u);
+ if (bshas(s->coalesced, u)) printf("%zd on coalesced\n", u);
+ if (bshas(s->spilled, u)) printf("%zd on stack\n", u);
+}
+
static void wladd(Isel *s, regid u)
{
size_t i;
@@ -515,10 +610,12 @@ static void wladd(Isel *s, regid u)
return;
if (s->degree[u] >= K)
return;
- for (i = 0; i < s->nwlfreeze; i++)
- if (s->wlfreeze[i]->reg.id == u)
- ldel(&s->wlfreeze, &s->nwlfreeze, i);
+
+ check(s);
+ assert(wlhas(s->wlfreeze, s->nwlfreeze, u, &i));
+ ldel(&s->wlfreeze, &s->nwlfreeze, i);
lappend(&s->wlsimp, &s->nwlsimp, locmap[u]);
+ check(s);
}
static int conservative(Isel *s, regid u, regid v)
@@ -539,19 +636,21 @@ static int conservative(Isel *s, regid u, regid v)
/* FIXME: is this actually correct? */
static int ok(Isel *s, regid t, regid r)
{
- if (s->degree[t] >= K)
- return 0;
- if (!bshas(s->prepainted, t))
- return 0;
- if (!gbhasedge(s, t, r))
- return 0;
- return 1;
+ if (s->degree[t] < K)
+ return 1;
+ if (bshas(s->prepainted, t))
+ return 1;
+ if (gbhasedge(s, t, r))
+ return 1;
+ return 0;
}
static int combinable(Isel *s, regid u, regid v)
{
regid t;
+ if (debugopt['r'])
+ printf("check combinable %zd <=> %zd\n", u, v);
/* Regs of different modes can't be combined as things stand.
* In principle they should be combinable, but it confused the
* whole mode dance. */
@@ -562,25 +661,12 @@ static int combinable(Isel *s, regid u, regid v)
return 1;
/* if it is, are the adjacent nodes ok to combine with this? */
- for (t = 0; adjiter(s, u, &t); t++)
+ for (t = 0; adjiter(s, v, &t); t++)
if (!ok(s, t, u))
return 0;
return 1;
}
-static int wlhas(Loc **wl, size_t nwl, regid v, size_t *idx)
-{
- size_t i;
-
- for (i = 0; i < nwl; i++) {
- if (wl[i]->reg.id == v) {
- *idx = i;
- return 1;
- }
- }
- return 0;
-}
-
static void combine(Isel *s, regid u, regid v)
{
regid t;
@@ -628,6 +714,7 @@ static void coalesce(Isel *s)
Insn *m;
regid u, v, tmp;
+ check(s);
m = lpop(&s->wlmove, &s->nwlmove);
u = getalias(s, m->args[0]->reg.id);
v = getalias(s, m->args[1]->reg.id);
@@ -649,7 +736,9 @@ static void coalesce(Isel *s)
} else if (combinable(s, u, v)) {
lappend(&s->mcoalesced, &s->nmcoalesced, m);
combine(s, u, v);
+ check(s);
wladd(s, u);
+ check(s);
} else {
lappend(&s->mactive, &s->nmactive, m);
}
@@ -679,22 +768,22 @@ static void freezemoves(Isel *s, Loc *u)
nml = nodemoves(s, u->reg.id, &ml);
for (i = 0; i < nml; i++) {
m = ml[i];
- if (m->args[0] == u)
- v = m->args[1];
- else if (m->args[1] == u)
- v = m->args[0];
+ if (getalias(s, m->args[0]->reg.id) == getalias(s, u->reg.id))
+ v = locmap[getalias(s, m->args[1]->reg.id)];
else
- continue;
+ v = locmap[getalias(s, m->args[0]->reg.id)];
if (!mldel(&s->mactive, &s->nmactive, m))
mldel(&s->wlmove, &s->nwlmove, m);
lappend(&s->mfrozen, &s->nmfrozen, m);
+ check(s);
if (!nodemoves(s, v->reg.id, NULL) && s->degree[v->reg.id] < K) {
if (!wlhas(s->wlfreeze, s->nwlfreeze, v->reg.id, &idx))
die("Reg %zd not in freeze wl\n", v->reg.id);
ldel(&s->wlfreeze, &s->nwlfreeze, idx);
lappend(&s->wlsimp, &s->nwlsimp, v);
}
+ check(s);
}
lfree(&ml, &nml);
@@ -704,9 +793,11 @@ static void freeze(Isel *s)
{
Loc *l;
+ check(s);
l = lpop(&s->wlfreeze, &s->nwlfreeze);
lappend(&s->wlsimp, &s->nwlsimp, l);
freezemoves(s, l);
+ check(s);
}
/* Select the spill candidates */
@@ -715,10 +806,10 @@ static void selspill(Isel *s)
size_t i;
Loc *m;
+ check(s);
/* FIXME: pick a better heuristic for spilling */
m = NULL;
for (i = 0; i < s->nwlspill; i++) {
- printf("Trying to spill %zd\n", s->wlspill[i]->reg.id);
if (!bshas(s->shouldspill, s->wlspill[i]->reg.id))
continue;
m = s->wlspill[i];
@@ -727,8 +818,10 @@ static void selspill(Isel *s)
}
if (!m) {
for (i = 0; i < s->nwlspill; i++) {
- if (bshas(s->neverspill, s->wlspill[i]->reg.id))
+ if (bshas(s->neverspill, s->wlspill[i]->reg.id)) {
+ printf("Not spilling %zd\n", s->wlspill[i]->reg.id);
continue;
+ }
m = s->wlspill[i];
ldel(&s->wlspill, &s->nwlspill, i);
break;
@@ -737,6 +830,7 @@ static void selspill(Isel *s)
assert(m != NULL);
lappend(&s->wlsimp, &s->nwlsimp, m);
freezemoves(s, m);
+ check(s);
}
/*
@@ -916,16 +1010,23 @@ static void rewritebb(Isel *s, Asmbb *bb)
new = NULL;
nnew = 0;
for (j = 0; j < bb->ni; j++) {
+ insn = bb->il[j];
+ if (ismove(insn)) {
+ if (getalias(s, insn->args[0]->reg.id) == getalias(s, insn->args[1]->reg.id))
+ continue;
+ }
/* if there is a remapping, insert the loads and stores as needed */
if (remap(s, bb->il[j], use, &nuse, def, &ndef)) {
for (i = 0; i < nuse; i++) {
insn = mkinsn(Imov, spillslot(s, use[i].oldreg), use[i].newreg, NULL);
lappend(&new, &nnew, insn);
- printf("loading ");
- locprint(stdout, locmap[use[i].oldreg], 'x');
- printf(" -> ");
- locprint(stdout, use[i].newreg, 'x');
- printf("\n");
+ if (debugopt['r']) {
+ printf("loading ");
+ locprint(stdout, locmap[use[i].oldreg], 'x');
+ printf(" -> ");
+ locprint(stdout, use[i].newreg, 'x');
+ printf("\n");
+ }
}
insn = bb->il[j];
updatelocs(s, insn, use, nuse, def, ndef);
@@ -933,11 +1034,13 @@ static void rewritebb(Isel *s, Asmbb *bb)
for (i = 0; i < ndef; i++) {
insn = mkinsn(Imov, def[i].newreg, spillslot(s, def[i].oldreg), NULL);
lappend(&new, &nnew, insn);
- printf("storing ");
- locprint(stdout, locmap[def[i].oldreg], 'x');
- printf(" -> ");
- locprint(stdout, def[i].newreg, 'x');
- printf("\n");
+ if (debugopt['r']) {
+ printf("storing ");
+ locprint(stdout, locmap[def[i].oldreg], 'x');
+ printf(" -> ");
+ locprint(stdout, def[i].newreg, 'x');
+ printf("\n");
+ }
}
} else {
lappend(&new, &nnew, bb->il[j]);
@@ -952,7 +1055,7 @@ static void addspill(Isel *s, Loc *l)
{
s->stksz->lit += modesize[l->mode];
s->stksz->lit = align(s->stksz->lit, modesize[l->mode]);
- if (debugopt['r'] || 1) {
+ if (debugopt['r']) {
printf("spill ");
locprint(stdout, l, 'x');
printf(" to %zd(%%rbp)\n", s->stksz->lit);
@@ -990,19 +1093,21 @@ static void rewrite(Isel *s)
void regalloc(Isel *s)
{
- size_t i;
int spilled;
+ size_t i;
+ /* Initialize the list of prepainted registers */
s->prepainted = mkbs();
+ bsput(s->prepainted, 0);
+ for (i = 0; i < Nreg; i++)
+ bsput(s->prepainted, i);
+
s->shouldspill = mkbs();
s->neverspill = mkbs();
-#if 0
+ s->initial = mkbs();
for (i = 0; i < Nsaved; i++)
bsput(s->shouldspill, s->calleesave[i]->reg.id);
-#endif
- for (i = 0; i < maxregid; i++)
- if (locmap[i]->reg.colour)
- bsput(s->prepainted, i);
+ spilled = 0;
do {
setup(s);
liveness(s);
@@ -1029,6 +1134,22 @@ void regalloc(Isel *s)
bsfree(s->neverspill);
}
+void wlprint(FILE *fd, char *name, Loc **wl, size_t nwl)
+{
+ size_t i;
+ char *sep;
+
+ sep = "";
+ fprintf(fd, "%s = [", name);
+ for (i = 0; i < nwl; i++) {
+ fprintf(fd, "%s", sep);
+ locprint(fd, wl[i], 'x');
+ fprintf(fd, "(%zd)", wl[i]->reg.id);
+ sep = ",";
+ }
+ fprintf(fd, "]\n");
+}
+
static void setprint(FILE *fd, Bitset *s)
{
char *sep;
@@ -1087,11 +1208,18 @@ void dumpasm(Isel *s, FILE *fd)
char *sep;
Asmbb *bb;
- fprintf(fd, "IGRAPH ----- \n");
- for (i = 0; i < maxregid; i++) {
- for (j = i; j < maxregid; j++) {
- if (gbhasedge(s, i, j))
- printedge(stdout, "", i, j);
+ fprintf(fd, "WORKLISTS -- \n");
+ wlprint(stdout, "spill", s->wlspill, s->nwlspill);
+ wlprint(stdout, "simp", s->wlsimp, s->nwlsimp);
+ wlprint(stdout, "freeze", s->wlfreeze, s->nwlfreeze);
+ /* noisy to dump this all the time; only dump for higher debug levels */
+ if (debugopt['r'] > 2) {
+ fprintf(fd, "IGRAPH ----- \n");
+ for (i = 0; i < maxregid; i++) {
+ for (j = i; j < maxregid; j++) {
+ if (gbhasedge(s, i, j))
+ printedge(stdout, "", i, j);
+ }
}
}
fprintf(fd, "ASM -------- \n");
@@ -1124,3 +1252,78 @@ void dumpasm(Isel *s, FILE *fd)
}
fprintf(fd, "ENDASM -------- \n");
}
+
+static int findmove(Isel *s, Insn *m)
+{
+ size_t i;
+ for (i = 0; i < s->nmactive; i++)
+ if (s->mactive[i] == m)
+ return 1;
+ for (i = 0; i < s->nwlmove; i++)
+ if (s->wlmove[i] == m)
+ return 1;
+ return 0;
+}
+
+static void check(Isel *s)
+{
+ size_t i, j;
+ size_t n;
+ size_t idx;
+ char foo[5];
+
+ for (i = 0; bsiter(s->initial, &i); i++) {
+ /* check worklists are disjoint */
+ n = 0;
+ if (bshas(s->prepainted, i)) {
+ foo[n] = 'p';
+ n++;
+ }
+ if (wlhas(s->wlsimp, s->nwlsimp, i, &idx)) {
+ foo[n] = 's';
+ /* check simplify invariant */
+ for (j = 0; j < s->nrmoves[j]; j++)
+ assert("simp invariant" && !findmove(s, s->rmoves[i][j]));
+ n++;
+ }
+ if (wlhas(s->wlfreeze, s->nwlfreeze, i, &idx)) {
+ foo[n] = 'f';
+ /* check freeze invariant */
+ for (j = 0; j < s->nrmoves[j]; j++)
+ assert("freeze invariant" && findmove(s, s->rmoves[i][j]));
+ n++;
+ }
+ if (wlhas(s->wlspill, s->nwlspill, i, &idx)) {
+ foo[n] = 'd';
+ n++;
+ }
+ if (wlhas(s->selstk, s->nselstk, i, &idx)) {
+ foo[n] = 't';
+ n++;
+ }
+ if (bshas(s->coalesced, i)) {
+ foo[n] = 'k';
+ n++;
+ }
+ if (bshas(s->spilled, i)) {
+ foo[n] = 'l';
+ n++;
+ }
+ foo[n]='\0';
+ if (n != 1)
+ printf("%s\n", foo);
+ assert(n == 1);
+ }
+}
+
+void edges(Isel *s, regid u)
+{
+ size_t i;
+
+ for (i = 0; i < maxregid; i++) {
+ if (gbhasedge(s, u, i))
+ printf("%zd ", i);
+ }
+ printf("\n");
+}
+
diff --git a/6/regs.def b/6/regs.def
index b767d7a..feb858e 100644
--- a/6/regs.def
+++ b/6/regs.def
@@ -67,8 +67,6 @@ Reg(Rrdx, "%rdx", ModeQ)
Reg(Rrbx, "%rbx", ModeQ)
Reg(Rrsi, "%rsi", ModeQ)
Reg(Rrdi, "%rdi", ModeQ)
-Reg(Rrsp, "%rsp", ModeQ)
-Reg(Rrbp, "%rbp", ModeQ)
Reg(Rr8, "%r8", ModeQ)
Reg(Rr9, "%r9", ModeQ)
Reg(Rr10, "%r10", ModeQ)
@@ -79,3 +77,5 @@ Reg(Rr14, "%r14", ModeQ)
Reg(Rr15, "%r15", ModeQ)
Reg(Rrip, "%rip", ModeQ)
+Reg(Rrsp, "%rsp", ModeQ)
+Reg(Rrbp, "%rbp", ModeQ)
diff --git a/parse/util.c b/parse/util.c
index 8760b68..f5bbbec 100644
--- a/parse/util.c
+++ b/parse/util.c
@@ -39,7 +39,7 @@ void *zrealloc(void *mem, size_t oldsz, size_t sz)
char *p;
p = xrealloc(mem, sz);
- if ((ssize_t)sz - (ssize_t)oldsz > 0)
+ if (sz > oldsz)
bzero(&p[oldsz], sz - oldsz);
return p;
}