17dd7cddfSDavid du Colombier #include "gc.h"
27dd7cddfSDavid du Colombier
37dd7cddfSDavid du Colombier void
noretval(int n)47dd7cddfSDavid du Colombier noretval(int n)
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier if(n & 1) {
87dd7cddfSDavid du Colombier gins(ANOP, Z, Z);
97dd7cddfSDavid du Colombier p->to.type = D_REG;
107dd7cddfSDavid du Colombier p->to.reg = REGRET;
117dd7cddfSDavid du Colombier }
127dd7cddfSDavid du Colombier if(n & 2) {
137dd7cddfSDavid du Colombier gins(ANOP, Z, Z);
147dd7cddfSDavid du Colombier p->to.type = D_FREG;
157dd7cddfSDavid du Colombier p->to.reg = FREGRET;
167dd7cddfSDavid du Colombier }
177dd7cddfSDavid du Colombier }
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier /*
207dd7cddfSDavid du Colombier * calculate addressability as follows
217dd7cddfSDavid du Colombier * CONST ==> 20 $value
227dd7cddfSDavid du Colombier * NAME ==> 10 name
237dd7cddfSDavid du Colombier * REGISTER ==> 11 register
247dd7cddfSDavid du Colombier * INDREG ==> 12 *[(reg)+offset]
257dd7cddfSDavid du Colombier * &10 ==> 2 $name
267dd7cddfSDavid du Colombier * ADD(2, 20) ==> 2 $name+offset
277dd7cddfSDavid du Colombier * ADD(3, 20) ==> 3 $(reg)+offset
287dd7cddfSDavid du Colombier * &12 ==> 3 $(reg)+offset
297dd7cddfSDavid du Colombier * *11 ==> 11 ??
307dd7cddfSDavid du Colombier * *2 ==> 10 name
317dd7cddfSDavid du Colombier * *3 ==> 12 *(reg)+offset
327dd7cddfSDavid du Colombier * calculate complexity (number of registers)
337dd7cddfSDavid du Colombier */
347dd7cddfSDavid du Colombier void
xcom(Node * n)357dd7cddfSDavid du Colombier xcom(Node *n)
367dd7cddfSDavid du Colombier {
377dd7cddfSDavid du Colombier Node *l, *r;
38*6891d857SDavid du Colombier int v, nr;
397dd7cddfSDavid du Colombier
407dd7cddfSDavid du Colombier if(n == Z)
417dd7cddfSDavid du Colombier return;
427dd7cddfSDavid du Colombier l = n->left;
437dd7cddfSDavid du Colombier r = n->right;
447dd7cddfSDavid du Colombier n->addable = 0;
457dd7cddfSDavid du Colombier n->complex = 0;
467dd7cddfSDavid du Colombier switch(n->op) {
477dd7cddfSDavid du Colombier case OCONST:
487dd7cddfSDavid du Colombier n->addable = 20;
497dd7cddfSDavid du Colombier return;
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier case OREGISTER:
527dd7cddfSDavid du Colombier n->addable = 11;
537dd7cddfSDavid du Colombier return;
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier case OINDREG:
567dd7cddfSDavid du Colombier n->addable = 12;
577dd7cddfSDavid du Colombier return;
587dd7cddfSDavid du Colombier
597dd7cddfSDavid du Colombier case ONAME:
607dd7cddfSDavid du Colombier n->addable = 10;
617dd7cddfSDavid du Colombier return;
627dd7cddfSDavid du Colombier
637dd7cddfSDavid du Colombier case OADDR:
647dd7cddfSDavid du Colombier xcom(l);
657dd7cddfSDavid du Colombier if(l->addable == 10)
667dd7cddfSDavid du Colombier n->addable = 2;
677dd7cddfSDavid du Colombier if(l->addable == 12)
687dd7cddfSDavid du Colombier n->addable = 3;
697dd7cddfSDavid du Colombier break;
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier case OIND:
727dd7cddfSDavid du Colombier xcom(l);
737dd7cddfSDavid du Colombier if(l->addable == 11)
747dd7cddfSDavid du Colombier n->addable = 12;
757dd7cddfSDavid du Colombier if(l->addable == 3)
767dd7cddfSDavid du Colombier n->addable = 12;
777dd7cddfSDavid du Colombier if(l->addable == 2)
787dd7cddfSDavid du Colombier n->addable = 10;
797dd7cddfSDavid du Colombier break;
807dd7cddfSDavid du Colombier
817dd7cddfSDavid du Colombier case OADD:
827dd7cddfSDavid du Colombier xcom(l);
837dd7cddfSDavid du Colombier xcom(r);
847dd7cddfSDavid du Colombier if(l->addable == 20) {
857dd7cddfSDavid du Colombier if(r->addable == 2)
867dd7cddfSDavid du Colombier n->addable = 2;
877dd7cddfSDavid du Colombier if(r->addable == 3)
887dd7cddfSDavid du Colombier n->addable = 3;
897dd7cddfSDavid du Colombier }
907dd7cddfSDavid du Colombier if(r->addable == 20) {
917dd7cddfSDavid du Colombier if(l->addable == 2)
927dd7cddfSDavid du Colombier n->addable = 2;
937dd7cddfSDavid du Colombier if(l->addable == 3)
947dd7cddfSDavid du Colombier n->addable = 3;
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier break;
977dd7cddfSDavid du Colombier
987dd7cddfSDavid du Colombier case OASMUL:
997dd7cddfSDavid du Colombier case OASLMUL:
1007dd7cddfSDavid du Colombier xcom(l);
1017dd7cddfSDavid du Colombier xcom(r);
1027dd7cddfSDavid du Colombier v = vlog(r);
1037dd7cddfSDavid du Colombier if(v >= 0) {
1047dd7cddfSDavid du Colombier n->op = OASASHL;
1057dd7cddfSDavid du Colombier r->vconst = v;
1067dd7cddfSDavid du Colombier r->type = types[TINT];
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier break;
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier case OMUL:
1117dd7cddfSDavid du Colombier case OLMUL:
1127dd7cddfSDavid du Colombier xcom(l);
1137dd7cddfSDavid du Colombier xcom(r);
1147dd7cddfSDavid du Colombier v = vlog(r);
1157dd7cddfSDavid du Colombier if(v >= 0) {
1167dd7cddfSDavid du Colombier n->op = OASHL;
1177dd7cddfSDavid du Colombier r->vconst = v;
1187dd7cddfSDavid du Colombier r->type = types[TINT];
1197dd7cddfSDavid du Colombier }
1207dd7cddfSDavid du Colombier v = vlog(l);
1217dd7cddfSDavid du Colombier if(v >= 0) {
1227dd7cddfSDavid du Colombier n->op = OASHL;
1237dd7cddfSDavid du Colombier n->left = r;
1247dd7cddfSDavid du Colombier n->right = l;
1257dd7cddfSDavid du Colombier r = l;
1267dd7cddfSDavid du Colombier l = n->left;
1277dd7cddfSDavid du Colombier r->vconst = v;
1287dd7cddfSDavid du Colombier r->type = types[TINT];
129375daca8SDavid du Colombier simplifyshift(n);
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier break;
1327dd7cddfSDavid du Colombier
1337dd7cddfSDavid du Colombier case OASLDIV:
1347dd7cddfSDavid du Colombier xcom(l);
1357dd7cddfSDavid du Colombier xcom(r);
1367dd7cddfSDavid du Colombier v = vlog(r);
1377dd7cddfSDavid du Colombier if(v >= 0) {
1387dd7cddfSDavid du Colombier n->op = OASLSHR;
1397dd7cddfSDavid du Colombier r->vconst = v;
1407dd7cddfSDavid du Colombier r->type = types[TINT];
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier break;
1437dd7cddfSDavid du Colombier
1447dd7cddfSDavid du Colombier case OLDIV:
1457dd7cddfSDavid du Colombier xcom(l);
1467dd7cddfSDavid du Colombier xcom(r);
1477dd7cddfSDavid du Colombier v = vlog(r);
1487dd7cddfSDavid du Colombier if(v >= 0) {
1497dd7cddfSDavid du Colombier n->op = OLSHR;
1507dd7cddfSDavid du Colombier r->vconst = v;
1517dd7cddfSDavid du Colombier r->type = types[TINT];
152375daca8SDavid du Colombier simplifyshift(n);
1537dd7cddfSDavid du Colombier }
1547dd7cddfSDavid du Colombier break;
1557dd7cddfSDavid du Colombier
1567dd7cddfSDavid du Colombier case OASLMOD:
1577dd7cddfSDavid du Colombier xcom(l);
1587dd7cddfSDavid du Colombier xcom(r);
1597dd7cddfSDavid du Colombier v = vlog(r);
1607dd7cddfSDavid du Colombier if(v >= 0) {
1617dd7cddfSDavid du Colombier n->op = OASAND;
1627dd7cddfSDavid du Colombier r->vconst--;
1637dd7cddfSDavid du Colombier }
1647dd7cddfSDavid du Colombier break;
1657dd7cddfSDavid du Colombier
1667dd7cddfSDavid du Colombier case OLMOD:
1677dd7cddfSDavid du Colombier xcom(l);
1687dd7cddfSDavid du Colombier xcom(r);
1697dd7cddfSDavid du Colombier v = vlog(r);
1707dd7cddfSDavid du Colombier if(v >= 0) {
1717dd7cddfSDavid du Colombier n->op = OAND;
1727dd7cddfSDavid du Colombier r->vconst--;
1737dd7cddfSDavid du Colombier }
1747dd7cddfSDavid du Colombier break;
1757dd7cddfSDavid du Colombier
176375daca8SDavid du Colombier case OLSHR:
177375daca8SDavid du Colombier case OASHL:
178375daca8SDavid du Colombier case OASHR:
179375daca8SDavid du Colombier xcom(l);
180375daca8SDavid du Colombier xcom(r);
181375daca8SDavid du Colombier simplifyshift(n);
182375daca8SDavid du Colombier break;
183375daca8SDavid du Colombier
1847dd7cddfSDavid du Colombier default:
1857dd7cddfSDavid du Colombier if(l != Z)
1867dd7cddfSDavid du Colombier xcom(l);
1877dd7cddfSDavid du Colombier if(r != Z)
1887dd7cddfSDavid du Colombier xcom(r);
1897dd7cddfSDavid du Colombier break;
1907dd7cddfSDavid du Colombier }
1917dd7cddfSDavid du Colombier if(n->addable >= 10)
1927dd7cddfSDavid du Colombier return;
1937dd7cddfSDavid du Colombier if(l != Z)
1947dd7cddfSDavid du Colombier n->complex = l->complex;
1957dd7cddfSDavid du Colombier if(r != Z) {
196*6891d857SDavid du Colombier nr = 1;
197*6891d857SDavid du Colombier if(r->type != T && typev[r->type->etype] || n->type != T && typev[n->type->etype]) {
198*6891d857SDavid du Colombier nr = 2;
199*6891d857SDavid du Colombier if(n->op == OMUL || n->op == OLMUL)
200*6891d857SDavid du Colombier nr += 3;
201*6891d857SDavid du Colombier }
2027dd7cddfSDavid du Colombier if(r->complex == n->complex)
203*6891d857SDavid du Colombier n->complex = r->complex+nr;
2047dd7cddfSDavid du Colombier else
2057dd7cddfSDavid du Colombier if(r->complex > n->complex)
2067dd7cddfSDavid du Colombier n->complex = r->complex;
2077dd7cddfSDavid du Colombier }
208*6891d857SDavid du Colombier if(n->complex == 0){
2097dd7cddfSDavid du Colombier n->complex++;
210*6891d857SDavid du Colombier if(n->type != T && typev[n->type->etype])
211*6891d857SDavid du Colombier n->complex++;
212*6891d857SDavid du Colombier }
2137dd7cddfSDavid du Colombier
2147dd7cddfSDavid du Colombier if(com64(n))
2157dd7cddfSDavid du Colombier return;
2167dd7cddfSDavid du Colombier
2177dd7cddfSDavid du Colombier switch(n->op) {
2187dd7cddfSDavid du Colombier
2197dd7cddfSDavid du Colombier case OFUNC:
2207dd7cddfSDavid du Colombier n->complex = FNX;
2217dd7cddfSDavid du Colombier break;
2227dd7cddfSDavid du Colombier
2237dd7cddfSDavid du Colombier case OEQ:
2247dd7cddfSDavid du Colombier case ONE:
2257dd7cddfSDavid du Colombier case OLE:
2267dd7cddfSDavid du Colombier case OLT:
2277dd7cddfSDavid du Colombier case OGE:
2287dd7cddfSDavid du Colombier case OGT:
2297dd7cddfSDavid du Colombier case OHI:
2307dd7cddfSDavid du Colombier case OHS:
2317dd7cddfSDavid du Colombier case OLO:
2327dd7cddfSDavid du Colombier case OLS:
2337dd7cddfSDavid du Colombier /*
2347dd7cddfSDavid du Colombier * immediate operators, make const on right
2357dd7cddfSDavid du Colombier */
2367dd7cddfSDavid du Colombier if(l->op == OCONST) {
2377dd7cddfSDavid du Colombier n->left = r;
2387dd7cddfSDavid du Colombier n->right = l;
2397dd7cddfSDavid du Colombier n->op = invrel[relindex(n->op)];
2407dd7cddfSDavid du Colombier }
2417dd7cddfSDavid du Colombier break;
2427dd7cddfSDavid du Colombier
2437dd7cddfSDavid du Colombier case OADD:
2447dd7cddfSDavid du Colombier case OXOR:
2457dd7cddfSDavid du Colombier case OAND:
2467dd7cddfSDavid du Colombier case OOR:
2477dd7cddfSDavid du Colombier /*
2487dd7cddfSDavid du Colombier * immediate operators, make const on right
2497dd7cddfSDavid du Colombier */
2507dd7cddfSDavid du Colombier if(l->op == OCONST) {
2517dd7cddfSDavid du Colombier n->left = r;
2527dd7cddfSDavid du Colombier n->right = l;
2537dd7cddfSDavid du Colombier }
2547dd7cddfSDavid du Colombier break;
2557dd7cddfSDavid du Colombier }
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier
258