cleanup error handling
This commit is contained in:
parent
beec05cd3b
commit
729aa97b79
10 changed files with 86 additions and 92 deletions
5
all.h
5
all.h
|
@ -6,6 +6,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
|
#define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
|
||||||
|
#define die(...) die_(__FILE__, __VA_ARGS__)
|
||||||
|
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef unsigned short ushort;
|
typedef unsigned short ushort;
|
||||||
|
@ -481,7 +482,7 @@ extern char debug['Z'+1];
|
||||||
/* util.c */
|
/* util.c */
|
||||||
extern Typ typ[NTyp];
|
extern Typ typ[NTyp];
|
||||||
extern Ins insb[NIns], *curi;
|
extern Ins insb[NIns], *curi;
|
||||||
void diag(char *) __attribute__((noreturn));
|
void die_(char *, char *, ...) __attribute__((noreturn));
|
||||||
void *emalloc(size_t);
|
void *emalloc(size_t);
|
||||||
void *alloc(size_t);
|
void *alloc(size_t);
|
||||||
void freeall(void);
|
void freeall(void);
|
||||||
|
@ -522,7 +523,7 @@ extern OpDesc opdesc[NOp];
|
||||||
void parse(FILE *, char *, void (Dat *), void (Fn *));
|
void parse(FILE *, char *, void (Dat *), void (Fn *));
|
||||||
void printfn(Fn *, FILE *);
|
void printfn(Fn *, FILE *);
|
||||||
void printref(Ref, Fn *, FILE *);
|
void printref(Ref, Fn *, FILE *);
|
||||||
void err(char *, ...);
|
void err(char *, ...) __attribute__((noreturn));
|
||||||
|
|
||||||
/* mem.c */
|
/* mem.c */
|
||||||
void memopt(Fn *);
|
void memopt(Fn *);
|
||||||
|
|
34
copy.c
34
copy.c
|
@ -47,7 +47,6 @@ visitphi(Phi *p, Ref *cp, RList **w)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert(!req(r, R));
|
|
||||||
update(p->to, r, cp, w);
|
update(p->to, r, cp, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +64,15 @@ visitins(Ins *i, Ref *cp, RList **w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
subst(Ref *r, Ref *cp, Fn *fn)
|
||||||
|
{
|
||||||
|
if (rtype(*r) == RTmp && req(copyof(*r, cp), R))
|
||||||
|
err("temporary %%%s is used undefined",
|
||||||
|
fn->tmp[r->val].name);
|
||||||
|
*r = copyof(*r, cp);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copy(Fn *fn)
|
copy(Fn *fn)
|
||||||
{
|
{
|
||||||
|
@ -93,8 +101,6 @@ copy(Fn *fn)
|
||||||
u1 = u + fn->tmp[t].nuse;
|
u1 = u + fn->tmp[t].nuse;
|
||||||
for (; u<u1; u++)
|
for (; u<u1; u++)
|
||||||
switch (u->type) {
|
switch (u->type) {
|
||||||
default:
|
|
||||||
diag("copy: invalid use");
|
|
||||||
case UPhi:
|
case UPhi:
|
||||||
visitphi(u->u.phi, cp, &w);
|
visitphi(u->u.phi, cp, &w);
|
||||||
break;
|
break;
|
||||||
|
@ -103,6 +109,8 @@ copy(Fn *fn)
|
||||||
break;
|
break;
|
||||||
case UJmp:
|
case UJmp:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("invalid use %d", u->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (b=fn->start; b; b=b->link) {
|
for (b=fn->start; b; b=b->link) {
|
||||||
|
@ -113,31 +121,19 @@ copy(Fn *fn)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (a=0; a<p->narg; a++)
|
for (a=0; a<p->narg; a++)
|
||||||
if (rtype(p->arg[a]) == RTmp) {
|
subst(&p->arg[a], cp, fn);
|
||||||
r = cp[p->arg[a].val];
|
|
||||||
assert(!req(r, R));
|
|
||||||
p->arg[a] = r;
|
|
||||||
}
|
|
||||||
pp=&p->link;
|
pp=&p->link;
|
||||||
}
|
}
|
||||||
for (i=b->ins; i-b->ins < b->nins; i++) {
|
for (i=b->ins; i-b->ins < b->nins; i++) {
|
||||||
r = cp[i->to.val];
|
r = copyof(i->to, cp);
|
||||||
if (!req(r, i->to)) {
|
if (!req(r, i->to)) {
|
||||||
*i = (Ins){.op = ONop};
|
*i = (Ins){.op = ONop};
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (a=0; a<2; a++)
|
for (a=0; a<2; a++)
|
||||||
if (rtype(i->arg[a]) == RTmp) {
|
subst(&i->arg[a], cp, fn);
|
||||||
r = cp[i->arg[a].val];
|
|
||||||
assert(!req(r, R));
|
|
||||||
i->arg[a] = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rtype(b->jmp.arg) == RTmp) {
|
|
||||||
r = cp[b->jmp.arg.val];
|
|
||||||
assert(!req(r, R));
|
|
||||||
b->jmp.arg = r;
|
|
||||||
}
|
}
|
||||||
|
subst(&b->jmp.arg, cp, fn);
|
||||||
}
|
}
|
||||||
if (debug['C']) {
|
if (debug['C']) {
|
||||||
fprintf(stderr, "\n> Copy information:");
|
fprintf(stderr, "\n> Copy information:");
|
||||||
|
|
40
emit.c
40
emit.c
|
@ -133,7 +133,7 @@ slot(int s, Fn *fn)
|
||||||
|
|
||||||
/* sign extend s using a bitfield */
|
/* sign extend s using a bitfield */
|
||||||
x.i = s;
|
x.i = s;
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
if (x.i < 0)
|
if (x.i < 0)
|
||||||
return -4 * x.i;
|
return -4 * x.i;
|
||||||
else {
|
else {
|
||||||
|
@ -146,8 +146,6 @@ static void
|
||||||
emitcon(Con *con, FILE *f)
|
emitcon(Con *con, FILE *f)
|
||||||
{
|
{
|
||||||
switch (con->type) {
|
switch (con->type) {
|
||||||
default:
|
|
||||||
diag("emit: invalid constant");
|
|
||||||
case CAddr:
|
case CAddr:
|
||||||
if (con->local)
|
if (con->local)
|
||||||
fprintf(f, "%s%s", locprefix, con->label);
|
fprintf(f, "%s%s", locprefix, con->label);
|
||||||
|
@ -159,6 +157,8 @@ emitcon(Con *con, FILE *f)
|
||||||
case CBits:
|
case CBits:
|
||||||
fprintf(f, "%"PRId64, con->bits.i);
|
fprintf(f, "%"PRId64, con->bits.i);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("unreachable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,14 +178,14 @@ static Ref
|
||||||
getarg(char c, Ins *i)
|
getarg(char c, Ins *i)
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
default:
|
|
||||||
diag("emit: 0, 1, = expected in format");
|
|
||||||
case '0':
|
case '0':
|
||||||
return i->arg[0];
|
return i->arg[0];
|
||||||
case '1':
|
case '1':
|
||||||
return i->arg[1];
|
return i->arg[1];
|
||||||
case '=':
|
case '=':
|
||||||
return i->to;
|
return i->to;
|
||||||
|
default:
|
||||||
|
die("invalid arg letter %c", c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,8 +222,8 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f)
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case '-':
|
case '-':
|
||||||
if (req(i->arg[1], i->to) && !req(i->arg[0], i->to))
|
assert((!req(i->arg[1], i->to) || req(i->arg[0], i->to)) &&
|
||||||
diag("emit: cannot convert to 2-address");
|
"cannot convert to 2-address");
|
||||||
emitcopy(i->to, i->arg[0], i->cls, fn, f);
|
emitcopy(i->to, i->arg[0], i->cls, fn, f);
|
||||||
s++;
|
s++;
|
||||||
break;
|
break;
|
||||||
|
@ -238,8 +238,6 @@ Next:
|
||||||
} else
|
} else
|
||||||
fputc(c, f);
|
fputc(c, f);
|
||||||
switch ((c = *s++)) {
|
switch ((c = *s++)) {
|
||||||
default:
|
|
||||||
diag("emit: invalid escape");
|
|
||||||
case '%':
|
case '%':
|
||||||
fputc('%', f);
|
fputc('%', f);
|
||||||
break;
|
break;
|
||||||
|
@ -258,8 +256,6 @@ Next:
|
||||||
c = *s++;
|
c = *s++;
|
||||||
ref = getarg(c, i);
|
ref = getarg(c, i);
|
||||||
switch (rtype(ref)) {
|
switch (rtype(ref)) {
|
||||||
default:
|
|
||||||
diag("emit: invalid reference");
|
|
||||||
case RTmp:
|
case RTmp:
|
||||||
assert(isreg(ref));
|
assert(isreg(ref));
|
||||||
fprintf(f, "%%%s", regtoa(ref.val, sz));
|
fprintf(f, "%%%s", regtoa(ref.val, sz));
|
||||||
|
@ -294,6 +290,8 @@ Next:
|
||||||
fputc('$', f);
|
fputc('$', f);
|
||||||
emitcon(&fn->con[ref.val], f);
|
emitcon(&fn->con[ref.val], f);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("unreachable");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
|
@ -312,8 +310,6 @@ Next:
|
||||||
c = *s++;
|
c = *s++;
|
||||||
ref = getarg(c, i);
|
ref = getarg(c, i);
|
||||||
switch (rtype(ref)) {
|
switch (rtype(ref)) {
|
||||||
default:
|
|
||||||
diag("emit: invalid memory reference");
|
|
||||||
case RAMem:
|
case RAMem:
|
||||||
goto Mem;
|
goto Mem;
|
||||||
case RSlot:
|
case RSlot:
|
||||||
|
@ -327,8 +323,12 @@ Next:
|
||||||
assert(isreg(ref));
|
assert(isreg(ref));
|
||||||
fprintf(f, "(%%%s)", regtoa(ref.val, SLong));
|
fprintf(f, "(%%%s)", regtoa(ref.val, SLong));
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("unreachable");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("invalid format specifier %%%c", c);
|
||||||
}
|
}
|
||||||
goto Next;
|
goto Next;
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ emitins(Ins i, Fn *fn, FILE *f)
|
||||||
/* this linear search should really be a binary
|
/* this linear search should really be a binary
|
||||||
* search */
|
* search */
|
||||||
if (omap[o].op == NOp)
|
if (omap[o].op == NOp)
|
||||||
diag("emit: no entry found for instruction");
|
die("not match for %d(%d)", i.op, i.cls);
|
||||||
if (omap[o].op == i.op)
|
if (omap[o].op == i.op)
|
||||||
if (omap[o].cls == i.cls
|
if (omap[o].cls == i.cls
|
||||||
|| (omap[o].cls == Ki && KBASE(i.cls) == 0)
|
|| (omap[o].cls == Ki && KBASE(i.cls) == 0)
|
||||||
|
@ -412,8 +412,6 @@ emitins(Ins i, Fn *fn, FILE *f)
|
||||||
/* calls simply have a weird syntax in AT&T
|
/* calls simply have a weird syntax in AT&T
|
||||||
* assembly... */
|
* assembly... */
|
||||||
switch (rtype(i.arg[0])) {
|
switch (rtype(i.arg[0])) {
|
||||||
default:
|
|
||||||
diag("emit: invalid call instruction");
|
|
||||||
case RCon:
|
case RCon:
|
||||||
fprintf(f, "\tcallq ");
|
fprintf(f, "\tcallq ");
|
||||||
emitcon(&fn->con[i.arg[0].val], f);
|
emitcon(&fn->con[i.arg[0].val], f);
|
||||||
|
@ -422,6 +420,8 @@ emitins(Ins i, Fn *fn, FILE *f)
|
||||||
case RTmp:
|
case RTmp:
|
||||||
emitf("callq *%L0", &i, fn, f);
|
emitf("callq *%L0", &i, fn, f);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("invalid call argument");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSAlloc:
|
case OSAlloc:
|
||||||
|
@ -450,7 +450,7 @@ static int
|
||||||
cneg(int cmp)
|
cneg(int cmp)
|
||||||
{
|
{
|
||||||
switch (cmp) {
|
switch (cmp) {
|
||||||
default: diag("emit: cneg() unhandled comparison");
|
default: die("invalid int comparison %d", cmp);
|
||||||
case ICule: return ICugt;
|
case ICule: return ICugt;
|
||||||
case ICult: return ICuge;
|
case ICult: return ICuge;
|
||||||
case ICsle: return ICsgt;
|
case ICsle: return ICsgt;
|
||||||
|
@ -471,7 +471,7 @@ framesz(Fn *fn)
|
||||||
{
|
{
|
||||||
int i, o, f;
|
int i, o, f;
|
||||||
|
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
for (i=0, o=0; i<NRClob; i++)
|
for (i=0, o=0; i<NRClob; i++)
|
||||||
o ^= 1 & (fn->reg >> rclob[i]);
|
o ^= 1 & (fn->reg >> rclob[i]);
|
||||||
f = fn->slot;
|
f = fn->slot;
|
||||||
|
@ -549,12 +549,12 @@ emitfn(Fn *fn, FILE *f)
|
||||||
c = cneg(c);
|
c = cneg(c);
|
||||||
s = b->s2;
|
s = b->s2;
|
||||||
} else
|
} else
|
||||||
diag("emit: unhandled jump (1)");
|
die("unhandled jump");
|
||||||
fprintf(f, "\tj%s %sbb%d /* %s */\n",
|
fprintf(f, "\tj%s %sbb%d /* %s */\n",
|
||||||
ctoa[c], locprefix, id0+s->id, s->name);
|
ctoa[c], locprefix, id0+s->id, s->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
diag("emit: unhandled jump (2)");
|
die("unhandled jump %d", b->jmp.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id0 += fn->nblk;
|
id0 += fn->nblk;
|
||||||
|
|
48
isel.c
48
isel.c
|
@ -35,7 +35,7 @@ static int
|
||||||
fcmptoi(int fc)
|
fcmptoi(int fc)
|
||||||
{
|
{
|
||||||
switch (fc) {
|
switch (fc) {
|
||||||
default: diag("isel: fcmptoi defaulted");
|
default: die("invalid fp comparison %d", fc);
|
||||||
case FCle: return ICule;
|
case FCle: return ICule;
|
||||||
case FClt: return ICult;
|
case FClt: return ICult;
|
||||||
case FCgt: return ICugt;
|
case FCgt: return ICugt;
|
||||||
|
@ -85,8 +85,6 @@ noimm(Ref r, Fn *fn)
|
||||||
if (rtype(r) != RCon)
|
if (rtype(r) != RCon)
|
||||||
return 0;
|
return 0;
|
||||||
switch (fn->con[r.val].type) {
|
switch (fn->con[r.val].type) {
|
||||||
default:
|
|
||||||
diag("isel: invalid constant");
|
|
||||||
case CAddr:
|
case CAddr:
|
||||||
/* we only support the 'small'
|
/* we only support the 'small'
|
||||||
* code model of the ABI, this
|
* code model of the ABI, this
|
||||||
|
@ -97,6 +95,8 @@ noimm(Ref r, Fn *fn)
|
||||||
case CBits:
|
case CBits:
|
||||||
val = fn->con[r.val].bits.i;
|
val = fn->con[r.val].bits.i;
|
||||||
return (val < INT32_MIN || val > INT32_MAX);
|
return (val < INT32_MIN || val > INT32_MAX);
|
||||||
|
default:
|
||||||
|
die("invalid constant");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ sel(Ins i, ANum *an, Fn *fn)
|
||||||
{
|
{
|
||||||
Ref r0, r1;
|
Ref r0, r1;
|
||||||
int x, k, kc;
|
int x, k, kc;
|
||||||
int64_t val;
|
int64_t sz;
|
||||||
Ins *i0;
|
Ins *i0;
|
||||||
|
|
||||||
if (rtype(i.to) == RTmp)
|
if (rtype(i.to) == RTmp)
|
||||||
|
@ -308,12 +308,11 @@ Emit:
|
||||||
* (rsp = 0) mod 16
|
* (rsp = 0) mod 16
|
||||||
*/
|
*/
|
||||||
if (rtype(i.arg[0]) == RCon) {
|
if (rtype(i.arg[0]) == RCon) {
|
||||||
assert(fn->con[i.arg[0].val].type == CBits);
|
sz = fn->con[i.arg[0].val].bits.i;
|
||||||
val = fn->con[i.arg[0].val].bits.i;
|
if (sz < 0 || sz >= INT_MAX-15)
|
||||||
val = (val + 15) & ~INT64_C(15);
|
err("invalid alloc size %"PRId64, sz);
|
||||||
if (val < 0 || val > INT32_MAX)
|
sz = (sz + 15) & -16;
|
||||||
diag("isel: alloc too large");
|
emit(OSAlloc, Kl, i.to, getcon(sz, fn), R);
|
||||||
emit(OSAlloc, Kl, i.to, getcon(val, fn), R);
|
|
||||||
} else {
|
} else {
|
||||||
/* r0 = (i.arg[0] + 15) & -16 */
|
/* r0 = (i.arg[0] + 15) & -16 */
|
||||||
r0 = newtmp("isel", Kl, fn);
|
r0 = newtmp("isel", Kl, fn);
|
||||||
|
@ -335,13 +334,13 @@ Emit:
|
||||||
selcmp(i.arg, kc, fn);
|
selcmp(i.arg, kc, fn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
diag("isel: non-exhaustive implementation");
|
die("unknown instruction");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (i0 > curi && --i0)
|
while (i0 > curi && --i0) {
|
||||||
if (rslot(i0->arg[0], fn) != -1
|
assert(rslot(i0->arg[0], fn) == -1);
|
||||||
|| rslot(i0->arg[1], fn) != -1)
|
assert(rslot(i0->arg[1], fn) == -1);
|
||||||
diag("isel: usupported address argument");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Ins *
|
static Ins *
|
||||||
|
@ -733,7 +732,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
|
||||||
}
|
}
|
||||||
/* allocate return pad */
|
/* allocate return pad */
|
||||||
ra = alloc(sizeof *ra);
|
ra = alloc(sizeof *ra);
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
aret.align -= 2;
|
aret.align -= 2;
|
||||||
if (aret.align < 0)
|
if (aret.align < 0)
|
||||||
aret.align = 0;
|
aret.align = 0;
|
||||||
|
@ -822,7 +821,7 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
|
||||||
} else
|
} else
|
||||||
classify(i0, i1, ac, OPar, 0);
|
classify(i0, i1, ac, OPar, 0);
|
||||||
|
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
|
|
||||||
s = 4;
|
s = 4;
|
||||||
for (i=i0, a=ac; i<i1; i++, a++) {
|
for (i=i0, a=ac; i<i1; i++, a++) {
|
||||||
|
@ -856,7 +855,6 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
|
||||||
for (i=i0, a=ac; i<i1; i++, a++) {
|
for (i=i0, a=ac; i<i1; i++, a++) {
|
||||||
if (i->op != OParc || a->inmem)
|
if (i->op != OParc || a->inmem)
|
||||||
continue;
|
continue;
|
||||||
assert(NAlign == 3);
|
|
||||||
for (al=0; a->align >> (al+2); al++)
|
for (al=0; a->align >> (al+2); al++)
|
||||||
;
|
;
|
||||||
r = TMP(a->cls[0]);
|
r = TMP(a->cls[0]);
|
||||||
|
@ -876,12 +874,12 @@ static int
|
||||||
aref(Ref r, ANum *ai)
|
aref(Ref r, ANum *ai)
|
||||||
{
|
{
|
||||||
switch (rtype(r)) {
|
switch (rtype(r)) {
|
||||||
default:
|
|
||||||
diag("isel: aref defaulted");
|
|
||||||
case RCon:
|
case RCon:
|
||||||
return 2;
|
return 2;
|
||||||
case RTmp:
|
case RTmp:
|
||||||
return ai[r.val].n;
|
return ai[r.val].n;
|
||||||
|
default:
|
||||||
|
die("constant or temporary expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,8 +984,6 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (ai[r.val].n) {
|
switch (ai[r.val].n) {
|
||||||
default:
|
|
||||||
diag("isel: amatch defaulted");
|
|
||||||
case 3: /* s * i */
|
case 3: /* s * i */
|
||||||
if (!top) {
|
if (!top) {
|
||||||
a->index = al;
|
a->index = al;
|
||||||
|
@ -1023,6 +1019,8 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
|
||||||
amatch(a, ar, ai, fn, 0);
|
amatch(a, ar, ai, fn, 0);
|
||||||
amatch(a, al, ai, fn, 0);
|
amatch(a, al, ai, fn, 0);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("unreachable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1092,15 +1090,15 @@ isel(Fn *fn)
|
||||||
|
|
||||||
/* assign slots to fast allocs */
|
/* assign slots to fast allocs */
|
||||||
b = fn->start;
|
b = fn->start;
|
||||||
assert(NAlign == 3 && "change n=4 and sz /= 4 below");
|
/* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
|
||||||
for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
|
for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
|
||||||
for (i=b->ins; i-b->ins < b->nins; i++)
|
for (i=b->ins; i-b->ins < b->nins; i++)
|
||||||
if (i->op == al) {
|
if (i->op == al) {
|
||||||
if (rtype(i->arg[0]) != RCon)
|
if (rtype(i->arg[0]) != RCon)
|
||||||
break;
|
break;
|
||||||
sz = fn->con[i->arg[0].val].bits.i;
|
sz = fn->con[i->arg[0].val].bits.i;
|
||||||
if (sz < 0 || sz >= INT_MAX-3)
|
if (sz < 0 || sz >= INT_MAX-15)
|
||||||
diag("isel: invalid alloc size");
|
err("invalid alloc size %"PRId64, sz);
|
||||||
sz = (sz + n-1) & -n;
|
sz = (sz + n-1) & -n;
|
||||||
sz /= 4;
|
sz /= 4;
|
||||||
fn->tmp[i->to.val].slot = fn->slot;
|
fn->tmp[i->to.val].slot = fn->slot;
|
||||||
|
|
2
mem.c
2
mem.c
|
@ -22,7 +22,7 @@ memopt(Fn *fn)
|
||||||
for (i=b->ins; i-b->ins < b->nins; i++) {
|
for (i=b->ins; i-b->ins < b->nins; i++) {
|
||||||
if (OAlloc > i->op || i->op > OAlloc1)
|
if (OAlloc > i->op || i->op > OAlloc1)
|
||||||
continue;
|
continue;
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
assert(rtype(i->to) == RTmp);
|
assert(rtype(i->to) == RTmp);
|
||||||
t = &fn->tmp[i->to.val];
|
t = &fn->tmp[i->to.val];
|
||||||
for (u=t->use; u != &t->use[t->nuse]; u++) {
|
for (u=t->use; u != &t->use[t->nuse]; u++) {
|
||||||
|
|
12
parse.c
12
parse.c
|
@ -159,18 +159,14 @@ static int ntyp;
|
||||||
void
|
void
|
||||||
err(char *s, ...)
|
err(char *s, ...)
|
||||||
{
|
{
|
||||||
char buf[100], *p, *end;
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
p = buf;
|
|
||||||
end = buf + sizeof(buf);
|
|
||||||
|
|
||||||
va_start(ap, s);
|
va_start(ap, s);
|
||||||
p += snprintf(p, end - p, "%s:%d: ", inpath, lnum);
|
fprintf(stderr, "%s:%d: ", inpath, lnum);
|
||||||
p += vsnprintf(p, end - p, s, ap);
|
vfprintf(stderr, s, ap);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
exit(1);
|
||||||
diag(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
4
rega.c
4
rega.c
|
@ -125,7 +125,7 @@ ralloc(RMap *m, int t)
|
||||||
for (r=r0; r<r1; r++)
|
for (r=r0; r<r1; r++)
|
||||||
if (!bshas(m->b, r))
|
if (!bshas(m->b, r))
|
||||||
goto Found;
|
goto Found;
|
||||||
diag("rega: no more regs");
|
die("no more regs");
|
||||||
}
|
}
|
||||||
Found:
|
Found:
|
||||||
radd(m, t, r);
|
radd(m, t, r);
|
||||||
|
@ -170,7 +170,7 @@ pmadd(Ref src, Ref dst, int k)
|
||||||
cpm = cpm * 2 + 16;
|
cpm = cpm * 2 + 16;
|
||||||
pm = realloc(pm, cpm * sizeof pm[0]);
|
pm = realloc(pm, cpm * sizeof pm[0]);
|
||||||
if (!pm)
|
if (!pm)
|
||||||
diag("pmadd: out of memory");
|
die("pmadd, out of memory");
|
||||||
}
|
}
|
||||||
pm[npm].src = src;
|
pm[npm].src = src;
|
||||||
pm[npm].dst = dst;
|
pm[npm].dst = dst;
|
||||||
|
|
10
spill.c
10
spill.c
|
@ -94,8 +94,7 @@ fillcost(Fn *fn)
|
||||||
tmpuse(p->to, 0, 0, fn);
|
tmpuse(p->to, 0, 0, fn);
|
||||||
for (a=0; a<p->narg; a++) {
|
for (a=0; a<p->narg; a++) {
|
||||||
n = p->blk[a]->loop;
|
n = p->blk[a]->loop;
|
||||||
assert(b->npred==p->narg &&
|
assert(b->npred==p->narg && "wrong cfg");
|
||||||
"wrong cfg");
|
|
||||||
n /= b->npred;
|
n /= b->npred;
|
||||||
tmpuse(p->arg[a], 1, n, fn);
|
tmpuse(p->arg[a], 1, n, fn);
|
||||||
}
|
}
|
||||||
|
@ -146,11 +145,10 @@ slot(int t)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
if (t < Tmp0)
|
assert(t >= Tmp0 && "cannot spill register");
|
||||||
diag("spill: cannot spill register");
|
|
||||||
s = tmp[t].slot;
|
s = tmp[t].slot;
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
/* nice logic to pack stack slots
|
/* nice logic to pack stack slots
|
||||||
* on demand, there can be only
|
* on demand, there can be only
|
||||||
* one hole and slot4 points to it
|
* one hole and slot4 points to it
|
||||||
|
@ -491,7 +489,7 @@ spill(Fn *fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* align the locals to a 16 byte boundary */
|
/* align the locals to a 16 byte boundary */
|
||||||
assert(NAlign == 3);
|
/* specific to NAlign == 3 */
|
||||||
slot8 += slot8 & 3;
|
slot8 += slot8 & 3;
|
||||||
fn->slot += slot8;
|
fn->slot += slot8;
|
||||||
|
|
||||||
|
|
6
ssa.c
6
ssa.c
|
@ -15,8 +15,6 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
|
||||||
u->type = ty;
|
u->type = ty;
|
||||||
u->bid = b->id;
|
u->bid = b->id;
|
||||||
switch (ty) {
|
switch (ty) {
|
||||||
default:
|
|
||||||
diag("ssa: adduse defaulted");
|
|
||||||
case UPhi:
|
case UPhi:
|
||||||
u->u.phi = va_arg(ap, Phi *);
|
u->u.phi = va_arg(ap, Phi *);
|
||||||
break;
|
break;
|
||||||
|
@ -25,6 +23,8 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
|
||||||
break;
|
break;
|
||||||
case UJmp:
|
case UJmp:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
die("unreachable");
|
||||||
}
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
@ -465,7 +465,7 @@ renblk(Blk *b, Name **stk, Fn *fn)
|
||||||
if ((t=fn->tmp[t].visit)) {
|
if ((t=fn->tmp[t].visit)) {
|
||||||
m = p->narg++;
|
m = p->narg++;
|
||||||
if (m == NPred)
|
if (m == NPred)
|
||||||
diag("ssa: too many phi arguments");
|
die("renblk, too many phi args");
|
||||||
p->arg[m] = getstk(t, b, stk);
|
p->arg[m] = getstk(t, b, stk);
|
||||||
p->blk[m] = b;
|
p->blk[m] = b;
|
||||||
}
|
}
|
||||||
|
|
17
util.c
17
util.c
|
@ -1,4 +1,5 @@
|
||||||
#include "all.h"
|
#include "all.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
typedef struct Bitset Bitset;
|
typedef struct Bitset Bitset;
|
||||||
typedef struct Vec Vec;
|
typedef struct Vec Vec;
|
||||||
|
@ -28,9 +29,14 @@ static void **pool = ptr;
|
||||||
static int nptr = 1;
|
static int nptr = 1;
|
||||||
|
|
||||||
void
|
void
|
||||||
diag(char *s)
|
die_(char *file, char *s, ...)
|
||||||
{
|
{
|
||||||
fputs(s, stderr);
|
va_list ap;
|
||||||
|
|
||||||
|
fprintf(stderr, "%s: dying: ", file);
|
||||||
|
va_start(ap, s);
|
||||||
|
vfprintf(stderr, s, ap);
|
||||||
|
va_end(ap);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -42,7 +48,7 @@ emalloc(size_t n)
|
||||||
|
|
||||||
p = calloc(1, n);
|
p = calloc(1, n);
|
||||||
if (!p)
|
if (!p)
|
||||||
diag("emalloc: out of memory");
|
die("emalloc, out of memory");
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +101,7 @@ void
|
||||||
emit(int op, int k, Ref to, Ref arg0, Ref arg1)
|
emit(int op, int k, Ref to, Ref arg0, Ref arg1)
|
||||||
{
|
{
|
||||||
if (curi == insb)
|
if (curi == insb)
|
||||||
diag("emit: too many instructions");
|
die("emit, too many instructions");
|
||||||
*--curi = (Ins){
|
*--curi = (Ins){
|
||||||
.op = op, .cls = k,
|
.op = op, .cls = k,
|
||||||
.to = to, .arg = {arg0, arg1}
|
.to = to, .arg = {arg0, arg1}
|
||||||
|
@ -210,8 +216,7 @@ addcon(Con *c0, Con *c1)
|
||||||
*c0 = *c1;
|
*c0 = *c1;
|
||||||
else {
|
else {
|
||||||
if (c1->type == CAddr) {
|
if (c1->type == CAddr) {
|
||||||
if (c0->type == CAddr)
|
assert(c0->type != CAddr && "adding two addresses");
|
||||||
diag("addcon: adding two addresses");
|
|
||||||
c0->type = CAddr;
|
c0->type = CAddr;
|
||||||
strcpy(c0->label, c1->label);
|
strcpy(c0->label, c1->label);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue