xref: /plan9/sys/src/cmd/vc/txt.c (revision 5ede6b933ae6ff5cdb9c502ac6721ed717ce4cfb)
13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier 
33e12c5d1SDavid du Colombier void
ginit(void)43e12c5d1SDavid du Colombier ginit(void)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier 	int i;
73e12c5d1SDavid du Colombier 	Type *t;
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier 	thechar = 'v';
103e12c5d1SDavid du Colombier 	thestring = "mips";
113e12c5d1SDavid du Colombier 	exregoffset = REGEXT;
123e12c5d1SDavid du Colombier 	exfregoffset = FREGEXT;
133e12c5d1SDavid du Colombier 	listinit();
143e12c5d1SDavid du Colombier 	nstring = 0;
153e12c5d1SDavid du Colombier 	mnstring = 0;
163e12c5d1SDavid du Colombier 	nrathole = 0;
173e12c5d1SDavid du Colombier 	pc = 0;
183e12c5d1SDavid du Colombier 	breakpc = -1;
193e12c5d1SDavid du Colombier 	continpc = -1;
203e12c5d1SDavid du Colombier 	cases = C;
213e12c5d1SDavid du Colombier 	firstp = P;
223e12c5d1SDavid du Colombier 	lastp = P;
237dd7cddfSDavid du Colombier 	tfield = types[TLONG];
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier 	zprog.link = P;
263e12c5d1SDavid du Colombier 	zprog.as = AGOK;
273e12c5d1SDavid du Colombier 	zprog.reg = NREG;
283e12c5d1SDavid du Colombier 	zprog.from.type = D_NONE;
293e12c5d1SDavid du Colombier 	zprog.from.name = D_NONE;
303e12c5d1SDavid du Colombier 	zprog.from.reg = NREG;
313e12c5d1SDavid du Colombier 	zprog.to = zprog.from;
323e12c5d1SDavid du Colombier 
333e12c5d1SDavid du Colombier 	regnode.op = OREGISTER;
343e12c5d1SDavid du Colombier 	regnode.class = CEXREG;
353e12c5d1SDavid du Colombier 	regnode.reg = REGTMP;
363e12c5d1SDavid du Colombier 	regnode.complex = 0;
373e12c5d1SDavid du Colombier 	regnode.addable = 11;
383e12c5d1SDavid du Colombier 	regnode.type = types[TLONG];
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier 	constnode.op = OCONST;
413e12c5d1SDavid du Colombier 	constnode.class = CXXX;
423e12c5d1SDavid du Colombier 	constnode.complex = 0;
433e12c5d1SDavid du Colombier 	constnode.addable = 20;
443e12c5d1SDavid du Colombier 	constnode.type = types[TLONG];
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	fconstnode.op = OCONST;
473e12c5d1SDavid du Colombier 	fconstnode.class = CXXX;
483e12c5d1SDavid du Colombier 	fconstnode.complex = 0;
493e12c5d1SDavid du Colombier 	fconstnode.addable = 20;
503e12c5d1SDavid du Colombier 	fconstnode.type = types[TDOUBLE];
513e12c5d1SDavid du Colombier 
523e12c5d1SDavid du Colombier 	nodsafe = new(ONAME, Z, Z);
533e12c5d1SDavid du Colombier 	nodsafe->sym = slookup(".safe");
547dd7cddfSDavid du Colombier 	nodsafe->type = types[TINT];
557dd7cddfSDavid du Colombier 	nodsafe->etype = types[TINT]->etype;
563e12c5d1SDavid du Colombier 	nodsafe->class = CAUTO;
573e12c5d1SDavid du Colombier 	complex(nodsafe);
583e12c5d1SDavid du Colombier 
593e12c5d1SDavid du Colombier 	t = typ(TARRAY, types[TCHAR]);
603e12c5d1SDavid du Colombier 	symrathole = slookup(".rathole");
613e12c5d1SDavid du Colombier 	symrathole->class = CGLOBL;
623e12c5d1SDavid du Colombier 	symrathole->type = t;
633e12c5d1SDavid du Colombier 
643e12c5d1SDavid du Colombier 	nodrat = new(ONAME, Z, Z);
653e12c5d1SDavid du Colombier 	nodrat->sym = symrathole;
663e12c5d1SDavid du Colombier 	nodrat->type = types[TIND];
673e12c5d1SDavid du Colombier 	nodrat->etype = TVOID;
683e12c5d1SDavid du Colombier 	nodrat->class = CGLOBL;
693e12c5d1SDavid du Colombier 	complex(nodrat);
703e12c5d1SDavid du Colombier 	nodrat->type = t;
713e12c5d1SDavid du Colombier 
723e12c5d1SDavid du Colombier 	nodret = new(ONAME, Z, Z);
733e12c5d1SDavid du Colombier 	nodret->sym = slookup(".ret");
743e12c5d1SDavid du Colombier 	nodret->type = types[TIND];
753e12c5d1SDavid du Colombier 	nodret->etype = TIND;
763e12c5d1SDavid du Colombier 	nodret->class = CPARAM;
773e12c5d1SDavid du Colombier 	nodret = new(OIND, nodret, Z);
783e12c5d1SDavid du Colombier 	complex(nodret);
793e12c5d1SDavid du Colombier 
80219b2ee8SDavid du Colombier 	com64init();
81219b2ee8SDavid du Colombier 
827dd7cddfSDavid du Colombier 	for(i=0; i<nelem(reg); i++) {
837dd7cddfSDavid du Colombier 		reg[i] = 0;
847dd7cddfSDavid du Colombier 		if(i == REGZERO ||
857dd7cddfSDavid du Colombier 		  (i >= NREG && ((i-NREG)&1)))
867dd7cddfSDavid du Colombier 			reg[i] = 1;
877dd7cddfSDavid du Colombier 	}
883e12c5d1SDavid du Colombier }
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier void
gclean(void)913e12c5d1SDavid du Colombier gclean(void)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier 	int i;
943e12c5d1SDavid du Colombier 	Sym *s;
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 	for(i=0; i<NREG; i++)
973e12c5d1SDavid du Colombier 		if(i != REGZERO)
983e12c5d1SDavid du Colombier 			if(reg[i])
993e12c5d1SDavid du Colombier 				diag(Z, "reg %d left allocated", i);
1003e12c5d1SDavid du Colombier 	for(i=NREG; i<NREG+NREG; i+=2)
1013e12c5d1SDavid du Colombier 		if(reg[i])
1023e12c5d1SDavid du Colombier 			diag(Z, "freg %d left allocated", i-NREG);
1033e12c5d1SDavid du Colombier 	while(mnstring)
1043e12c5d1SDavid du Colombier 		outstring("", 1L);
1053e12c5d1SDavid du Colombier 	symstring->type->width = nstring;
1063e12c5d1SDavid du Colombier 	symrathole->type->width = nrathole;
1073e12c5d1SDavid du Colombier 	for(i=0; i<NHASH; i++)
1083e12c5d1SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link) {
1093e12c5d1SDavid du Colombier 		if(s->type == T)
1103e12c5d1SDavid du Colombier 			continue;
1113e12c5d1SDavid du Colombier 		if(s->type->width == 0)
1123e12c5d1SDavid du Colombier 			continue;
1133e12c5d1SDavid du Colombier 		if(s->class != CGLOBL && s->class != CSTATIC)
1143e12c5d1SDavid du Colombier 			continue;
1153e12c5d1SDavid du Colombier 		if(s->type == types[TENUM])
1163e12c5d1SDavid du Colombier 			continue;
1173e12c5d1SDavid du Colombier 		gpseudo(AGLOBL, s, nodconst(s->type->width));
1183e12c5d1SDavid du Colombier 	}
1193e12c5d1SDavid du Colombier 	nextpc();
1203e12c5d1SDavid du Colombier 	p->as = AEND;
1213e12c5d1SDavid du Colombier 	outcode();
1223e12c5d1SDavid du Colombier }
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier void
nextpc(void)1253e12c5d1SDavid du Colombier nextpc(void)
1263e12c5d1SDavid du Colombier {
1273e12c5d1SDavid du Colombier 
1287dd7cddfSDavid du Colombier 	p = alloc(sizeof(*p));
1293e12c5d1SDavid du Colombier 	*p = zprog;
1303e12c5d1SDavid du Colombier 	p->lineno = nearln;
1313e12c5d1SDavid du Colombier 	pc++;
1323e12c5d1SDavid du Colombier 	if(firstp == P) {
1333e12c5d1SDavid du Colombier 		firstp = p;
1343e12c5d1SDavid du Colombier 		lastp = p;
1353e12c5d1SDavid du Colombier 		return;
1363e12c5d1SDavid du Colombier 	}
1373e12c5d1SDavid du Colombier 	lastp->link = p;
1383e12c5d1SDavid du Colombier 	lastp = p;
1393e12c5d1SDavid du Colombier }
1403e12c5d1SDavid du Colombier 
1413e12c5d1SDavid du Colombier void
gargs(Node * n,Node * tn1,Node * tn2)1423e12c5d1SDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2)
1433e12c5d1SDavid du Colombier {
1443e12c5d1SDavid du Colombier 	long regs;
1453e12c5d1SDavid du Colombier 	Node fnxargs[20], *fnxp;
1463e12c5d1SDavid du Colombier 
1473e12c5d1SDavid du Colombier 	regs = cursafe;
1483e12c5d1SDavid du Colombier 
1493e12c5d1SDavid du Colombier 	fnxp = fnxargs;
1503e12c5d1SDavid du Colombier 	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
1513e12c5d1SDavid du Colombier 
1523e12c5d1SDavid du Colombier 	curarg = 0;
1533e12c5d1SDavid du Colombier 	fnxp = fnxargs;
1543e12c5d1SDavid du Colombier 	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
1553e12c5d1SDavid du Colombier 
1563e12c5d1SDavid du Colombier 	cursafe = regs;
1573e12c5d1SDavid du Colombier }
1583e12c5d1SDavid du Colombier 
1593e12c5d1SDavid du Colombier void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)1603e12c5d1SDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
1613e12c5d1SDavid du Colombier {
1623e12c5d1SDavid du Colombier 	Node nod;
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 	if(n == Z)
1653e12c5d1SDavid du Colombier 		return;
1663e12c5d1SDavid du Colombier 	if(n->op == OLIST) {
1673e12c5d1SDavid du Colombier 		garg1(n->left, tn1, tn2, f, fnxp);
1683e12c5d1SDavid du Colombier 		garg1(n->right, tn1, tn2, f, fnxp);
1693e12c5d1SDavid du Colombier 		return;
1703e12c5d1SDavid du Colombier 	}
1713e12c5d1SDavid du Colombier 	if(f == 0) {
1723e12c5d1SDavid du Colombier 		if(n->complex >= FNX) {
1733e12c5d1SDavid du Colombier 			regsalloc(*fnxp, n);
1743e12c5d1SDavid du Colombier 			nod = znode;
1753e12c5d1SDavid du Colombier 			nod.op = OAS;
1763e12c5d1SDavid du Colombier 			nod.left = *fnxp;
1773e12c5d1SDavid du Colombier 			nod.right = n;
1783e12c5d1SDavid du Colombier 			nod.type = n->type;
1793e12c5d1SDavid du Colombier 			cgen(&nod, Z);
1803e12c5d1SDavid du Colombier 			(*fnxp)++;
1813e12c5d1SDavid du Colombier 		}
1823e12c5d1SDavid du Colombier 		return;
1833e12c5d1SDavid du Colombier 	}
184219b2ee8SDavid du Colombier 	if(typesuv[n->type->etype]) {
1853e12c5d1SDavid du Colombier 		regaalloc(tn2, n);
1863e12c5d1SDavid du Colombier 		if(n->complex >= FNX) {
1873e12c5d1SDavid du Colombier 			sugen(*fnxp, tn2, n->type->width);
1883e12c5d1SDavid du Colombier 			(*fnxp)++;
1893e12c5d1SDavid du Colombier 		} else
1903e12c5d1SDavid du Colombier 			sugen(n, tn2, n->type->width);
1913e12c5d1SDavid du Colombier 		return;
1923e12c5d1SDavid du Colombier 	}
1933e12c5d1SDavid du Colombier 	if(REGARG && curarg == 0 && typechlp[n->type->etype]) {
1943e12c5d1SDavid du Colombier 		regaalloc1(tn1, n);
1953e12c5d1SDavid du Colombier 		if(n->complex >= FNX) {
1963e12c5d1SDavid du Colombier 			cgen(*fnxp, tn1);
1973e12c5d1SDavid du Colombier 			(*fnxp)++;
1983e12c5d1SDavid du Colombier 		} else
1993e12c5d1SDavid du Colombier 			cgen(n, tn1);
2003e12c5d1SDavid du Colombier 		return;
2013e12c5d1SDavid du Colombier 	}
2023e12c5d1SDavid du Colombier 	if(vconst(n) == 0) {
2033e12c5d1SDavid du Colombier 		regaalloc(tn2, n);
2043e12c5d1SDavid du Colombier 		gopcode(OAS, n, Z, tn2);
2053e12c5d1SDavid du Colombier 		return;
2063e12c5d1SDavid du Colombier 	}
2073e12c5d1SDavid du Colombier 	regalloc(tn1, n, Z);
2083e12c5d1SDavid du Colombier 	if(n->complex >= FNX) {
2093e12c5d1SDavid du Colombier 		cgen(*fnxp, tn1);
2103e12c5d1SDavid du Colombier 		(*fnxp)++;
2113e12c5d1SDavid du Colombier 	} else
2123e12c5d1SDavid du Colombier 		cgen(n, tn1);
2133e12c5d1SDavid du Colombier 	regaalloc(tn2, n);
2143e12c5d1SDavid du Colombier 	gopcode(OAS, tn1, Z, tn2);
2153e12c5d1SDavid du Colombier 	regfree(tn1);
2163e12c5d1SDavid du Colombier }
2173e12c5d1SDavid du Colombier 
2183e12c5d1SDavid du Colombier Node*
nodconst(long v)2193e12c5d1SDavid du Colombier nodconst(long v)
2203e12c5d1SDavid du Colombier {
221219b2ee8SDavid du Colombier 	constnode.vconst = v;
222219b2ee8SDavid du Colombier 	return &constnode;
223219b2ee8SDavid du Colombier }
224219b2ee8SDavid du Colombier 
225219b2ee8SDavid du Colombier Node*
nod32const(vlong v)226219b2ee8SDavid du Colombier nod32const(vlong v)
227219b2ee8SDavid du Colombier {
228219b2ee8SDavid du Colombier 	constnode.vconst = v & MASK(32);
2293e12c5d1SDavid du Colombier 	return &constnode;
2303e12c5d1SDavid du Colombier }
2313e12c5d1SDavid du Colombier 
2323e12c5d1SDavid du Colombier Node*
nodfconst(double d)233bd389b36SDavid du Colombier nodfconst(double d)
2343e12c5d1SDavid du Colombier {
235219b2ee8SDavid du Colombier 	fconstnode.fconst = d;
2363e12c5d1SDavid du Colombier 	return &fconstnode;
2373e12c5d1SDavid du Colombier }
2383e12c5d1SDavid du Colombier 
2393e12c5d1SDavid du Colombier void
nodreg(Node * n,Node * nn,int reg)2403e12c5d1SDavid du Colombier nodreg(Node *n, Node *nn, int reg)
2413e12c5d1SDavid du Colombier {
2423e12c5d1SDavid du Colombier 	*n = regnode;
2433e12c5d1SDavid du Colombier 	n->reg = reg;
2443e12c5d1SDavid du Colombier 	n->type = nn->type;
2453e12c5d1SDavid du Colombier 	n->lineno = nn->lineno;
2463e12c5d1SDavid du Colombier }
2473e12c5d1SDavid du Colombier 
2483e12c5d1SDavid du Colombier void
regret(Node * n,Node * nn)2493e12c5d1SDavid du Colombier regret(Node *n, Node *nn)
2503e12c5d1SDavid du Colombier {
2513e12c5d1SDavid du Colombier 	int r;
2523e12c5d1SDavid du Colombier 
2533e12c5d1SDavid du Colombier 	r = REGRET;
254219b2ee8SDavid du Colombier 	if(typefd[nn->type->etype])
2553e12c5d1SDavid du Colombier 		r = FREGRET+NREG;
2563e12c5d1SDavid du Colombier 	nodreg(n, nn, r);
2573e12c5d1SDavid du Colombier 	reg[r]++;
2583e12c5d1SDavid du Colombier }
2593e12c5d1SDavid du Colombier 
2607dd7cddfSDavid du Colombier int
tmpreg(void)2613e12c5d1SDavid du Colombier tmpreg(void)
2623e12c5d1SDavid du Colombier {
2633e12c5d1SDavid du Colombier 	int i;
2643e12c5d1SDavid du Colombier 
2653e12c5d1SDavid du Colombier 	for(i=REGRET+1; i<NREG; i++)
2663e12c5d1SDavid du Colombier 		if(reg[i] == 0)
2673e12c5d1SDavid du Colombier 			return i;
2683e12c5d1SDavid du Colombier 	diag(Z, "out of fixed registers");
2693e12c5d1SDavid du Colombier 	return 0;
2703e12c5d1SDavid du Colombier }
2713e12c5d1SDavid du Colombier 
2723e12c5d1SDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)2733e12c5d1SDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
2743e12c5d1SDavid du Colombier {
2753e12c5d1SDavid du Colombier 	int i, j;
276375daca8SDavid du Colombier 	static int lasti;
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier 	switch(tn->type->etype) {
2793e12c5d1SDavid du Colombier 	case TCHAR:
2803e12c5d1SDavid du Colombier 	case TUCHAR:
2813e12c5d1SDavid du Colombier 	case TSHORT:
2823e12c5d1SDavid du Colombier 	case TUSHORT:
2837dd7cddfSDavid du Colombier 	case TINT:
2847dd7cddfSDavid du Colombier 	case TUINT:
2853e12c5d1SDavid du Colombier 	case TLONG:
2863e12c5d1SDavid du Colombier 	case TULONG:
2873e12c5d1SDavid du Colombier 	case TIND:
2883e12c5d1SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
2893e12c5d1SDavid du Colombier 			i = o->reg;
2903e12c5d1SDavid du Colombier 			if(i > 0 && i < NREG)
2913e12c5d1SDavid du Colombier 				goto out;
2923e12c5d1SDavid du Colombier 		}
2933e12c5d1SDavid du Colombier 		j = lasti + REGRET+1;
2943e12c5d1SDavid du Colombier 		for(i=REGRET+1; i<NREG; i++) {
2953e12c5d1SDavid du Colombier 			if(j >= NREG)
2963e12c5d1SDavid du Colombier 				j = REGRET+1;
2973e12c5d1SDavid du Colombier 			if(reg[j] == 0) {
2983e12c5d1SDavid du Colombier 				i = j;
2993e12c5d1SDavid du Colombier 				goto out;
3003e12c5d1SDavid du Colombier 			}
3013e12c5d1SDavid du Colombier 			j++;
3023e12c5d1SDavid du Colombier 		}
3033e12c5d1SDavid du Colombier 		diag(tn, "out of fixed registers");
3043e12c5d1SDavid du Colombier 		goto err;
3053e12c5d1SDavid du Colombier 
3063e12c5d1SDavid du Colombier 	case TFLOAT:
3073e12c5d1SDavid du Colombier 	case TDOUBLE:
3083e12c5d1SDavid du Colombier 	case TVLONG:
3093e12c5d1SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
3103e12c5d1SDavid du Colombier 			i = o->reg;
3113e12c5d1SDavid du Colombier 			if(i >= NREG && i < NREG+NREG)
3123e12c5d1SDavid du Colombier 				goto out;
3133e12c5d1SDavid du Colombier 		}
314219b2ee8SDavid du Colombier 		j = 0*2 + NREG;
3153e12c5d1SDavid du Colombier 		for(i=NREG; i<NREG+NREG; i+=2) {
3163e12c5d1SDavid du Colombier 			if(j >= NREG+NREG)
3173e12c5d1SDavid du Colombier 				j = NREG;
3183e12c5d1SDavid du Colombier 			if(reg[j] == 0) {
3193e12c5d1SDavid du Colombier 				i = j;
3203e12c5d1SDavid du Colombier 				goto out;
3213e12c5d1SDavid du Colombier 			}
3223e12c5d1SDavid du Colombier 			j += 2;
3233e12c5d1SDavid du Colombier 		}
3243e12c5d1SDavid du Colombier 		diag(tn, "out of float registers");
3253e12c5d1SDavid du Colombier 		goto err;
3263e12c5d1SDavid du Colombier 	}
3273e12c5d1SDavid du Colombier 	diag(tn, "unknown type in regalloc: %T", tn->type);
3283e12c5d1SDavid du Colombier err:
3297dd7cddfSDavid du Colombier 	nodreg(n, tn, 0);
3307dd7cddfSDavid du Colombier 	return;
3313e12c5d1SDavid du Colombier out:
3323e12c5d1SDavid du Colombier 	reg[i]++;
3333e12c5d1SDavid du Colombier 	lasti++;
3343e12c5d1SDavid du Colombier 	if(lasti >= 5)
3353e12c5d1SDavid du Colombier 		lasti = 0;
3363e12c5d1SDavid du Colombier 	nodreg(n, tn, i);
3373e12c5d1SDavid du Colombier }
3383e12c5d1SDavid du Colombier 
3393e12c5d1SDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)3403e12c5d1SDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
3413e12c5d1SDavid du Colombier {
3423e12c5d1SDavid du Colombier 	Node nod;
3433e12c5d1SDavid du Colombier 
3443e12c5d1SDavid du Colombier 	nod = *tn;
3453e12c5d1SDavid du Colombier 	nod.type = types[TIND];
3463e12c5d1SDavid du Colombier 	regalloc(n, &nod, o);
3473e12c5d1SDavid du Colombier }
3483e12c5d1SDavid du Colombier 
3493e12c5d1SDavid du Colombier void
regfree(Node * n)3503e12c5d1SDavid du Colombier regfree(Node *n)
3513e12c5d1SDavid du Colombier {
3523e12c5d1SDavid du Colombier 	int i;
3533e12c5d1SDavid du Colombier 
3543e12c5d1SDavid du Colombier 	i = 0;
3553e12c5d1SDavid du Colombier 	if(n->op != OREGISTER && n->op != OINDREG)
3563e12c5d1SDavid du Colombier 		goto err;
3573e12c5d1SDavid du Colombier 	i = n->reg;
3583e12c5d1SDavid du Colombier 	if(i < 0 || i >= sizeof(reg))
3593e12c5d1SDavid du Colombier 		goto err;
3603e12c5d1SDavid du Colombier 	if(reg[i] <= 0)
3613e12c5d1SDavid du Colombier 		goto err;
3623e12c5d1SDavid du Colombier 	reg[i]--;
3633e12c5d1SDavid du Colombier 	return;
3643e12c5d1SDavid du Colombier err:
3653e12c5d1SDavid du Colombier 	diag(n, "error in regfree: %d", i);
3663e12c5d1SDavid du Colombier }
3673e12c5d1SDavid du Colombier 
3683e12c5d1SDavid du Colombier void
regsalloc(Node * n,Node * nn)3693e12c5d1SDavid du Colombier regsalloc(Node *n, Node *nn)
3703e12c5d1SDavid du Colombier {
3717dd7cddfSDavid du Colombier 	cursafe = align(cursafe, nn->type, Aaut3);
3727dd7cddfSDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3733e12c5d1SDavid du Colombier 	*n = *nodsafe;
374219b2ee8SDavid du Colombier 	n->xoffset = -(stkoff + cursafe);
3753e12c5d1SDavid du Colombier 	n->type = nn->type;
3763e12c5d1SDavid du Colombier 	n->etype = nn->type->etype;
3773e12c5d1SDavid du Colombier 	n->lineno = nn->lineno;
3783e12c5d1SDavid du Colombier }
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier void
regaalloc1(Node * n,Node * nn)3813e12c5d1SDavid du Colombier regaalloc1(Node *n, Node *nn)
3823e12c5d1SDavid du Colombier {
3837dd7cddfSDavid du Colombier 	nodreg(n, nn, REGARG);
3847dd7cddfSDavid du Colombier 	reg[REGARG]++;
3857dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
3867dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
3877dd7cddfSDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3883e12c5d1SDavid du Colombier }
3893e12c5d1SDavid du Colombier 
3903e12c5d1SDavid du Colombier void
regaalloc(Node * n,Node * nn)3913e12c5d1SDavid du Colombier regaalloc(Node *n, Node *nn)
3923e12c5d1SDavid du Colombier {
3937dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
3943e12c5d1SDavid du Colombier 	*n = *nn;
3953e12c5d1SDavid du Colombier 	n->op = OINDREG;
3963e12c5d1SDavid du Colombier 	n->reg = REGSP;
3977dd7cddfSDavid du Colombier 	n->xoffset = curarg + SZ_LONG;
3983e12c5d1SDavid du Colombier 	n->complex = 0;
3993e12c5d1SDavid du Colombier 	n->addable = 20;
4007dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
4017dd7cddfSDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
4023e12c5d1SDavid du Colombier }
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier void
regind(Node * n,Node * nn)4053e12c5d1SDavid du Colombier regind(Node *n, Node *nn)
4063e12c5d1SDavid du Colombier {
4073e12c5d1SDavid du Colombier 
4083e12c5d1SDavid du Colombier 	if(n->op != OREGISTER) {
4093e12c5d1SDavid du Colombier 		diag(n, "regind not OREGISTER");
4103e12c5d1SDavid du Colombier 		return;
4113e12c5d1SDavid du Colombier 	}
4123e12c5d1SDavid du Colombier 	n->op = OINDREG;
4133e12c5d1SDavid du Colombier 	n->type = nn->type;
4143e12c5d1SDavid du Colombier }
4153e12c5d1SDavid du Colombier 
4163e12c5d1SDavid du Colombier void
raddr(Node * n,Prog * p)4173e12c5d1SDavid du Colombier raddr(Node *n, Prog *p)
4183e12c5d1SDavid du Colombier {
4193e12c5d1SDavid du Colombier 	Adr a;
4203e12c5d1SDavid du Colombier 
4213e12c5d1SDavid du Colombier 	naddr(n, &a);
4223e12c5d1SDavid du Colombier 	if(a.type == D_CONST && a.offset == 0) {
4233e12c5d1SDavid du Colombier 		a.type = D_REG;
4243e12c5d1SDavid du Colombier 		a.reg = 0;
4253e12c5d1SDavid du Colombier 	}
4263e12c5d1SDavid du Colombier 	if(a.type != D_REG && a.type != D_FREG) {
4273e12c5d1SDavid du Colombier 		if(n)
4283e12c5d1SDavid du Colombier 			diag(n, "bad in raddr: %O", n->op);
4293e12c5d1SDavid du Colombier 		else
4303e12c5d1SDavid du Colombier 			diag(n, "bad in raddr: <null>");
4313e12c5d1SDavid du Colombier 		p->reg = NREG;
4323e12c5d1SDavid du Colombier 	} else
4333e12c5d1SDavid du Colombier 		p->reg = a.reg;
4343e12c5d1SDavid du Colombier }
4353e12c5d1SDavid du Colombier 
4363e12c5d1SDavid du Colombier void
naddr(Node * n,Adr * a)4373e12c5d1SDavid du Colombier naddr(Node *n, Adr *a)
4383e12c5d1SDavid du Colombier {
4393e12c5d1SDavid du Colombier 	long v;
4403e12c5d1SDavid du Colombier 
4413e12c5d1SDavid du Colombier 	a->type = D_NONE;
4423e12c5d1SDavid du Colombier 	if(n == Z)
4433e12c5d1SDavid du Colombier 		return;
4443e12c5d1SDavid du Colombier 	switch(n->op) {
4453e12c5d1SDavid du Colombier 	default:
4463e12c5d1SDavid du Colombier 	bad:
4473e12c5d1SDavid du Colombier 		diag(n, "bad in naddr: %O", n->op);
4483e12c5d1SDavid du Colombier 		break;
4493e12c5d1SDavid du Colombier 
4503e12c5d1SDavid du Colombier 	case OREGISTER:
4513e12c5d1SDavid du Colombier 		a->type = D_REG;
4523e12c5d1SDavid du Colombier 		a->sym = S;
4533e12c5d1SDavid du Colombier 		a->reg = n->reg;
4543e12c5d1SDavid du Colombier 		if(a->reg >= NREG) {
4553e12c5d1SDavid du Colombier 			a->type = D_FREG;
4563e12c5d1SDavid du Colombier 			a->reg -= NREG;
4573e12c5d1SDavid du Colombier 		}
4583e12c5d1SDavid du Colombier 		break;
4593e12c5d1SDavid du Colombier 
4603e12c5d1SDavid du Colombier 	case OIND:
4613e12c5d1SDavid du Colombier 		naddr(n->left, a);
4623e12c5d1SDavid du Colombier 		if(a->type == D_REG) {
4633e12c5d1SDavid du Colombier 			a->type = D_OREG;
4643e12c5d1SDavid du Colombier 			break;
4653e12c5d1SDavid du Colombier 		}
4663e12c5d1SDavid du Colombier 		if(a->type == D_CONST) {
4673e12c5d1SDavid du Colombier 			a->type = D_OREG;
4683e12c5d1SDavid du Colombier 			break;
4693e12c5d1SDavid du Colombier 		}
4703e12c5d1SDavid du Colombier 		goto bad;
4713e12c5d1SDavid du Colombier 
4723e12c5d1SDavid du Colombier 	case OINDREG:
4733e12c5d1SDavid du Colombier 		a->type = D_OREG;
4743e12c5d1SDavid du Colombier 		a->sym = S;
475219b2ee8SDavid du Colombier 		a->offset = n->xoffset;
4763e12c5d1SDavid du Colombier 		a->reg = n->reg;
4773e12c5d1SDavid du Colombier 		break;
4783e12c5d1SDavid du Colombier 
4793e12c5d1SDavid du Colombier 	case ONAME:
4803e12c5d1SDavid du Colombier 		a->etype = n->etype;
4813e12c5d1SDavid du Colombier 		a->type = D_OREG;
4823e12c5d1SDavid du Colombier 		a->name = D_STATIC;
4833e12c5d1SDavid du Colombier 		a->sym = n->sym;
484219b2ee8SDavid du Colombier 		a->offset = n->xoffset;
4853e12c5d1SDavid du Colombier 		if(n->class == CSTATIC)
4863e12c5d1SDavid du Colombier 			break;
4873e12c5d1SDavid du Colombier 		if(n->class == CEXTERN || n->class == CGLOBL) {
4883e12c5d1SDavid du Colombier 			a->name = D_EXTERN;
4893e12c5d1SDavid du Colombier 			break;
4903e12c5d1SDavid du Colombier 		}
4913e12c5d1SDavid du Colombier 		if(n->class == CAUTO) {
4923e12c5d1SDavid du Colombier 			a->name = D_AUTO;
4933e12c5d1SDavid du Colombier 			break;
4943e12c5d1SDavid du Colombier 		}
4953e12c5d1SDavid du Colombier 		if(n->class == CPARAM) {
4963e12c5d1SDavid du Colombier 			a->name = D_PARAM;
4973e12c5d1SDavid du Colombier 			break;
4983e12c5d1SDavid du Colombier 		}
4993e12c5d1SDavid du Colombier 		goto bad;
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier 	case OCONST:
5023e12c5d1SDavid du Colombier 		a->sym = S;
5033e12c5d1SDavid du Colombier 		a->reg = NREG;
504219b2ee8SDavid du Colombier 		if(typefd[n->type->etype]) {
5053e12c5d1SDavid du Colombier 			a->type = D_FCONST;
506219b2ee8SDavid du Colombier 			a->dval = n->fconst;
5073e12c5d1SDavid du Colombier 		} else {
5083e12c5d1SDavid du Colombier 			a->type = D_CONST;
509219b2ee8SDavid du Colombier 			a->offset = n->vconst;
5103e12c5d1SDavid du Colombier 		}
5113e12c5d1SDavid du Colombier 		break;
5123e12c5d1SDavid du Colombier 
5133e12c5d1SDavid du Colombier 	case OADDR:
5143e12c5d1SDavid du Colombier 		naddr(n->left, a);
5153e12c5d1SDavid du Colombier 		if(a->type == D_OREG) {
5163e12c5d1SDavid du Colombier 			a->type = D_CONST;
5173e12c5d1SDavid du Colombier 			break;
5183e12c5d1SDavid du Colombier 		}
5193e12c5d1SDavid du Colombier 		goto bad;
5203e12c5d1SDavid du Colombier 
5213e12c5d1SDavid du Colombier 	case OADD:
5223e12c5d1SDavid du Colombier 		if(n->left->op == OCONST) {
5233e12c5d1SDavid du Colombier 			naddr(n->left, a);
5243e12c5d1SDavid du Colombier 			v = a->offset;
5253e12c5d1SDavid du Colombier 			naddr(n->right, a);
5263e12c5d1SDavid du Colombier 		} else {
5273e12c5d1SDavid du Colombier 			naddr(n->right, a);
5283e12c5d1SDavid du Colombier 			v = a->offset;
5293e12c5d1SDavid du Colombier 			naddr(n->left, a);
5303e12c5d1SDavid du Colombier 		}
5313e12c5d1SDavid du Colombier 		a->offset += v;
5323e12c5d1SDavid du Colombier 		break;
5333e12c5d1SDavid du Colombier 
5343e12c5d1SDavid du Colombier 	}
5353e12c5d1SDavid du Colombier }
5363e12c5d1SDavid du Colombier 
5373e12c5d1SDavid du Colombier void
fop(int as,int f1,int f2,Node * t)5383e12c5d1SDavid du Colombier fop(int as, int f1, int f2, Node *t)
5393e12c5d1SDavid du Colombier {
5403e12c5d1SDavid du Colombier 	Node nod1, nod2, nod3;
5413e12c5d1SDavid du Colombier 
5423e12c5d1SDavid du Colombier 	nodreg(&nod1, t, NREG+f1);
5433e12c5d1SDavid du Colombier 	nodreg(&nod2, t, NREG+f2);
5443e12c5d1SDavid du Colombier 	regalloc(&nod3, t, t);
5453e12c5d1SDavid du Colombier 	gopcode(as, &nod1, &nod2, &nod3);
5463e12c5d1SDavid du Colombier 	gmove(&nod3, t);
5473e12c5d1SDavid du Colombier 	regfree(&nod3);
5483e12c5d1SDavid du Colombier }
5493e12c5d1SDavid du Colombier 
5503e12c5d1SDavid du Colombier void
gmove(Node * f,Node * t)5513e12c5d1SDavid du Colombier gmove(Node *f, Node *t)
5523e12c5d1SDavid du Colombier {
5533e12c5d1SDavid du Colombier 	int ft, tt, a;
5543e12c5d1SDavid du Colombier 	Node nod, nod1, nod2;
555bd389b36SDavid du Colombier 	Prog *p1;
5563e12c5d1SDavid du Colombier 	double d;
5573e12c5d1SDavid du Colombier 
5583e12c5d1SDavid du Colombier 	ft = f->type->etype;
5593e12c5d1SDavid du Colombier 	tt = t->type->etype;
5603e12c5d1SDavid du Colombier 
5613e12c5d1SDavid du Colombier 	if(ft == TDOUBLE && f->op == OCONST) {
562219b2ee8SDavid du Colombier 		d = f->fconst;
5633e12c5d1SDavid du Colombier 		if(d == 0.0) {
5643e12c5d1SDavid du Colombier 			a = FREGZERO;
5653e12c5d1SDavid du Colombier 			goto ffreg;
5663e12c5d1SDavid du Colombier 		}
5673e12c5d1SDavid du Colombier 		if(d == 0.5) {
5683e12c5d1SDavid du Colombier 			a = FREGHALF;
5693e12c5d1SDavid du Colombier 			goto ffreg;
5703e12c5d1SDavid du Colombier 		}
5713e12c5d1SDavid du Colombier 		if(d == 1.0) {
5723e12c5d1SDavid du Colombier 			a = FREGONE;
5733e12c5d1SDavid du Colombier 			goto ffreg;
5743e12c5d1SDavid du Colombier 		}
5753e12c5d1SDavid du Colombier 		if(d == 2.0) {
5763e12c5d1SDavid du Colombier 			a = FREGTWO;
5773e12c5d1SDavid du Colombier 			goto ffreg;
5783e12c5d1SDavid du Colombier 		}
5793e12c5d1SDavid du Colombier 		if(d == -.5) {
5803e12c5d1SDavid du Colombier 			fop(OSUB, FREGHALF, FREGZERO, t);
5813e12c5d1SDavid du Colombier 			return;
5823e12c5d1SDavid du Colombier 		}
5833e12c5d1SDavid du Colombier 		if(d == -1.0) {
5843e12c5d1SDavid du Colombier 			fop(OSUB, FREGONE, FREGZERO, t);
5853e12c5d1SDavid du Colombier 			return;
5863e12c5d1SDavid du Colombier 		}
5873e12c5d1SDavid du Colombier 		if(d == -2.0) {
5883e12c5d1SDavid du Colombier 			fop(OSUB, FREGTWO, FREGZERO, t);
5893e12c5d1SDavid du Colombier 			return;
5903e12c5d1SDavid du Colombier 		}
5913e12c5d1SDavid du Colombier 		if(d == 1.5) {
5923e12c5d1SDavid du Colombier 			fop(OADD, FREGONE, FREGHALF, t);
5933e12c5d1SDavid du Colombier 			return;
5943e12c5d1SDavid du Colombier 		}
5953e12c5d1SDavid du Colombier 		if(d == 2.5) {
5963e12c5d1SDavid du Colombier 			fop(OADD, FREGTWO, FREGHALF, t);
5973e12c5d1SDavid du Colombier 			return;
5983e12c5d1SDavid du Colombier 		}
5993e12c5d1SDavid du Colombier 		if(d == 3.0) {
6003e12c5d1SDavid du Colombier 			fop(OADD, FREGTWO, FREGONE, t);
6013e12c5d1SDavid du Colombier 			return;
6023e12c5d1SDavid du Colombier 		}
6033e12c5d1SDavid du Colombier 	}
6043e12c5d1SDavid du Colombier 	if(ft == TFLOAT && f->op == OCONST) {
605219b2ee8SDavid du Colombier 		d = f->fconst;
6063e12c5d1SDavid du Colombier 		if(d == 0) {
6073e12c5d1SDavid du Colombier 			a = FREGZERO;
6083e12c5d1SDavid du Colombier 		ffreg:
6093e12c5d1SDavid du Colombier 			nodreg(&nod, f, NREG+a);
6103e12c5d1SDavid du Colombier 			gmove(&nod, t);
6113e12c5d1SDavid du Colombier 			return;
6123e12c5d1SDavid du Colombier 		}
6133e12c5d1SDavid du Colombier 	}
6143e12c5d1SDavid du Colombier 	/*
6153e12c5d1SDavid du Colombier 	 * a load --
6163e12c5d1SDavid du Colombier 	 * put it into a register then
6173e12c5d1SDavid du Colombier 	 * worry what to do with it.
6183e12c5d1SDavid du Colombier 	 */
6193e12c5d1SDavid du Colombier 	if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
6203e12c5d1SDavid du Colombier 		switch(ft) {
6213e12c5d1SDavid du Colombier 		default:
622219b2ee8SDavid du Colombier 			if(typefd[tt]) {
6233e12c5d1SDavid du Colombier 				/* special case can load mem to Freg */
6243e12c5d1SDavid du Colombier 				regalloc(&nod, t, t);
6253e12c5d1SDavid du Colombier 				gins(AMOVW, f, &nod);
6263e12c5d1SDavid du Colombier 				a = AMOVWD;
6273e12c5d1SDavid du Colombier 				if(tt == TFLOAT)
6283e12c5d1SDavid du Colombier 					a = AMOVWF;
6293e12c5d1SDavid du Colombier 				gins(a, &nod, &nod);
6303e12c5d1SDavid du Colombier 				gmove(&nod, t);
6313e12c5d1SDavid du Colombier 				regfree(&nod);
6323e12c5d1SDavid du Colombier 				return;
6333e12c5d1SDavid du Colombier 			}
6343e12c5d1SDavid du Colombier 			a = AMOVW;
6353e12c5d1SDavid du Colombier 			break;
6363e12c5d1SDavid du Colombier 		case TFLOAT:
6373e12c5d1SDavid du Colombier 			a = AMOVF;
6383e12c5d1SDavid du Colombier 			break;
6393e12c5d1SDavid du Colombier 		case TDOUBLE:
6403e12c5d1SDavid du Colombier 			a = AMOVD;
6413e12c5d1SDavid du Colombier 			break;
6423e12c5d1SDavid du Colombier 		case TCHAR:
6433e12c5d1SDavid du Colombier 			a = AMOVB;
6443e12c5d1SDavid du Colombier 			break;
6453e12c5d1SDavid du Colombier 		case TUCHAR:
6463e12c5d1SDavid du Colombier 			a = AMOVBU;
6473e12c5d1SDavid du Colombier 			break;
6483e12c5d1SDavid du Colombier 		case TSHORT:
6493e12c5d1SDavid du Colombier 			a = AMOVH;
6503e12c5d1SDavid du Colombier 			break;
6513e12c5d1SDavid du Colombier 		case TUSHORT:
6523e12c5d1SDavid du Colombier 			a = AMOVHU;
6533e12c5d1SDavid du Colombier 			break;
6543e12c5d1SDavid du Colombier 		}
6557dd7cddfSDavid du Colombier 		if(typechlp[ft] && typeilp[tt])
6563e12c5d1SDavid du Colombier 			regalloc(&nod, t, t);
6573e12c5d1SDavid du Colombier 		else
6583e12c5d1SDavid du Colombier 			regalloc(&nod, f, t);
6593e12c5d1SDavid du Colombier 		gins(a, f, &nod);
6603e12c5d1SDavid du Colombier 		gmove(&nod, t);
6613e12c5d1SDavid du Colombier 		regfree(&nod);
6623e12c5d1SDavid du Colombier 		return;
6633e12c5d1SDavid du Colombier 	}
6643e12c5d1SDavid du Colombier 
6653e12c5d1SDavid du Colombier 	/*
6663e12c5d1SDavid du Colombier 	 * a store --
6673e12c5d1SDavid du Colombier 	 * put it into a register then
6683e12c5d1SDavid du Colombier 	 * store it.
6693e12c5d1SDavid du Colombier 	 */
6703e12c5d1SDavid du Colombier 	if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
6713e12c5d1SDavid du Colombier 		switch(tt) {
6723e12c5d1SDavid du Colombier 		default:
6733e12c5d1SDavid du Colombier 			a = AMOVW;
6743e12c5d1SDavid du Colombier 			break;
6753e12c5d1SDavid du Colombier 		case TUCHAR:
676375daca8SDavid du Colombier 			a = AMOVBU;
677375daca8SDavid du Colombier 			break;
6783e12c5d1SDavid du Colombier 		case TCHAR:
6793e12c5d1SDavid du Colombier 			a = AMOVB;
6803e12c5d1SDavid du Colombier 			break;
6813e12c5d1SDavid du Colombier 		case TUSHORT:
682375daca8SDavid du Colombier 			a = AMOVHU;
683375daca8SDavid du Colombier 			break;
6843e12c5d1SDavid du Colombier 		case TSHORT:
6853e12c5d1SDavid du Colombier 			a = AMOVH;
6863e12c5d1SDavid du Colombier 			break;
6873e12c5d1SDavid du Colombier 		case TFLOAT:
6883e12c5d1SDavid du Colombier 			a = AMOVF;
6893e12c5d1SDavid du Colombier 			break;
6903e12c5d1SDavid du Colombier 		case TDOUBLE:
6913e12c5d1SDavid du Colombier 			a = AMOVD;
6923e12c5d1SDavid du Colombier 			break;
6933e12c5d1SDavid du Colombier 		}
694219b2ee8SDavid du Colombier 		if(!typefd[ft] && vconst(f) == 0) {
6953e12c5d1SDavid du Colombier 			gins(a, f, t);
6963e12c5d1SDavid du Colombier 			return;
6973e12c5d1SDavid du Colombier 		}
6983e12c5d1SDavid du Colombier 		if(ft == tt)
6993e12c5d1SDavid du Colombier 			regalloc(&nod, t, f);
7003e12c5d1SDavid du Colombier 		else
7013e12c5d1SDavid du Colombier 			regalloc(&nod, t, Z);
7023e12c5d1SDavid du Colombier 		gmove(f, &nod);
7033e12c5d1SDavid du Colombier 		gins(a, &nod, t);
7043e12c5d1SDavid du Colombier 		regfree(&nod);
7053e12c5d1SDavid du Colombier 		return;
7063e12c5d1SDavid du Colombier 	}
7073e12c5d1SDavid du Colombier 
7083e12c5d1SDavid du Colombier 	/*
7093e12c5d1SDavid du Colombier 	 * type x type cross table
7103e12c5d1SDavid du Colombier 	 */
7113e12c5d1SDavid du Colombier 	a = AGOK;
7123e12c5d1SDavid du Colombier 	switch(ft) {
7133e12c5d1SDavid du Colombier 	case TDOUBLE:
7143e12c5d1SDavid du Colombier 	case TVLONG:
7153e12c5d1SDavid du Colombier 	case TFLOAT:
7163e12c5d1SDavid du Colombier 		switch(tt) {
7173e12c5d1SDavid du Colombier 		case TDOUBLE:
7183e12c5d1SDavid du Colombier 		case TVLONG:
7193e12c5d1SDavid du Colombier 			a = AMOVD;
7203e12c5d1SDavid du Colombier 			if(ft == TFLOAT)
7213e12c5d1SDavid du Colombier 				a = AMOVFD;
7223e12c5d1SDavid du Colombier 			break;
7233e12c5d1SDavid du Colombier 		case TFLOAT:
7243e12c5d1SDavid du Colombier 			a = AMOVDF;
7253e12c5d1SDavid du Colombier 			if(ft == TFLOAT)
7263e12c5d1SDavid du Colombier 				a = AMOVF;
7273e12c5d1SDavid du Colombier 			break;
7287dd7cddfSDavid du Colombier 		case TINT:
7297dd7cddfSDavid du Colombier 		case TUINT:
7303e12c5d1SDavid du Colombier 		case TLONG:
7313e12c5d1SDavid du Colombier 		case TULONG:
7323e12c5d1SDavid du Colombier 		case TIND:
7333e12c5d1SDavid du Colombier 		case TSHORT:
7343e12c5d1SDavid du Colombier 		case TUSHORT:
7353e12c5d1SDavid du Colombier 		case TCHAR:
7363e12c5d1SDavid du Colombier 		case TUCHAR:
7377dd7cddfSDavid du Colombier 			if(fproundflg) {
7387dd7cddfSDavid du Colombier 				/* convert f, t */
7397dd7cddfSDavid du Colombier 				regalloc(&nod, f, Z);
7407dd7cddfSDavid du Colombier 				gins(AMOVDW, f, &nod);
7417dd7cddfSDavid du Colombier 				if(ft == TFLOAT)
7427dd7cddfSDavid du Colombier 					p->as = AMOVFW;
7437dd7cddfSDavid du Colombier 				gins(AMOVW, &nod, t);
7447dd7cddfSDavid du Colombier 				regfree(&nod);
7457dd7cddfSDavid du Colombier 				gins(AMOVW, t, t);
7467dd7cddfSDavid du Colombier 				return;
7477dd7cddfSDavid du Colombier 			}
7483e12c5d1SDavid du Colombier 			regalloc(&nod1, &regnode, Z);
7493e12c5d1SDavid du Colombier 			regalloc(&nod2, &regnode, Z);
750219b2ee8SDavid du Colombier 
751219b2ee8SDavid du Colombier 			/* movw fcr, rx */
7523e12c5d1SDavid du Colombier 			gins(AMOVW, Z, &nod1);
7533e12c5d1SDavid du Colombier 			p->from.type = D_FCREG;
7543e12c5d1SDavid du Colombier 			p->from.reg = 31;
7553e12c5d1SDavid du Colombier 
756219b2ee8SDavid du Colombier 			/* nop */
7573e12c5d1SDavid du Colombier 			gins(ANOR, nodconst(0), nodconst(0));
7583e12c5d1SDavid du Colombier 			p->to.type = D_REG;
7593e12c5d1SDavid du Colombier 			p->to.reg = 0;
7603e12c5d1SDavid du Colombier 
761219b2ee8SDavid du Colombier 			/* nop */
762219b2ee8SDavid du Colombier 			gins(ANOR, nodconst(0), nodconst(0));
763219b2ee8SDavid du Colombier 			p->to.type = D_REG;
764219b2ee8SDavid du Colombier 			p->to.reg = 0;
765219b2ee8SDavid du Colombier 
766219b2ee8SDavid du Colombier 			/* or $3, rx, ry */
767219b2ee8SDavid du Colombier 			gins(AOR, nodconst(3), &nod2);
768219b2ee8SDavid du Colombier 			p->reg = nod1.reg;
769219b2ee8SDavid du Colombier 
770219b2ee8SDavid du Colombier 			/* xor $2, ry */
771219b2ee8SDavid du Colombier 			gins(AXOR, nodconst(2), &nod2);
772219b2ee8SDavid du Colombier 
773219b2ee8SDavid du Colombier 			/* movw ry, fcr */
774219b2ee8SDavid du Colombier 			gins(AMOVW, &nod2, Z);
775219b2ee8SDavid du Colombier 			p->to.type = D_FCREG;
776219b2ee8SDavid du Colombier 			p->to.reg = 31;
777219b2ee8SDavid du Colombier 
778219b2ee8SDavid du Colombier 			/* nop */
779219b2ee8SDavid du Colombier 			gins(ANOR, nodconst(0), nodconst(0));
780219b2ee8SDavid du Colombier 			p->to.type = D_REG;
781219b2ee8SDavid du Colombier 			p->to.reg = 0;
782219b2ee8SDavid du Colombier 
783219b2ee8SDavid du Colombier 			/* nop */
784219b2ee8SDavid du Colombier 			gins(ANOR, nodconst(0), nodconst(0));
785219b2ee8SDavid du Colombier 			p->to.type = D_REG;
786219b2ee8SDavid du Colombier 			p->to.reg = 0;
787219b2ee8SDavid du Colombier 
788219b2ee8SDavid du Colombier 			/* convert f, t */
7893e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
7903e12c5d1SDavid du Colombier 			gins(AMOVDW, f, &nod);
7913e12c5d1SDavid du Colombier 			if(ft == TFLOAT)
7923e12c5d1SDavid du Colombier 				p->as = AMOVFW;
7933e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
7943e12c5d1SDavid du Colombier 			regfree(&nod);
7953e12c5d1SDavid du Colombier 			gins(AMOVW, t, t);
7963e12c5d1SDavid du Colombier 
797219b2ee8SDavid du Colombier 			/* movw rx, fcr */
7983e12c5d1SDavid du Colombier 			gins(AMOVW, &nod1, Z);
7993e12c5d1SDavid du Colombier 			p->to.type = D_FCREG;
8003e12c5d1SDavid du Colombier 			p->to.reg = 31;
801219b2ee8SDavid du Colombier 
802219b2ee8SDavid du Colombier 			/* nop */
8033e12c5d1SDavid du Colombier 			gins(ANOR, nodconst(0), nodconst(0));
8043e12c5d1SDavid du Colombier 			p->to.type = D_REG;
8053e12c5d1SDavid du Colombier 			p->to.reg = 0;
806219b2ee8SDavid du Colombier 
807219b2ee8SDavid du Colombier 			/* nop */
808219b2ee8SDavid du Colombier 			gins(ANOR, nodconst(0), nodconst(0));
809219b2ee8SDavid du Colombier 			p->to.type = D_REG;
810219b2ee8SDavid du Colombier 			p->to.reg = 0;
811219b2ee8SDavid du Colombier 
8123e12c5d1SDavid du Colombier 			regfree(&nod1);
8133e12c5d1SDavid du Colombier 			regfree(&nod2);
8143e12c5d1SDavid du Colombier 			return;
8153e12c5d1SDavid du Colombier 		}
8163e12c5d1SDavid du Colombier 		break;
8177dd7cddfSDavid du Colombier 	case TINT:
8187dd7cddfSDavid du Colombier 	case TUINT:
819bd389b36SDavid du Colombier 	case TLONG:
8207dd7cddfSDavid du Colombier 	case TULONG:
8213e12c5d1SDavid du Colombier 	case TIND:
8223e12c5d1SDavid du Colombier 		switch(tt) {
8233e12c5d1SDavid du Colombier 		case TDOUBLE:
8243e12c5d1SDavid du Colombier 		case TVLONG:
8253e12c5d1SDavid du Colombier 			gins(AMOVW, f, t);
8263e12c5d1SDavid du Colombier 			gins(AMOVWD, t, t);
8277dd7cddfSDavid du Colombier 			if(ft == TULONG || ft == TUINT) {
828bd389b36SDavid du Colombier 				regalloc(&nod, t, Z);
829bd389b36SDavid du Colombier 				gins(ACMPGED, t, Z);
830bd389b36SDavid du Colombier 				p->reg = FREGZERO;
831bd389b36SDavid du Colombier 				gins(ABFPT, Z, Z);
832bd389b36SDavid du Colombier 				p1 = p;
833bd389b36SDavid du Colombier 				gins(AMOVD, nodfconst(4294967296.), &nod);
834bd389b36SDavid du Colombier 				gins(AADDD, &nod, t);
835bd389b36SDavid du Colombier 				patch(p1, pc);
836bd389b36SDavid du Colombier 				regfree(&nod);
837bd389b36SDavid du Colombier 			}
8383e12c5d1SDavid du Colombier 			return;
8393e12c5d1SDavid du Colombier 		case TFLOAT:
8403e12c5d1SDavid du Colombier 			gins(AMOVW, f, t);
8413e12c5d1SDavid du Colombier 			gins(AMOVWF, t, t);
8427dd7cddfSDavid du Colombier 			if(ft == TULONG || ft == TUINT) {
843bd389b36SDavid du Colombier 				regalloc(&nod, t, Z);
844bd389b36SDavid du Colombier 				gins(ACMPGEF, t, Z);
845bd389b36SDavid du Colombier 				p->reg = FREGZERO;
846bd389b36SDavid du Colombier 				gins(ABFPT, Z, Z);
847bd389b36SDavid du Colombier 				p1 = p;
848bd389b36SDavid du Colombier 				gins(AMOVF, nodfconst(4294967296.), &nod);
849bd389b36SDavid du Colombier 				gins(AADDF, &nod, t);
850bd389b36SDavid du Colombier 				patch(p1, pc);
851bd389b36SDavid du Colombier 				regfree(&nod);
852bd389b36SDavid du Colombier 			}
8533e12c5d1SDavid du Colombier 			return;
8547dd7cddfSDavid du Colombier 		case TINT:
8557dd7cddfSDavid du Colombier 		case TUINT:
8563e12c5d1SDavid du Colombier 		case TLONG:
8573e12c5d1SDavid du Colombier 		case TULONG:
8583e12c5d1SDavid du Colombier 		case TIND:
8593e12c5d1SDavid du Colombier 		case TSHORT:
8603e12c5d1SDavid du Colombier 		case TUSHORT:
8613e12c5d1SDavid du Colombier 		case TCHAR:
8623e12c5d1SDavid du Colombier 		case TUCHAR:
8633e12c5d1SDavid du Colombier 			a = AMOVW;
8643e12c5d1SDavid du Colombier 			break;
8653e12c5d1SDavid du Colombier 		}
8663e12c5d1SDavid du Colombier 		break;
8673e12c5d1SDavid du Colombier 	case TSHORT:
8683e12c5d1SDavid du Colombier 		switch(tt) {
8693e12c5d1SDavid du Colombier 		case TDOUBLE:
8703e12c5d1SDavid du Colombier 		case TVLONG:
8713e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
8723e12c5d1SDavid du Colombier 			gins(AMOVH, f, &nod);
8733e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
8743e12c5d1SDavid du Colombier 			gins(AMOVWD, t, t);
8753e12c5d1SDavid du Colombier 			regfree(&nod);
8763e12c5d1SDavid du Colombier 			return;
8773e12c5d1SDavid du Colombier 		case TFLOAT:
8783e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
8793e12c5d1SDavid du Colombier 			gins(AMOVH, f, &nod);
8803e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
8813e12c5d1SDavid du Colombier 			gins(AMOVWF, t, t);
8823e12c5d1SDavid du Colombier 			regfree(&nod);
8833e12c5d1SDavid du Colombier 			return;
8847dd7cddfSDavid du Colombier 		case TINT:
8857dd7cddfSDavid du Colombier 		case TUINT:
8863e12c5d1SDavid du Colombier 		case TLONG:
8877dd7cddfSDavid du Colombier 		case TULONG:
8883e12c5d1SDavid du Colombier 		case TIND:
8893e12c5d1SDavid du Colombier 			a = AMOVH;
8903e12c5d1SDavid du Colombier 			break;
8913e12c5d1SDavid du Colombier 		case TSHORT:
8923e12c5d1SDavid du Colombier 		case TUSHORT:
8933e12c5d1SDavid du Colombier 		case TCHAR:
8943e12c5d1SDavid du Colombier 		case TUCHAR:
8953e12c5d1SDavid du Colombier 			a = AMOVW;
8963e12c5d1SDavid du Colombier 			break;
8973e12c5d1SDavid du Colombier 		}
8983e12c5d1SDavid du Colombier 		break;
8993e12c5d1SDavid du Colombier 	case TUSHORT:
9003e12c5d1SDavid du Colombier 		switch(tt) {
9013e12c5d1SDavid du Colombier 		case TDOUBLE:
9023e12c5d1SDavid du Colombier 		case TVLONG:
9033e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
9043e12c5d1SDavid du Colombier 			gins(AMOVHU, f, &nod);
9053e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
9063e12c5d1SDavid du Colombier 			gins(AMOVWD, t, t);
9073e12c5d1SDavid du Colombier 			regfree(&nod);
9083e12c5d1SDavid du Colombier 			return;
9093e12c5d1SDavid du Colombier 		case TFLOAT:
9103e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
9113e12c5d1SDavid du Colombier 			gins(AMOVHU, f, &nod);
9123e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
9133e12c5d1SDavid du Colombier 			gins(AMOVWF, t, t);
9143e12c5d1SDavid du Colombier 			regfree(&nod);
9153e12c5d1SDavid du Colombier 			return;
9167dd7cddfSDavid du Colombier 		case TINT:
9177dd7cddfSDavid du Colombier 		case TUINT:
9183e12c5d1SDavid du Colombier 		case TLONG:
9193e12c5d1SDavid du Colombier 		case TULONG:
9203e12c5d1SDavid du Colombier 		case TIND:
9213e12c5d1SDavid du Colombier 			a = AMOVHU;
9223e12c5d1SDavid du Colombier 			break;
9233e12c5d1SDavid du Colombier 		case TSHORT:
9243e12c5d1SDavid du Colombier 		case TUSHORT:
9253e12c5d1SDavid du Colombier 		case TCHAR:
9263e12c5d1SDavid du Colombier 		case TUCHAR:
9273e12c5d1SDavid du Colombier 			a = AMOVW;
9283e12c5d1SDavid du Colombier 			break;
9293e12c5d1SDavid du Colombier 		}
9303e12c5d1SDavid du Colombier 		break;
9313e12c5d1SDavid du Colombier 	case TCHAR:
9323e12c5d1SDavid du Colombier 		switch(tt) {
9333e12c5d1SDavid du Colombier 		case TDOUBLE:
9343e12c5d1SDavid du Colombier 		case TVLONG:
9353e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
9363e12c5d1SDavid du Colombier 			gins(AMOVB, f, &nod);
9373e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
9383e12c5d1SDavid du Colombier 			gins(AMOVWD, t, t);
9393e12c5d1SDavid du Colombier 			regfree(&nod);
9403e12c5d1SDavid du Colombier 			return;
9413e12c5d1SDavid du Colombier 		case TFLOAT:
9423e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
9433e12c5d1SDavid du Colombier 			gins(AMOVB, f, &nod);
9443e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
9453e12c5d1SDavid du Colombier 			gins(AMOVWF, t, t);
9463e12c5d1SDavid du Colombier 			regfree(&nod);
9473e12c5d1SDavid du Colombier 			return;
9487dd7cddfSDavid du Colombier 		case TINT:
9497dd7cddfSDavid du Colombier 		case TUINT:
9503e12c5d1SDavid du Colombier 		case TLONG:
9513e12c5d1SDavid du Colombier 		case TULONG:
9523e12c5d1SDavid du Colombier 		case TIND:
9533e12c5d1SDavid du Colombier 		case TSHORT:
9543e12c5d1SDavid du Colombier 		case TUSHORT:
9553e12c5d1SDavid du Colombier 			a = AMOVB;
9563e12c5d1SDavid du Colombier 			break;
9573e12c5d1SDavid du Colombier 		case TCHAR:
9583e12c5d1SDavid du Colombier 		case TUCHAR:
9593e12c5d1SDavid du Colombier 			a = AMOVW;
9603e12c5d1SDavid du Colombier 			break;
9613e12c5d1SDavid du Colombier 		}
9623e12c5d1SDavid du Colombier 		break;
9633e12c5d1SDavid du Colombier 	case TUCHAR:
9643e12c5d1SDavid du Colombier 		switch(tt) {
9653e12c5d1SDavid du Colombier 		case TDOUBLE:
9663e12c5d1SDavid du Colombier 		case TVLONG:
9673e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
9683e12c5d1SDavid du Colombier 			gins(AMOVBU, f, &nod);
9693e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
9703e12c5d1SDavid du Colombier 			gins(AMOVWD, t, t);
9713e12c5d1SDavid du Colombier 			regfree(&nod);
9723e12c5d1SDavid du Colombier 			return;
9733e12c5d1SDavid du Colombier 		case TFLOAT:
9743e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);
9753e12c5d1SDavid du Colombier 			gins(AMOVBU, f, &nod);
9763e12c5d1SDavid du Colombier 			gins(AMOVW, &nod, t);
9773e12c5d1SDavid du Colombier 			gins(AMOVWF, t, t);
9783e12c5d1SDavid du Colombier 			regfree(&nod);
9793e12c5d1SDavid du Colombier 			return;
9807dd7cddfSDavid du Colombier 		case TINT:
9817dd7cddfSDavid du Colombier 		case TUINT:
9823e12c5d1SDavid du Colombier 		case TLONG:
9833e12c5d1SDavid du Colombier 		case TULONG:
9843e12c5d1SDavid du Colombier 		case TIND:
9853e12c5d1SDavid du Colombier 		case TSHORT:
9863e12c5d1SDavid du Colombier 		case TUSHORT:
9873e12c5d1SDavid du Colombier 			a = AMOVBU;
9883e12c5d1SDavid du Colombier 			break;
9893e12c5d1SDavid du Colombier 		case TCHAR:
9903e12c5d1SDavid du Colombier 		case TUCHAR:
9913e12c5d1SDavid du Colombier 			a = AMOVW;
9923e12c5d1SDavid du Colombier 			break;
9933e12c5d1SDavid du Colombier 		}
9943e12c5d1SDavid du Colombier 		break;
9953e12c5d1SDavid du Colombier 	}
9967dd7cddfSDavid du Colombier 	if(a == AGOK)
9977dd7cddfSDavid du Colombier 		diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
9983e12c5d1SDavid du Colombier 	if(a == AMOVW || a == AMOVF || a == AMOVD)
9993e12c5d1SDavid du Colombier 	if(samaddr(f, t))
10003e12c5d1SDavid du Colombier 		return;
10013e12c5d1SDavid du Colombier 	gins(a, f, t);
10023e12c5d1SDavid du Colombier }
10033e12c5d1SDavid du Colombier 
10043e12c5d1SDavid du Colombier void
gins(int a,Node * f,Node * t)10053e12c5d1SDavid du Colombier gins(int a, Node *f, Node *t)
10063e12c5d1SDavid du Colombier {
10073e12c5d1SDavid du Colombier 
10083e12c5d1SDavid du Colombier 	nextpc();
10093e12c5d1SDavid du Colombier 	p->as = a;
10103e12c5d1SDavid du Colombier 	if(f != Z)
10113e12c5d1SDavid du Colombier 		naddr(f, &p->from);
10123e12c5d1SDavid du Colombier 	if(t != Z)
10133e12c5d1SDavid du Colombier 		naddr(t, &p->to);
10143e12c5d1SDavid du Colombier 	if(debug['g'])
10153e12c5d1SDavid du Colombier 		print("%P\n", p);
10163e12c5d1SDavid du Colombier }
10173e12c5d1SDavid du Colombier 
10183e12c5d1SDavid du Colombier void
gopcode(int o,Node * f1,Node * f2,Node * t)10193e12c5d1SDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t)
10203e12c5d1SDavid du Colombier {
10213e12c5d1SDavid du Colombier 	int a, et;
10223e12c5d1SDavid du Colombier 	Adr ta;
10233e12c5d1SDavid du Colombier 
10243e12c5d1SDavid du Colombier 	et = TLONG;
10253e12c5d1SDavid du Colombier 	if(f1 != Z && f1->type != T)
10263e12c5d1SDavid du Colombier 		et = f1->type->etype;
10273e12c5d1SDavid du Colombier 	a = AGOK;
10283e12c5d1SDavid du Colombier 	switch(o) {
10293e12c5d1SDavid du Colombier 	case OAS:
10303e12c5d1SDavid du Colombier 		gmove(f1, t);
10313e12c5d1SDavid du Colombier 		return;
10323e12c5d1SDavid du Colombier 
10333e12c5d1SDavid du Colombier 	case OASADD:
10343e12c5d1SDavid du Colombier 	case OADD:
10353e12c5d1SDavid du Colombier 		a = AADDU;
10363e12c5d1SDavid du Colombier 		if(et == TFLOAT)
10373e12c5d1SDavid du Colombier 			a = AADDF;
10383e12c5d1SDavid du Colombier 		else
10393e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG)
10403e12c5d1SDavid du Colombier 			a = AADDD;
10413e12c5d1SDavid du Colombier 		break;
10423e12c5d1SDavid du Colombier 
10433e12c5d1SDavid du Colombier 	case OASSUB:
10443e12c5d1SDavid du Colombier 	case OSUB:
10453e12c5d1SDavid du Colombier 		a = ASUBU;
10463e12c5d1SDavid du Colombier 		if(et == TFLOAT)
10473e12c5d1SDavid du Colombier 			a = ASUBF;
10483e12c5d1SDavid du Colombier 		else
10493e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG)
10503e12c5d1SDavid du Colombier 			a = ASUBD;
10513e12c5d1SDavid du Colombier 		break;
10523e12c5d1SDavid du Colombier 
10533e12c5d1SDavid du Colombier 	case OASOR:
10543e12c5d1SDavid du Colombier 	case OOR:
10553e12c5d1SDavid du Colombier 		a = AOR;
10563e12c5d1SDavid du Colombier 		break;
10573e12c5d1SDavid du Colombier 
10583e12c5d1SDavid du Colombier 	case OASAND:
10593e12c5d1SDavid du Colombier 	case OAND:
10603e12c5d1SDavid du Colombier 		a = AAND;
10613e12c5d1SDavid du Colombier 		break;
10623e12c5d1SDavid du Colombier 
10633e12c5d1SDavid du Colombier 	case OASXOR:
10643e12c5d1SDavid du Colombier 	case OXOR:
10653e12c5d1SDavid du Colombier 		a = AXOR;
10663e12c5d1SDavid du Colombier 		break;
10673e12c5d1SDavid du Colombier 
10683e12c5d1SDavid du Colombier 	case OASLSHR:
10693e12c5d1SDavid du Colombier 	case OLSHR:
10703e12c5d1SDavid du Colombier 		a = ASRL;
10713e12c5d1SDavid du Colombier 		break;
10723e12c5d1SDavid du Colombier 
10733e12c5d1SDavid du Colombier 	case OASASHR:
10743e12c5d1SDavid du Colombier 	case OASHR:
10753e12c5d1SDavid du Colombier 		a = ASRA;
10763e12c5d1SDavid du Colombier 		break;
10773e12c5d1SDavid du Colombier 
10783e12c5d1SDavid du Colombier 	case OASASHL:
10793e12c5d1SDavid du Colombier 	case OASHL:
10803e12c5d1SDavid du Colombier 		a = ASLL;
10813e12c5d1SDavid du Colombier 		break;
10823e12c5d1SDavid du Colombier 
10833e12c5d1SDavid du Colombier 	case OFUNC:
10843e12c5d1SDavid du Colombier 		a = AJAL;
10853e12c5d1SDavid du Colombier 		break;
10863e12c5d1SDavid du Colombier 
10877dd7cddfSDavid du Colombier 	case OCOND:
10887dd7cddfSDavid du Colombier 		a = ASGTU;
10897dd7cddfSDavid du Colombier 		break;
10907dd7cddfSDavid du Colombier 
10917dd7cddfSDavid du Colombier 	case OCOMMA:
10927dd7cddfSDavid du Colombier 		a = ASGT;
10937dd7cddfSDavid du Colombier 		break;
10947dd7cddfSDavid du Colombier 
10953e12c5d1SDavid du Colombier 	case OASMUL:
10963e12c5d1SDavid du Colombier 	case OMUL:
10973e12c5d1SDavid du Colombier 		if(et == TFLOAT) {
10983e12c5d1SDavid du Colombier 			a = AMULF;
10993e12c5d1SDavid du Colombier 			break;
11003e12c5d1SDavid du Colombier 		} else
11013e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG) {
11023e12c5d1SDavid du Colombier 			a = AMULD;
11033e12c5d1SDavid du Colombier 			break;
11043e12c5d1SDavid du Colombier 		}
11053e12c5d1SDavid du Colombier 		a = AMUL;
11063e12c5d1SDavid du Colombier 		goto muldiv;
11073e12c5d1SDavid du Colombier 
11083e12c5d1SDavid du Colombier 	case OASDIV:
11093e12c5d1SDavid du Colombier 	case ODIV:
11103e12c5d1SDavid du Colombier 		if(et == TFLOAT) {
11113e12c5d1SDavid du Colombier 			a = ADIVF;
11123e12c5d1SDavid du Colombier 			break;
11133e12c5d1SDavid du Colombier 		} else
11143e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG) {
11153e12c5d1SDavid du Colombier 			a = ADIVD;
11163e12c5d1SDavid du Colombier 			break;
11173e12c5d1SDavid du Colombier 		}
11183e12c5d1SDavid du Colombier 		a = ADIV;
11193e12c5d1SDavid du Colombier 		goto muldiv;
11203e12c5d1SDavid du Colombier 
11213e12c5d1SDavid du Colombier 	case OASMOD:
11223e12c5d1SDavid du Colombier 	case OMOD:
11233e12c5d1SDavid du Colombier 		a = ADIV;
11243e12c5d1SDavid du Colombier 		o = OMOD;
11253e12c5d1SDavid du Colombier 		goto muldiv;
11263e12c5d1SDavid du Colombier 
11273e12c5d1SDavid du Colombier 	case OASLMUL:
11283e12c5d1SDavid du Colombier 	case OLMUL:
11293e12c5d1SDavid du Colombier 		a = AMULU;
11303e12c5d1SDavid du Colombier 		goto muldiv;
11313e12c5d1SDavid du Colombier 
11323e12c5d1SDavid du Colombier 	case OASLMOD:
11333e12c5d1SDavid du Colombier 	case OLMOD:
11343e12c5d1SDavid du Colombier 		a = ADIVU;
11353e12c5d1SDavid du Colombier 		o = OMOD;
11363e12c5d1SDavid du Colombier 		goto muldiv;
11373e12c5d1SDavid du Colombier 
11383e12c5d1SDavid du Colombier 	case OASLDIV:
11393e12c5d1SDavid du Colombier 	case OLDIV:
11403e12c5d1SDavid du Colombier 		a = ADIVU;
11413e12c5d1SDavid du Colombier 		goto muldiv;
11423e12c5d1SDavid du Colombier 
11433e12c5d1SDavid du Colombier 	muldiv:
11443e12c5d1SDavid du Colombier 		nextpc();
11453e12c5d1SDavid du Colombier 		naddr(f1, &p->from);
11463e12c5d1SDavid du Colombier 		if(f2 == Z)
11473e12c5d1SDavid du Colombier 			raddr(t, p);
11483e12c5d1SDavid du Colombier 		else
11493e12c5d1SDavid du Colombier 			raddr(f2, p);
11503e12c5d1SDavid du Colombier 		p->as = a;
11513e12c5d1SDavid du Colombier 		if(debug['g'])
11523e12c5d1SDavid du Colombier 			print("%P\n", p);
11533e12c5d1SDavid du Colombier 
11543e12c5d1SDavid du Colombier 		nextpc();
11553e12c5d1SDavid du Colombier 		p->as = AMOVW;
11563e12c5d1SDavid du Colombier 		a = D_LO;
11573e12c5d1SDavid du Colombier 		if(o == OMOD)
11583e12c5d1SDavid du Colombier 			a = D_HI;
11593e12c5d1SDavid du Colombier 		p->from.type = a;
11603e12c5d1SDavid du Colombier 		naddr(t, &p->to);
11613e12c5d1SDavid du Colombier 		if(debug['g'])
11623e12c5d1SDavid du Colombier 			print("%P\n", p);
11633e12c5d1SDavid du Colombier 		return;
11643e12c5d1SDavid du Colombier 
11653e12c5d1SDavid du Colombier 	case OEQ:
1166219b2ee8SDavid du Colombier 		if(!typefd[et]) {
11673e12c5d1SDavid du Colombier 			a = ABEQ;
11683e12c5d1SDavid du Colombier 			break;
11693e12c5d1SDavid du Colombier 		}
11703e12c5d1SDavid du Colombier 
11713e12c5d1SDavid du Colombier 	case ONE:
1172219b2ee8SDavid du Colombier 		if(!typefd[et]) {
11733e12c5d1SDavid du Colombier 			a = ABNE;
11743e12c5d1SDavid du Colombier 			break;
11753e12c5d1SDavid du Colombier 		}
11763e12c5d1SDavid du Colombier 
11773e12c5d1SDavid du Colombier 	case OLT:
11783e12c5d1SDavid du Colombier 	case OLE:
11793e12c5d1SDavid du Colombier 	case OGE:
11803e12c5d1SDavid du Colombier 	case OGT:
1181219b2ee8SDavid du Colombier 		if(typefd[et]) {
11823e12c5d1SDavid du Colombier 			nextpc();
11833e12c5d1SDavid du Colombier 			if(et == TFLOAT) {
11843e12c5d1SDavid du Colombier 				a = ACMPGTF;
11853e12c5d1SDavid du Colombier 				if(o == OEQ || o == ONE)
11863e12c5d1SDavid du Colombier 					a = ACMPEQF;
11873e12c5d1SDavid du Colombier 				else
11883e12c5d1SDavid du Colombier 				if(o == OLT || o == OGE)
11893e12c5d1SDavid du Colombier 					a = ACMPGEF;
11903e12c5d1SDavid du Colombier 			} else {
11913e12c5d1SDavid du Colombier 				a = ACMPGTD;
11923e12c5d1SDavid du Colombier 				if(o == OEQ || o == ONE)
11933e12c5d1SDavid du Colombier 					a = ACMPEQD;
11943e12c5d1SDavid du Colombier 				else
11953e12c5d1SDavid du Colombier 				if(o == OLT || o == OGE)
11963e12c5d1SDavid du Colombier 					a = ACMPGED;
11973e12c5d1SDavid du Colombier 			}
11983e12c5d1SDavid du Colombier 			p->as = a;
11993e12c5d1SDavid du Colombier 			naddr(f1, &p->from);
12003e12c5d1SDavid du Colombier 			raddr(f2, p);
12013e12c5d1SDavid du Colombier 			if(debug['g'])
12023e12c5d1SDavid du Colombier 				print("%P\n", p);
12033e12c5d1SDavid du Colombier 			nextpc();
12043e12c5d1SDavid du Colombier 			a = ABFPF;
12053e12c5d1SDavid du Colombier 			if(o == OEQ || o == OGE || o == OGT)
12063e12c5d1SDavid du Colombier 				a = ABFPT;
12073e12c5d1SDavid du Colombier 			p->as = a;
12083e12c5d1SDavid du Colombier 			if(debug['g'])
12093e12c5d1SDavid du Colombier 				print("%P\n", p);
12103e12c5d1SDavid du Colombier 			return;
12113e12c5d1SDavid du Colombier 		}
12123e12c5d1SDavid du Colombier 		if(vconst(f1) == 0 || vconst(f2) == 0) {
12133e12c5d1SDavid du Colombier 			if(vconst(f1) == 0) {
12143e12c5d1SDavid du Colombier 				o = invrel[relindex(o)];
12153e12c5d1SDavid du Colombier 				f1 = f2;
12163e12c5d1SDavid du Colombier 			}
12173e12c5d1SDavid du Colombier 			switch(o) {
12183e12c5d1SDavid du Colombier 			case OLT:
12193e12c5d1SDavid du Colombier 				a = ABLTZ;
12203e12c5d1SDavid du Colombier 				break;
12213e12c5d1SDavid du Colombier 			case OLE:
12223e12c5d1SDavid du Colombier 				a = ABLEZ;
12233e12c5d1SDavid du Colombier 				break;
12243e12c5d1SDavid du Colombier 			case OGE:
12253e12c5d1SDavid du Colombier 				a = ABGEZ;
12263e12c5d1SDavid du Colombier 				break;
12273e12c5d1SDavid du Colombier 			case OGT:
12283e12c5d1SDavid du Colombier 				a = ABGTZ;
12293e12c5d1SDavid du Colombier 				break;
12303e12c5d1SDavid du Colombier 			}
12313e12c5d1SDavid du Colombier 			f2 = Z;
12323e12c5d1SDavid du Colombier 			break;
12333e12c5d1SDavid du Colombier 		}
12343e12c5d1SDavid du Colombier 
12353e12c5d1SDavid du Colombier 	case OLO:
12363e12c5d1SDavid du Colombier 	case OLS:
12373e12c5d1SDavid du Colombier 	case OHS:
12383e12c5d1SDavid du Colombier 	case OHI:
12393e12c5d1SDavid du Colombier 		nextpc();
12403e12c5d1SDavid du Colombier 		if(o == OLE || o == OGT || o == OLS || o == OHI) {
12413e12c5d1SDavid du Colombier 			naddr(f1, &p->from);
12423e12c5d1SDavid du Colombier 			raddr(f2, p);
12433e12c5d1SDavid du Colombier 		} else {
12443e12c5d1SDavid du Colombier 			naddr(f2, &p->from);
12453e12c5d1SDavid du Colombier 			raddr(f1, p);
12463e12c5d1SDavid du Colombier 		}
12473e12c5d1SDavid du Colombier 		naddr(&regnode, &p->to);
12483e12c5d1SDavid du Colombier 		p->to.reg = tmpreg();
12493e12c5d1SDavid du Colombier 		a = ASGT;
12503e12c5d1SDavid du Colombier 		if(o == OLO || o == OLS || o == OHS || o == OHI)
12513e12c5d1SDavid du Colombier 			a = ASGTU;
12523e12c5d1SDavid du Colombier 		p->as = a;
12533e12c5d1SDavid du Colombier 		if(debug['g'])
12543e12c5d1SDavid du Colombier 			print("%P\n", p);
12553e12c5d1SDavid du Colombier 
12563e12c5d1SDavid du Colombier 		nextpc();
12573e12c5d1SDavid du Colombier 		naddr(&regnode, &p->from);
12583e12c5d1SDavid du Colombier 		p->from.reg = tmpreg();
12593e12c5d1SDavid du Colombier 		a = ABEQ;
12603e12c5d1SDavid du Colombier 		if(o == OLT || o == OGT || o == OLO || o == OHI)
12613e12c5d1SDavid du Colombier 			a = ABNE;
12623e12c5d1SDavid du Colombier 		p->as = a;
12633e12c5d1SDavid du Colombier 		if(debug['g'])
12643e12c5d1SDavid du Colombier 			print("%P\n", p);
12653e12c5d1SDavid du Colombier 		return;
12663e12c5d1SDavid du Colombier 	}
12673e12c5d1SDavid du Colombier 	if(a == AGOK)
12683e12c5d1SDavid du Colombier 		diag(Z, "bad in gopcode %O", o);
12693e12c5d1SDavid du Colombier 	nextpc();
12703e12c5d1SDavid du Colombier 	p->as = a;
12713e12c5d1SDavid du Colombier 	if(f1 != Z)
12723e12c5d1SDavid du Colombier 		naddr(f1, &p->from);
12733e12c5d1SDavid du Colombier 	if(f2 != Z) {
12743e12c5d1SDavid du Colombier 		naddr(f2, &ta);
12753e12c5d1SDavid du Colombier 		p->reg = ta.reg;
1276219b2ee8SDavid du Colombier 		if(ta.type == D_CONST && ta.offset == 0)
1277219b2ee8SDavid du Colombier 			p->reg = REGZERO;
12783e12c5d1SDavid du Colombier 	}
12793e12c5d1SDavid du Colombier 	if(t != Z)
12803e12c5d1SDavid du Colombier 		naddr(t, &p->to);
12813e12c5d1SDavid du Colombier 	if(debug['g'])
12823e12c5d1SDavid du Colombier 		print("%P\n", p);
12833e12c5d1SDavid du Colombier }
12843e12c5d1SDavid du Colombier 
12857dd7cddfSDavid du Colombier int
samaddr(Node * f,Node * t)12863e12c5d1SDavid du Colombier samaddr(Node *f, Node *t)
12873e12c5d1SDavid du Colombier {
12883e12c5d1SDavid du Colombier 
12893e12c5d1SDavid du Colombier 	if(f->op != t->op)
12903e12c5d1SDavid du Colombier 		return 0;
12913e12c5d1SDavid du Colombier 	switch(f->op) {
12923e12c5d1SDavid du Colombier 
12933e12c5d1SDavid du Colombier 	case OREGISTER:
12943e12c5d1SDavid du Colombier 		if(f->reg != t->reg)
12953e12c5d1SDavid du Colombier 			break;
12963e12c5d1SDavid du Colombier 		return 1;
12973e12c5d1SDavid du Colombier 	}
12983e12c5d1SDavid du Colombier 	return 0;
12993e12c5d1SDavid du Colombier }
13003e12c5d1SDavid du Colombier 
13013e12c5d1SDavid du Colombier void
gbranch(int o)13023e12c5d1SDavid du Colombier gbranch(int o)
13033e12c5d1SDavid du Colombier {
13043e12c5d1SDavid du Colombier 	int a;
13053e12c5d1SDavid du Colombier 
13063e12c5d1SDavid du Colombier 	a = AGOK;
13073e12c5d1SDavid du Colombier 	switch(o) {
13083e12c5d1SDavid du Colombier 	case ORETURN:
13093e12c5d1SDavid du Colombier 		a = ARET;
13103e12c5d1SDavid du Colombier 		break;
13113e12c5d1SDavid du Colombier 	case OGOTO:
13123e12c5d1SDavid du Colombier 		a = AJMP;
13133e12c5d1SDavid du Colombier 		break;
13143e12c5d1SDavid du Colombier 	}
13153e12c5d1SDavid du Colombier 	nextpc();
13163e12c5d1SDavid du Colombier 	if(a == AGOK) {
13173e12c5d1SDavid du Colombier 		diag(Z, "bad in gbranch %O",  o);
13183e12c5d1SDavid du Colombier 		nextpc();
13193e12c5d1SDavid du Colombier 	}
13203e12c5d1SDavid du Colombier 	p->as = a;
13213e12c5d1SDavid du Colombier }
13223e12c5d1SDavid du Colombier 
13233e12c5d1SDavid du Colombier void
patch(Prog * op,long pc)13243e12c5d1SDavid du Colombier patch(Prog *op, long pc)
13253e12c5d1SDavid du Colombier {
13263e12c5d1SDavid du Colombier 
13273e12c5d1SDavid du Colombier 	op->to.offset = pc;
13283e12c5d1SDavid du Colombier 	op->to.type = D_BRANCH;
13293e12c5d1SDavid du Colombier }
13303e12c5d1SDavid du Colombier 
13313e12c5d1SDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)13323e12c5d1SDavid du Colombier gpseudo(int a, Sym *s, Node *n)
13333e12c5d1SDavid du Colombier {
13343e12c5d1SDavid du Colombier 
13353e12c5d1SDavid du Colombier 	nextpc();
13363e12c5d1SDavid du Colombier 	p->as = a;
13373e12c5d1SDavid du Colombier 	p->from.type = D_OREG;
13383e12c5d1SDavid du Colombier 	p->from.sym = s;
1339*5ede6b93SDavid du Colombier 	if(a == ATEXT)
1340e288d156SDavid du Colombier 		p->reg = (profileflg ? 0 : NOPROF);
13413e12c5d1SDavid du Colombier 	p->from.name = D_EXTERN;
13423e12c5d1SDavid du Colombier 	if(s->class == CSTATIC)
13433e12c5d1SDavid du Colombier 		p->from.name = D_STATIC;
13443e12c5d1SDavid du Colombier 	naddr(n, &p->to);
13453e12c5d1SDavid du Colombier 	if(a == ADATA || a == AGLOBL)
13463e12c5d1SDavid du Colombier 		pc--;
13473e12c5d1SDavid du Colombier }
13483e12c5d1SDavid du Colombier 
13493e12c5d1SDavid du Colombier int
sconst(Node * n)13503e12c5d1SDavid du Colombier sconst(Node *n)
13513e12c5d1SDavid du Colombier {
1352219b2ee8SDavid du Colombier 	vlong vv;
13533e12c5d1SDavid du Colombier 
1354219b2ee8SDavid du Colombier 	if(n->op == OCONST) {
1355219b2ee8SDavid du Colombier 		if(!typefd[n->type->etype]) {
1356219b2ee8SDavid du Colombier 			vv = n->vconst;
1357375daca8SDavid du Colombier 			if(vv >= (vlong)(-32766) && vv < (vlong)32766)
13583e12c5d1SDavid du Colombier 				return 1;
13593e12c5d1SDavid du Colombier 		}
1360219b2ee8SDavid du Colombier 	}
13613e12c5d1SDavid du Colombier 	return 0;
13623e12c5d1SDavid du Colombier }
13633e12c5d1SDavid du Colombier 
13643e12c5d1SDavid du Colombier int
sval(long v)13653e12c5d1SDavid du Colombier sval(long v)
13663e12c5d1SDavid du Colombier {
13673e12c5d1SDavid du Colombier 	if(v >= -32766L && v < 32766L)
13683e12c5d1SDavid du Colombier 		return 1;
13693e12c5d1SDavid du Colombier 	return 0;
13703e12c5d1SDavid du Colombier }
13713e12c5d1SDavid du Colombier 
13723e12c5d1SDavid du Colombier long
exreg(Type * t)13733e12c5d1SDavid du Colombier exreg(Type *t)
13743e12c5d1SDavid du Colombier {
13753e12c5d1SDavid du Colombier 	long o;
13763e12c5d1SDavid du Colombier 
13773e12c5d1SDavid du Colombier 	if(typechlp[t->etype]) {
13783e12c5d1SDavid du Colombier 		if(exregoffset <= 16)
13793e12c5d1SDavid du Colombier 			return 0;
13803e12c5d1SDavid du Colombier 		o = exregoffset;
13813e12c5d1SDavid du Colombier 		exregoffset--;
13823e12c5d1SDavid du Colombier 		return o;
13833e12c5d1SDavid du Colombier 	}
1384219b2ee8SDavid du Colombier 	if(typefd[t->etype]) {
13853e12c5d1SDavid du Colombier 		if(exfregoffset <= 16)
13863e12c5d1SDavid du Colombier 			return 0;
13873e12c5d1SDavid du Colombier 		o = exfregoffset + NREG;
13883e12c5d1SDavid du Colombier 		exfregoffset--;
13893e12c5d1SDavid du Colombier 		return o;
13903e12c5d1SDavid du Colombier 	}
13913e12c5d1SDavid du Colombier 	return 0;
13923e12c5d1SDavid du Colombier }
13933e12c5d1SDavid du Colombier 
13947dd7cddfSDavid du Colombier schar	ewidth[NTYPE] =
13953e12c5d1SDavid du Colombier {
13967dd7cddfSDavid du Colombier 	-1,		/* [TXXX] */
13977dd7cddfSDavid du Colombier 	SZ_CHAR,	/* [TCHAR] */
13987dd7cddfSDavid du Colombier 	SZ_CHAR,	/* [TUCHAR] */
13997dd7cddfSDavid du Colombier 	SZ_SHORT,	/* [TSHORT] */
14007dd7cddfSDavid du Colombier 	SZ_SHORT,	/* [TUSHORT] */
14017dd7cddfSDavid du Colombier 	SZ_INT,		/* [TINT] */
14027dd7cddfSDavid du Colombier 	SZ_INT,		/* [TUINT] */
14037dd7cddfSDavid du Colombier 	SZ_LONG,	/* [TLONG] */
14047dd7cddfSDavid du Colombier 	SZ_LONG,	/* [TULONG] */
14057dd7cddfSDavid du Colombier 	SZ_VLONG,	/* [TVLONG] */
14067dd7cddfSDavid du Colombier 	SZ_VLONG,	/* [TUVLONG] */
14077dd7cddfSDavid du Colombier 	SZ_FLOAT,	/* [TFLOAT] */
14087dd7cddfSDavid du Colombier 	SZ_DOUBLE,	/* [TDOUBLE] */
14097dd7cddfSDavid du Colombier 	SZ_IND,		/* [TIND] */
14107dd7cddfSDavid du Colombier 	0,		/* [TFUNC] */
14117dd7cddfSDavid du Colombier 	-1,		/* [TARRAY] */
14127dd7cddfSDavid du Colombier 	0,		/* [TVOID] */
14137dd7cddfSDavid du Colombier 	-1,		/* [TSTRUCT] */
14147dd7cddfSDavid du Colombier 	-1,		/* [TUNION] */
14157dd7cddfSDavid du Colombier 	SZ_INT,		/* [TENUM] */
14163e12c5d1SDavid du Colombier };
14177dd7cddfSDavid du Colombier 
14187dd7cddfSDavid du Colombier long	ncast[NTYPE] =
14193e12c5d1SDavid du Colombier {
14207dd7cddfSDavid du Colombier 	0,				/* [TXXX] */
14217dd7cddfSDavid du Colombier 	BCHAR|BUCHAR,			/* [TCHAR] */
14227dd7cddfSDavid du Colombier 	BCHAR|BUCHAR,			/* [TUCHAR] */
14237dd7cddfSDavid du Colombier 	BSHORT|BUSHORT,			/* [TSHORT] */
14247dd7cddfSDavid du Colombier 	BSHORT|BUSHORT,			/* [TUSHORT] */
14257dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TINT] */
14267dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TUINT] */
14277dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TLONG] */
14287dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TULONG] */
14297dd7cddfSDavid du Colombier 	BVLONG|BUVLONG,			/* [TVLONG] */
14307dd7cddfSDavid du Colombier 	BVLONG|BUVLONG,			/* [TUVLONG] */
14317dd7cddfSDavid du Colombier 	BFLOAT,				/* [TFLOAT] */
14327dd7cddfSDavid du Colombier 	BDOUBLE,			/* [TDOUBLE] */
14337dd7cddfSDavid du Colombier 	BLONG|BULONG|BIND,		/* [TIND] */
14347dd7cddfSDavid du Colombier 	0,				/* [TFUNC] */
14357dd7cddfSDavid du Colombier 	0,				/* [TARRAY] */
14367dd7cddfSDavid du Colombier 	0,				/* [TVOID] */
14377dd7cddfSDavid du Colombier 	BSTRUCT,			/* [TSTRUCT] */
14387dd7cddfSDavid du Colombier 	BUNION,				/* [TUNION] */
14397dd7cddfSDavid du Colombier 	0,				/* [TENUM] */
14403e12c5d1SDavid du Colombier };
1441