xref: /plan9-contrib/sys/src/cmd/4c/sgen.c (revision f8bc6aaf8056e137bcdfb6117a990ac3eff62cc9)
17edc7532SDavid du Colombier #include "gc.h"
27edc7532SDavid du Colombier 
37edc7532SDavid du Colombier void
noretval(int n)47edc7532SDavid du Colombier noretval(int n)
57edc7532SDavid du Colombier {
67edc7532SDavid du Colombier 
77edc7532SDavid du Colombier 	if(n & 1) {
87edc7532SDavid du Colombier 		gins(ANOP, Z, Z);
97edc7532SDavid du Colombier 		p->to.type = D_REG;
107edc7532SDavid du Colombier 		p->to.reg = REGRET;
117edc7532SDavid du Colombier 	}
127edc7532SDavid du Colombier 	if(n & 2) {
137edc7532SDavid du Colombier 		gins(ANOP, Z, Z);
147edc7532SDavid du Colombier 		p->to.type = D_FREG;
157edc7532SDavid du Colombier 		p->to.reg = FREGRET;
167edc7532SDavid du Colombier 	}
177edc7532SDavid du Colombier }
187edc7532SDavid du Colombier 
197edc7532SDavid du Colombier /*
207edc7532SDavid du Colombier  *	calculate addressability as follows
217edc7532SDavid du Colombier  *		CONST ==> 20		$value
227edc7532SDavid du Colombier  *		NAME ==> 10		name
237edc7532SDavid du Colombier  *		REGISTER ==> 11		register
247edc7532SDavid du Colombier  *		INDREG ==> 12		*[(reg)+offset]
257edc7532SDavid du Colombier  *		&10 ==> 2		$name
267edc7532SDavid du Colombier  *		ADD(2, 20) ==> 2	$name+offset
277edc7532SDavid du Colombier  *		ADD(3, 20) ==> 3	$(reg)+offset
287edc7532SDavid du Colombier  *		&12 ==> 3		$(reg)+offset
297edc7532SDavid du Colombier  *		*11 ==> 11		??
307edc7532SDavid du Colombier  *		*2 ==> 10		name
317edc7532SDavid du Colombier  *		*3 ==> 12		*(reg)+offset
327edc7532SDavid du Colombier  *	calculate complexity (number of registers)
337edc7532SDavid du Colombier  */
347edc7532SDavid du Colombier void
xcom(Node * n)357edc7532SDavid du Colombier xcom(Node *n)
367edc7532SDavid du Colombier {
377edc7532SDavid du Colombier 	Node *l, *r;
387edc7532SDavid du Colombier 	int t;
397edc7532SDavid du Colombier 
407edc7532SDavid du Colombier 	if(n == Z)
417edc7532SDavid du Colombier 		return;
427edc7532SDavid du Colombier 	l = n->left;
437edc7532SDavid du Colombier 	r = n->right;
447edc7532SDavid du Colombier 	n->addable = 0;
457edc7532SDavid du Colombier 	n->complex = 0;
467edc7532SDavid du Colombier 	switch(n->op) {
477edc7532SDavid du Colombier 	case OCONST:
487edc7532SDavid du Colombier 		n->addable = 20;
497edc7532SDavid du Colombier 		return;
507edc7532SDavid du Colombier 
517edc7532SDavid du Colombier 	case OREGISTER:
527edc7532SDavid du Colombier 		n->addable = 11;
537edc7532SDavid du Colombier 		return;
547edc7532SDavid du Colombier 
557edc7532SDavid du Colombier 	case OINDREG:
567edc7532SDavid du Colombier 		n->addable = 12;
577edc7532SDavid du Colombier 		return;
587edc7532SDavid du Colombier 
597edc7532SDavid du Colombier 	case ONAME:
607edc7532SDavid du Colombier 		n->addable = 10;
617edc7532SDavid du Colombier 		return;
627edc7532SDavid du Colombier 
637edc7532SDavid du Colombier 	case OADDR:
647edc7532SDavid du Colombier 		xcom(l);
657edc7532SDavid du Colombier 		if(l->addable == 10)
667edc7532SDavid du Colombier 			n->addable = 2;
677edc7532SDavid du Colombier 		if(l->addable == 12)
687edc7532SDavid du Colombier 			n->addable = 3;
697edc7532SDavid du Colombier 		break;
707edc7532SDavid du Colombier 
717edc7532SDavid du Colombier 	case OIND:
727edc7532SDavid du Colombier 		xcom(l);
737edc7532SDavid du Colombier 		if(l->addable == 11)
747edc7532SDavid du Colombier 			n->addable = 12;
757edc7532SDavid du Colombier 		if(l->addable == 3)
767edc7532SDavid du Colombier 			n->addable = 12;
777edc7532SDavid du Colombier 		if(l->addable == 2)
787edc7532SDavid du Colombier 			n->addable = 10;
797edc7532SDavid du Colombier 		break;
807edc7532SDavid du Colombier 
817edc7532SDavid du Colombier 	case OADD:
827edc7532SDavid du Colombier 		xcom(l);
837edc7532SDavid du Colombier 		xcom(r);
847edc7532SDavid du Colombier 		if(l->addable == 20) {
857edc7532SDavid du Colombier 			if(r->addable == 2)
867edc7532SDavid du Colombier 				n->addable = 2;
877edc7532SDavid du Colombier 			if(r->addable == 3)
887edc7532SDavid du Colombier 				n->addable = 3;
897edc7532SDavid du Colombier 		}
907edc7532SDavid du Colombier 		if(r->addable == 20) {
917edc7532SDavid du Colombier 			if(l->addable == 2)
927edc7532SDavid du Colombier 				n->addable = 2;
937edc7532SDavid du Colombier 			if(l->addable == 3)
947edc7532SDavid du Colombier 				n->addable = 3;
957edc7532SDavid du Colombier 		}
967edc7532SDavid du Colombier 		break;
977edc7532SDavid du Colombier 
987edc7532SDavid du Colombier 	case OASLMUL:
997edc7532SDavid du Colombier 	case OASMUL:
1007edc7532SDavid du Colombier 		xcom(l);
1017edc7532SDavid du Colombier 		xcom(r);
1027edc7532SDavid du Colombier 		t = vlog(r);
1037edc7532SDavid du Colombier 		if(t >= 0) {
1047edc7532SDavid du Colombier 			n->op = OASASHL;
1057edc7532SDavid du Colombier 			r->vconst = t;
1067edc7532SDavid du Colombier 			r->type = types[TINT];
1077edc7532SDavid du Colombier 		}
1087edc7532SDavid du Colombier 		break;
1097edc7532SDavid du Colombier 
1107edc7532SDavid du Colombier 	case OMUL:
1117edc7532SDavid du Colombier 	case OLMUL:
1127edc7532SDavid du Colombier 		xcom(l);
1137edc7532SDavid du Colombier 		xcom(r);
114*f8bc6aafSDavid du Colombier 		t = vlog(l);
115*f8bc6aafSDavid du Colombier 		if(t >= 0) {
116*f8bc6aafSDavid du Colombier 			n->left = r;
117*f8bc6aafSDavid du Colombier 			n->right = l;
118*f8bc6aafSDavid du Colombier 			l = r;
119*f8bc6aafSDavid du Colombier 			r = n->right;
120*f8bc6aafSDavid du Colombier 		}
1217edc7532SDavid du Colombier 		t = vlog(r);
1227edc7532SDavid du Colombier 		if(t >= 0) {
1237edc7532SDavid du Colombier 			n->op = OASHL;
1247edc7532SDavid du Colombier 			r->vconst = t;
1257edc7532SDavid du Colombier 			r->type = types[TINT];
126*f8bc6aafSDavid du Colombier 			simplifyshift(n);
1277edc7532SDavid du Colombier 		}
1287edc7532SDavid du Colombier 		break;
1297edc7532SDavid du Colombier 
1307edc7532SDavid du Colombier 	case OASLDIV:
1317edc7532SDavid du Colombier 		xcom(l);
1327edc7532SDavid du Colombier 		xcom(r);
1337edc7532SDavid du Colombier 		t = vlog(r);
1347edc7532SDavid du Colombier 		if(t >= 0) {
1357edc7532SDavid du Colombier 			n->op = OASLSHR;
1367edc7532SDavid du Colombier 			r->vconst = t;
1377edc7532SDavid du Colombier 			r->type = types[TINT];
1387edc7532SDavid du Colombier 		}
1397edc7532SDavid du Colombier 		break;
1407edc7532SDavid du Colombier 
1417edc7532SDavid du Colombier 	case OLDIV:
1427edc7532SDavid du Colombier 		xcom(l);
1437edc7532SDavid du Colombier 		xcom(r);
1447edc7532SDavid du Colombier 		t = vlog(r);
1457edc7532SDavid du Colombier 		if(t >= 0) {
1467edc7532SDavid du Colombier 			n->op = OLSHR;
1477edc7532SDavid du Colombier 			r->vconst = t;
1487edc7532SDavid du Colombier 			r->type = types[TINT];
149*f8bc6aafSDavid du Colombier 			simplifyshift(n);
1507edc7532SDavid du Colombier 		}
1517edc7532SDavid du Colombier 		break;
1527edc7532SDavid du Colombier 
1537edc7532SDavid du Colombier 	case OASLMOD:
1547edc7532SDavid du Colombier 		xcom(l);
1557edc7532SDavid du Colombier 		xcom(r);
1567edc7532SDavid du Colombier 		t = vlog(r);
1577edc7532SDavid du Colombier 		if(t >= 0) {
1587edc7532SDavid du Colombier 			n->op = OASAND;
1597edc7532SDavid du Colombier 			r->vconst--;
1607edc7532SDavid du Colombier 		}
1617edc7532SDavid du Colombier 		break;
1627edc7532SDavid du Colombier 
1637edc7532SDavid du Colombier 	case OLMOD:
1647edc7532SDavid du Colombier 		xcom(l);
1657edc7532SDavid du Colombier 		xcom(r);
1667edc7532SDavid du Colombier 		t = vlog(r);
1677edc7532SDavid du Colombier 		if(t >= 0) {
1687edc7532SDavid du Colombier 			n->op = OAND;
1697edc7532SDavid du Colombier 			r->vconst--;
1707edc7532SDavid du Colombier 		}
1717edc7532SDavid du Colombier 		break;
1727edc7532SDavid du Colombier 
173*f8bc6aafSDavid du Colombier 	case OLSHR:
174*f8bc6aafSDavid du Colombier 	case OASHL:
175*f8bc6aafSDavid du Colombier 	case OASHR:
176*f8bc6aafSDavid du Colombier 		xcom(l);
177*f8bc6aafSDavid du Colombier 		xcom(r);
178*f8bc6aafSDavid du Colombier 		simplifyshift(n);
179*f8bc6aafSDavid du Colombier 		break;
180*f8bc6aafSDavid du Colombier 
1817edc7532SDavid du Colombier 	default:
1827edc7532SDavid du Colombier 		if(l != Z)
1837edc7532SDavid du Colombier 			xcom(l);
1847edc7532SDavid du Colombier 		if(r != Z)
1857edc7532SDavid du Colombier 			xcom(r);
1867edc7532SDavid du Colombier 		break;
1877edc7532SDavid du Colombier 	}
1887edc7532SDavid du Colombier 	if(n->addable >= 10)
1897edc7532SDavid du Colombier 		return;
1907edc7532SDavid du Colombier 
1917edc7532SDavid du Colombier 	if(l != Z)
1927edc7532SDavid du Colombier 		n->complex = l->complex;
1937edc7532SDavid du Colombier 	if(r != Z) {
1947edc7532SDavid du Colombier 		if(r->complex == n->complex)
1957edc7532SDavid du Colombier 			n->complex = r->complex+1;
1967edc7532SDavid du Colombier 		else
1977edc7532SDavid du Colombier 		if(r->complex > n->complex)
1987edc7532SDavid du Colombier 			n->complex = r->complex;
1997edc7532SDavid du Colombier 	}
2007edc7532SDavid du Colombier 	if(n->complex == 0)
2017edc7532SDavid du Colombier 		n->complex++;
2027edc7532SDavid du Colombier 
2037edc7532SDavid du Colombier 	switch(n->op) {
2047edc7532SDavid du Colombier 	case OFUNC:
2057edc7532SDavid du Colombier 		n->complex = FNX;
2067edc7532SDavid du Colombier 		break;
2077edc7532SDavid du Colombier 
2087edc7532SDavid du Colombier 	case OADD:
2097edc7532SDavid du Colombier 	case OXOR:
2107edc7532SDavid du Colombier 	case OAND:
2117edc7532SDavid du Colombier 	case OOR:
2127edc7532SDavid du Colombier 	case OEQ:
2137edc7532SDavid du Colombier 	case ONE:
2147edc7532SDavid du Colombier 		/*
2157edc7532SDavid du Colombier 		 * immediate operators, make const on right
2167edc7532SDavid du Colombier 		 */
2177edc7532SDavid du Colombier 		if(l->op == OCONST) {
2187edc7532SDavid du Colombier 			n->left = r;
2197edc7532SDavid du Colombier 			n->right = l;
2207edc7532SDavid du Colombier 		}
2217edc7532SDavid du Colombier 		break;
2227edc7532SDavid du Colombier 	}
2237edc7532SDavid du Colombier }
224