xref: /plan9/sys/src/cmd/kc/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 v;
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 OASMUL:
993e12c5d1SDavid du Colombier 	case OASLMUL:
1003e12c5d1SDavid du Colombier 		xcom(l);
1013e12c5d1SDavid du Colombier 		xcom(r);
1023e12c5d1SDavid du Colombier 		v = vlog(r);
1033e12c5d1SDavid du Colombier 		if(v >= 0) {
1043e12c5d1SDavid du Colombier 			n->op = OASASHL;
105219b2ee8SDavid du Colombier 			r->vconst = v;
106*7dd7cddfSDavid 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);
1143e12c5d1SDavid du Colombier 		v = vlog(r);
1153e12c5d1SDavid du Colombier 		if(v >= 0) {
1163e12c5d1SDavid du Colombier 			n->op = OASHL;
117219b2ee8SDavid du Colombier 			r->vconst = v;
118*7dd7cddfSDavid du Colombier 			r->type = types[TINT];
1193e12c5d1SDavid du Colombier 		}
1203e12c5d1SDavid du Colombier 		v = vlog(l);
1213e12c5d1SDavid du Colombier 		if(v >= 0) {
1223e12c5d1SDavid du Colombier 			n->op = OASHL;
1233e12c5d1SDavid du Colombier 			n->left = r;
1243e12c5d1SDavid du Colombier 			n->right = l;
1253e12c5d1SDavid du Colombier 			r = l;
1263e12c5d1SDavid du Colombier 			l = n->left;
127219b2ee8SDavid du Colombier 			r->vconst = v;
128*7dd7cddfSDavid du Colombier 			r->type = types[TINT];
1293e12c5d1SDavid du Colombier 		}
1303e12c5d1SDavid du Colombier 		break;
1313e12c5d1SDavid du Colombier 
1323e12c5d1SDavid du Colombier 	case OASLDIV:
1333e12c5d1SDavid du Colombier 		xcom(l);
1343e12c5d1SDavid du Colombier 		xcom(r);
1353e12c5d1SDavid du Colombier 		v = vlog(r);
1363e12c5d1SDavid du Colombier 		if(v >= 0) {
1373e12c5d1SDavid du Colombier 			n->op = OASLSHR;
138219b2ee8SDavid du Colombier 			r->vconst = v;
139*7dd7cddfSDavid du Colombier 			r->type = types[TINT];
1403e12c5d1SDavid du Colombier 		}
1413e12c5d1SDavid du Colombier 		break;
1423e12c5d1SDavid du Colombier 
1433e12c5d1SDavid du Colombier 	case OLDIV:
1443e12c5d1SDavid du Colombier 		xcom(l);
1453e12c5d1SDavid du Colombier 		xcom(r);
1463e12c5d1SDavid du Colombier 		v = vlog(r);
1473e12c5d1SDavid du Colombier 		if(v >= 0) {
1483e12c5d1SDavid du Colombier 			n->op = OLSHR;
149219b2ee8SDavid du Colombier 			r->vconst = v;
150*7dd7cddfSDavid du Colombier 			r->type = types[TINT];
1513e12c5d1SDavid du Colombier 		}
1523e12c5d1SDavid du Colombier 		break;
1533e12c5d1SDavid du Colombier 
1543e12c5d1SDavid du Colombier 	case OASLMOD:
1553e12c5d1SDavid du Colombier 		xcom(l);
1563e12c5d1SDavid du Colombier 		xcom(r);
1573e12c5d1SDavid du Colombier 		v = vlog(r);
1583e12c5d1SDavid du Colombier 		if(v >= 0) {
1593e12c5d1SDavid du Colombier 			n->op = OASAND;
160219b2ee8SDavid du Colombier 			r->vconst--;
1613e12c5d1SDavid du Colombier 		}
1623e12c5d1SDavid du Colombier 		break;
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 	case OLMOD:
1653e12c5d1SDavid du Colombier 		xcom(l);
1663e12c5d1SDavid du Colombier 		xcom(r);
1673e12c5d1SDavid du Colombier 		v = vlog(r);
1683e12c5d1SDavid du Colombier 		if(v >= 0) {
1693e12c5d1SDavid du Colombier 			n->op = OAND;
170219b2ee8SDavid du Colombier 			r->vconst--;
1713e12c5d1SDavid du Colombier 		}
1723e12c5d1SDavid du Colombier 		break;
1733e12c5d1SDavid du Colombier 
1743e12c5d1SDavid du Colombier 	default:
1753e12c5d1SDavid du Colombier 		if(l != Z)
1763e12c5d1SDavid du Colombier 			xcom(l);
1773e12c5d1SDavid du Colombier 		if(r != Z)
1783e12c5d1SDavid du Colombier 			xcom(r);
1793e12c5d1SDavid du Colombier 		break;
1803e12c5d1SDavid du Colombier 	}
1813e12c5d1SDavid du Colombier 	if(n->addable >= 10)
1823e12c5d1SDavid du Colombier 		return;
1833e12c5d1SDavid du Colombier 	if(l != Z)
1843e12c5d1SDavid du Colombier 		n->complex = l->complex;
1853e12c5d1SDavid du Colombier 	if(r != Z) {
1863e12c5d1SDavid du Colombier 		if(r->complex == n->complex)
1873e12c5d1SDavid du Colombier 			n->complex = r->complex+1;
1883e12c5d1SDavid du Colombier 		else
1893e12c5d1SDavid du Colombier 		if(r->complex > n->complex)
1903e12c5d1SDavid du Colombier 			n->complex = r->complex;
1913e12c5d1SDavid du Colombier 	}
1923e12c5d1SDavid du Colombier 	if(n->complex == 0)
1933e12c5d1SDavid du Colombier 		n->complex++;
194219b2ee8SDavid du Colombier 
195219b2ee8SDavid du Colombier 	if(com64(n))
196219b2ee8SDavid du Colombier 		return;
197219b2ee8SDavid du Colombier 
1983e12c5d1SDavid du Colombier 	switch(n->op) {
1993e12c5d1SDavid du Colombier 
2003e12c5d1SDavid du Colombier 	case OFUNC:
2013e12c5d1SDavid du Colombier 		n->complex = FNX;
2023e12c5d1SDavid du Colombier 		break;
2033e12c5d1SDavid du Colombier 
2043e12c5d1SDavid du Colombier 	case OEQ:
2053e12c5d1SDavid du Colombier 	case ONE:
2063e12c5d1SDavid du Colombier 	case OLE:
2073e12c5d1SDavid du Colombier 	case OLT:
2083e12c5d1SDavid du Colombier 	case OGE:
2093e12c5d1SDavid du Colombier 	case OGT:
2103e12c5d1SDavid du Colombier 	case OHI:
2113e12c5d1SDavid du Colombier 	case OHS:
2123e12c5d1SDavid du Colombier 	case OLO:
2133e12c5d1SDavid du Colombier 	case OLS:
2143e12c5d1SDavid du Colombier 		/*
2153e12c5d1SDavid du Colombier 		 * immediate operators, make const on right
2163e12c5d1SDavid du Colombier 		 */
2173e12c5d1SDavid du Colombier 		if(l->op == OCONST) {
2183e12c5d1SDavid du Colombier 			n->left = r;
2193e12c5d1SDavid du Colombier 			n->right = l;
2203e12c5d1SDavid du Colombier 			n->op = invrel[relindex(n->op)];
2213e12c5d1SDavid du Colombier 		}
2223e12c5d1SDavid du Colombier 		break;
2233e12c5d1SDavid du Colombier 
2243e12c5d1SDavid du Colombier 	case OADD:
2253e12c5d1SDavid du Colombier 	case OXOR:
2263e12c5d1SDavid du Colombier 	case OAND:
2273e12c5d1SDavid du Colombier 	case OOR:
2283e12c5d1SDavid du Colombier 		/*
2293e12c5d1SDavid du Colombier 		 * immediate operators, make const on right
2303e12c5d1SDavid du Colombier 		 */
2313e12c5d1SDavid du Colombier 		if(l->op == OCONST) {
2323e12c5d1SDavid du Colombier 			n->left = r;
2333e12c5d1SDavid du Colombier 			n->right = l;
2343e12c5d1SDavid du Colombier 		}
2353e12c5d1SDavid du Colombier 		break;
2363e12c5d1SDavid du Colombier 	}
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier 
239