xref: /plan9/sys/src/cmd/vc/sgen.c (revision 4ac975e2e38b792d24bc60de7fce5e6173f046ea)
13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
noretval(int n)43e12c5d1SDavid du Colombier noretval(int n)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier 	if(n & 1) {
83e12c5d1SDavid du Colombier 		gins(ANOP, Z, Z);
93e12c5d1SDavid du Colombier 		p->to.type = D_REG;
103e12c5d1SDavid du Colombier 		p->to.reg = REGRET;
113e12c5d1SDavid du Colombier 	}
123e12c5d1SDavid du Colombier 	if(n & 2) {
133e12c5d1SDavid du Colombier 		gins(ANOP, Z, Z);
143e12c5d1SDavid du Colombier 		p->to.type = D_FREG;
153e12c5d1SDavid du Colombier 		p->to.reg = FREGRET;
163e12c5d1SDavid du Colombier 	}
173e12c5d1SDavid du Colombier }
183e12c5d1SDavid du Colombier 
193e12c5d1SDavid du Colombier /*
203e12c5d1SDavid du Colombier  *	calculate addressability as follows
213e12c5d1SDavid du Colombier  *		CONST ==> 20		$value
223e12c5d1SDavid du Colombier  *		NAME ==> 10		name
233e12c5d1SDavid du Colombier  *		REGISTER ==> 11		register
243e12c5d1SDavid du Colombier  *		INDREG ==> 12		*[(reg)+offset]
253e12c5d1SDavid du Colombier  *		&10 ==> 2		$name
263e12c5d1SDavid du Colombier  *		ADD(2, 20) ==> 2	$name+offset
273e12c5d1SDavid du Colombier  *		ADD(3, 20) ==> 3	$(reg)+offset
283e12c5d1SDavid du Colombier  *		&12 ==> 3		$(reg)+offset
293e12c5d1SDavid du Colombier  *		*11 ==> 11		??
303e12c5d1SDavid du Colombier  *		*2 ==> 10		name
313e12c5d1SDavid du Colombier  *		*3 ==> 12		*(reg)+offset
323e12c5d1SDavid du Colombier  *	calculate complexity (number of registers)
333e12c5d1SDavid du Colombier  */
343e12c5d1SDavid du Colombier void
xcom(Node * n)353e12c5d1SDavid du Colombier xcom(Node *n)
363e12c5d1SDavid du Colombier {
373e12c5d1SDavid du Colombier 	Node *l, *r;
383e12c5d1SDavid du Colombier 	int t;
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier 	if(n == Z)
413e12c5d1SDavid du Colombier 		return;
423e12c5d1SDavid du Colombier 	l = n->left;
433e12c5d1SDavid du Colombier 	r = n->right;
443e12c5d1SDavid du Colombier 	n->addable = 0;
453e12c5d1SDavid du Colombier 	n->complex = 0;
463e12c5d1SDavid du Colombier 	switch(n->op) {
473e12c5d1SDavid du Colombier 	case OCONST:
483e12c5d1SDavid du Colombier 		n->addable = 20;
493e12c5d1SDavid du Colombier 		return;
503e12c5d1SDavid du Colombier 
513e12c5d1SDavid du Colombier 	case OREGISTER:
523e12c5d1SDavid du Colombier 		n->addable = 11;
533e12c5d1SDavid du Colombier 		return;
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier 	case OINDREG:
563e12c5d1SDavid du Colombier 		n->addable = 12;
573e12c5d1SDavid du Colombier 		return;
583e12c5d1SDavid du Colombier 
593e12c5d1SDavid du Colombier 	case ONAME:
603e12c5d1SDavid du Colombier 		n->addable = 10;
613e12c5d1SDavid du Colombier 		return;
623e12c5d1SDavid du Colombier 
633e12c5d1SDavid du Colombier 	case OADDR:
643e12c5d1SDavid du Colombier 		xcom(l);
653e12c5d1SDavid du Colombier 		if(l->addable == 10)
663e12c5d1SDavid du Colombier 			n->addable = 2;
673e12c5d1SDavid du Colombier 		if(l->addable == 12)
683e12c5d1SDavid du Colombier 			n->addable = 3;
693e12c5d1SDavid du Colombier 		break;
703e12c5d1SDavid du Colombier 
713e12c5d1SDavid du Colombier 	case OIND:
723e12c5d1SDavid du Colombier 		xcom(l);
733e12c5d1SDavid du Colombier 		if(l->addable == 11)
743e12c5d1SDavid du Colombier 			n->addable = 12;
753e12c5d1SDavid du Colombier 		if(l->addable == 3)
763e12c5d1SDavid du Colombier 			n->addable = 12;
773e12c5d1SDavid du Colombier 		if(l->addable == 2)
783e12c5d1SDavid du Colombier 			n->addable = 10;
793e12c5d1SDavid du Colombier 		break;
803e12c5d1SDavid du Colombier 
813e12c5d1SDavid du Colombier 	case OADD:
823e12c5d1SDavid du Colombier 		xcom(l);
833e12c5d1SDavid du Colombier 		xcom(r);
843e12c5d1SDavid du Colombier 		if(l->addable == 20) {
853e12c5d1SDavid du Colombier 			if(r->addable == 2)
863e12c5d1SDavid du Colombier 				n->addable = 2;
873e12c5d1SDavid du Colombier 			if(r->addable == 3)
883e12c5d1SDavid du Colombier 				n->addable = 3;
893e12c5d1SDavid du Colombier 		}
903e12c5d1SDavid du Colombier 		if(r->addable == 20) {
913e12c5d1SDavid du Colombier 			if(l->addable == 2)
923e12c5d1SDavid du Colombier 				n->addable = 2;
933e12c5d1SDavid du Colombier 			if(l->addable == 3)
943e12c5d1SDavid du Colombier 				n->addable = 3;
953e12c5d1SDavid du Colombier 		}
963e12c5d1SDavid du Colombier 		break;
973e12c5d1SDavid du Colombier 
983e12c5d1SDavid du Colombier 	case OASLMUL:
993e12c5d1SDavid du Colombier 	case OASMUL:
1003e12c5d1SDavid du Colombier 		xcom(l);
1013e12c5d1SDavid du Colombier 		xcom(r);
1023e12c5d1SDavid du Colombier 		t = vlog(r);
1033e12c5d1SDavid du Colombier 		if(t >= 0) {
1043e12c5d1SDavid du Colombier 			n->op = OASASHL;
105219b2ee8SDavid du Colombier 			r->vconst = t;
1067dd7cddfSDavid du Colombier 			r->type = types[TINT];
1073e12c5d1SDavid du Colombier 		}
1083e12c5d1SDavid du Colombier 		break;
1093e12c5d1SDavid du Colombier 
1103e12c5d1SDavid du Colombier 	case OMUL:
1113e12c5d1SDavid du Colombier 	case OLMUL:
1123e12c5d1SDavid du Colombier 		xcom(l);
1133e12c5d1SDavid du Colombier 		xcom(r);
11480ee5cbfSDavid du Colombier 		t = vlog(l);
11580ee5cbfSDavid du Colombier 		if(t >= 0) {
11680ee5cbfSDavid du Colombier 			n->left = r;
11780ee5cbfSDavid du Colombier 			n->right = l;
11880ee5cbfSDavid du Colombier 			l = r;
11980ee5cbfSDavid du Colombier 			r = n->right;
12080ee5cbfSDavid du Colombier 		}
1213e12c5d1SDavid du Colombier 		t = vlog(r);
1223e12c5d1SDavid du Colombier 		if(t >= 0) {
1233e12c5d1SDavid du Colombier 			n->op = OASHL;
124219b2ee8SDavid du Colombier 			r->vconst = t;
1257dd7cddfSDavid du Colombier 			r->type = types[TINT];
126*375daca8SDavid du Colombier 			simplifyshift(n);
1273e12c5d1SDavid du Colombier 		}
1283e12c5d1SDavid du Colombier 		break;
1293e12c5d1SDavid du Colombier 
1303e12c5d1SDavid du Colombier 	case OASLDIV:
1313e12c5d1SDavid du Colombier 		xcom(l);
1323e12c5d1SDavid du Colombier 		xcom(r);
1333e12c5d1SDavid du Colombier 		t = vlog(r);
1343e12c5d1SDavid du Colombier 		if(t >= 0) {
1353e12c5d1SDavid du Colombier 			n->op = OASLSHR;
136219b2ee8SDavid du Colombier 			r->vconst = t;
1377dd7cddfSDavid du Colombier 			r->type = types[TINT];
1383e12c5d1SDavid du Colombier 		}
1393e12c5d1SDavid du Colombier 		break;
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier 	case OLDIV:
1423e12c5d1SDavid du Colombier 		xcom(l);
1433e12c5d1SDavid du Colombier 		xcom(r);
1443e12c5d1SDavid du Colombier 		t = vlog(r);
1453e12c5d1SDavid du Colombier 		if(t >= 0) {
1463e12c5d1SDavid du Colombier 			n->op = OLSHR;
147219b2ee8SDavid du Colombier 			r->vconst = t;
1487dd7cddfSDavid du Colombier 			r->type = types[TINT];
149*375daca8SDavid du Colombier 			simplifyshift(n);
1503e12c5d1SDavid du Colombier 		}
1513e12c5d1SDavid du Colombier 		break;
1523e12c5d1SDavid du Colombier 
1533e12c5d1SDavid du Colombier 	case OASLMOD:
1543e12c5d1SDavid du Colombier 		xcom(l);
1553e12c5d1SDavid du Colombier 		xcom(r);
1563e12c5d1SDavid du Colombier 		t = vlog(r);
1573e12c5d1SDavid du Colombier 		if(t >= 0) {
1583e12c5d1SDavid du Colombier 			n->op = OASAND;
159219b2ee8SDavid du Colombier 			r->vconst--;
1603e12c5d1SDavid du Colombier 		}
1613e12c5d1SDavid du Colombier 		break;
1623e12c5d1SDavid du Colombier 
1633e12c5d1SDavid du Colombier 	case OLMOD:
1643e12c5d1SDavid du Colombier 		xcom(l);
1653e12c5d1SDavid du Colombier 		xcom(r);
1663e12c5d1SDavid du Colombier 		t = vlog(r);
1673e12c5d1SDavid du Colombier 		if(t >= 0) {
1683e12c5d1SDavid du Colombier 			n->op = OAND;
169219b2ee8SDavid du Colombier 			r->vconst--;
1703e12c5d1SDavid du Colombier 		}
1713e12c5d1SDavid du Colombier 		break;
1723e12c5d1SDavid du Colombier 
1737dd7cddfSDavid du Colombier 	case OLSHR:
1747dd7cddfSDavid du Colombier 	case OASHL:
1757dd7cddfSDavid du Colombier 	case OASHR:
1767dd7cddfSDavid du Colombier 		xcom(l);
1777dd7cddfSDavid du Colombier 		xcom(r);
178*375daca8SDavid du Colombier 		simplifyshift(n);
1797dd7cddfSDavid du Colombier 		break;
1807dd7cddfSDavid du Colombier 
1813e12c5d1SDavid du Colombier 	default:
1823e12c5d1SDavid du Colombier 		if(l != Z)
1833e12c5d1SDavid du Colombier 			xcom(l);
1843e12c5d1SDavid du Colombier 		if(r != Z)
1853e12c5d1SDavid du Colombier 			xcom(r);
1863e12c5d1SDavid du Colombier 		break;
1873e12c5d1SDavid du Colombier 	}
1883e12c5d1SDavid du Colombier 	if(n->addable >= 10)
1893e12c5d1SDavid du Colombier 		return;
190219b2ee8SDavid du Colombier 
1913e12c5d1SDavid du Colombier 	if(l != Z)
1923e12c5d1SDavid du Colombier 		n->complex = l->complex;
1933e12c5d1SDavid du Colombier 	if(r != Z) {
1943e12c5d1SDavid du Colombier 		if(r->complex == n->complex)
195219b2ee8SDavid du Colombier 			n->complex = r->complex+1;
196219b2ee8SDavid du Colombier 		else
1973e12c5d1SDavid du Colombier 		if(r->complex > n->complex)
1983e12c5d1SDavid du Colombier 			n->complex = r->complex;
1993e12c5d1SDavid du Colombier 	}
2003e12c5d1SDavid du Colombier 	if(n->complex == 0)
2013e12c5d1SDavid du Colombier 		n->complex++;
2023e12c5d1SDavid du Colombier 
203219b2ee8SDavid du Colombier 	if(com64(n))
204219b2ee8SDavid du Colombier 		return;
205219b2ee8SDavid du Colombier 
206219b2ee8SDavid du Colombier 	switch(n->op) {
2073e12c5d1SDavid du Colombier 	case OFUNC:
2083e12c5d1SDavid du Colombier 		n->complex = FNX;
2093e12c5d1SDavid du Colombier 		break;
2103e12c5d1SDavid du Colombier 
2113e12c5d1SDavid du Colombier 	case OADD:
2123e12c5d1SDavid du Colombier 	case OXOR:
2133e12c5d1SDavid du Colombier 	case OAND:
2143e12c5d1SDavid du Colombier 	case OOR:
2153e12c5d1SDavid du Colombier 	case OEQ:
2163e12c5d1SDavid du Colombier 	case ONE:
2173e12c5d1SDavid du Colombier 		/*
2183e12c5d1SDavid du Colombier 		 * immediate operators, make const on right
2193e12c5d1SDavid du Colombier 		 */
2203e12c5d1SDavid du Colombier 		if(l->op == OCONST) {
2213e12c5d1SDavid du Colombier 			n->left = r;
2223e12c5d1SDavid du Colombier 			n->right = l;
2233e12c5d1SDavid du Colombier 		}
2243e12c5d1SDavid du Colombier 		break;
2253e12c5d1SDavid du Colombier 	}
2263e12c5d1SDavid du Colombier }
2273e12c5d1SDavid du Colombier 
228