174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth void
peep(void)474a4d8c2SCharles.Forsyth peep(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth Reg *r, *r1, *r2;
774a4d8c2SCharles.Forsyth Prog *p, *p1;
874a4d8c2SCharles.Forsyth int t;
974a4d8c2SCharles.Forsyth /*
1074a4d8c2SCharles.Forsyth * complete R structure
1174a4d8c2SCharles.Forsyth */
1274a4d8c2SCharles.Forsyth t = 0;
1374a4d8c2SCharles.Forsyth for(r=firstr; r!=R; r=r1) {
1474a4d8c2SCharles.Forsyth r1 = r->link;
1574a4d8c2SCharles.Forsyth if(r1 == R)
1674a4d8c2SCharles.Forsyth break;
1774a4d8c2SCharles.Forsyth p = r->prog->link;
1874a4d8c2SCharles.Forsyth while(p != r1->prog)
1974a4d8c2SCharles.Forsyth switch(p->as) {
2074a4d8c2SCharles.Forsyth default:
2174a4d8c2SCharles.Forsyth r2 = rega();
2274a4d8c2SCharles.Forsyth r->link = r2;
2374a4d8c2SCharles.Forsyth r2->link = r1;
2474a4d8c2SCharles.Forsyth
2574a4d8c2SCharles.Forsyth r2->prog = p;
2674a4d8c2SCharles.Forsyth r2->p1 = r;
2774a4d8c2SCharles.Forsyth r->s1 = r2;
2874a4d8c2SCharles.Forsyth r2->s1 = r1;
2974a4d8c2SCharles.Forsyth r1->p1 = r2;
3074a4d8c2SCharles.Forsyth
3174a4d8c2SCharles.Forsyth r = r2;
3274a4d8c2SCharles.Forsyth t++;
3374a4d8c2SCharles.Forsyth
3474a4d8c2SCharles.Forsyth case ADATA:
3574a4d8c2SCharles.Forsyth case AGLOBL:
3674a4d8c2SCharles.Forsyth case ANAME:
3774a4d8c2SCharles.Forsyth case ASIGNAME:
3874a4d8c2SCharles.Forsyth p = p->link;
3974a4d8c2SCharles.Forsyth }
4074a4d8c2SCharles.Forsyth }
4174a4d8c2SCharles.Forsyth
4274a4d8c2SCharles.Forsyth loop1:
4374a4d8c2SCharles.Forsyth t = 0;
4474a4d8c2SCharles.Forsyth for(r=firstr; r!=R; r=r->link) {
4574a4d8c2SCharles.Forsyth p = r->prog;
4674a4d8c2SCharles.Forsyth if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD)
4774a4d8c2SCharles.Forsyth if(regtyp(&p->to)) {
4874a4d8c2SCharles.Forsyth if(regtyp(&p->from))
4974a4d8c2SCharles.Forsyth if(p->from.type == p->to.type) {
5074a4d8c2SCharles.Forsyth if(copyprop(r)) {
5174a4d8c2SCharles.Forsyth excise(r);
5274a4d8c2SCharles.Forsyth t++;
5374a4d8c2SCharles.Forsyth } else
5474a4d8c2SCharles.Forsyth if(subprop(r) && copyprop(r)) {
5574a4d8c2SCharles.Forsyth excise(r);
5674a4d8c2SCharles.Forsyth t++;
5774a4d8c2SCharles.Forsyth }
5874a4d8c2SCharles.Forsyth }
5974a4d8c2SCharles.Forsyth if(regzer(&p->from))
6074a4d8c2SCharles.Forsyth if(p->to.type == D_REG) {
6174a4d8c2SCharles.Forsyth p->from.type = D_REG;
6274a4d8c2SCharles.Forsyth p->from.reg = 0;
6374a4d8c2SCharles.Forsyth if(copyprop(r)) {
6474a4d8c2SCharles.Forsyth excise(r);
6574a4d8c2SCharles.Forsyth t++;
6674a4d8c2SCharles.Forsyth } else
6774a4d8c2SCharles.Forsyth if(subprop(r) && copyprop(r)) {
6874a4d8c2SCharles.Forsyth excise(r);
6974a4d8c2SCharles.Forsyth t++;
7074a4d8c2SCharles.Forsyth }
7174a4d8c2SCharles.Forsyth }
7274a4d8c2SCharles.Forsyth }
7374a4d8c2SCharles.Forsyth }
7474a4d8c2SCharles.Forsyth if(t)
7574a4d8c2SCharles.Forsyth goto loop1;
7674a4d8c2SCharles.Forsyth /*
7774a4d8c2SCharles.Forsyth * look for MOVB x,R; MOVB R,R
7874a4d8c2SCharles.Forsyth */
7974a4d8c2SCharles.Forsyth for(r=firstr; r!=R; r=r->link) {
8074a4d8c2SCharles.Forsyth p = r->prog;
8174a4d8c2SCharles.Forsyth switch(p->as) {
8274a4d8c2SCharles.Forsyth default:
8374a4d8c2SCharles.Forsyth continue;
8474a4d8c2SCharles.Forsyth case AMOVH:
8574a4d8c2SCharles.Forsyth case AMOVHU:
8674a4d8c2SCharles.Forsyth case AMOVB:
8774a4d8c2SCharles.Forsyth case AMOVBU:
8874a4d8c2SCharles.Forsyth if(p->to.type != D_REG)
8974a4d8c2SCharles.Forsyth continue;
9074a4d8c2SCharles.Forsyth break;
9174a4d8c2SCharles.Forsyth }
9274a4d8c2SCharles.Forsyth r1 = r->link;
9374a4d8c2SCharles.Forsyth if(r1 == R)
9474a4d8c2SCharles.Forsyth continue;
9574a4d8c2SCharles.Forsyth p1 = r1->prog;
9674a4d8c2SCharles.Forsyth if(p1->as != p->as)
9774a4d8c2SCharles.Forsyth continue;
9874a4d8c2SCharles.Forsyth if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
9974a4d8c2SCharles.Forsyth continue;
10074a4d8c2SCharles.Forsyth if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
10174a4d8c2SCharles.Forsyth continue;
10274a4d8c2SCharles.Forsyth excise(r1);
10374a4d8c2SCharles.Forsyth }
10474a4d8c2SCharles.Forsyth }
10574a4d8c2SCharles.Forsyth
10674a4d8c2SCharles.Forsyth void
excise(Reg * r)10774a4d8c2SCharles.Forsyth excise(Reg *r)
10874a4d8c2SCharles.Forsyth {
10974a4d8c2SCharles.Forsyth Prog *p;
11074a4d8c2SCharles.Forsyth
11174a4d8c2SCharles.Forsyth p = r->prog;
11274a4d8c2SCharles.Forsyth p->as = ANOP;
11374a4d8c2SCharles.Forsyth p->from = zprog.from;
11474a4d8c2SCharles.Forsyth p->to = zprog.to;
11574a4d8c2SCharles.Forsyth p->reg = zprog.reg; /**/
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth
11874a4d8c2SCharles.Forsyth Reg*
uniqp(Reg * r)11974a4d8c2SCharles.Forsyth uniqp(Reg *r)
12074a4d8c2SCharles.Forsyth {
12174a4d8c2SCharles.Forsyth Reg *r1;
12274a4d8c2SCharles.Forsyth
12374a4d8c2SCharles.Forsyth r1 = r->p1;
12474a4d8c2SCharles.Forsyth if(r1 == R) {
12574a4d8c2SCharles.Forsyth r1 = r->p2;
12674a4d8c2SCharles.Forsyth if(r1 == R || r1->p2link != R)
12774a4d8c2SCharles.Forsyth return R;
12874a4d8c2SCharles.Forsyth } else
12974a4d8c2SCharles.Forsyth if(r->p2 != R)
13074a4d8c2SCharles.Forsyth return R;
13174a4d8c2SCharles.Forsyth return r1;
13274a4d8c2SCharles.Forsyth }
13374a4d8c2SCharles.Forsyth
13474a4d8c2SCharles.Forsyth Reg*
uniqs(Reg * r)13574a4d8c2SCharles.Forsyth uniqs(Reg *r)
13674a4d8c2SCharles.Forsyth {
13774a4d8c2SCharles.Forsyth Reg *r1;
13874a4d8c2SCharles.Forsyth
13974a4d8c2SCharles.Forsyth r1 = r->s1;
14074a4d8c2SCharles.Forsyth if(r1 == R) {
14174a4d8c2SCharles.Forsyth r1 = r->s2;
14274a4d8c2SCharles.Forsyth if(r1 == R)
14374a4d8c2SCharles.Forsyth return R;
14474a4d8c2SCharles.Forsyth } else
14574a4d8c2SCharles.Forsyth if(r->s2 != R)
14674a4d8c2SCharles.Forsyth return R;
14774a4d8c2SCharles.Forsyth return r1;
14874a4d8c2SCharles.Forsyth }
14974a4d8c2SCharles.Forsyth
15074a4d8c2SCharles.Forsyth int
regzer(Adr * a)15174a4d8c2SCharles.Forsyth regzer(Adr *a)
15274a4d8c2SCharles.Forsyth {
15374a4d8c2SCharles.Forsyth
15474a4d8c2SCharles.Forsyth if(a->type == D_CONST)
15574a4d8c2SCharles.Forsyth if(a->sym == S)
15674a4d8c2SCharles.Forsyth if(a->offset == 0)
15774a4d8c2SCharles.Forsyth return 1;
15874a4d8c2SCharles.Forsyth if(a->type == D_REG)
15974a4d8c2SCharles.Forsyth if(a->reg == 0)
16074a4d8c2SCharles.Forsyth return 1;
16174a4d8c2SCharles.Forsyth return 0;
16274a4d8c2SCharles.Forsyth }
16374a4d8c2SCharles.Forsyth
16474a4d8c2SCharles.Forsyth int
regtyp(Adr * a)16574a4d8c2SCharles.Forsyth regtyp(Adr *a)
16674a4d8c2SCharles.Forsyth {
16774a4d8c2SCharles.Forsyth
16874a4d8c2SCharles.Forsyth if(a->type == D_REG) {
16974a4d8c2SCharles.Forsyth if(a->reg != 0)
17074a4d8c2SCharles.Forsyth return 1;
17174a4d8c2SCharles.Forsyth return 0;
17274a4d8c2SCharles.Forsyth }
17374a4d8c2SCharles.Forsyth if(a->type == D_FREG)
17474a4d8c2SCharles.Forsyth return 1;
17574a4d8c2SCharles.Forsyth return 0;
17674a4d8c2SCharles.Forsyth }
17774a4d8c2SCharles.Forsyth
17874a4d8c2SCharles.Forsyth /*
17974a4d8c2SCharles.Forsyth * the idea is to substitute
18074a4d8c2SCharles.Forsyth * one register for another
18174a4d8c2SCharles.Forsyth * from one MOV to another
18274a4d8c2SCharles.Forsyth * MOV a, R0
18374a4d8c2SCharles.Forsyth * ADD b, R0 / no use of R1
18474a4d8c2SCharles.Forsyth * MOV R0, R1
18574a4d8c2SCharles.Forsyth * would be converted to
18674a4d8c2SCharles.Forsyth * MOV a, R1
18774a4d8c2SCharles.Forsyth * ADD b, R1
18874a4d8c2SCharles.Forsyth * MOV R1, R0
18974a4d8c2SCharles.Forsyth * hopefully, then the former or latter MOV
19074a4d8c2SCharles.Forsyth * will be eliminated by copy propagation.
19174a4d8c2SCharles.Forsyth */
19274a4d8c2SCharles.Forsyth int
subprop(Reg * r0)19374a4d8c2SCharles.Forsyth subprop(Reg *r0)
19474a4d8c2SCharles.Forsyth {
19574a4d8c2SCharles.Forsyth Prog *p;
19674a4d8c2SCharles.Forsyth Adr *v1, *v2;
19774a4d8c2SCharles.Forsyth Reg *r;
19874a4d8c2SCharles.Forsyth int t;
19974a4d8c2SCharles.Forsyth
20074a4d8c2SCharles.Forsyth p = r0->prog;
20174a4d8c2SCharles.Forsyth v1 = &p->from;
20274a4d8c2SCharles.Forsyth if(!regtyp(v1))
20374a4d8c2SCharles.Forsyth return 0;
20474a4d8c2SCharles.Forsyth v2 = &p->to;
20574a4d8c2SCharles.Forsyth if(!regtyp(v2))
20674a4d8c2SCharles.Forsyth return 0;
20774a4d8c2SCharles.Forsyth for(r=uniqp(r0); r!=R; r=uniqp(r)) {
20874a4d8c2SCharles.Forsyth if(uniqs(r) == R)
20974a4d8c2SCharles.Forsyth break;
21074a4d8c2SCharles.Forsyth p = r->prog;
21174a4d8c2SCharles.Forsyth switch(p->as) {
21274a4d8c2SCharles.Forsyth case AJAL:
21374a4d8c2SCharles.Forsyth return 0;
21474a4d8c2SCharles.Forsyth
21574a4d8c2SCharles.Forsyth case ASGT:
21674a4d8c2SCharles.Forsyth case ASGTU:
21774a4d8c2SCharles.Forsyth
21874a4d8c2SCharles.Forsyth case AADD:
21974a4d8c2SCharles.Forsyth case AADDU:
22074a4d8c2SCharles.Forsyth case ASUB:
22174a4d8c2SCharles.Forsyth case ASUBU:
22274a4d8c2SCharles.Forsyth case ASLL:
22374a4d8c2SCharles.Forsyth case ASRL:
22474a4d8c2SCharles.Forsyth case ASRA:
22574a4d8c2SCharles.Forsyth case AOR:
22674a4d8c2SCharles.Forsyth case AAND:
22774a4d8c2SCharles.Forsyth case AXOR:
22874a4d8c2SCharles.Forsyth case AMUL:
22974a4d8c2SCharles.Forsyth case AMULU:
23074a4d8c2SCharles.Forsyth case ADIV:
23174a4d8c2SCharles.Forsyth case ADIVU:
23274a4d8c2SCharles.Forsyth
23374a4d8c2SCharles.Forsyth case AADDD:
23474a4d8c2SCharles.Forsyth case AADDF:
23574a4d8c2SCharles.Forsyth case ASUBD:
23674a4d8c2SCharles.Forsyth case ASUBF:
23774a4d8c2SCharles.Forsyth case AMULD:
23874a4d8c2SCharles.Forsyth case AMULF:
23974a4d8c2SCharles.Forsyth case ADIVD:
24074a4d8c2SCharles.Forsyth case ADIVF:
24174a4d8c2SCharles.Forsyth if(p->to.type == v1->type)
24274a4d8c2SCharles.Forsyth if(p->to.reg == v1->reg) {
24374a4d8c2SCharles.Forsyth if(p->reg == NREG)
24474a4d8c2SCharles.Forsyth p->reg = p->to.reg;
24574a4d8c2SCharles.Forsyth goto gotit;
24674a4d8c2SCharles.Forsyth }
24774a4d8c2SCharles.Forsyth break;
24874a4d8c2SCharles.Forsyth
24974a4d8c2SCharles.Forsyth case AMOVF:
25074a4d8c2SCharles.Forsyth case AMOVD:
25174a4d8c2SCharles.Forsyth case AMOVW:
25274a4d8c2SCharles.Forsyth if(p->to.type == v1->type)
25374a4d8c2SCharles.Forsyth if(p->to.reg == v1->reg)
25474a4d8c2SCharles.Forsyth goto gotit;
25574a4d8c2SCharles.Forsyth break;
25674a4d8c2SCharles.Forsyth }
25774a4d8c2SCharles.Forsyth if(copyau(&p->from, v2) ||
25874a4d8c2SCharles.Forsyth copyau1(p, v2) ||
25974a4d8c2SCharles.Forsyth copyau(&p->to, v2))
26074a4d8c2SCharles.Forsyth break;
26174a4d8c2SCharles.Forsyth if(copysub(&p->from, v1, v2, 0) ||
26274a4d8c2SCharles.Forsyth copysub1(p, v1, v2, 0) ||
26374a4d8c2SCharles.Forsyth copysub(&p->to, v1, v2, 0))
26474a4d8c2SCharles.Forsyth break;
26574a4d8c2SCharles.Forsyth }
26674a4d8c2SCharles.Forsyth return 0;
26774a4d8c2SCharles.Forsyth
26874a4d8c2SCharles.Forsyth gotit:
26974a4d8c2SCharles.Forsyth copysub(&p->to, v1, v2, 1);
27074a4d8c2SCharles.Forsyth if(debug['P']) {
27174a4d8c2SCharles.Forsyth print("gotit: %D->%D\n%P", v1, v2, r->prog);
27274a4d8c2SCharles.Forsyth if(p->from.type == v2->type)
27374a4d8c2SCharles.Forsyth print(" excise");
27474a4d8c2SCharles.Forsyth print("\n");
27574a4d8c2SCharles.Forsyth }
27674a4d8c2SCharles.Forsyth for(r=uniqs(r); r!=r0; r=uniqs(r)) {
27774a4d8c2SCharles.Forsyth p = r->prog;
27874a4d8c2SCharles.Forsyth copysub(&p->from, v1, v2, 1);
27974a4d8c2SCharles.Forsyth copysub1(p, v1, v2, 1);
28074a4d8c2SCharles.Forsyth copysub(&p->to, v1, v2, 1);
28174a4d8c2SCharles.Forsyth if(debug['P'])
28274a4d8c2SCharles.Forsyth print("%P\n", r->prog);
28374a4d8c2SCharles.Forsyth }
28474a4d8c2SCharles.Forsyth t = v1->reg;
28574a4d8c2SCharles.Forsyth v1->reg = v2->reg;
28674a4d8c2SCharles.Forsyth v2->reg = t;
28774a4d8c2SCharles.Forsyth if(debug['P'])
28874a4d8c2SCharles.Forsyth print("%P last\n", r->prog);
28974a4d8c2SCharles.Forsyth return 1;
29074a4d8c2SCharles.Forsyth }
29174a4d8c2SCharles.Forsyth
29274a4d8c2SCharles.Forsyth /*
29374a4d8c2SCharles.Forsyth * The idea is to remove redundant copies.
29474a4d8c2SCharles.Forsyth * v1->v2 F=0
29574a4d8c2SCharles.Forsyth * (use v2 s/v2/v1/)*
29674a4d8c2SCharles.Forsyth * set v1 F=1
29774a4d8c2SCharles.Forsyth * use v2 return fail
29874a4d8c2SCharles.Forsyth * -----------------
29974a4d8c2SCharles.Forsyth * v1->v2 F=0
30074a4d8c2SCharles.Forsyth * (use v2 s/v2/v1/)*
30174a4d8c2SCharles.Forsyth * set v1 F=1
30274a4d8c2SCharles.Forsyth * set v2 return success
30374a4d8c2SCharles.Forsyth */
30474a4d8c2SCharles.Forsyth int
copyprop(Reg * r0)30574a4d8c2SCharles.Forsyth copyprop(Reg *r0)
30674a4d8c2SCharles.Forsyth {
30774a4d8c2SCharles.Forsyth Prog *p;
30874a4d8c2SCharles.Forsyth Adr *v1, *v2;
30974a4d8c2SCharles.Forsyth Reg *r;
31074a4d8c2SCharles.Forsyth
31174a4d8c2SCharles.Forsyth p = r0->prog;
31274a4d8c2SCharles.Forsyth v1 = &p->from;
31374a4d8c2SCharles.Forsyth v2 = &p->to;
31474a4d8c2SCharles.Forsyth if(copyas(v1, v2))
31574a4d8c2SCharles.Forsyth return 1;
31674a4d8c2SCharles.Forsyth for(r=firstr; r!=R; r=r->link)
31774a4d8c2SCharles.Forsyth r->active = 0;
31874a4d8c2SCharles.Forsyth return copy1(v1, v2, r0->s1, 0);
31974a4d8c2SCharles.Forsyth }
32074a4d8c2SCharles.Forsyth
32174a4d8c2SCharles.Forsyth int
copy1(Adr * v1,Adr * v2,Reg * r,int f)32274a4d8c2SCharles.Forsyth copy1(Adr *v1, Adr *v2, Reg *r, int f)
32374a4d8c2SCharles.Forsyth {
32474a4d8c2SCharles.Forsyth int t;
32574a4d8c2SCharles.Forsyth Prog *p;
32674a4d8c2SCharles.Forsyth
32774a4d8c2SCharles.Forsyth if(r->active) {
32874a4d8c2SCharles.Forsyth if(debug['P'])
32974a4d8c2SCharles.Forsyth print("act set; return 1\n");
33074a4d8c2SCharles.Forsyth return 1;
33174a4d8c2SCharles.Forsyth }
33274a4d8c2SCharles.Forsyth r->active = 1;
33374a4d8c2SCharles.Forsyth if(debug['P'])
33474a4d8c2SCharles.Forsyth print("copy %D->%D f=%d\n", v1, v2, f);
33574a4d8c2SCharles.Forsyth for(; r != R; r = r->s1) {
33674a4d8c2SCharles.Forsyth p = r->prog;
33774a4d8c2SCharles.Forsyth if(debug['P'])
33874a4d8c2SCharles.Forsyth print("%P", p);
33974a4d8c2SCharles.Forsyth if(!f && uniqp(r) == R) {
34074a4d8c2SCharles.Forsyth f = 1;
34174a4d8c2SCharles.Forsyth if(debug['P'])
34274a4d8c2SCharles.Forsyth print("; merge; f=%d", f);
34374a4d8c2SCharles.Forsyth }
34474a4d8c2SCharles.Forsyth t = copyu(p, v2, A);
34574a4d8c2SCharles.Forsyth switch(t) {
34674a4d8c2SCharles.Forsyth case 2: /* rar, cant split */
34774a4d8c2SCharles.Forsyth if(debug['P'])
34874a4d8c2SCharles.Forsyth print("; %Drar; return 0\n", v2);
34974a4d8c2SCharles.Forsyth return 0;
35074a4d8c2SCharles.Forsyth
35174a4d8c2SCharles.Forsyth case 3: /* set */
35274a4d8c2SCharles.Forsyth if(debug['P'])
35374a4d8c2SCharles.Forsyth print("; %Dset; return 1\n", v2);
35474a4d8c2SCharles.Forsyth return 1;
35574a4d8c2SCharles.Forsyth
35674a4d8c2SCharles.Forsyth case 1: /* used, substitute */
35774a4d8c2SCharles.Forsyth case 4: /* use and set */
35874a4d8c2SCharles.Forsyth if(f) {
35974a4d8c2SCharles.Forsyth if(!debug['P'])
36074a4d8c2SCharles.Forsyth return 0;
36174a4d8c2SCharles.Forsyth if(t == 4)
36274a4d8c2SCharles.Forsyth print("; %Dused+set and f=%d; return 0\n", v2, f);
36374a4d8c2SCharles.Forsyth else
36474a4d8c2SCharles.Forsyth print("; %Dused and f=%d; return 0\n", v2, f);
36574a4d8c2SCharles.Forsyth return 0;
36674a4d8c2SCharles.Forsyth }
36774a4d8c2SCharles.Forsyth if(copyu(p, v2, v1)) {
36874a4d8c2SCharles.Forsyth if(debug['P'])
36974a4d8c2SCharles.Forsyth print("; sub fail; return 0\n");
37074a4d8c2SCharles.Forsyth return 0;
37174a4d8c2SCharles.Forsyth }
37274a4d8c2SCharles.Forsyth if(debug['P'])
37374a4d8c2SCharles.Forsyth print("; sub%D/%D", v2, v1);
37474a4d8c2SCharles.Forsyth if(t == 4) {
37574a4d8c2SCharles.Forsyth if(debug['P'])
37674a4d8c2SCharles.Forsyth print("; %Dused+set; return 1\n", v2);
37774a4d8c2SCharles.Forsyth return 1;
37874a4d8c2SCharles.Forsyth }
37974a4d8c2SCharles.Forsyth break;
38074a4d8c2SCharles.Forsyth }
38174a4d8c2SCharles.Forsyth if(!f) {
38274a4d8c2SCharles.Forsyth t = copyu(p, v1, A);
38374a4d8c2SCharles.Forsyth if(!f && (t == 2 || t == 3 || t == 4)) {
38474a4d8c2SCharles.Forsyth f = 1;
38574a4d8c2SCharles.Forsyth if(debug['P'])
38674a4d8c2SCharles.Forsyth print("; %Dset and !f; f=%d", v1, f);
38774a4d8c2SCharles.Forsyth }
38874a4d8c2SCharles.Forsyth }
38974a4d8c2SCharles.Forsyth if(debug['P'])
39074a4d8c2SCharles.Forsyth print("\n");
39174a4d8c2SCharles.Forsyth if(r->s2)
39274a4d8c2SCharles.Forsyth if(!copy1(v1, v2, r->s2, f))
39374a4d8c2SCharles.Forsyth return 0;
39474a4d8c2SCharles.Forsyth }
39574a4d8c2SCharles.Forsyth return 1;
39674a4d8c2SCharles.Forsyth }
39774a4d8c2SCharles.Forsyth
39874a4d8c2SCharles.Forsyth /*
39974a4d8c2SCharles.Forsyth * return
40074a4d8c2SCharles.Forsyth * 1 if v only used (and substitute),
40174a4d8c2SCharles.Forsyth * 2 if read-alter-rewrite
40274a4d8c2SCharles.Forsyth * 3 if set
40374a4d8c2SCharles.Forsyth * 4 if set and used
40474a4d8c2SCharles.Forsyth * 0 otherwise (not touched)
40574a4d8c2SCharles.Forsyth */
4066e425a9dSCharles.Forsyth int
copyu(Prog * p,Adr * v,Adr * s)40774a4d8c2SCharles.Forsyth copyu(Prog *p, Adr *v, Adr *s)
40874a4d8c2SCharles.Forsyth {
40974a4d8c2SCharles.Forsyth
41074a4d8c2SCharles.Forsyth switch(p->as) {
41174a4d8c2SCharles.Forsyth
41274a4d8c2SCharles.Forsyth default:
41374a4d8c2SCharles.Forsyth if(debug['P'])
4146e425a9dSCharles.Forsyth print(" (?)");
41574a4d8c2SCharles.Forsyth return 2;
41674a4d8c2SCharles.Forsyth
41774a4d8c2SCharles.Forsyth
41874a4d8c2SCharles.Forsyth case ANOP: /* read, write */
41974a4d8c2SCharles.Forsyth case AMOVW:
42074a4d8c2SCharles.Forsyth case AMOVF:
42174a4d8c2SCharles.Forsyth case AMOVD:
42274a4d8c2SCharles.Forsyth case AMOVH:
42374a4d8c2SCharles.Forsyth case AMOVHU:
42474a4d8c2SCharles.Forsyth case AMOVB:
42574a4d8c2SCharles.Forsyth case AMOVBU:
42674a4d8c2SCharles.Forsyth case AMOVDW:
42774a4d8c2SCharles.Forsyth case AMOVWD:
42874a4d8c2SCharles.Forsyth case AMOVFD:
42974a4d8c2SCharles.Forsyth case AMOVDF:
43074a4d8c2SCharles.Forsyth if(s != A) {
43174a4d8c2SCharles.Forsyth if(copysub(&p->from, v, s, 1))
43274a4d8c2SCharles.Forsyth return 1;
43374a4d8c2SCharles.Forsyth if(!copyas(&p->to, v))
43474a4d8c2SCharles.Forsyth if(copysub(&p->to, v, s, 1))
43574a4d8c2SCharles.Forsyth return 1;
43674a4d8c2SCharles.Forsyth return 0;
43774a4d8c2SCharles.Forsyth }
43874a4d8c2SCharles.Forsyth if(copyas(&p->to, v)) {
43974a4d8c2SCharles.Forsyth if(copyau(&p->from, v))
44074a4d8c2SCharles.Forsyth return 4;
44174a4d8c2SCharles.Forsyth return 3;
44274a4d8c2SCharles.Forsyth }
44374a4d8c2SCharles.Forsyth if(copyau(&p->from, v))
44474a4d8c2SCharles.Forsyth return 1;
44574a4d8c2SCharles.Forsyth if(copyau(&p->to, v))
44674a4d8c2SCharles.Forsyth return 1;
44774a4d8c2SCharles.Forsyth return 0;
44874a4d8c2SCharles.Forsyth
44974a4d8c2SCharles.Forsyth case ASGT: /* read, read, write */
45074a4d8c2SCharles.Forsyth case ASGTU:
45174a4d8c2SCharles.Forsyth
45274a4d8c2SCharles.Forsyth case AADD:
45374a4d8c2SCharles.Forsyth case AADDU:
45474a4d8c2SCharles.Forsyth case ASUB:
45574a4d8c2SCharles.Forsyth case ASUBU:
45674a4d8c2SCharles.Forsyth case ASLL:
45774a4d8c2SCharles.Forsyth case ASRL:
45874a4d8c2SCharles.Forsyth case ASRA:
45974a4d8c2SCharles.Forsyth case AOR:
46074a4d8c2SCharles.Forsyth case ANOR:
46174a4d8c2SCharles.Forsyth case AAND:
46274a4d8c2SCharles.Forsyth case AXOR:
46374a4d8c2SCharles.Forsyth case AMUL:
46474a4d8c2SCharles.Forsyth case AMULU:
46574a4d8c2SCharles.Forsyth case ADIV:
46674a4d8c2SCharles.Forsyth case ADIVU:
46774a4d8c2SCharles.Forsyth
46874a4d8c2SCharles.Forsyth case AADDF:
46974a4d8c2SCharles.Forsyth case AADDD:
47074a4d8c2SCharles.Forsyth case ASUBF:
47174a4d8c2SCharles.Forsyth case ASUBD:
47274a4d8c2SCharles.Forsyth case AMULF:
47374a4d8c2SCharles.Forsyth case AMULD:
47474a4d8c2SCharles.Forsyth case ADIVF:
47574a4d8c2SCharles.Forsyth case ADIVD:
47674a4d8c2SCharles.Forsyth if(s != A) {
47774a4d8c2SCharles.Forsyth if(copysub(&p->from, v, s, 1))
47874a4d8c2SCharles.Forsyth return 1;
47974a4d8c2SCharles.Forsyth if(copysub1(p, v, s, 1))
48074a4d8c2SCharles.Forsyth return 1;
48174a4d8c2SCharles.Forsyth if(!copyas(&p->to, v))
48274a4d8c2SCharles.Forsyth if(copysub(&p->to, v, s, 1))
48374a4d8c2SCharles.Forsyth return 1;
48474a4d8c2SCharles.Forsyth return 0;
48574a4d8c2SCharles.Forsyth }
48674a4d8c2SCharles.Forsyth if(copyas(&p->to, v)) {
48774a4d8c2SCharles.Forsyth if(p->reg == NREG)
48874a4d8c2SCharles.Forsyth p->reg = p->to.reg;
48974a4d8c2SCharles.Forsyth if(copyau(&p->from, v))
49074a4d8c2SCharles.Forsyth return 4;
49174a4d8c2SCharles.Forsyth if(copyau1(p, v))
49274a4d8c2SCharles.Forsyth return 4;
49374a4d8c2SCharles.Forsyth return 3;
49474a4d8c2SCharles.Forsyth }
49574a4d8c2SCharles.Forsyth if(copyau(&p->from, v))
49674a4d8c2SCharles.Forsyth return 1;
49774a4d8c2SCharles.Forsyth if(copyau1(p, v))
49874a4d8c2SCharles.Forsyth return 1;
49974a4d8c2SCharles.Forsyth if(copyau(&p->to, v))
50074a4d8c2SCharles.Forsyth return 1;
50174a4d8c2SCharles.Forsyth return 0;
50274a4d8c2SCharles.Forsyth
50374a4d8c2SCharles.Forsyth case ABEQ: /* read, read */
50474a4d8c2SCharles.Forsyth case ABNE:
50574a4d8c2SCharles.Forsyth case ABGTZ:
50674a4d8c2SCharles.Forsyth case ABGEZ:
50774a4d8c2SCharles.Forsyth case ABLTZ:
50874a4d8c2SCharles.Forsyth case ABLEZ:
50974a4d8c2SCharles.Forsyth
51074a4d8c2SCharles.Forsyth case ACMPEQD:
51174a4d8c2SCharles.Forsyth case ACMPEQF:
51274a4d8c2SCharles.Forsyth case ACMPGED:
51374a4d8c2SCharles.Forsyth case ACMPGEF:
51474a4d8c2SCharles.Forsyth case ACMPGTD:
51574a4d8c2SCharles.Forsyth case ACMPGTF:
51674a4d8c2SCharles.Forsyth case ABFPF:
51774a4d8c2SCharles.Forsyth case ABFPT:
51874a4d8c2SCharles.Forsyth if(s != A) {
51974a4d8c2SCharles.Forsyth if(copysub(&p->from, v, s, 1))
52074a4d8c2SCharles.Forsyth return 1;
52174a4d8c2SCharles.Forsyth return copysub1(p, v, s, 1);
52274a4d8c2SCharles.Forsyth }
52374a4d8c2SCharles.Forsyth if(copyau(&p->from, v))
52474a4d8c2SCharles.Forsyth return 1;
52574a4d8c2SCharles.Forsyth if(copyau1(p, v))
52674a4d8c2SCharles.Forsyth return 1;
52774a4d8c2SCharles.Forsyth return 0;
52874a4d8c2SCharles.Forsyth
52974a4d8c2SCharles.Forsyth case AJMP: /* funny */
53074a4d8c2SCharles.Forsyth if(s != A) {
53174a4d8c2SCharles.Forsyth if(copysub(&p->to, v, s, 1))
53274a4d8c2SCharles.Forsyth return 1;
53374a4d8c2SCharles.Forsyth return 0;
53474a4d8c2SCharles.Forsyth }
53574a4d8c2SCharles.Forsyth if(copyau(&p->to, v))
53674a4d8c2SCharles.Forsyth return 1;
53774a4d8c2SCharles.Forsyth return 0;
53874a4d8c2SCharles.Forsyth
53974a4d8c2SCharles.Forsyth case ARET: /* funny */
54074a4d8c2SCharles.Forsyth if(v->type == D_REG)
54174a4d8c2SCharles.Forsyth if(v->reg == REGRET)
54274a4d8c2SCharles.Forsyth return 2;
54374a4d8c2SCharles.Forsyth if(v->type == D_FREG)
54474a4d8c2SCharles.Forsyth if(v->reg == FREGRET)
54574a4d8c2SCharles.Forsyth return 2;
54674a4d8c2SCharles.Forsyth
54774a4d8c2SCharles.Forsyth case AJAL: /* funny */
54874a4d8c2SCharles.Forsyth if(v->type == D_REG) {
54974a4d8c2SCharles.Forsyth if(v->reg <= REGEXT && v->reg > exregoffset)
55074a4d8c2SCharles.Forsyth return 2;
55174a4d8c2SCharles.Forsyth if(REGARG && v->reg == REGARG)
55274a4d8c2SCharles.Forsyth return 2;
55374a4d8c2SCharles.Forsyth }
55474a4d8c2SCharles.Forsyth if(v->type == D_FREG)
55574a4d8c2SCharles.Forsyth if(v->reg <= FREGEXT && v->reg > exfregoffset)
55674a4d8c2SCharles.Forsyth return 2;
55774a4d8c2SCharles.Forsyth
55874a4d8c2SCharles.Forsyth if(s != A) {
55974a4d8c2SCharles.Forsyth if(copysub(&p->to, v, s, 1))
56074a4d8c2SCharles.Forsyth return 1;
56174a4d8c2SCharles.Forsyth return 0;
56274a4d8c2SCharles.Forsyth }
56374a4d8c2SCharles.Forsyth if(copyau(&p->to, v))
56474a4d8c2SCharles.Forsyth return 4;
56574a4d8c2SCharles.Forsyth return 3;
56674a4d8c2SCharles.Forsyth
56774a4d8c2SCharles.Forsyth case ATEXT: /* funny */
56874a4d8c2SCharles.Forsyth if(v->type == D_REG)
56974a4d8c2SCharles.Forsyth if(v->reg == REGARG)
57074a4d8c2SCharles.Forsyth return 3;
57174a4d8c2SCharles.Forsyth return 0;
57274a4d8c2SCharles.Forsyth }
573*d67b7dadSforsyth /* not reached */
57474a4d8c2SCharles.Forsyth }
57574a4d8c2SCharles.Forsyth
57674a4d8c2SCharles.Forsyth int
a2type(Prog * p)57774a4d8c2SCharles.Forsyth a2type(Prog *p)
57874a4d8c2SCharles.Forsyth {
57974a4d8c2SCharles.Forsyth
58074a4d8c2SCharles.Forsyth switch(p->as) {
58174a4d8c2SCharles.Forsyth case ABEQ:
58274a4d8c2SCharles.Forsyth case ABNE:
58374a4d8c2SCharles.Forsyth case ABGTZ:
58474a4d8c2SCharles.Forsyth case ABGEZ:
58574a4d8c2SCharles.Forsyth case ABLTZ:
58674a4d8c2SCharles.Forsyth case ABLEZ:
58774a4d8c2SCharles.Forsyth
58874a4d8c2SCharles.Forsyth case ASGT:
58974a4d8c2SCharles.Forsyth case ASGTU:
59074a4d8c2SCharles.Forsyth
59174a4d8c2SCharles.Forsyth case AADD:
59274a4d8c2SCharles.Forsyth case AADDU:
59374a4d8c2SCharles.Forsyth case ASUB:
59474a4d8c2SCharles.Forsyth case ASUBU:
59574a4d8c2SCharles.Forsyth case ASLL:
59674a4d8c2SCharles.Forsyth case ASRL:
59774a4d8c2SCharles.Forsyth case ASRA:
59874a4d8c2SCharles.Forsyth case AOR:
59974a4d8c2SCharles.Forsyth case AAND:
60074a4d8c2SCharles.Forsyth case AXOR:
60174a4d8c2SCharles.Forsyth case AMUL:
60274a4d8c2SCharles.Forsyth case AMULU:
60374a4d8c2SCharles.Forsyth case ADIV:
60474a4d8c2SCharles.Forsyth case ADIVU:
60574a4d8c2SCharles.Forsyth return D_REG;
60674a4d8c2SCharles.Forsyth
60774a4d8c2SCharles.Forsyth case ACMPEQD:
60874a4d8c2SCharles.Forsyth case ACMPEQF:
60974a4d8c2SCharles.Forsyth case ACMPGED:
61074a4d8c2SCharles.Forsyth case ACMPGEF:
61174a4d8c2SCharles.Forsyth case ACMPGTD:
61274a4d8c2SCharles.Forsyth case ACMPGTF:
61374a4d8c2SCharles.Forsyth
61474a4d8c2SCharles.Forsyth case AADDF:
61574a4d8c2SCharles.Forsyth case AADDD:
61674a4d8c2SCharles.Forsyth case ASUBF:
61774a4d8c2SCharles.Forsyth case ASUBD:
61874a4d8c2SCharles.Forsyth case AMULF:
61974a4d8c2SCharles.Forsyth case AMULD:
62074a4d8c2SCharles.Forsyth case ADIVF:
62174a4d8c2SCharles.Forsyth case ADIVD:
62274a4d8c2SCharles.Forsyth return D_FREG;
62374a4d8c2SCharles.Forsyth }
62474a4d8c2SCharles.Forsyth return D_NONE;
62574a4d8c2SCharles.Forsyth }
62674a4d8c2SCharles.Forsyth
62774a4d8c2SCharles.Forsyth /*
62874a4d8c2SCharles.Forsyth * direct reference,
62974a4d8c2SCharles.Forsyth * could be set/use depending on
63074a4d8c2SCharles.Forsyth * semantics
63174a4d8c2SCharles.Forsyth */
63274a4d8c2SCharles.Forsyth int
copyas(Adr * a,Adr * v)63374a4d8c2SCharles.Forsyth copyas(Adr *a, Adr *v)
63474a4d8c2SCharles.Forsyth {
63574a4d8c2SCharles.Forsyth
63674a4d8c2SCharles.Forsyth if(regtyp(v))
63774a4d8c2SCharles.Forsyth if(a->type == v->type)
63874a4d8c2SCharles.Forsyth if(a->reg == v->reg)
63974a4d8c2SCharles.Forsyth return 1;
64074a4d8c2SCharles.Forsyth return 0;
64174a4d8c2SCharles.Forsyth }
64274a4d8c2SCharles.Forsyth
64374a4d8c2SCharles.Forsyth /*
64474a4d8c2SCharles.Forsyth * either direct or indirect
64574a4d8c2SCharles.Forsyth */
64674a4d8c2SCharles.Forsyth int
copyau(Adr * a,Adr * v)64774a4d8c2SCharles.Forsyth copyau(Adr *a, Adr *v)
64874a4d8c2SCharles.Forsyth {
64974a4d8c2SCharles.Forsyth
65074a4d8c2SCharles.Forsyth if(copyas(a, v))
65174a4d8c2SCharles.Forsyth return 1;
65274a4d8c2SCharles.Forsyth if(v->type == D_REG)
65374a4d8c2SCharles.Forsyth if(a->type == D_OREG)
65474a4d8c2SCharles.Forsyth if(v->reg == a->reg)
65574a4d8c2SCharles.Forsyth return 1;
65674a4d8c2SCharles.Forsyth return 0;
65774a4d8c2SCharles.Forsyth }
65874a4d8c2SCharles.Forsyth
65974a4d8c2SCharles.Forsyth int
copyau1(Prog * p,Adr * v)66074a4d8c2SCharles.Forsyth copyau1(Prog *p, Adr *v)
66174a4d8c2SCharles.Forsyth {
66274a4d8c2SCharles.Forsyth
66374a4d8c2SCharles.Forsyth if(regtyp(v))
66474a4d8c2SCharles.Forsyth if(p->from.type == v->type || p->to.type == v->type)
66574a4d8c2SCharles.Forsyth if(p->reg == v->reg) {
66674a4d8c2SCharles.Forsyth if(a2type(p) != v->type)
66774a4d8c2SCharles.Forsyth print("botch a2type %P\n", p);
66874a4d8c2SCharles.Forsyth return 1;
66974a4d8c2SCharles.Forsyth }
67074a4d8c2SCharles.Forsyth return 0;
67174a4d8c2SCharles.Forsyth }
67274a4d8c2SCharles.Forsyth
67374a4d8c2SCharles.Forsyth /*
67474a4d8c2SCharles.Forsyth * substitute s for v in a
67574a4d8c2SCharles.Forsyth * return failure to substitute
67674a4d8c2SCharles.Forsyth */
67774a4d8c2SCharles.Forsyth int
copysub(Adr * a,Adr * v,Adr * s,int f)67874a4d8c2SCharles.Forsyth copysub(Adr *a, Adr *v, Adr *s, int f)
67974a4d8c2SCharles.Forsyth {
68074a4d8c2SCharles.Forsyth
68174a4d8c2SCharles.Forsyth if(f)
68274a4d8c2SCharles.Forsyth if(copyau(a, v))
68374a4d8c2SCharles.Forsyth a->reg = s->reg;
68474a4d8c2SCharles.Forsyth return 0;
68574a4d8c2SCharles.Forsyth }
68674a4d8c2SCharles.Forsyth
68774a4d8c2SCharles.Forsyth int
copysub1(Prog * p1,Adr * v,Adr * s,int f)68874a4d8c2SCharles.Forsyth copysub1(Prog *p1, Adr *v, Adr *s, int f)
68974a4d8c2SCharles.Forsyth {
69074a4d8c2SCharles.Forsyth
69174a4d8c2SCharles.Forsyth if(f)
69274a4d8c2SCharles.Forsyth if(copyau1(p1, v))
69374a4d8c2SCharles.Forsyth p1->reg = s->reg;
69474a4d8c2SCharles.Forsyth return 0;
69574a4d8c2SCharles.Forsyth }
696