174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth
374a4d8c2SCharles.Forsyth void
noretval(int n)474a4d8c2SCharles.Forsyth noretval(int n)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth
774a4d8c2SCharles.Forsyth if(n & 1) {
874a4d8c2SCharles.Forsyth gins(ANOP, Z, Z);
974a4d8c2SCharles.Forsyth p->to.type = REGRET;
1074a4d8c2SCharles.Forsyth }
1174a4d8c2SCharles.Forsyth if(n & 2) {
1274a4d8c2SCharles.Forsyth gins(ANOP, Z, Z);
1374a4d8c2SCharles.Forsyth p->to.type = FREGRET;
1474a4d8c2SCharles.Forsyth }
15c0927006Sforsyth if((n&3) == 3)
16c0927006Sforsyth if(thisfn && thisfn->link && typefd[thisfn->link->etype])
17c0927006Sforsyth gins(AFLDZ, Z, Z);
1874a4d8c2SCharles.Forsyth }
1974a4d8c2SCharles.Forsyth
2074a4d8c2SCharles.Forsyth /* welcome to commute */
2174a4d8c2SCharles.Forsyth static void
commute(Node * n)2274a4d8c2SCharles.Forsyth commute(Node *n)
2374a4d8c2SCharles.Forsyth {
2474a4d8c2SCharles.Forsyth Node *l, *r;
2574a4d8c2SCharles.Forsyth
2674a4d8c2SCharles.Forsyth l = n->left;
2774a4d8c2SCharles.Forsyth r = n->right;
2874a4d8c2SCharles.Forsyth if(r->complex > l->complex) {
2974a4d8c2SCharles.Forsyth n->left = r;
3074a4d8c2SCharles.Forsyth n->right = l;
3174a4d8c2SCharles.Forsyth }
3274a4d8c2SCharles.Forsyth }
3374a4d8c2SCharles.Forsyth
3474a4d8c2SCharles.Forsyth void
indexshift(Node * n)3574a4d8c2SCharles.Forsyth indexshift(Node *n)
3674a4d8c2SCharles.Forsyth {
3774a4d8c2SCharles.Forsyth int g;
3874a4d8c2SCharles.Forsyth
3974a4d8c2SCharles.Forsyth if(!typechlp[n->type->etype])
4074a4d8c2SCharles.Forsyth return;
4174a4d8c2SCharles.Forsyth simplifyshift(n);
4274a4d8c2SCharles.Forsyth if(n->op == OASHL && n->right->op == OCONST){
4374a4d8c2SCharles.Forsyth g = vconst(n->right);
4474a4d8c2SCharles.Forsyth if(g >= 0 && g < 4)
4574a4d8c2SCharles.Forsyth n->addable = 7;
4674a4d8c2SCharles.Forsyth }
4774a4d8c2SCharles.Forsyth }
4874a4d8c2SCharles.Forsyth
4974a4d8c2SCharles.Forsyth /*
5074a4d8c2SCharles.Forsyth * calculate addressability as follows
5174a4d8c2SCharles.Forsyth * NAME ==> 10/11 name+value(SB/SP)
5274a4d8c2SCharles.Forsyth * REGISTER ==> 12 register
5374a4d8c2SCharles.Forsyth * CONST ==> 20 $value
5474a4d8c2SCharles.Forsyth * *(20) ==> 21 value
5574a4d8c2SCharles.Forsyth * &(10) ==> 13 $name+value(SB)
5674a4d8c2SCharles.Forsyth * &(11) ==> 1 $name+value(SP)
5774a4d8c2SCharles.Forsyth * (13) + (20) ==> 13 fold constants
5874a4d8c2SCharles.Forsyth * (1) + (20) ==> 1 fold constants
5974a4d8c2SCharles.Forsyth * *(13) ==> 10 back to name
6074a4d8c2SCharles.Forsyth * *(1) ==> 11 back to name
6174a4d8c2SCharles.Forsyth *
6274a4d8c2SCharles.Forsyth * (20) * (X) ==> 7 multiplier in indexing
6374a4d8c2SCharles.Forsyth * (X,7) + (13,1) ==> 8 adder in indexing (addresses)
6474a4d8c2SCharles.Forsyth * (8) ==> &9(OINDEX) index, almost addressable
6574a4d8c2SCharles.Forsyth *
6674a4d8c2SCharles.Forsyth * calculate complexity (number of registers)
6774a4d8c2SCharles.Forsyth */
6874a4d8c2SCharles.Forsyth void
xcom(Node * n)6974a4d8c2SCharles.Forsyth xcom(Node *n)
7074a4d8c2SCharles.Forsyth {
7174a4d8c2SCharles.Forsyth Node *l, *r;
7274a4d8c2SCharles.Forsyth int g;
7374a4d8c2SCharles.Forsyth
7474a4d8c2SCharles.Forsyth if(n == Z)
7574a4d8c2SCharles.Forsyth return;
7674a4d8c2SCharles.Forsyth l = n->left;
7774a4d8c2SCharles.Forsyth r = n->right;
7874a4d8c2SCharles.Forsyth n->complex = 0;
7974a4d8c2SCharles.Forsyth n->addable = 0;
8074a4d8c2SCharles.Forsyth switch(n->op) {
8174a4d8c2SCharles.Forsyth case OCONST:
8274a4d8c2SCharles.Forsyth n->addable = 20;
8374a4d8c2SCharles.Forsyth break;
8474a4d8c2SCharles.Forsyth
8574a4d8c2SCharles.Forsyth case ONAME:
8674a4d8c2SCharles.Forsyth n->addable = 10;
8774a4d8c2SCharles.Forsyth if(n->class == CPARAM || n->class == CAUTO)
8874a4d8c2SCharles.Forsyth n->addable = 11;
8974a4d8c2SCharles.Forsyth break;
9074a4d8c2SCharles.Forsyth
91*45a20ab7Sforsyth case OEXREG:
92*45a20ab7Sforsyth n->addable = 12;
93*45a20ab7Sforsyth break;
94*45a20ab7Sforsyth
9574a4d8c2SCharles.Forsyth case OREGISTER:
9674a4d8c2SCharles.Forsyth n->addable = 12;
9774a4d8c2SCharles.Forsyth break;
9874a4d8c2SCharles.Forsyth
9974a4d8c2SCharles.Forsyth case OINDREG:
10074a4d8c2SCharles.Forsyth n->addable = 12;
10174a4d8c2SCharles.Forsyth break;
10274a4d8c2SCharles.Forsyth
10374a4d8c2SCharles.Forsyth case OADDR:
10474a4d8c2SCharles.Forsyth xcom(l);
10574a4d8c2SCharles.Forsyth if(l->addable == 10)
10674a4d8c2SCharles.Forsyth n->addable = 13;
10774a4d8c2SCharles.Forsyth else
10874a4d8c2SCharles.Forsyth if(l->addable == 11)
10974a4d8c2SCharles.Forsyth n->addable = 1;
11074a4d8c2SCharles.Forsyth break;
11174a4d8c2SCharles.Forsyth
11274a4d8c2SCharles.Forsyth case OADD:
11374a4d8c2SCharles.Forsyth xcom(l);
11474a4d8c2SCharles.Forsyth xcom(r);
11574a4d8c2SCharles.Forsyth if(n->type->etype != TIND)
11674a4d8c2SCharles.Forsyth break;
11774a4d8c2SCharles.Forsyth
11874a4d8c2SCharles.Forsyth switch(r->addable) {
11974a4d8c2SCharles.Forsyth case 20:
12074a4d8c2SCharles.Forsyth switch(l->addable) {
12174a4d8c2SCharles.Forsyth case 1:
12274a4d8c2SCharles.Forsyth case 13:
12374a4d8c2SCharles.Forsyth commadd:
12474a4d8c2SCharles.Forsyth l->type = n->type;
12574a4d8c2SCharles.Forsyth *n = *l;
12674a4d8c2SCharles.Forsyth l = new(0, Z, Z);
12774a4d8c2SCharles.Forsyth *l = *(n->left);
12874a4d8c2SCharles.Forsyth l->xoffset += r->vconst;
12974a4d8c2SCharles.Forsyth n->left = l;
13074a4d8c2SCharles.Forsyth r = n->right;
13174a4d8c2SCharles.Forsyth goto brk;
13274a4d8c2SCharles.Forsyth }
13374a4d8c2SCharles.Forsyth break;
13474a4d8c2SCharles.Forsyth
13574a4d8c2SCharles.Forsyth case 1:
13674a4d8c2SCharles.Forsyth case 13:
13774a4d8c2SCharles.Forsyth case 10:
13874a4d8c2SCharles.Forsyth case 11:
13974a4d8c2SCharles.Forsyth /* l is the base, r is the index */
14074a4d8c2SCharles.Forsyth if(l->addable != 20)
14174a4d8c2SCharles.Forsyth n->addable = 8;
14274a4d8c2SCharles.Forsyth break;
14374a4d8c2SCharles.Forsyth }
14474a4d8c2SCharles.Forsyth switch(l->addable) {
14574a4d8c2SCharles.Forsyth case 20:
14674a4d8c2SCharles.Forsyth switch(r->addable) {
14774a4d8c2SCharles.Forsyth case 13:
14874a4d8c2SCharles.Forsyth case 1:
14974a4d8c2SCharles.Forsyth r = n->left;
15074a4d8c2SCharles.Forsyth l = n->right;
15174a4d8c2SCharles.Forsyth n->left = l;
15274a4d8c2SCharles.Forsyth n->right = r;
15374a4d8c2SCharles.Forsyth goto commadd;
15474a4d8c2SCharles.Forsyth }
15574a4d8c2SCharles.Forsyth break;
15674a4d8c2SCharles.Forsyth
15774a4d8c2SCharles.Forsyth case 13:
15874a4d8c2SCharles.Forsyth case 1:
15974a4d8c2SCharles.Forsyth case 10:
16074a4d8c2SCharles.Forsyth case 11:
16174a4d8c2SCharles.Forsyth /* r is the base, l is the index */
16274a4d8c2SCharles.Forsyth if(r->addable != 20)
16374a4d8c2SCharles.Forsyth n->addable = 8;
16474a4d8c2SCharles.Forsyth break;
16574a4d8c2SCharles.Forsyth }
16674a4d8c2SCharles.Forsyth if(n->addable == 8 && !side(n)) {
16774a4d8c2SCharles.Forsyth indx(n);
16874a4d8c2SCharles.Forsyth l = new1(OINDEX, idx.basetree, idx.regtree);
16974a4d8c2SCharles.Forsyth l->scale = idx.scale;
17074a4d8c2SCharles.Forsyth l->addable = 9;
17174a4d8c2SCharles.Forsyth l->complex = l->right->complex;
17274a4d8c2SCharles.Forsyth l->type = l->left->type;
17374a4d8c2SCharles.Forsyth n->op = OADDR;
17474a4d8c2SCharles.Forsyth n->left = l;
17574a4d8c2SCharles.Forsyth n->right = Z;
17674a4d8c2SCharles.Forsyth n->addable = 8;
17774a4d8c2SCharles.Forsyth break;
17874a4d8c2SCharles.Forsyth }
17974a4d8c2SCharles.Forsyth break;
18074a4d8c2SCharles.Forsyth
18174a4d8c2SCharles.Forsyth case OINDEX:
18274a4d8c2SCharles.Forsyth xcom(l);
18374a4d8c2SCharles.Forsyth xcom(r);
18474a4d8c2SCharles.Forsyth n->addable = 9;
18574a4d8c2SCharles.Forsyth break;
18674a4d8c2SCharles.Forsyth
18774a4d8c2SCharles.Forsyth case OIND:
18874a4d8c2SCharles.Forsyth xcom(l);
18974a4d8c2SCharles.Forsyth if(l->op == OADDR) {
19074a4d8c2SCharles.Forsyth l = l->left;
19174a4d8c2SCharles.Forsyth l->type = n->type;
19274a4d8c2SCharles.Forsyth *n = *l;
19374a4d8c2SCharles.Forsyth return;
19474a4d8c2SCharles.Forsyth }
19574a4d8c2SCharles.Forsyth switch(l->addable) {
19674a4d8c2SCharles.Forsyth case 20:
19774a4d8c2SCharles.Forsyth n->addable = 21;
19874a4d8c2SCharles.Forsyth break;
19974a4d8c2SCharles.Forsyth case 1:
20074a4d8c2SCharles.Forsyth n->addable = 11;
20174a4d8c2SCharles.Forsyth break;
20274a4d8c2SCharles.Forsyth case 13:
20374a4d8c2SCharles.Forsyth n->addable = 10;
20474a4d8c2SCharles.Forsyth break;
20574a4d8c2SCharles.Forsyth }
20674a4d8c2SCharles.Forsyth break;
20774a4d8c2SCharles.Forsyth
20874a4d8c2SCharles.Forsyth case OASHL:
20974a4d8c2SCharles.Forsyth xcom(l);
21074a4d8c2SCharles.Forsyth xcom(r);
21174a4d8c2SCharles.Forsyth indexshift(n);
21274a4d8c2SCharles.Forsyth break;
21374a4d8c2SCharles.Forsyth
21474a4d8c2SCharles.Forsyth case OMUL:
21574a4d8c2SCharles.Forsyth case OLMUL:
21674a4d8c2SCharles.Forsyth xcom(l);
21774a4d8c2SCharles.Forsyth xcom(r);
21874a4d8c2SCharles.Forsyth g = vlog(l);
21974a4d8c2SCharles.Forsyth if(g >= 0) {
22074a4d8c2SCharles.Forsyth n->left = r;
22174a4d8c2SCharles.Forsyth n->right = l;
22274a4d8c2SCharles.Forsyth l = r;
22374a4d8c2SCharles.Forsyth r = n->right;
22474a4d8c2SCharles.Forsyth }
22574a4d8c2SCharles.Forsyth g = vlog(r);
22674a4d8c2SCharles.Forsyth if(g >= 0) {
22774a4d8c2SCharles.Forsyth n->op = OASHL;
22874a4d8c2SCharles.Forsyth r->vconst = g;
22974a4d8c2SCharles.Forsyth r->type = types[TINT];
23074a4d8c2SCharles.Forsyth indexshift(n);
23174a4d8c2SCharles.Forsyth break;
23274a4d8c2SCharles.Forsyth }
23374a4d8c2SCharles.Forsyth commute(n);
23474a4d8c2SCharles.Forsyth break;
23574a4d8c2SCharles.Forsyth
23674a4d8c2SCharles.Forsyth case OASLDIV:
23774a4d8c2SCharles.Forsyth xcom(l);
23874a4d8c2SCharles.Forsyth xcom(r);
23974a4d8c2SCharles.Forsyth g = vlog(r);
24074a4d8c2SCharles.Forsyth if(g >= 0) {
24174a4d8c2SCharles.Forsyth n->op = OASLSHR;
24274a4d8c2SCharles.Forsyth r->vconst = g;
24374a4d8c2SCharles.Forsyth r->type = types[TINT];
24474a4d8c2SCharles.Forsyth }
24574a4d8c2SCharles.Forsyth break;
24674a4d8c2SCharles.Forsyth
24774a4d8c2SCharles.Forsyth case OLDIV:
24874a4d8c2SCharles.Forsyth xcom(l);
24974a4d8c2SCharles.Forsyth xcom(r);
25074a4d8c2SCharles.Forsyth g = vlog(r);
25174a4d8c2SCharles.Forsyth if(g >= 0) {
25274a4d8c2SCharles.Forsyth n->op = OLSHR;
25374a4d8c2SCharles.Forsyth r->vconst = g;
25474a4d8c2SCharles.Forsyth r->type = types[TINT];
25574a4d8c2SCharles.Forsyth indexshift(n);
25674a4d8c2SCharles.Forsyth break;
25774a4d8c2SCharles.Forsyth }
25874a4d8c2SCharles.Forsyth break;
25974a4d8c2SCharles.Forsyth
26074a4d8c2SCharles.Forsyth case OASLMOD:
26174a4d8c2SCharles.Forsyth xcom(l);
26274a4d8c2SCharles.Forsyth xcom(r);
26374a4d8c2SCharles.Forsyth g = vlog(r);
26474a4d8c2SCharles.Forsyth if(g >= 0) {
26574a4d8c2SCharles.Forsyth n->op = OASAND;
26674a4d8c2SCharles.Forsyth r->vconst--;
26774a4d8c2SCharles.Forsyth }
26874a4d8c2SCharles.Forsyth break;
26974a4d8c2SCharles.Forsyth
27074a4d8c2SCharles.Forsyth case OLMOD:
27174a4d8c2SCharles.Forsyth xcom(l);
27274a4d8c2SCharles.Forsyth xcom(r);
27374a4d8c2SCharles.Forsyth g = vlog(r);
27474a4d8c2SCharles.Forsyth if(g >= 0) {
27574a4d8c2SCharles.Forsyth n->op = OAND;
27674a4d8c2SCharles.Forsyth r->vconst--;
27774a4d8c2SCharles.Forsyth }
27874a4d8c2SCharles.Forsyth break;
27974a4d8c2SCharles.Forsyth
28074a4d8c2SCharles.Forsyth case OASMUL:
28174a4d8c2SCharles.Forsyth case OASLMUL:
28274a4d8c2SCharles.Forsyth xcom(l);
28374a4d8c2SCharles.Forsyth xcom(r);
28474a4d8c2SCharles.Forsyth g = vlog(r);
28574a4d8c2SCharles.Forsyth if(g >= 0) {
28674a4d8c2SCharles.Forsyth n->op = OASASHL;
28774a4d8c2SCharles.Forsyth r->vconst = g;
28874a4d8c2SCharles.Forsyth }
28974a4d8c2SCharles.Forsyth break;
29074a4d8c2SCharles.Forsyth
29174a4d8c2SCharles.Forsyth case OLSHR:
29274a4d8c2SCharles.Forsyth case OASHR:
29374a4d8c2SCharles.Forsyth xcom(l);
29474a4d8c2SCharles.Forsyth xcom(r);
29574a4d8c2SCharles.Forsyth indexshift(n);
29674a4d8c2SCharles.Forsyth break;
29774a4d8c2SCharles.Forsyth
29874a4d8c2SCharles.Forsyth default:
29974a4d8c2SCharles.Forsyth if(l != Z)
30074a4d8c2SCharles.Forsyth xcom(l);
30174a4d8c2SCharles.Forsyth if(r != Z)
30274a4d8c2SCharles.Forsyth xcom(r);
30374a4d8c2SCharles.Forsyth break;
30474a4d8c2SCharles.Forsyth }
30574a4d8c2SCharles.Forsyth brk:
30674a4d8c2SCharles.Forsyth if(n->addable >= 10)
30774a4d8c2SCharles.Forsyth return;
30874a4d8c2SCharles.Forsyth if(l != Z)
30974a4d8c2SCharles.Forsyth n->complex = l->complex;
31074a4d8c2SCharles.Forsyth if(r != Z) {
31174a4d8c2SCharles.Forsyth if(r->complex == n->complex)
31274a4d8c2SCharles.Forsyth n->complex = r->complex+1;
31374a4d8c2SCharles.Forsyth else
31474a4d8c2SCharles.Forsyth if(r->complex > n->complex)
31574a4d8c2SCharles.Forsyth n->complex = r->complex;
31674a4d8c2SCharles.Forsyth }
31774a4d8c2SCharles.Forsyth if(n->complex == 0)
31874a4d8c2SCharles.Forsyth n->complex++;
31974a4d8c2SCharles.Forsyth
32074a4d8c2SCharles.Forsyth if(com64(n))
32174a4d8c2SCharles.Forsyth return;
32274a4d8c2SCharles.Forsyth
32374a4d8c2SCharles.Forsyth switch(n->op) {
32474a4d8c2SCharles.Forsyth
32574a4d8c2SCharles.Forsyth case OFUNC:
32674a4d8c2SCharles.Forsyth n->complex = FNX;
32774a4d8c2SCharles.Forsyth break;
32874a4d8c2SCharles.Forsyth
32974a4d8c2SCharles.Forsyth case OLMOD:
33074a4d8c2SCharles.Forsyth case OMOD:
33174a4d8c2SCharles.Forsyth case OLMUL:
33274a4d8c2SCharles.Forsyth case OLDIV:
33374a4d8c2SCharles.Forsyth case OMUL:
33474a4d8c2SCharles.Forsyth case ODIV:
33574a4d8c2SCharles.Forsyth case OASLMUL:
33674a4d8c2SCharles.Forsyth case OASLDIV:
33774a4d8c2SCharles.Forsyth case OASLMOD:
33874a4d8c2SCharles.Forsyth case OASMUL:
33974a4d8c2SCharles.Forsyth case OASDIV:
34074a4d8c2SCharles.Forsyth case OASMOD:
34174a4d8c2SCharles.Forsyth if(r->complex >= l->complex) {
34274a4d8c2SCharles.Forsyth n->complex = l->complex + 3;
34374a4d8c2SCharles.Forsyth if(r->complex > n->complex)
34474a4d8c2SCharles.Forsyth n->complex = r->complex;
34574a4d8c2SCharles.Forsyth } else {
34674a4d8c2SCharles.Forsyth n->complex = r->complex + 3;
34774a4d8c2SCharles.Forsyth if(l->complex > n->complex)
34874a4d8c2SCharles.Forsyth n->complex = l->complex;
34974a4d8c2SCharles.Forsyth }
35074a4d8c2SCharles.Forsyth break;
35174a4d8c2SCharles.Forsyth
35274a4d8c2SCharles.Forsyth case OLSHR:
35374a4d8c2SCharles.Forsyth case OASHL:
35474a4d8c2SCharles.Forsyth case OASHR:
35574a4d8c2SCharles.Forsyth case OASLSHR:
35674a4d8c2SCharles.Forsyth case OASASHL:
35774a4d8c2SCharles.Forsyth case OASASHR:
35874a4d8c2SCharles.Forsyth if(r->complex >= l->complex) {
35974a4d8c2SCharles.Forsyth n->complex = l->complex + 2;
36074a4d8c2SCharles.Forsyth if(r->complex > n->complex)
36174a4d8c2SCharles.Forsyth n->complex = r->complex;
36274a4d8c2SCharles.Forsyth } else {
36374a4d8c2SCharles.Forsyth n->complex = r->complex + 2;
36474a4d8c2SCharles.Forsyth if(l->complex > n->complex)
36574a4d8c2SCharles.Forsyth n->complex = l->complex;
36674a4d8c2SCharles.Forsyth }
36774a4d8c2SCharles.Forsyth break;
36874a4d8c2SCharles.Forsyth
36974a4d8c2SCharles.Forsyth case OADD:
37074a4d8c2SCharles.Forsyth case OXOR:
37174a4d8c2SCharles.Forsyth case OAND:
37274a4d8c2SCharles.Forsyth case OOR:
37374a4d8c2SCharles.Forsyth /*
37474a4d8c2SCharles.Forsyth * immediate operators, make const on right
37574a4d8c2SCharles.Forsyth */
37674a4d8c2SCharles.Forsyth if(l->op == OCONST) {
37774a4d8c2SCharles.Forsyth n->left = r;
37874a4d8c2SCharles.Forsyth n->right = l;
37974a4d8c2SCharles.Forsyth }
38074a4d8c2SCharles.Forsyth break;
38174a4d8c2SCharles.Forsyth
38274a4d8c2SCharles.Forsyth case OEQ:
38374a4d8c2SCharles.Forsyth case ONE:
38474a4d8c2SCharles.Forsyth case OLE:
38574a4d8c2SCharles.Forsyth case OLT:
38674a4d8c2SCharles.Forsyth case OGE:
38774a4d8c2SCharles.Forsyth case OGT:
38874a4d8c2SCharles.Forsyth case OHI:
38974a4d8c2SCharles.Forsyth case OHS:
39074a4d8c2SCharles.Forsyth case OLO:
39174a4d8c2SCharles.Forsyth case OLS:
39274a4d8c2SCharles.Forsyth /*
39374a4d8c2SCharles.Forsyth * compare operators, make const on left
39474a4d8c2SCharles.Forsyth */
39574a4d8c2SCharles.Forsyth if(r->op == OCONST) {
39674a4d8c2SCharles.Forsyth n->left = r;
39774a4d8c2SCharles.Forsyth n->right = l;
39874a4d8c2SCharles.Forsyth n->op = invrel[relindex(n->op)];
39974a4d8c2SCharles.Forsyth }
40074a4d8c2SCharles.Forsyth break;
40174a4d8c2SCharles.Forsyth }
40274a4d8c2SCharles.Forsyth }
40374a4d8c2SCharles.Forsyth
40474a4d8c2SCharles.Forsyth void
indx(Node * n)40574a4d8c2SCharles.Forsyth indx(Node *n)
40674a4d8c2SCharles.Forsyth {
40774a4d8c2SCharles.Forsyth Node *l, *r;
40874a4d8c2SCharles.Forsyth
40974a4d8c2SCharles.Forsyth if(debug['x'])
41074a4d8c2SCharles.Forsyth prtree(n, "indx");
41174a4d8c2SCharles.Forsyth
41274a4d8c2SCharles.Forsyth l = n->left;
41374a4d8c2SCharles.Forsyth r = n->right;
41474a4d8c2SCharles.Forsyth if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) {
41574a4d8c2SCharles.Forsyth n->right = l;
41674a4d8c2SCharles.Forsyth n->left = r;
41774a4d8c2SCharles.Forsyth l = r;
41874a4d8c2SCharles.Forsyth r = n->right;
41974a4d8c2SCharles.Forsyth }
42074a4d8c2SCharles.Forsyth if(l->addable != 7) {
42174a4d8c2SCharles.Forsyth idx.regtree = l;
42274a4d8c2SCharles.Forsyth idx.scale = 1;
42374a4d8c2SCharles.Forsyth } else
42474a4d8c2SCharles.Forsyth if(l->right->addable == 20) {
42574a4d8c2SCharles.Forsyth idx.regtree = l->left;
42674a4d8c2SCharles.Forsyth idx.scale = 1 << l->right->vconst;
42774a4d8c2SCharles.Forsyth } else
42874a4d8c2SCharles.Forsyth if(l->left->addable == 20) {
42974a4d8c2SCharles.Forsyth idx.regtree = l->right;
43074a4d8c2SCharles.Forsyth idx.scale = 1 << l->left->vconst;
43174a4d8c2SCharles.Forsyth } else
43274a4d8c2SCharles.Forsyth diag(n, "bad index");
43374a4d8c2SCharles.Forsyth
43474a4d8c2SCharles.Forsyth idx.basetree = r;
43574a4d8c2SCharles.Forsyth if(debug['x']) {
43674a4d8c2SCharles.Forsyth print("scale = %d\n", idx.scale);
43774a4d8c2SCharles.Forsyth prtree(idx.regtree, "index");
43874a4d8c2SCharles.Forsyth prtree(idx.basetree, "base");
43974a4d8c2SCharles.Forsyth }
44074a4d8c2SCharles.Forsyth }
441