Commit e081f25c authored by Ken Thompson's avatar Ken Thompson

reg and peep

R=r
OCL=19871
CL=19871
parent 5169bb44
...@@ -176,12 +176,14 @@ cgen(Node *n, Node *res) ...@@ -176,12 +176,14 @@ cgen(Node *n, Node *res)
gins(optoas(OCMP, types[tptr]), &n1, &n2); gins(optoas(OCMP, types[tptr]), &n1, &n2);
p1 = gbranch(optoas(OEQ, types[tptr]), T); p1 = gbranch(optoas(OEQ, types[tptr]), T);
n1.op = OINDREG; n2 = n1;
n1.type = types[TINT32]; n2.op = OINDREG;
gmove(&n1, res); n2.type = types[TINT32];
gmove(&n2, &n1);
patch(p1, pc); patch(p1, pc);
gmove(&n1, res);
regfree(&n1); regfree(&n1);
break; break;
} }
......
...@@ -100,9 +100,8 @@ if(throwreturn == N) { ...@@ -100,9 +100,8 @@ if(throwreturn == N) {
pc->as = ARET; // overwrite AEND pc->as = ARET; // overwrite AEND
pc->lineno = lineno; pc->lineno = lineno;
if(debug['N']) { if(!debug['N'] || debug['R'] || debug['P'])
regopt(ptxt); regopt(ptxt);
}
// fill in argument size // fill in argument size
ptxt->to.offset = rnd(curfn->type->argwid, maxround); ptxt->to.offset = rnd(curfn->type->argwid, maxround);
...@@ -918,6 +917,33 @@ cgen_asop(Node *n) ...@@ -918,6 +917,33 @@ cgen_asop(Node *n)
nl = n->left; nl = n->left;
nr = n->right; nr = n->right;
if(nl->addable && nr->op == OLITERAL)
switch(n->etype) {
case OADD:
if(!isint[nl->type->etype])
goto com;
if(mpgetfix(nr->val.u.xval) != 1)
goto com;
gins(optoas(OINC, nl->type), N, nl);
goto ret;
case OSUB:
if(!isint[nl->type->etype])
goto com;
if(mpgetfix(nr->val.u.xval) != 1)
goto com;
gins(optoas(ODEC, nl->type), N, nl);
goto ret;
com:
case OXOR:
case OAND:
case OOR:
if(!isint[nl->type->etype])
break;
gins(optoas(n->etype, nl->type), nr, nl);
goto ret;
}
if(nr->ullman >= UINF && nl->ullman >= UINF) { if(nr->ullman >= UINF && nl->ullman >= UINF) {
tempname(&n1, nr->type); tempname(&n1, nr->type);
cgen(nr, &n1); cgen(nr, &n1);
...@@ -960,10 +986,12 @@ cgen_as(Node *nl, Node *nr, int op) ...@@ -960,10 +986,12 @@ cgen_as(Node *nl, Node *nr, int op)
Node nc, n1; Node nc, n1;
Type *tl; Type *tl;
uint32 w, c; uint32 w, c;
int iszer;
if(nl == N) if(nl == N)
return; return;
iszer = 0;
if(nr == N || isnil(nr)) { if(nr == N || isnil(nr)) {
if(nl->op == OLIST) { if(nl->op == OLIST) {
cgen_as(nl->left, nr, op); cgen_as(nl->left, nr, op);
...@@ -1008,6 +1036,7 @@ cgen_as(Node *nl, Node *nr, int op) ...@@ -1008,6 +1036,7 @@ cgen_as(Node *nl, Node *nr, int op)
} }
/* invent a "zero" for the rhs */ /* invent a "zero" for the rhs */
iszer = 1;
nr = &nc; nr = &nc;
memset(nr, 0, sizeof(*nr)); memset(nr, 0, sizeof(*nr));
switch(tl->etype) { switch(tl->etype) {
...@@ -1062,6 +1091,9 @@ cgen_as(Node *nl, Node *nr, int op) ...@@ -1062,6 +1091,9 @@ cgen_as(Node *nl, Node *nr, int op)
return; return;
cgen(nr, nl); cgen(nr, nl);
if(iszer && nl->addable)
gins(ANOP, nl, N); // used
ret: ret:
; ;
......
...@@ -383,7 +383,7 @@ gmove(Node *f, Node *t) ...@@ -383,7 +383,7 @@ gmove(Node *f, Node *t)
case TPTR32: case TPTR32:
a = AMOVL; a = AMOVL;
if(t64) if(t64)
a = AMOVLQZX; /* could probably use plain MOVL */ a = AMOVLQZX;
goto ld; goto ld;
case TINT64: case TINT64:
if(isfloat[tt]) { if(isfloat[tt]) {
...@@ -480,50 +480,50 @@ gmove(Node *f, Node *t) ...@@ -480,50 +480,50 @@ gmove(Node *f, Node *t)
/* /*
* integer to integer * integer to integer
******** ********
a = AGOK; break; * a = AGOK; break;
case CASE(TBOOL, TBOOL): * case CASE(TBOOL, TBOOL):
case CASE(TINT8, TBOOL): * case CASE(TINT8, TBOOL):
case CASE(TUINT8, TBOOL): * case CASE(TUINT8, TBOOL):
case CASE(TINT16, TBOOL): * case CASE(TINT16, TBOOL):
case CASE(TUINT16, TBOOL): * case CASE(TUINT16, TBOOL):
case CASE(TINT32, TBOOL): * case CASE(TINT32, TBOOL):
case CASE(TUINT32, TBOOL): * case CASE(TUINT32, TBOOL):
case CASE(TPTR64, TBOOL): * case CASE(TPTR64, TBOOL):
case CASE(TBOOL, TINT8): * case CASE(TBOOL, TINT8):
case CASE(TINT8, TINT8): * case CASE(TINT8, TINT8):
case CASE(TUINT8, TINT8): * case CASE(TUINT8, TINT8):
case CASE(TINT16, TINT8): * case CASE(TINT16, TINT8):
case CASE(TUINT16, TINT8): * case CASE(TUINT16, TINT8):
case CASE(TINT32, TINT8): * case CASE(TINT32, TINT8):
case CASE(TUINT32, TINT8): * case CASE(TUINT32, TINT8):
case CASE(TPTR64, TINT8): * case CASE(TPTR64, TINT8):
case CASE(TBOOL, TUINT8): * case CASE(TBOOL, TUINT8):
case CASE(TINT8, TUINT8): * case CASE(TINT8, TUINT8):
case CASE(TUINT8, TUINT8): * case CASE(TUINT8, TUINT8):
case CASE(TINT16, TUINT8): * case CASE(TINT16, TUINT8):
case CASE(TUINT16, TUINT8): * case CASE(TUINT16, TUINT8):
case CASE(TINT32, TUINT8): * case CASE(TINT32, TUINT8):
case CASE(TUINT32, TUINT8): * case CASE(TUINT32, TUINT8):
case CASE(TPTR64, TUINT8): * case CASE(TPTR64, TUINT8):
case CASE(TINT16, TINT16): * case CASE(TINT16, TINT16):
case CASE(TUINT16, TINT16): * case CASE(TUINT16, TINT16):
case CASE(TINT32, TINT16): * case CASE(TINT32, TINT16):
case CASE(TUINT32, TINT16): * case CASE(TUINT32, TINT16):
case CASE(TPTR64, TINT16): * case CASE(TPTR64, TINT16):
case CASE(TINT16, TUINT16): * case CASE(TINT16, TUINT16):
case CASE(TUINT16, TUINT16): * case CASE(TUINT16, TUINT16):
case CASE(TINT32, TUINT16): * case CASE(TINT32, TUINT16):
case CASE(TUINT32, TUINT16): * case CASE(TUINT32, TUINT16):
case CASE(TPTR64, TUINT16): * case CASE(TPTR64, TUINT16):
case CASE(TINT64, TUINT): * case CASE(TINT64, TUINT):
case CASE(TINT64, TUINT32): * case CASE(TINT64, TUINT32):
case CASE(TUINT64, TUINT32): * case CASE(TUINT64, TUINT32):
*****/ *****/
a = AMOVL; a = AMOVL;
break; break;
...@@ -534,25 +534,21 @@ gmove(Node *f, Node *t) ...@@ -534,25 +534,21 @@ gmove(Node *f, Node *t)
case CASE(TUINT64, TINT8): case CASE(TUINT64, TINT8):
case CASE(TUINT64, TINT16): case CASE(TUINT64, TINT16):
case CASE(TUINT64, TINT32): case CASE(TUINT64, TINT32):
a = AMOVLQSX; // this looks bad
break;
case CASE(TINT32, TINT64): case CASE(TINT32, TINT64):
case CASE(TINT32, TPTR64): case CASE(TINT32, TPTR64):
a = AMOVLQSX; a = AMOVLQSX;
// if(f->op == OCONST) {
// f->val.vval &= (uvlong)0xffffffffU;
// if(f->val.vval & 0x80000000)
// f->val.vval |= (vlong)0xffffffff << 32;
// a = AMOVQ;
// }
break; break;
case CASE(TUINT32, TINT64): case CASE(TUINT32, TINT64):
case CASE(TUINT32, TUINT64): case CASE(TUINT32, TUINT64):
case CASE(TUINT32, TPTR64): case CASE(TUINT32, TPTR64):
a = AMOVL; /* same effect as AMOVLQZX */ case CASE(TPTR32, TINT64):
// if(f->op == OCONST) { case CASE(TPTR32, TUINT64):
// f->val.vval &= (uvlong)0xffffffffU; case CASE(TPTR32, TPTR64):
// a = AMOVQ; a = AMOVLQZX;
// }
break; break;
case CASE(TPTR64, TINT64): case CASE(TPTR64, TINT64):
...@@ -1239,6 +1235,50 @@ optoas(int op, Type *t) ...@@ -1239,6 +1235,50 @@ optoas(int op, Type *t)
a = ASUBSD; a = ASUBSD;
break; break;
case CASE(OINC, TINT8):
case CASE(OINC, TUINT8):
a = AINCB;
break;
case CASE(OINC, TINT16):
case CASE(OINC, TUINT16):
a = AINCW;
break;
case CASE(OINC, TINT32):
case CASE(OINC, TUINT32):
case CASE(OINC, TPTR32):
a = AINCL;
break;
case CASE(OINC, TINT64):
case CASE(OINC, TUINT64):
case CASE(OINC, TPTR64):
a = AINCQ;
break;
case CASE(ODEC, TINT8):
case CASE(ODEC, TUINT8):
a = ADECB;
break;
case CASE(ODEC, TINT16):
case CASE(ODEC, TUINT16):
a = ADECW;
break;
case CASE(ODEC, TINT32):
case CASE(ODEC, TUINT32):
case CASE(ODEC, TPTR32):
a = ADECL;
break;
case CASE(ODEC, TINT64):
case CASE(ODEC, TUINT64):
case CASE(ODEC, TPTR64):
a = ADECQ;
break;
case CASE(OMINUS, TINT8): case CASE(OMINUS, TINT8):
case CASE(OMINUS, TUINT8): case CASE(OMINUS, TUINT8):
a = ANEGB; a = ANEGB;
......
...@@ -60,7 +60,6 @@ struct Bits ...@@ -60,7 +60,6 @@ struct Bits
uint32 b[BITS]; uint32 b[BITS];
}; };
struct Reg struct Reg
{ {
...@@ -75,14 +74,12 @@ struct Reg ...@@ -75,14 +74,12 @@ struct Reg
Bits regdiff; Bits regdiff;
Bits act; Bits act;
int32 regu; int32 regu; // register used bitmap
int32 loop; /* could be shorter */ int32 rpo; // reverse post ordering
int32 rpo; /* reverse post ordering */
int32 active; int32 active;
// uint32 magic; uint16 loop; // x5 for every loop
// int32 pc; uchar refset; // diagnostic generated
// Reg* log5;
Reg* p1; Reg* p1;
Reg* p2; Reg* p2;
...@@ -130,10 +127,9 @@ EXTERN Bits externs; ...@@ -130,10 +127,9 @@ EXTERN Bits externs;
EXTERN Bits params; EXTERN Bits params;
EXTERN Bits consts; EXTERN Bits consts;
EXTERN Bits addrs; EXTERN Bits addrs;
EXTERN Bits ovar;
EXTERN int change; EXTERN int change;
EXTERN Bits zbits; EXTERN Bits zbits;
EXTERN uchar typechlpfd[NTYPE]; // botch
EXTERN uchar typev[NTYPE]; // botch
EXTERN int32 maxnr; EXTERN int32 maxnr;
EXTERN int32* idom; EXTERN int32* idom;
...@@ -150,6 +146,15 @@ int beq(Bits, Bits); ...@@ -150,6 +146,15 @@ int beq(Bits, Bits);
int bset(Bits, uint); int bset(Bits, uint);
int Qconv(Fmt *fp); int Qconv(Fmt *fp);
int bitno(int32); int bitno(int32);
struct
{
int32 ncvtreg;
int32 nspill;
int32 nreload;
int32 ndelmov;
int32 nvar;
int32 naddr;
} ostats;
/* /*
* reg.c * reg.c
...@@ -167,6 +172,8 @@ void paint1(Reg*, int); ...@@ -167,6 +172,8 @@ void paint1(Reg*, int);
uint32 paint2(Reg*, int); uint32 paint2(Reg*, int);
void paint3(Reg*, int, int32, int); void paint3(Reg*, int, int32, int);
void addreg(Adr*, int); void addreg(Adr*, int);
void dumpit(char *str, Reg *r0);
int noreturn(Prog *p);
/* /*
* peep.c * peep.c
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "gg.h" #include "gg.h"
#include "opt.h" #include "opt.h"
static int static int
needc(Prog *p) needc(Prog *p)
{ {
...@@ -67,7 +68,7 @@ rnops(Reg *r) ...@@ -67,7 +68,7 @@ rnops(Reg *r)
Reg *r1; Reg *r1;
if(r != R) if(r != R)
for(;;){ for(;;) {
p = r->prog; p = r->prog;
if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE) if(p->as != ANOP || p->from.type != D_NONE || p->to.type != D_NONE)
break; break;
...@@ -103,6 +104,8 @@ peep(void) ...@@ -103,6 +104,8 @@ peep(void)
r2->link = r1; r2->link = r1;
r2->prog = p; r2->prog = p;
p->reg = r2;
r2->p1 = r; r2->p1 = r;
r->s1 = r2; r->s1 = r2;
r2->s1 = r1; r2->s1 = r1;
...@@ -119,10 +122,11 @@ peep(void) ...@@ -119,10 +122,11 @@ peep(void)
} }
} }
pc = 0; /* speculating it won't kill */
loop1: loop1:
if(debug['P'] && debug['v'])
dumpit("loop1", firstr);
t = 0; t = 0;
for(r=firstr; r!=R; r=r->link) { for(r=firstr; r!=R; r=r->link) {
p = r->prog; p = r->prog;
...@@ -186,13 +190,15 @@ loop1: ...@@ -186,13 +190,15 @@ loop1:
if(p->from.offset == -1){ if(p->from.offset == -1){
if(p->as == AADDQ) if(p->as == AADDQ)
p->as = ADECQ; p->as = ADECQ;
else if(p->as == AADDL) else
if(p->as == AADDL)
p->as = ADECL; p->as = ADECL;
else else
p->as = ADECW; p->as = ADECW;
p->from = zprog.from; p->from = zprog.from;
} }
else if(p->from.offset == 1){ else
if(p->from.offset == 1){
if(p->as == AADDQ) if(p->as == AADDQ)
p->as = AINCQ; p->as = AINCQ;
else if(p->as == AADDL) else if(p->as == AADDL)
...@@ -211,16 +217,19 @@ loop1: ...@@ -211,16 +217,19 @@ loop1:
if(p->from.offset == -1) { if(p->from.offset == -1) {
if(p->as == ASUBQ) if(p->as == ASUBQ)
p->as = AINCQ; p->as = AINCQ;
else if(p->as == ASUBL) else
if(p->as == ASUBL)
p->as = AINCL; p->as = AINCL;
else else
p->as = AINCW; p->as = AINCW;
p->from = zprog.from; p->from = zprog.from;
} }
else if(p->from.offset == 1){ else
if(p->from.offset == 1){
if(p->as == ASUBQ) if(p->as == ASUBQ)
p->as = ADECQ; p->as = ADECQ;
else if(p->as == ASUBL) else
if(p->as == ASUBL)
p->as = ADECL; p->as = ADECL;
else else
p->as = ADECW; p->as = ADECW;
...@@ -239,9 +248,14 @@ excise(Reg *r) ...@@ -239,9 +248,14 @@ excise(Reg *r)
Prog *p; Prog *p;
p = r->prog; p = r->prog;
if(debug['P'] && debug['v'])
print("%P ===delete===\n", p);
p->as = ANOP; p->as = ANOP;
p->from = zprog.from; p->from = zprog.from;
p->to = zprog.to; p->to = zprog.to;
ostats.ndelmov++;
} }
Reg* Reg*
......
...@@ -34,11 +34,8 @@ ...@@ -34,11 +34,8 @@
#include "opt.h" #include "opt.h"
#define P2R(p) (Reg*)(p->reg) #define P2R(p) (Reg*)(p->reg)
#define MAGIC 0xb00fbabe
static int first = 1; static int first = 1;
static void dumpit(char *str, Reg *r0);
static int noreturn(Prog *p);
Reg* Reg*
rega(void) rega(void)
...@@ -70,6 +67,30 @@ rcmp(const void *a1, const void *a2) ...@@ -70,6 +67,30 @@ rcmp(const void *a1, const void *a2)
return p2->varno - p1->varno; return p2->varno - p1->varno;
} }
void
setoutvar(void)
{
Type *t;
Node *n;
Addr a;
Iter save;
Bits bit;
int z;
t = structfirst(&save, getoutarg(curfn->type));
while(t != T) {
n = nodarg(t, 1);
a = zprog.from;
naddr(n, &a);
bit = mkvar(R, &a);
for(z=0; z<BITS; z++)
ovar.b[z] |= bit.b[z];
t = structnext(&save);
}
//if(bany(b))
//print("ovars = %Q\n", &ovar);
}
void void
regopt(Prog *firstp) regopt(Prog *firstp)
{ {
...@@ -93,8 +114,12 @@ regopt(Prog *firstp) ...@@ -93,8 +114,12 @@ regopt(Prog *firstp)
params.b[z] = 0; params.b[z] = 0;
consts.b[z] = 0; consts.b[z] = 0;
addrs.b[z] = 0; addrs.b[z] = 0;
ovar.b[z] = 0;
} }
// build list of return variables
setoutvar();
/* /*
* pass 1 * pass 1
* build aux data structure * build aux data structure
...@@ -221,6 +246,15 @@ regopt(Prog *firstp) ...@@ -221,6 +246,15 @@ regopt(Prog *firstp)
/* /*
* right side read+write * right side read+write
*/ */
case AINCB:
case AINCL:
case AINCQ:
case AINCW:
case ADECB:
case ADECL:
case ADECQ:
case ADECW:
case AADDB: case AADDB:
case AADDL: case AADDL:
case AADDQ: case AADDQ:
...@@ -380,7 +414,9 @@ regopt(Prog *firstp) ...@@ -380,7 +414,9 @@ regopt(Prog *firstp)
} }
if(firstr == R) if(firstr == R)
return; return;
//dumpit("pass1", firstr);
if(debug['R'] && debug['v'])
dumpit("pass1", firstr);
/* /*
* pass 2 * pass 2
...@@ -396,7 +432,7 @@ regopt(Prog *firstp) ...@@ -396,7 +432,7 @@ regopt(Prog *firstp)
if(r1 == R) if(r1 == R)
fatal("rnil %P", p); fatal("rnil %P", p);
if(r1 == r) { if(r1 == r) {
fatal("ref to self %P", p); //fatal("ref to self %P", p);
continue; continue;
} }
r->s2 = r1; r->s2 = r1;
...@@ -404,7 +440,9 @@ regopt(Prog *firstp) ...@@ -404,7 +440,9 @@ regopt(Prog *firstp)
r1->p2 = r; r1->p2 = r;
} }
} }
//dumpit("pass2", firstr);
if(debug['R'] && debug['v'])
dumpit("pass2", firstr);
/* /*
* pass 2.5 * pass 2.5
...@@ -414,7 +452,9 @@ regopt(Prog *firstp) ...@@ -414,7 +452,9 @@ regopt(Prog *firstp)
r->active = 0; r->active = 0;
change = 0; change = 0;
loopit(firstr, nr); loopit(firstr, nr);
//dumpit("pass2.5", firstr);
if(debug['R'] && debug['v'])
dumpit("pass2.5", firstr);
/* /*
* pass 3 * pass 3
...@@ -443,7 +483,8 @@ loop11: ...@@ -443,7 +483,8 @@ loop11:
if(change) if(change)
goto loop1; goto loop1;
//dumpit("pass3", firstr); if(debug['R'] && debug['v'])
dumpit("pass3", firstr);
/* /*
* pass 4 * pass 4
...@@ -458,7 +499,8 @@ loop2: ...@@ -458,7 +499,8 @@ loop2:
if(change) if(change)
goto loop2; goto loop2;
//dumpit("pass4", firstr); if(debug['R'] && debug['v'])
dumpit("pass4", firstr);
/* /*
* pass 5 * pass 5
...@@ -470,10 +512,11 @@ loop2: ...@@ -470,10 +512,11 @@ loop2:
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]); ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
if(bany(&bit)) { if(bany(&bit) && !r->refset) {
warn("used and not set: %Q", bit); // should never happen - all variables are preset
if(debug['R'] && !debug['w']) if(debug['w'])
print("used and not set: %Q\n", bit); print("%L: used and not set: %Q\n", r->prog->lineno, bit);
r->refset = 1;
} }
} }
for(r = firstr; r != R; r = r->link) for(r = firstr; r != R; r = r->link)
...@@ -484,10 +527,10 @@ loop2: ...@@ -484,10 +527,10 @@ loop2:
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
bit.b[z] = r->set.b[z] & bit.b[z] = r->set.b[z] &
~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
if(bany(&bit)) { if(bany(&bit) && !r->refset) {
warn("set and not used: %Q", bit); if(debug['w'])
if(debug['R']) print("%L: set and not used: %Q\n", r->prog->lineno, bit);
print("set and not used: %Q\n", bit); r->refset = 1;
excise(r); excise(r);
} }
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
...@@ -497,20 +540,15 @@ loop2: ...@@ -497,20 +540,15 @@ loop2:
rgp->enter = r; rgp->enter = r;
rgp->varno = i; rgp->varno = i;
change = 0; change = 0;
if(debug['R'] && debug['v'])
print("\n");
paint1(r, i); paint1(r, i);
bit.b[i/32] &= ~(1L<<(i%32)); bit.b[i/32] &= ~(1L<<(i%32));
if(change <= 0) { if(change <= 0)
if(debug['R'])
print("%L$%d: %Q\n",
r->prog->lineno, change, blsh(i));
continue; continue;
}
rgp->cost = change; rgp->cost = change;
nregion++; nregion++;
if(nregion >= NRGN) { if(nregion >= NRGN) {
fatal("too many regions"); if(debug['R'] && debug['v'])
print("too many regions\n");
goto brk; goto brk;
} }
rgp++; rgp++;
...@@ -534,11 +572,14 @@ brk: ...@@ -534,11 +572,14 @@ brk:
rgp++; rgp++;
} }
if(debug['R'] && debug['v'])
dumpit("pass6", firstr);
/* /*
* pass 7 * pass 7
* peep-hole on basic block * peep-hole on basic block
*/ */
if(debug['P']) { if(!debug['R'] || debug['P']) {
peep(); peep();
} }
...@@ -547,14 +588,43 @@ brk: ...@@ -547,14 +588,43 @@ brk:
* free aux structures * free aux structures
*/ */
for(p=firstp; p!=P; p=p->link) { for(p=firstp; p!=P; p=p->link) {
while(p->link && p->link->as == ANOP) while(p->link != P && p->link->as == ANOP)
p->link = p->link->link; p->link = p->link->link;
if(p->to.type == D_BRANCH)
while(p->to.branch != P && p->to.branch->as == ANOP)
p->to.branch = p->to.branch->link;
} }
if(r1 != R) { if(r1 != R) {
r1->link = freer; r1->link = freer;
freer = firstr; freer = firstr;
} }
if(debug['R']) {
if(ostats.ncvtreg ||
ostats.nspill ||
ostats.nreload ||
ostats.ndelmov ||
ostats.nvar ||
ostats.naddr ||
0)
print("\nstats\n");
if(ostats.ncvtreg)
print(" %4ld cvtreg\n", ostats.ncvtreg);
if(ostats.nspill)
print(" %4ld spill\n", ostats.nspill);
if(ostats.nreload)
print(" %4ld reload\n", ostats.nreload);
if(ostats.ndelmov)
print(" %4ld delmov\n", ostats.ndelmov);
if(ostats.nvar)
print(" %4ld delmov\n", ostats.nvar);
if(ostats.naddr)
print(" %4ld delmov\n", ostats.naddr);
memset(&ostats, 0, sizeof(ostats));
}
} }
/* /*
...@@ -585,7 +655,7 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -585,7 +655,7 @@ addmove(Reg *r, int bn, int rn, int f)
a->etype = v->etype; a->etype = v->etype;
a->type = v->name; a->type = v->name;
// need to chean this up with wptr and // need to clean this up with wptr and
// some of the defaults // some of the defaults
p1->as = AMOVL; p1->as = AMOVL;
switch(v->etype) { switch(v->etype) {
...@@ -611,7 +681,7 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -611,7 +681,7 @@ addmove(Reg *r, int bn, int rn, int f)
p1->as = AMOVSS; p1->as = AMOVSS;
break; break;
case TFLOAT64: case TFLOAT64:
p1->as = AMOVSS; p1->as = AMOVSD;
break; break;
case TINT: case TINT:
case TUINT: case TUINT:
...@@ -631,8 +701,9 @@ addmove(Reg *r, int bn, int rn, int f) ...@@ -631,8 +701,9 @@ addmove(Reg *r, int bn, int rn, int f)
if(v->etype == TUINT16) if(v->etype == TUINT16)
p1->as = AMOVW; p1->as = AMOVW;
} }
// if(debug['R']) if(debug['R'] && debug['v'])
print("%P\t.a%P\n", p, p1); print("%P ===add=== %P\n", p, p1);
ostats.nspill++;
} }
uint32 uint32
...@@ -670,8 +741,10 @@ mkvar(Reg *r, Adr *a) ...@@ -670,8 +741,10 @@ mkvar(Reg *r, Adr *a)
* mark registers used * mark registers used
*/ */
t = a->type; t = a->type;
r->regu |= doregbits(t); if(r != R) {
r->regu |= doregbits(a->index); r->regu |= doregbits(t);
r->regu |= doregbits(a->index);
}
switch(t) { switch(t) {
default: default:
...@@ -682,6 +755,7 @@ mkvar(Reg *r, Adr *a) ...@@ -682,6 +755,7 @@ mkvar(Reg *r, Adr *a)
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
addrs.b[z] |= bit.b[z]; addrs.b[z] |= bit.b[z];
a->type = t; a->type = t;
ostats.naddr++;
goto none; goto none;
case D_EXTERN: case D_EXTERN:
case D_STATIC: case D_STATIC:
...@@ -727,6 +801,7 @@ mkvar(Reg *r, Adr *a) ...@@ -727,6 +801,7 @@ mkvar(Reg *r, Adr *a)
v->etype = et; v->etype = et;
if(debug['R']) if(debug['R'])
print("bit=%2d et=%2d %D\n", i, et, a); print("bit=%2d et=%2d %D\n", i, et, a);
ostats.nvar++;
out: out:
bit = blsh(i); bit = blsh(i);
...@@ -738,7 +813,8 @@ out: ...@@ -738,7 +813,8 @@ out:
params.b[z] |= bit.b[z]; params.b[z] |= bit.b[z];
if(v->etype != et) { if(v->etype != et) {
/* funny punning */ /* funny punning */
print("pun %d %d %S\n", v->etype, et, s); if(debug['R'])
print("pun %d %d %S\n", v->etype, et, s);
for(z=0; z<BITS; z++) for(z=0; z<BITS; z++)
addrs.b[z] |= bit.b[z]; addrs.b[z] |= bit.b[z];
} }
...@@ -787,9 +863,10 @@ prop(Reg *r, Bits ref, Bits cal) ...@@ -787,9 +863,10 @@ prop(Reg *r, Bits ref, Bits cal)
case ARET: case ARET:
for(z=0; z<BITS; z++) { for(z=0; z<BITS; z++) {
cal.b[z] = externs.b[z]; cal.b[z] = externs.b[z] | ovar.b[z];
ref.b[z] = 0; ref.b[z] = 0;
} }
break;
} }
for(z=0; z<BITS; z++) { for(z=0; z<BITS; z++) {
ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
...@@ -1044,9 +1121,6 @@ paint1(Reg *r, int bn) ...@@ -1044,9 +1121,6 @@ paint1(Reg *r, int bn)
if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
change -= CLOAD * r->loop; change -= CLOAD * r->loop;
if(debug['R'] && debug['v'])
print("%ld%P\tld %Q $%d\n", r->loop,
r->prog, blsh(bn), change);
} }
for(;;) { for(;;) {
r->act.b[z] |= bb; r->act.b[z] |= bb;
...@@ -1054,23 +1128,14 @@ paint1(Reg *r, int bn) ...@@ -1054,23 +1128,14 @@ paint1(Reg *r, int bn)
if(r->use1.b[z] & bb) { if(r->use1.b[z] & bb) {
change += CREF * r->loop; change += CREF * r->loop;
if(debug['R'] && debug['v'])
print("%ld%P\tu1 %Q $%d\n", r->loop,
p, blsh(bn), change);
} }
if((r->use2.b[z]|r->set.b[z]) & bb) { if((r->use2.b[z]|r->set.b[z]) & bb) {
change += CREF * r->loop; change += CREF * r->loop;
if(debug['R'] && debug['v'])
print("%ld%P\tu2 %Q $%d\n", r->loop,
p, blsh(bn), change);
} }
if(STORE(r) & r->regdiff.b[z] & bb) { if(STORE(r) & r->regdiff.b[z] & bb) {
change -= CLOAD * r->loop; change -= CLOAD * r->loop;
if(debug['R'] && debug['v'])
print("%ld%P\tst %Q $%d\n", r->loop,
p, blsh(bn), change);
} }
if(r->refbehind.b[z] & bb) if(r->refbehind.b[z] & bb)
...@@ -1226,18 +1291,18 @@ paint3(Reg *r, int bn, int32 rb, int rn) ...@@ -1226,18 +1291,18 @@ paint3(Reg *r, int bn, int32 rb, int rn)
p = r->prog; p = r->prog;
if(r->use1.b[z] & bb) { if(r->use1.b[z] & bb) {
if(debug['R']) if(debug['R'] && debug['v'])
print("%P", p); print("%P", p);
addreg(&p->from, rn); addreg(&p->from, rn);
if(debug['R']) if(debug['R'] && debug['v'])
print("\t.c%P\n", p); print(" ===change== %P\n", p);
} }
if((r->use2.b[z]|r->set.b[z]) & bb) { if((r->use2.b[z]|r->set.b[z]) & bb) {
if(debug['R']) if(debug['R'] && debug['v'])
print("%P", p); print("%P", p);
addreg(&p->to, rn); addreg(&p->to, rn);
if(debug['R']) if(debug['R'] && debug['v'])
print("\t.c%P\n", p); print(" ===change== %P\n", p);
} }
if(STORE(r) & r->regdiff.b[z] & bb) if(STORE(r) & r->regdiff.b[z] & bb)
...@@ -1272,6 +1337,8 @@ addreg(Adr *a, int rn) ...@@ -1272,6 +1337,8 @@ addreg(Adr *a, int rn)
a->sym = 0; a->sym = 0;
a->offset = 0; a->offset = 0;
a->type = rn; a->type = rn;
ostats.ncvtreg++;
} }
int32 int32
...@@ -1286,8 +1353,7 @@ RtoB(int r) ...@@ -1286,8 +1353,7 @@ RtoB(int r)
int int
BtoR(int32 b) BtoR(int32 b)
{ {
b &= 0x3fffL; // no R14 or R15
b &= 0xffffL;
if(b == 0) if(b == 0)
return 0; return 0;
return bitno(b) + D_AX; return bitno(b) + D_AX;
...@@ -1317,7 +1383,7 @@ BtoF(int32 b) ...@@ -1317,7 +1383,7 @@ BtoF(int32 b)
return bitno(b) - 16 + FREGMIN; return bitno(b) - 16 + FREGMIN;
} }
static void void
dumpit(char *str, Reg *r0) dumpit(char *str, Reg *r0)
{ {
Reg *r, *r1; Reg *r, *r1;
...@@ -1380,7 +1446,7 @@ dumpit(char *str, Reg *r0) ...@@ -1380,7 +1446,7 @@ dumpit(char *str, Reg *r0)
static Sym* symlist[10]; static Sym* symlist[10];
static int int
noreturn(Prog *p) noreturn(Prog *p)
{ {
Sym *s; Sym *s;
...@@ -1388,6 +1454,7 @@ noreturn(Prog *p) ...@@ -1388,6 +1454,7 @@ noreturn(Prog *p)
if(symlist[0] == S) { if(symlist[0] == S) {
symlist[0] = pkglookup("throwindex", "sys"); symlist[0] = pkglookup("throwindex", "sys");
symlist[1] = pkglookup("panicl", "sys");
} }
s = p->to.sym; s = p->to.sym;
......
...@@ -284,6 +284,7 @@ enum ...@@ -284,6 +284,7 @@ enum
OEQ, ONE, OLT, OLE, OGE, OGT, OEQ, ONE, OLT, OLE, OGE, OGT,
OADD, OSUB, OOR, OXOR, OADD, OSUB, OOR, OXOR,
OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OMUL, ODIV, OMOD, OLSH, ORSH, OAND,
OINC, ODEC, // placeholders - not used
OFUNC, OFUNC,
OLABEL, OLABEL,
OBREAK, OBREAK,
......
...@@ -1094,7 +1094,20 @@ loop: ...@@ -1094,7 +1094,20 @@ loop:
goto ret; goto ret;
nottop: nottop:
yyerror("didn't expect %O here", n->op); switch(top) {
default:
yyerror("didn't expect %O here", n->op);
break;
case Etop:
yyerror("operation %O not allowed in statement context", n->op);
break;
case Elv:
yyerror("operation %O not allowed in assignment context", n->op);
break;
case Erv:
yyerror("operation %O not allowed in expression context", n->op);
break;
}
goto ret; goto ret;
badt: badt:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment