xref: /plan9-contrib/sys/src/cmd/kc/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 = 'k';
103e12c5d1SDavid du Colombier 	thestring = "sparc";
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 = 0;
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 
823e12c5d1SDavid du Colombier 	memset(reg, 0, sizeof(reg));
833e12c5d1SDavid du Colombier 	reg[REGZERO] = 1;
843e12c5d1SDavid du Colombier 	reg[REGLINK] = 1;
853e12c5d1SDavid du Colombier 	reg[REGTMP] = 1;
863e12c5d1SDavid du Colombier 	for(i=NREG; i<NREG+NREG; i+=2)
873e12c5d1SDavid du Colombier 		reg[i+1] = 1;
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 && i != REGTMP && i != REGLINK)
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*
nod32const(vlong v)219219b2ee8SDavid du Colombier nod32const(vlong v)
220219b2ee8SDavid du Colombier {
221219b2ee8SDavid du Colombier 	constnode.vconst = v & MASK(32);
222219b2ee8SDavid du Colombier 	return &constnode;
223219b2ee8SDavid du Colombier }
224219b2ee8SDavid du Colombier 
225219b2ee8SDavid du Colombier Node*
nodconst(long v)2263e12c5d1SDavid du Colombier nodconst(long v)
2273e12c5d1SDavid du Colombier {
228219b2ee8SDavid du Colombier 	constnode.vconst = v;
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 
2603e12c5d1SDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)2613e12c5d1SDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
2623e12c5d1SDavid du Colombier {
2633e12c5d1SDavid du Colombier 	int i, j;
264375daca8SDavid du Colombier 	static int lasti;
2653e12c5d1SDavid du Colombier 
2663e12c5d1SDavid du Colombier 	switch(tn->type->etype) {
2673e12c5d1SDavid du Colombier 	case TCHAR:
2683e12c5d1SDavid du Colombier 	case TUCHAR:
2693e12c5d1SDavid du Colombier 	case TSHORT:
2703e12c5d1SDavid du Colombier 	case TUSHORT:
2717dd7cddfSDavid du Colombier 	case TINT:
2727dd7cddfSDavid du Colombier 	case TUINT:
2733e12c5d1SDavid du Colombier 	case TLONG:
2743e12c5d1SDavid du Colombier 	case TULONG:
2753e12c5d1SDavid du Colombier 	case TIND:
2763e12c5d1SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
2773e12c5d1SDavid du Colombier 			i = o->reg;
2783e12c5d1SDavid du Colombier 			if(i > 0 && i < NREG)
2793e12c5d1SDavid du Colombier 				goto out;
2803e12c5d1SDavid du Colombier 		}
2813e12c5d1SDavid du Colombier 		j = lasti + REGRET+1;
2823e12c5d1SDavid du Colombier 		for(i=REGRET+1; i<NREG; i++) {
2833e12c5d1SDavid du Colombier 			if(j >= NREG)
2843e12c5d1SDavid du Colombier 				j = REGRET+1;
2853e12c5d1SDavid du Colombier 			if(reg[j] == 0) {
2863e12c5d1SDavid du Colombier 				i = j;
2873e12c5d1SDavid du Colombier 				goto out;
2883e12c5d1SDavid du Colombier 			}
2893e12c5d1SDavid du Colombier 			j++;
2903e12c5d1SDavid du Colombier 		}
2913e12c5d1SDavid du Colombier 		diag(tn, "out of fixed registers");
2923e12c5d1SDavid du Colombier 		goto err;
2933e12c5d1SDavid du Colombier 
2943e12c5d1SDavid du Colombier 	case TFLOAT:
2953e12c5d1SDavid du Colombier 	case TDOUBLE:
2963e12c5d1SDavid du Colombier 	case TVLONG:
2973e12c5d1SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
2983e12c5d1SDavid du Colombier 			i = o->reg;
2993e12c5d1SDavid du Colombier 			if(i >= NREG && i < NREG+NREG)
3003e12c5d1SDavid du Colombier 				goto out;
3013e12c5d1SDavid du Colombier 		}
3023e12c5d1SDavid du Colombier 		j = lasti*2 + NREG;
3033e12c5d1SDavid du Colombier 		for(i=NREG; i<NREG+NREG; i+=2) {
3043e12c5d1SDavid du Colombier 			if(j >= NREG+NREG)
3053e12c5d1SDavid du Colombier 				j = NREG;
3063e12c5d1SDavid du Colombier 			if(reg[j] == 0) {
3073e12c5d1SDavid du Colombier 				i = j;
3083e12c5d1SDavid du Colombier 				goto out;
3093e12c5d1SDavid du Colombier 			}
3103e12c5d1SDavid du Colombier 			j += 2;
3113e12c5d1SDavid du Colombier 		}
3123e12c5d1SDavid du Colombier 		diag(tn, "out of float registers");
3133e12c5d1SDavid du Colombier 		goto err;
3143e12c5d1SDavid du Colombier 	}
3153e12c5d1SDavid du Colombier 	diag(tn, "unknown type in regalloc: %T", tn->type);
3163e12c5d1SDavid du Colombier err:
3173e12c5d1SDavid du Colombier 	i = 0;
3183e12c5d1SDavid du Colombier out:
3193e12c5d1SDavid du Colombier 	if(i)
3203e12c5d1SDavid du Colombier 		reg[i]++;
3213e12c5d1SDavid du Colombier 	lasti++;
3223e12c5d1SDavid du Colombier 	if(lasti >= 5)
3233e12c5d1SDavid du Colombier 		lasti = 0;
3243e12c5d1SDavid du Colombier 	nodreg(n, tn, i);
3253e12c5d1SDavid du Colombier }
3263e12c5d1SDavid du Colombier 
3273e12c5d1SDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)3283e12c5d1SDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
3293e12c5d1SDavid du Colombier {
3303e12c5d1SDavid du Colombier 	Node nod;
3313e12c5d1SDavid du Colombier 
3323e12c5d1SDavid du Colombier 	nod = *tn;
3333e12c5d1SDavid du Colombier 	nod.type = types[TIND];
3343e12c5d1SDavid du Colombier 	regalloc(n, &nod, o);
3353e12c5d1SDavid du Colombier }
3363e12c5d1SDavid du Colombier 
3373e12c5d1SDavid du Colombier void
regfree(Node * n)3383e12c5d1SDavid du Colombier regfree(Node *n)
3393e12c5d1SDavid du Colombier {
3403e12c5d1SDavid du Colombier 	int i;
3413e12c5d1SDavid du Colombier 
3423e12c5d1SDavid du Colombier 	i = 0;
3433e12c5d1SDavid du Colombier 	if(n->op != OREGISTER && n->op != OINDREG)
3443e12c5d1SDavid du Colombier 		goto err;
3453e12c5d1SDavid du Colombier 	i = n->reg;
3463e12c5d1SDavid du Colombier 	if(i < 0 || i >= sizeof(reg))
3473e12c5d1SDavid du Colombier 		goto err;
3483e12c5d1SDavid du Colombier 	if(reg[i] <= 0)
3493e12c5d1SDavid du Colombier 		goto err;
3503e12c5d1SDavid du Colombier 	reg[i]--;
3513e12c5d1SDavid du Colombier 	return;
3523e12c5d1SDavid du Colombier err:
3533e12c5d1SDavid du Colombier 	diag(n, "error in regfree: %d", i);
3543e12c5d1SDavid du Colombier }
3553e12c5d1SDavid du Colombier 
3563e12c5d1SDavid du Colombier void
regsalloc(Node * n,Node * nn)3573e12c5d1SDavid du Colombier regsalloc(Node *n, Node *nn)
3583e12c5d1SDavid du Colombier {
3597dd7cddfSDavid du Colombier 	cursafe = align(cursafe, nn->type, Aaut3);
3607dd7cddfSDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3613e12c5d1SDavid du Colombier 	*n = *nodsafe;
362219b2ee8SDavid du Colombier 	n->xoffset = -(stkoff + cursafe);
3633e12c5d1SDavid du Colombier 	n->type = nn->type;
3643e12c5d1SDavid du Colombier 	n->etype = nn->type->etype;
3653e12c5d1SDavid du Colombier 	n->lineno = nn->lineno;
3663e12c5d1SDavid du Colombier }
3673e12c5d1SDavid du Colombier 
3683e12c5d1SDavid du Colombier void
regaalloc1(Node * n,Node * nn)3693e12c5d1SDavid du Colombier regaalloc1(Node *n, Node *nn)
3703e12c5d1SDavid du Colombier {
3717dd7cddfSDavid du Colombier 	nodreg(n, nn, REGARG);
3727dd7cddfSDavid du Colombier 	reg[REGARG]++;
3737dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
3747dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
3757dd7cddfSDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3763e12c5d1SDavid du Colombier }
3773e12c5d1SDavid du Colombier 
3783e12c5d1SDavid du Colombier void
regaalloc(Node * n,Node * nn)3793e12c5d1SDavid du Colombier regaalloc(Node *n, Node *nn)
3803e12c5d1SDavid du Colombier {
3817dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
3823e12c5d1SDavid du Colombier 	*n = *nn;
3833e12c5d1SDavid du Colombier 	n->op = OINDREG;
3843e12c5d1SDavid du Colombier 	n->reg = REGSP;
3857dd7cddfSDavid du Colombier 	n->xoffset = curarg + SZ_LONG;
3863e12c5d1SDavid du Colombier 	n->complex = 0;
3873e12c5d1SDavid du Colombier 	n->addable = 20;
3887dd7cddfSDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
3897dd7cddfSDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3903e12c5d1SDavid du Colombier }
3913e12c5d1SDavid du Colombier 
3923e12c5d1SDavid du Colombier void
regind(Node * n,Node * nn)3933e12c5d1SDavid du Colombier regind(Node *n, Node *nn)
3943e12c5d1SDavid du Colombier {
3953e12c5d1SDavid du Colombier 
3963e12c5d1SDavid du Colombier 	if(n->op != OREGISTER) {
3973e12c5d1SDavid du Colombier 		diag(n, "regind not OREGISTER");
3983e12c5d1SDavid du Colombier 		return;
3993e12c5d1SDavid du Colombier 	}
4003e12c5d1SDavid du Colombier 	n->op = OINDREG;
4013e12c5d1SDavid du Colombier 	n->type = nn->type;
4023e12c5d1SDavid du Colombier }
4033e12c5d1SDavid du Colombier 
4043e12c5d1SDavid du Colombier void
raddr(Node * n,Prog * p)4053e12c5d1SDavid du Colombier raddr(Node *n, Prog *p)
4063e12c5d1SDavid du Colombier {
4073e12c5d1SDavid du Colombier 	Adr a;
4083e12c5d1SDavid du Colombier 
4093e12c5d1SDavid du Colombier 	naddr(n, &a);
4103e12c5d1SDavid du Colombier 	if(a.type == D_CONST && a.offset == 0) {
4113e12c5d1SDavid du Colombier 		a.type = D_REG;
4123e12c5d1SDavid du Colombier 		a.reg = 0;
4133e12c5d1SDavid du Colombier 	}
4143e12c5d1SDavid du Colombier 	if(a.type != D_REG && a.type != D_FREG) {
4153e12c5d1SDavid du Colombier 		if(n)
4163e12c5d1SDavid du Colombier 			diag(n, "bad in raddr: %O", n->op);
4173e12c5d1SDavid du Colombier 		else
4183e12c5d1SDavid du Colombier 			diag(n, "bad in raddr: <null>");
4193e12c5d1SDavid du Colombier 		p->reg = NREG;
4203e12c5d1SDavid du Colombier 	} else
4213e12c5d1SDavid du Colombier 		p->reg = a.reg;
4223e12c5d1SDavid du Colombier }
4233e12c5d1SDavid du Colombier 
4243e12c5d1SDavid du Colombier void
naddr(Node * n,Adr * a)4253e12c5d1SDavid du Colombier naddr(Node *n, Adr *a)
4263e12c5d1SDavid du Colombier {
4273e12c5d1SDavid du Colombier 	long v;
4283e12c5d1SDavid du Colombier 
4293e12c5d1SDavid du Colombier 	a->type = D_NONE;
4303e12c5d1SDavid du Colombier 	if(n == Z)
4313e12c5d1SDavid du Colombier 		return;
4323e12c5d1SDavid du Colombier 	switch(n->op) {
4333e12c5d1SDavid du Colombier 	default:
4343e12c5d1SDavid du Colombier 	bad:
4353e12c5d1SDavid du Colombier 		diag(n, "bad in naddr: %O", n->op);
4363e12c5d1SDavid du Colombier 		break;
4373e12c5d1SDavid du Colombier 
4383e12c5d1SDavid du Colombier 	case OREGISTER:
4393e12c5d1SDavid du Colombier 		a->type = D_REG;
4403e12c5d1SDavid du Colombier 		a->sym = S;
4413e12c5d1SDavid du Colombier 		a->reg = n->reg;
4423e12c5d1SDavid du Colombier 		if(a->reg >= NREG) {
4433e12c5d1SDavid du Colombier 			a->type = D_FREG;
4443e12c5d1SDavid du Colombier 			a->reg -= NREG;
4453e12c5d1SDavid du Colombier 		}
4463e12c5d1SDavid du Colombier 		break;
4473e12c5d1SDavid du Colombier 
4483e12c5d1SDavid du Colombier 	case OIND:
4493e12c5d1SDavid du Colombier 		naddr(n->left, a);
4503e12c5d1SDavid du Colombier 		if(a->type == D_REG) {
4513e12c5d1SDavid du Colombier 			a->type = D_OREG;
4523e12c5d1SDavid du Colombier 			break;
4533e12c5d1SDavid du Colombier 		}
4543e12c5d1SDavid du Colombier 		if(a->type == D_CONST) {
4553e12c5d1SDavid du Colombier 			a->type = D_OREG;
4563e12c5d1SDavid du Colombier 			break;
4573e12c5d1SDavid du Colombier 		}
4583e12c5d1SDavid du Colombier 		goto bad;
4593e12c5d1SDavid du Colombier 
4603e12c5d1SDavid du Colombier 	case OINDREG:
4613e12c5d1SDavid du Colombier 		a->type = D_OREG;
4623e12c5d1SDavid du Colombier 		a->sym = S;
463219b2ee8SDavid du Colombier 		a->offset = n->xoffset;
4643e12c5d1SDavid du Colombier 		a->reg = n->reg;
4653e12c5d1SDavid du Colombier 		break;
4663e12c5d1SDavid du Colombier 
4673e12c5d1SDavid du Colombier 	case ONAME:
4683e12c5d1SDavid du Colombier 		a->etype = n->etype;
4693e12c5d1SDavid du Colombier 		a->type = D_OREG;
4703e12c5d1SDavid du Colombier 		a->name = D_STATIC;
4713e12c5d1SDavid du Colombier 		a->sym = n->sym;
472219b2ee8SDavid du Colombier 		a->offset = n->xoffset;
4733e12c5d1SDavid du Colombier 		if(n->class == CSTATIC)
4743e12c5d1SDavid du Colombier 			break;
4753e12c5d1SDavid du Colombier 		if(n->class == CEXTERN || n->class == CGLOBL) {
4763e12c5d1SDavid du Colombier 			a->name = D_EXTERN;
4773e12c5d1SDavid du Colombier 			break;
4783e12c5d1SDavid du Colombier 		}
4793e12c5d1SDavid du Colombier 		if(n->class == CAUTO) {
4803e12c5d1SDavid du Colombier 			a->name = D_AUTO;
4813e12c5d1SDavid du Colombier 			break;
4823e12c5d1SDavid du Colombier 		}
4833e12c5d1SDavid du Colombier 		if(n->class == CPARAM) {
4843e12c5d1SDavid du Colombier 			a->name = D_PARAM;
4853e12c5d1SDavid du Colombier 			break;
4863e12c5d1SDavid du Colombier 		}
4873e12c5d1SDavid du Colombier 		goto bad;
4883e12c5d1SDavid du Colombier 
4893e12c5d1SDavid du Colombier 	case OCONST:
4903e12c5d1SDavid du Colombier 		a->sym = S;
4913e12c5d1SDavid du Colombier 		a->reg = NREG;
492219b2ee8SDavid du Colombier 		if(typefd[n->type->etype]) {
4933e12c5d1SDavid du Colombier 			a->type = D_FCONST;
494219b2ee8SDavid du Colombier 			a->dval = n->fconst;
4953e12c5d1SDavid du Colombier 		} else {
4963e12c5d1SDavid du Colombier 			a->type = D_CONST;
497219b2ee8SDavid du Colombier 			a->offset = n->vconst;
4983e12c5d1SDavid du Colombier 		}
4993e12c5d1SDavid du Colombier 		break;
5003e12c5d1SDavid du Colombier 
5013e12c5d1SDavid du Colombier 	case OADDR:
5023e12c5d1SDavid du Colombier 		naddr(n->left, a);
5033e12c5d1SDavid du Colombier 		if(a->type == D_OREG) {
5043e12c5d1SDavid du Colombier 			a->type = D_CONST;
5053e12c5d1SDavid du Colombier 			break;
5063e12c5d1SDavid du Colombier 		}
5073e12c5d1SDavid du Colombier 		goto bad;
5083e12c5d1SDavid du Colombier 
5093e12c5d1SDavid du Colombier 	case OADD:
5103e12c5d1SDavid du Colombier 		if(n->left->op == OCONST) {
5113e12c5d1SDavid du Colombier 			naddr(n->left, a);
5123e12c5d1SDavid du Colombier 			v = a->offset;
5133e12c5d1SDavid du Colombier 			naddr(n->right, a);
5143e12c5d1SDavid du Colombier 		} else {
5153e12c5d1SDavid du Colombier 			naddr(n->right, a);
5163e12c5d1SDavid du Colombier 			v = a->offset;
5173e12c5d1SDavid du Colombier 			naddr(n->left, a);
5183e12c5d1SDavid du Colombier 		}
5193e12c5d1SDavid du Colombier 		a->offset += v;
5203e12c5d1SDavid du Colombier 		break;
5213e12c5d1SDavid du Colombier 
5223e12c5d1SDavid du Colombier 	}
5233e12c5d1SDavid du Colombier }
5243e12c5d1SDavid du Colombier 
5253e12c5d1SDavid du Colombier void
fop(int as,int f1,int f2,Node * t)5263e12c5d1SDavid du Colombier fop(int as, int f1, int f2, Node *t)
5273e12c5d1SDavid du Colombier {
5283e12c5d1SDavid du Colombier 	Node nod1, nod2, nod3;
5293e12c5d1SDavid du Colombier 
5303e12c5d1SDavid du Colombier 	nodreg(&nod1, t, NREG+f1);
5313e12c5d1SDavid du Colombier 	nodreg(&nod2, t, NREG+f2);
5323e12c5d1SDavid du Colombier 	regalloc(&nod3, t, t);
5333e12c5d1SDavid du Colombier 	gopcode(as, &nod1, &nod2, &nod3);
5343e12c5d1SDavid du Colombier 	gmove(&nod3, t);
5353e12c5d1SDavid du Colombier 	regfree(&nod3);
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier 
5383e12c5d1SDavid du Colombier void
gmove(Node * f,Node * t)5393e12c5d1SDavid du Colombier gmove(Node *f, Node *t)
5403e12c5d1SDavid du Colombier {
5413e12c5d1SDavid du Colombier 	int ft, tt, a;
5423e12c5d1SDavid du Colombier 	Node nod;
543bd389b36SDavid du Colombier 	Prog *p1;
5443e12c5d1SDavid du Colombier 	double d;
5453e12c5d1SDavid du Colombier 
5463e12c5d1SDavid du Colombier 	ft = f->type->etype;
5473e12c5d1SDavid du Colombier 	tt = t->type->etype;
5483e12c5d1SDavid du Colombier 
5493e12c5d1SDavid du Colombier 	if(ft == TDOUBLE && f->op == OCONST) {
550219b2ee8SDavid du Colombier 		d = f->fconst;
5513e12c5d1SDavid du Colombier 		if(d == 0.0) {
5523e12c5d1SDavid du Colombier 			a = FREGZERO;
5533e12c5d1SDavid du Colombier 			goto ffreg;
5543e12c5d1SDavid du Colombier 		}
5553e12c5d1SDavid du Colombier 		if(d == 0.5) {
5563e12c5d1SDavid du Colombier 			a = FREGHALF;
5573e12c5d1SDavid du Colombier 			goto ffreg;
5583e12c5d1SDavid du Colombier 		}
5593e12c5d1SDavid du Colombier 		if(d == 1.0) {
5603e12c5d1SDavid du Colombier 			a = FREGONE;
5613e12c5d1SDavid du Colombier 			goto ffreg;
5623e12c5d1SDavid du Colombier 		}
5633e12c5d1SDavid du Colombier 		if(d == 2.0) {
5643e12c5d1SDavid du Colombier 			a = FREGTWO;
5653e12c5d1SDavid du Colombier 			goto ffreg;
5663e12c5d1SDavid du Colombier 		}
5673e12c5d1SDavid du Colombier 		if(d == -.5) {
5683e12c5d1SDavid du Colombier 			fop(OSUB, FREGHALF, FREGZERO, t);
5693e12c5d1SDavid du Colombier 			return;
5703e12c5d1SDavid du Colombier 		}
5713e12c5d1SDavid du Colombier 		if(d == -1.0) {
5723e12c5d1SDavid du Colombier 			fop(OSUB, FREGONE, FREGZERO, t);
5733e12c5d1SDavid du Colombier 			return;
5743e12c5d1SDavid du Colombier 		}
5753e12c5d1SDavid du Colombier 		if(d == -2.0) {
5763e12c5d1SDavid du Colombier 			fop(OSUB, FREGTWO, FREGZERO, t);
5773e12c5d1SDavid du Colombier 			return;
5783e12c5d1SDavid du Colombier 		}
5793e12c5d1SDavid du Colombier 		if(d == 1.5) {
5803e12c5d1SDavid du Colombier 			fop(OADD, FREGONE, FREGHALF, t);
5813e12c5d1SDavid du Colombier 			return;
5823e12c5d1SDavid du Colombier 		}
5833e12c5d1SDavid du Colombier 		if(d == 2.5) {
5843e12c5d1SDavid du Colombier 			fop(OADD, FREGTWO, FREGHALF, t);
5853e12c5d1SDavid du Colombier 			return;
5863e12c5d1SDavid du Colombier 		}
5873e12c5d1SDavid du Colombier 		if(d == 3.0) {
5883e12c5d1SDavid du Colombier 			fop(OADD, FREGTWO, FREGONE, t);
5893e12c5d1SDavid du Colombier 			return;
5903e12c5d1SDavid du Colombier 		}
5913e12c5d1SDavid du Colombier 	}
5923e12c5d1SDavid du Colombier 	if(ft == TFLOAT && f->op == OCONST) {
593219b2ee8SDavid du Colombier 		d = f->fconst;
5943e12c5d1SDavid du Colombier 		if(d == 0) {
5953e12c5d1SDavid du Colombier 			a = FREGZERO;
5963e12c5d1SDavid du Colombier 		ffreg:
5973e12c5d1SDavid du Colombier 			nodreg(&nod, f, NREG+a);
5983e12c5d1SDavid du Colombier 			gmove(&nod, t);
5993e12c5d1SDavid du Colombier 			return;
6003e12c5d1SDavid du Colombier 		}
6013e12c5d1SDavid du Colombier 	}
6023e12c5d1SDavid du Colombier 	/*
6033e12c5d1SDavid du Colombier 	 * a load --
6043e12c5d1SDavid du Colombier 	 * put it into a register then
6053e12c5d1SDavid du Colombier 	 * worry what to do with it.
6063e12c5d1SDavid du Colombier 	 */
6073e12c5d1SDavid du Colombier 	if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
6083e12c5d1SDavid du Colombier 		switch(ft) {
6093e12c5d1SDavid du Colombier 		default:
610219b2ee8SDavid du Colombier 			if(typefd[tt]) {
6113e12c5d1SDavid du Colombier 				/* special case can load mem to Freg */
6123e12c5d1SDavid du Colombier 				regalloc(&nod, t, t);
6133e12c5d1SDavid du Colombier 				gins(AMOVW, f, &nod);
6143e12c5d1SDavid du Colombier 				a = AFMOVWD;
6153e12c5d1SDavid du Colombier 				if(tt == TFLOAT)
6163e12c5d1SDavid du Colombier 					a = AFMOVWF;
6173e12c5d1SDavid du Colombier 				gins(a, &nod, &nod);
6183e12c5d1SDavid du Colombier 				gmove(&nod, t);
6193e12c5d1SDavid du Colombier 				regfree(&nod);
6203e12c5d1SDavid du Colombier 				return;
6213e12c5d1SDavid du Colombier 			}
6223e12c5d1SDavid du Colombier 			a = AMOVW;
6233e12c5d1SDavid du Colombier 			break;
6243e12c5d1SDavid du Colombier 		case TFLOAT:
6253e12c5d1SDavid du Colombier 			a = AFMOVF;
6263e12c5d1SDavid du Colombier 			break;
6273e12c5d1SDavid du Colombier 		case TDOUBLE:
6283e12c5d1SDavid du Colombier 			a = AFMOVD;
6293e12c5d1SDavid du Colombier 			break;
6303e12c5d1SDavid du Colombier 		case TCHAR:
6313e12c5d1SDavid du Colombier 			a = AMOVB;
6323e12c5d1SDavid du Colombier 			break;
6333e12c5d1SDavid du Colombier 		case TUCHAR:
6343e12c5d1SDavid du Colombier 			a = AMOVBU;
6353e12c5d1SDavid du Colombier 			break;
6363e12c5d1SDavid du Colombier 		case TSHORT:
6373e12c5d1SDavid du Colombier 			a = AMOVH;
6383e12c5d1SDavid du Colombier 			break;
6393e12c5d1SDavid du Colombier 		case TUSHORT:
6403e12c5d1SDavid du Colombier 			a = AMOVHU;
6413e12c5d1SDavid du Colombier 			break;
6423e12c5d1SDavid du Colombier 		}
6433e12c5d1SDavid du Colombier 		regalloc(&nod, f, t);
6443e12c5d1SDavid du Colombier 		gins(a, f, &nod);
6453e12c5d1SDavid du Colombier 		gmove(&nod, t);
6463e12c5d1SDavid du Colombier 		regfree(&nod);
6473e12c5d1SDavid du Colombier 		return;
6483e12c5d1SDavid du Colombier 	}
6493e12c5d1SDavid du Colombier 
6503e12c5d1SDavid du Colombier 	/*
6513e12c5d1SDavid du Colombier 	 * a store --
6523e12c5d1SDavid du Colombier 	 * put it into a register then
6533e12c5d1SDavid du Colombier 	 * store it.
6543e12c5d1SDavid du Colombier 	 */
6553e12c5d1SDavid du Colombier 	if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
6563e12c5d1SDavid du Colombier 		switch(tt) {
6573e12c5d1SDavid du Colombier 		default:
658219b2ee8SDavid du Colombier 			if(typefd[ft]) {
6593e12c5d1SDavid du Colombier 				/* special case can store mem from Freg */
6603e12c5d1SDavid du Colombier 				regalloc(&nod, f, Z);
6613e12c5d1SDavid du Colombier 				a = AFMOVDW;
6623e12c5d1SDavid du Colombier 				if(ft == TFLOAT)
6633e12c5d1SDavid du Colombier 					a = AFMOVFW;
6643e12c5d1SDavid du Colombier 				gins(a, f, &nod);
6653e12c5d1SDavid du Colombier 				gins(AMOVW, &nod, t);
6663e12c5d1SDavid du Colombier 				regfree(&nod);
6673e12c5d1SDavid du Colombier 				return;
6683e12c5d1SDavid du Colombier 			}
6693e12c5d1SDavid du Colombier 			a = AMOVW;
6703e12c5d1SDavid du Colombier 			break;
6713e12c5d1SDavid du Colombier 		case TUCHAR:
672375daca8SDavid du Colombier 			a = AMOVBU;
673375daca8SDavid du Colombier 			break;
6743e12c5d1SDavid du Colombier 		case TCHAR:
6753e12c5d1SDavid du Colombier 			a = AMOVB;
6763e12c5d1SDavid du Colombier 			break;
6773e12c5d1SDavid du Colombier 		case TUSHORT:
678375daca8SDavid du Colombier 			a = AMOVHU;
679375daca8SDavid du Colombier 			break;
6803e12c5d1SDavid du Colombier 		case TSHORT:
6813e12c5d1SDavid du Colombier 			a = AMOVH;
6823e12c5d1SDavid du Colombier 			break;
6833e12c5d1SDavid du Colombier 		case TFLOAT:
6843e12c5d1SDavid du Colombier 			a = AFMOVF;
6853e12c5d1SDavid du Colombier 			break;
6863e12c5d1SDavid du Colombier 		case TVLONG:
6873e12c5d1SDavid du Colombier 		case TDOUBLE:
6883e12c5d1SDavid du Colombier 			a = AFMOVD;
6893e12c5d1SDavid du Colombier 			break;
6903e12c5d1SDavid du Colombier 		}
691219b2ee8SDavid du Colombier 		if(!typefd[ft] && vconst(f) == 0) {
6923e12c5d1SDavid du Colombier 			gins(a, f, t);
6933e12c5d1SDavid du Colombier 			return;
6943e12c5d1SDavid du Colombier 		}
6953e12c5d1SDavid du Colombier 		if(ft == tt)
6963e12c5d1SDavid du Colombier 			regalloc(&nod, t, f);
6973e12c5d1SDavid du Colombier 		else
6983e12c5d1SDavid du Colombier 			regalloc(&nod, t, Z);
6993e12c5d1SDavid du Colombier 		gmove(f, &nod);
7003e12c5d1SDavid du Colombier 		gins(a, &nod, t);
7013e12c5d1SDavid du Colombier 		regfree(&nod);
7023e12c5d1SDavid du Colombier 		return;
7033e12c5d1SDavid du Colombier 	}
7043e12c5d1SDavid du Colombier 
7053e12c5d1SDavid du Colombier 	/*
7063e12c5d1SDavid du Colombier 	 * type x type cross table
7073e12c5d1SDavid du Colombier 	 */
7083e12c5d1SDavid du Colombier 	a = AGOK;
7093e12c5d1SDavid du Colombier 	switch(ft) {
7103e12c5d1SDavid du Colombier 	case TDOUBLE:
7113e12c5d1SDavid du Colombier 	case TVLONG:
7123e12c5d1SDavid du Colombier 	case TFLOAT:
7133e12c5d1SDavid du Colombier 		switch(tt) {
7143e12c5d1SDavid du Colombier 		case TDOUBLE:
7153e12c5d1SDavid du Colombier 		case TVLONG:
7163e12c5d1SDavid du Colombier 			a = AFMOVD;
7173e12c5d1SDavid du Colombier 			if(ft == TFLOAT)
7183e12c5d1SDavid du Colombier 				a = AFMOVFD;
7193e12c5d1SDavid du Colombier 			break;
7203e12c5d1SDavid du Colombier 		case TFLOAT:
7213e12c5d1SDavid du Colombier 			a = AFMOVDF;
7223e12c5d1SDavid du Colombier 			if(ft == TFLOAT)
7233e12c5d1SDavid du Colombier 				a = AFMOVF;
7243e12c5d1SDavid du Colombier 			break;
7253e12c5d1SDavid du Colombier 		case TLONG:
7263e12c5d1SDavid du Colombier 		case TULONG:
7273e12c5d1SDavid du Colombier 		case TIND:
7287dd7cddfSDavid du Colombier 		case TINT:
7297dd7cddfSDavid du Colombier 		case TUINT:
7303e12c5d1SDavid du Colombier 		case TSHORT:
7313e12c5d1SDavid du Colombier 		case TUSHORT:
7323e12c5d1SDavid du Colombier 		case TCHAR:
7333e12c5d1SDavid du Colombier 		case TUCHAR:
7343e12c5d1SDavid du Colombier 			regalloc(&nod, f, Z);	/* should be type float */
7353e12c5d1SDavid du Colombier 			a = AFMOVDW;
7363e12c5d1SDavid du Colombier 			if(ft == TFLOAT)
7373e12c5d1SDavid du Colombier 				a = AFMOVFW;
7383e12c5d1SDavid du Colombier 			gins(a, f, &nod);
7393e12c5d1SDavid du Colombier 			gins(AFMOVF, &nod, nodrat);
7403e12c5d1SDavid du Colombier 			regfree(&nod);
7413e12c5d1SDavid du Colombier 			gins(AMOVW, nodrat, t);
7423e12c5d1SDavid du Colombier 			gmove(t, t);
7433e12c5d1SDavid du Colombier 			if(nrathole < SZ_LONG)
7443e12c5d1SDavid du Colombier 				nrathole = SZ_LONG;
7453e12c5d1SDavid du Colombier 			return;
7463e12c5d1SDavid du Colombier 		}
7473e12c5d1SDavid du Colombier 		break;
7487dd7cddfSDavid du Colombier 	case TINT:
7497dd7cddfSDavid du Colombier 	case TUINT:
7503e12c5d1SDavid du Colombier 	case TLONG:
7513e12c5d1SDavid du Colombier 	case TULONG:
7523e12c5d1SDavid du Colombier 	case TIND:
7533e12c5d1SDavid du Colombier 		switch(tt) {
7543e12c5d1SDavid du Colombier 		case TDOUBLE:
7553e12c5d1SDavid du Colombier 		case TVLONG:
7563e12c5d1SDavid du Colombier 		case TFLOAT:
7573e12c5d1SDavid du Colombier 			goto fxtofl;
7583e12c5d1SDavid du Colombier 		case TLONG:
7593e12c5d1SDavid du Colombier 		case TULONG:
7607dd7cddfSDavid du Colombier 		case TINT:
7617dd7cddfSDavid du Colombier 		case TUINT:
7623e12c5d1SDavid du Colombier 		case TIND:
7633e12c5d1SDavid du Colombier 		case TSHORT:
7643e12c5d1SDavid du Colombier 		case TUSHORT:
7653e12c5d1SDavid du Colombier 		case TCHAR:
7663e12c5d1SDavid du Colombier 		case TUCHAR:
7673e12c5d1SDavid du Colombier 			a = AMOVW;
7683e12c5d1SDavid du Colombier 			break;
7693e12c5d1SDavid du Colombier 		}
7703e12c5d1SDavid du Colombier 		break;
7713e12c5d1SDavid du Colombier 	case TSHORT:
7723e12c5d1SDavid du Colombier 		switch(tt) {
7733e12c5d1SDavid du Colombier 		case TDOUBLE:
7743e12c5d1SDavid du Colombier 		case TVLONG:
7753e12c5d1SDavid du Colombier 		case TFLOAT:
7763e12c5d1SDavid du Colombier 			goto fxtofl;
7777dd7cddfSDavid du Colombier 		case TUINT:
7787dd7cddfSDavid du Colombier 		case TINT:
7793e12c5d1SDavid du Colombier 		case TULONG:
7803e12c5d1SDavid du Colombier 		case TLONG:
7813e12c5d1SDavid du Colombier 		case TIND:
7823e12c5d1SDavid du Colombier 			a = AMOVH;
7833e12c5d1SDavid du Colombier 			break;
7843e12c5d1SDavid du Colombier 		case TSHORT:
7853e12c5d1SDavid du Colombier 		case TUSHORT:
7863e12c5d1SDavid du Colombier 		case TCHAR:
7873e12c5d1SDavid du Colombier 		case TUCHAR:
7883e12c5d1SDavid du Colombier 			a = AMOVW;
7893e12c5d1SDavid du Colombier 			break;
7903e12c5d1SDavid du Colombier 		}
7913e12c5d1SDavid du Colombier 		break;
7923e12c5d1SDavid du Colombier 	case TUSHORT:
7933e12c5d1SDavid du Colombier 		switch(tt) {
7943e12c5d1SDavid du Colombier 		case TDOUBLE:
7953e12c5d1SDavid du Colombier 		case TVLONG:
7963e12c5d1SDavid du Colombier 		case TFLOAT:
7973e12c5d1SDavid du Colombier 			goto fxtofl;
7987dd7cddfSDavid du Colombier 		case TINT:
7997dd7cddfSDavid du Colombier 		case TUINT:
8003e12c5d1SDavid du Colombier 		case TLONG:
8013e12c5d1SDavid du Colombier 		case TULONG:
8023e12c5d1SDavid du Colombier 		case TIND:
8033e12c5d1SDavid du Colombier 			a = AMOVHU;
8043e12c5d1SDavid du Colombier 			break;
8053e12c5d1SDavid du Colombier 		case TSHORT:
8063e12c5d1SDavid du Colombier 		case TUSHORT:
8073e12c5d1SDavid du Colombier 		case TCHAR:
8083e12c5d1SDavid du Colombier 		case TUCHAR:
8093e12c5d1SDavid du Colombier 			a = AMOVW;
8103e12c5d1SDavid du Colombier 			break;
8113e12c5d1SDavid du Colombier 		}
8123e12c5d1SDavid du Colombier 		break;
8133e12c5d1SDavid du Colombier 	case TCHAR:
8143e12c5d1SDavid du Colombier 		switch(tt) {
8153e12c5d1SDavid du Colombier 		case TDOUBLE:
8163e12c5d1SDavid du Colombier 		case TVLONG:
8173e12c5d1SDavid du Colombier 		case TFLOAT:
8183e12c5d1SDavid du Colombier 			goto fxtofl;
8197dd7cddfSDavid du Colombier 		case TINT:
8207dd7cddfSDavid du Colombier 		case TUINT:
8213e12c5d1SDavid du Colombier 		case TLONG:
8223e12c5d1SDavid du Colombier 		case TULONG:
8233e12c5d1SDavid du Colombier 		case TIND:
8243e12c5d1SDavid du Colombier 		case TSHORT:
8253e12c5d1SDavid du Colombier 		case TUSHORT:
8263e12c5d1SDavid du Colombier 			a = AMOVB;
8273e12c5d1SDavid du Colombier 			break;
8283e12c5d1SDavid du Colombier 		case TCHAR:
8293e12c5d1SDavid du Colombier 		case TUCHAR:
8303e12c5d1SDavid du Colombier 			a = AMOVW;
8313e12c5d1SDavid du Colombier 			break;
8323e12c5d1SDavid du Colombier 		}
8333e12c5d1SDavid du Colombier 		break;
8343e12c5d1SDavid du Colombier 	case TUCHAR:
8353e12c5d1SDavid du Colombier 		switch(tt) {
8363e12c5d1SDavid du Colombier 		case TDOUBLE:
8373e12c5d1SDavid du Colombier 		case TVLONG:
8383e12c5d1SDavid du Colombier 		case TFLOAT:
8393e12c5d1SDavid du Colombier 		fxtofl:
8403e12c5d1SDavid du Colombier 			regalloc(&nod, t, t);	/* should be type float */
8413e12c5d1SDavid du Colombier 			gins(AMOVW, f, nodrat);
8423e12c5d1SDavid du Colombier 			gins(AFMOVF, nodrat, &nod);
8433e12c5d1SDavid du Colombier 			a = AFMOVWD;
8443e12c5d1SDavid du Colombier 			if(tt == TFLOAT)
8453e12c5d1SDavid du Colombier 				a = AFMOVWF;
8463e12c5d1SDavid du Colombier 			gins(a, &nod, t);
8473e12c5d1SDavid du Colombier 			regfree(&nod);
8483e12c5d1SDavid du Colombier 			if(nrathole < SZ_LONG)
8493e12c5d1SDavid du Colombier 				nrathole = SZ_LONG;
850bd389b36SDavid du Colombier 			if(ft == TULONG) {
851bd389b36SDavid du Colombier 				regalloc(&nod, t, Z);
852bd389b36SDavid du Colombier 				if(tt == TFLOAT) {
853bd389b36SDavid du Colombier 					gins(AFCMPF, t, Z);
854bd389b36SDavid du Colombier 					p->to.type = D_FREG;
855bd389b36SDavid du Colombier 					p->to.reg = FREGZERO;
856bd389b36SDavid du Colombier 					gins(AFBGE, Z, Z);
857bd389b36SDavid du Colombier 					p1 = p;
858bd389b36SDavid du Colombier 					gins(AFMOVF, nodfconst(4294967296.), &nod);
859bd389b36SDavid du Colombier 					gins(AFADDF, &nod, t);
860bd389b36SDavid du Colombier 				} else {
861bd389b36SDavid du Colombier 					gins(AFCMPD, t, Z);
862bd389b36SDavid du Colombier 					p->to.type = D_FREG;
863bd389b36SDavid du Colombier 					p->to.reg = FREGZERO;
864bd389b36SDavid du Colombier 					gins(AFBGE, Z, Z);
865bd389b36SDavid du Colombier 					p1 = p;
866bd389b36SDavid du Colombier 					gins(AFMOVD, nodfconst(4294967296.), &nod);
867bd389b36SDavid du Colombier 					gins(AFADDD, &nod, t);
868bd389b36SDavid du Colombier 				}
869bd389b36SDavid du Colombier 				patch(p1, pc);
870bd389b36SDavid du Colombier 				regfree(&nod);
871bd389b36SDavid du Colombier 			}
8723e12c5d1SDavid du Colombier 			return;
8737dd7cddfSDavid du Colombier 		case TINT:
8747dd7cddfSDavid du Colombier 		case TUINT:
8753e12c5d1SDavid du Colombier 		case TLONG:
8763e12c5d1SDavid du Colombier 		case TULONG:
8773e12c5d1SDavid du Colombier 		case TIND:
8783e12c5d1SDavid du Colombier 		case TSHORT:
8793e12c5d1SDavid du Colombier 		case TUSHORT:
8803e12c5d1SDavid du Colombier 			a = AMOVBU;
8813e12c5d1SDavid du Colombier 			break;
8823e12c5d1SDavid du Colombier 		case TCHAR:
8833e12c5d1SDavid du Colombier 		case TUCHAR:
8843e12c5d1SDavid du Colombier 			a = AMOVW;
8853e12c5d1SDavid du Colombier 			break;
8863e12c5d1SDavid du Colombier 		}
8873e12c5d1SDavid du Colombier 		break;
8883e12c5d1SDavid du Colombier 	}
8897dd7cddfSDavid du Colombier 	if(a == AGOK)
8907dd7cddfSDavid du Colombier 		diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
8913e12c5d1SDavid du Colombier 	if(a == AMOVW || a == AFMOVF || a == AFMOVD)
8923e12c5d1SDavid du Colombier 	if(samaddr(f, t))
8933e12c5d1SDavid du Colombier 		return;
8943e12c5d1SDavid du Colombier 	gins(a, f, t);
8953e12c5d1SDavid du Colombier }
8963e12c5d1SDavid du Colombier 
8973e12c5d1SDavid du Colombier void
gins(int a,Node * f,Node * t)8983e12c5d1SDavid du Colombier gins(int a, Node *f, Node *t)
8993e12c5d1SDavid du Colombier {
9003e12c5d1SDavid du Colombier 
9013e12c5d1SDavid du Colombier 	nextpc();
9023e12c5d1SDavid du Colombier 	p->as = a;
9033e12c5d1SDavid du Colombier 	if(f != Z)
9043e12c5d1SDavid du Colombier 		naddr(f, &p->from);
9053e12c5d1SDavid du Colombier 	if(t != Z)
9063e12c5d1SDavid du Colombier 		naddr(t, &p->to);
9073e12c5d1SDavid du Colombier 	if(debug['g'])
9083e12c5d1SDavid du Colombier 		print("%P\n", p);
9093e12c5d1SDavid du Colombier }
9103e12c5d1SDavid du Colombier 
9113e12c5d1SDavid du Colombier void
gopcode(int o,Node * f1,Node * f2,Node * t)9123e12c5d1SDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t)
9133e12c5d1SDavid du Colombier {
9143e12c5d1SDavid du Colombier 	int a, et;
9153e12c5d1SDavid du Colombier 	Adr ta;
9163e12c5d1SDavid du Colombier 
9173e12c5d1SDavid du Colombier 	et = TLONG;
9183e12c5d1SDavid du Colombier 	if(f1 != Z && f1->type != T)
9193e12c5d1SDavid du Colombier 		et = f1->type->etype;
9203e12c5d1SDavid du Colombier 	a = AGOK;
9213e12c5d1SDavid du Colombier 	switch(o) {
9223e12c5d1SDavid du Colombier 	case OAS:
9233e12c5d1SDavid du Colombier 		gmove(f1, t);
9243e12c5d1SDavid du Colombier 		return;
9253e12c5d1SDavid du Colombier 
9263e12c5d1SDavid du Colombier 	case OASADD:
9273e12c5d1SDavid du Colombier 	case OADD:
9283e12c5d1SDavid du Colombier 		a = AADD;
9293e12c5d1SDavid du Colombier 		if(et == TFLOAT)
9303e12c5d1SDavid du Colombier 			a = AFADDF;
9313e12c5d1SDavid du Colombier 		else
9323e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG)
9333e12c5d1SDavid du Colombier 			a = AFADDD;
9343e12c5d1SDavid du Colombier 		break;
9353e12c5d1SDavid du Colombier 
9363e12c5d1SDavid du Colombier 	case OASSUB:
9373e12c5d1SDavid du Colombier 	case OSUB:
9383e12c5d1SDavid du Colombier 		a = ASUB;
9393e12c5d1SDavid du Colombier 		if(et == TFLOAT)
9403e12c5d1SDavid du Colombier 			a = AFSUBF;
9413e12c5d1SDavid du Colombier 		else
9423e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG)
9433e12c5d1SDavid du Colombier 			a = AFSUBD;
9443e12c5d1SDavid du Colombier 		break;
9453e12c5d1SDavid du Colombier 
9463e12c5d1SDavid du Colombier 	case OASOR:
9473e12c5d1SDavid du Colombier 	case OOR:
9483e12c5d1SDavid du Colombier 		a = AOR;
9493e12c5d1SDavid du Colombier 		break;
9503e12c5d1SDavid du Colombier 
9513e12c5d1SDavid du Colombier 	case OASAND:
9523e12c5d1SDavid du Colombier 	case OAND:
9533e12c5d1SDavid du Colombier 		a = AAND;
9543e12c5d1SDavid du Colombier 		break;
9553e12c5d1SDavid du Colombier 
9563e12c5d1SDavid du Colombier 	case OASXOR:
9573e12c5d1SDavid du Colombier 	case OXOR:
9583e12c5d1SDavid du Colombier 		a = AXOR;
9593e12c5d1SDavid du Colombier 		break;
9603e12c5d1SDavid du Colombier 
9613e12c5d1SDavid du Colombier 	case OASLSHR:
9623e12c5d1SDavid du Colombier 	case OLSHR:
9633e12c5d1SDavid du Colombier 		a = ASRL;
9643e12c5d1SDavid du Colombier 		break;
9653e12c5d1SDavid du Colombier 
9663e12c5d1SDavid du Colombier 	case OASASHR:
9673e12c5d1SDavid du Colombier 	case OASHR:
9683e12c5d1SDavid du Colombier 		a = ASRA;
9693e12c5d1SDavid du Colombier 		break;
9703e12c5d1SDavid du Colombier 
9713e12c5d1SDavid du Colombier 	case OASASHL:
9723e12c5d1SDavid du Colombier 	case OASHL:
9733e12c5d1SDavid du Colombier 		a = ASLL;
9743e12c5d1SDavid du Colombier 		break;
9753e12c5d1SDavid du Colombier 
9763e12c5d1SDavid du Colombier 	case OFUNC:
9773e12c5d1SDavid du Colombier 		a = AJMPL;
9783e12c5d1SDavid du Colombier 		break;
9793e12c5d1SDavid du Colombier 
9803e12c5d1SDavid du Colombier 	case OASLMUL:
9813e12c5d1SDavid du Colombier 	case OLMUL:
9823e12c5d1SDavid du Colombier 	case OASMUL:
9833e12c5d1SDavid du Colombier 	case OMUL:
9843e12c5d1SDavid du Colombier 		if(et == TFLOAT) {
9853e12c5d1SDavid du Colombier 			a = AFMULF;
9863e12c5d1SDavid du Colombier 			break;
9873e12c5d1SDavid du Colombier 		} else
9883e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG) {
9893e12c5d1SDavid du Colombier 			a = AFMULD;
9903e12c5d1SDavid du Colombier 			break;
9913e12c5d1SDavid du Colombier 		}
9923e12c5d1SDavid du Colombier 		a = AMUL;
9933e12c5d1SDavid du Colombier 		break;
9943e12c5d1SDavid du Colombier 
9953e12c5d1SDavid du Colombier 	case OASDIV:
9963e12c5d1SDavid du Colombier 	case ODIV:
9973e12c5d1SDavid du Colombier 		if(et == TFLOAT) {
9983e12c5d1SDavid du Colombier 			a = AFDIVF;
9993e12c5d1SDavid du Colombier 			break;
10003e12c5d1SDavid du Colombier 		} else
10013e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG) {
10023e12c5d1SDavid du Colombier 			a = AFDIVD;
10033e12c5d1SDavid du Colombier 			break;
10043e12c5d1SDavid du Colombier 		}
10053e12c5d1SDavid du Colombier 		a = ADIV;
10063e12c5d1SDavid du Colombier 		break;
10073e12c5d1SDavid du Colombier 
10083e12c5d1SDavid du Colombier 	case OASMOD:
10093e12c5d1SDavid du Colombier 	case OMOD:
10103e12c5d1SDavid du Colombier 		a = AMOD;
10113e12c5d1SDavid du Colombier 		break;
10123e12c5d1SDavid du Colombier 
10133e12c5d1SDavid du Colombier 	case OASLMOD:
10143e12c5d1SDavid du Colombier 	case OLMOD:
10153e12c5d1SDavid du Colombier 		a = AMODL;
10163e12c5d1SDavid du Colombier 		break;
10173e12c5d1SDavid du Colombier 
10183e12c5d1SDavid du Colombier 	case OASLDIV:
10193e12c5d1SDavid du Colombier 	case OLDIV:
10203e12c5d1SDavid du Colombier 		a = ADIVL;
10213e12c5d1SDavid du Colombier 		break;
10223e12c5d1SDavid du Colombier 
10233e12c5d1SDavid du Colombier 	case OEQ:
10243e12c5d1SDavid du Colombier 		a = ABE;
1025219b2ee8SDavid du Colombier 		if(typefd[et])
10263e12c5d1SDavid du Colombier 			a = AFBE;
10273e12c5d1SDavid du Colombier 		goto cmp;
10283e12c5d1SDavid du Colombier 
10293e12c5d1SDavid du Colombier 	case ONE:
10303e12c5d1SDavid du Colombier 		a = ABNE;
1031219b2ee8SDavid du Colombier 		if(typefd[et])
10323e12c5d1SDavid du Colombier 			a = AFBLG;
10333e12c5d1SDavid du Colombier 		goto cmp;
10343e12c5d1SDavid du Colombier 
10353e12c5d1SDavid du Colombier 	case OLT:
10363e12c5d1SDavid du Colombier 		a = ABL;
1037219b2ee8SDavid du Colombier 		if(typefd[et])
10383e12c5d1SDavid du Colombier 			a = AFBL;
10393e12c5d1SDavid du Colombier 		goto cmp;
10403e12c5d1SDavid du Colombier 
10413e12c5d1SDavid du Colombier 	case OLE:
10423e12c5d1SDavid du Colombier 		a = ABLE;
1043219b2ee8SDavid du Colombier 		if(typefd[et])
10443e12c5d1SDavid du Colombier 			a = AFBLE;
10453e12c5d1SDavid du Colombier 		goto cmp;
10463e12c5d1SDavid du Colombier 
10473e12c5d1SDavid du Colombier 	case OGE:
10483e12c5d1SDavid du Colombier 		a = ABGE;
1049219b2ee8SDavid du Colombier 		if(typefd[et])
10503e12c5d1SDavid du Colombier 			a = AFBGE;
10513e12c5d1SDavid du Colombier 		goto cmp;
10523e12c5d1SDavid du Colombier 
10533e12c5d1SDavid du Colombier 	case OGT:
10543e12c5d1SDavid du Colombier 		a = ABG;
1055219b2ee8SDavid du Colombier 		if(typefd[et])
10563e12c5d1SDavid du Colombier 			a = AFBG;
10573e12c5d1SDavid du Colombier 		goto cmp;
10583e12c5d1SDavid du Colombier 
10593e12c5d1SDavid du Colombier 	case OLO:
10603e12c5d1SDavid du Colombier 		a = ABCS;
10613e12c5d1SDavid du Colombier 		goto cmp;
10623e12c5d1SDavid du Colombier 
10633e12c5d1SDavid du Colombier 	case OLS:
10643e12c5d1SDavid du Colombier 		a = ABLEU;
10653e12c5d1SDavid du Colombier 		goto cmp;
10663e12c5d1SDavid du Colombier 
10673e12c5d1SDavid du Colombier 	case OHS:
10683e12c5d1SDavid du Colombier 		a = ABCC;
10693e12c5d1SDavid du Colombier 		goto cmp;
10703e12c5d1SDavid du Colombier 
10713e12c5d1SDavid du Colombier 	case OHI:
10723e12c5d1SDavid du Colombier 		a = ABGU;
10733e12c5d1SDavid du Colombier 		goto cmp;
10743e12c5d1SDavid du Colombier 
10753e12c5d1SDavid du Colombier 	cmp:
10763e12c5d1SDavid du Colombier 		nextpc();
10773e12c5d1SDavid du Colombier 		p->as = ACMP;
10783e12c5d1SDavid du Colombier 		if(et == TFLOAT)
10793e12c5d1SDavid du Colombier 			p->as = AFCMPF;
10803e12c5d1SDavid du Colombier 		else
10813e12c5d1SDavid du Colombier 		if(et == TDOUBLE || et == TVLONG)
10823e12c5d1SDavid du Colombier 			p->as = AFCMPD;
10833e12c5d1SDavid du Colombier 		if(f1 != Z)
10843e12c5d1SDavid du Colombier 			naddr(f1, &p->from);
10853e12c5d1SDavid du Colombier 		if(t != Z)
10863e12c5d1SDavid du Colombier 			naddr(t, &p->to);
10873e12c5d1SDavid du Colombier 		if(f1 == Z || t == Z || f2 != Z)
10883e12c5d1SDavid du Colombier 			diag(Z, "bad cmp in gopcode %O", o);
10893e12c5d1SDavid du Colombier 		if(debug['g'])
10903e12c5d1SDavid du Colombier 			print("%P\n", p);
10913e12c5d1SDavid du Colombier 		f1 = Z;
10923e12c5d1SDavid du Colombier 		f2 = Z;
10933e12c5d1SDavid du Colombier 		t = Z;
10943e12c5d1SDavid du Colombier 		break;
10953e12c5d1SDavid du Colombier 	}
10963e12c5d1SDavid du Colombier 	if(a == AGOK)
10973e12c5d1SDavid du Colombier 		diag(Z, "bad in gopcode %O", o);
10983e12c5d1SDavid du Colombier 	nextpc();
10993e12c5d1SDavid du Colombier 	p->as = a;
11003e12c5d1SDavid du Colombier 	if(f1 != Z)
11013e12c5d1SDavid du Colombier 		naddr(f1, &p->from);
11023e12c5d1SDavid du Colombier 	if(f2 != Z) {
11033e12c5d1SDavid du Colombier 		naddr(f2, &ta);
11043e12c5d1SDavid du Colombier 		p->reg = ta.reg;
11053e12c5d1SDavid du Colombier 		if(ta.type == D_CONST && ta.offset == 0)
11063e12c5d1SDavid du Colombier 			p->reg = REGZERO;
11073e12c5d1SDavid du Colombier 	}
11083e12c5d1SDavid du Colombier 	if(t != Z)
11093e12c5d1SDavid du Colombier 		naddr(t, &p->to);
11103e12c5d1SDavid du Colombier 	if(debug['g'])
11113e12c5d1SDavid du Colombier 		print("%P\n", p);
11123e12c5d1SDavid du Colombier }
11133e12c5d1SDavid du Colombier 
samaddr(Node * f,Node * t)11143e12c5d1SDavid du Colombier samaddr(Node *f, Node *t)
11153e12c5d1SDavid du Colombier {
11163e12c5d1SDavid du Colombier 
11173e12c5d1SDavid du Colombier 	if(f->op != t->op)
11183e12c5d1SDavid du Colombier 		return 0;
11193e12c5d1SDavid du Colombier 	switch(f->op) {
11203e12c5d1SDavid du Colombier 
11213e12c5d1SDavid du Colombier 	case OREGISTER:
11223e12c5d1SDavid du Colombier 		if(f->reg != t->reg)
11233e12c5d1SDavid du Colombier 			break;
11243e12c5d1SDavid du Colombier 		return 1;
11253e12c5d1SDavid du Colombier 	}
11263e12c5d1SDavid du Colombier 	return 0;
11273e12c5d1SDavid du Colombier }
11283e12c5d1SDavid du Colombier 
11293e12c5d1SDavid du Colombier void
gbranch(int o)11303e12c5d1SDavid du Colombier gbranch(int o)
11313e12c5d1SDavid du Colombier {
11323e12c5d1SDavid du Colombier 	int a;
11333e12c5d1SDavid du Colombier 
11343e12c5d1SDavid du Colombier 	a = AGOK;
11353e12c5d1SDavid du Colombier 	switch(o) {
11363e12c5d1SDavid du Colombier 	case ORETURN:
11373e12c5d1SDavid du Colombier 		a = ARETURN;
11383e12c5d1SDavid du Colombier 		break;
11393e12c5d1SDavid du Colombier 	case OGOTO:
11403e12c5d1SDavid du Colombier 		a = AJMP;
11413e12c5d1SDavid du Colombier 		break;
11423e12c5d1SDavid du Colombier 	}
11433e12c5d1SDavid du Colombier 	nextpc();
11443e12c5d1SDavid du Colombier 	if(a == AGOK) {
11453e12c5d1SDavid du Colombier 		diag(Z, "bad in gbranch %O",  o);
11463e12c5d1SDavid du Colombier 		nextpc();
11473e12c5d1SDavid du Colombier 	}
11483e12c5d1SDavid du Colombier 	p->as = a;
11493e12c5d1SDavid du Colombier }
11503e12c5d1SDavid du Colombier 
11513e12c5d1SDavid du Colombier void
patch(Prog * op,long pc)11523e12c5d1SDavid du Colombier patch(Prog *op, long pc)
11533e12c5d1SDavid du Colombier {
11543e12c5d1SDavid du Colombier 
11553e12c5d1SDavid du Colombier 	op->to.offset = pc;
11563e12c5d1SDavid du Colombier 	op->to.type = D_BRANCH;
11573e12c5d1SDavid du Colombier }
11583e12c5d1SDavid du Colombier 
11593e12c5d1SDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)11603e12c5d1SDavid du Colombier gpseudo(int a, Sym *s, Node *n)
11613e12c5d1SDavid du Colombier {
11623e12c5d1SDavid du Colombier 
11633e12c5d1SDavid du Colombier 	nextpc();
11643e12c5d1SDavid du Colombier 	p->as = a;
11653e12c5d1SDavid du Colombier 	p->from.type = D_OREG;
11663e12c5d1SDavid du Colombier 	p->from.sym = s;
1167*5ede6b93SDavid du Colombier 	if(a == ATEXT)
1168e288d156SDavid du Colombier 		p->reg = (profileflg ? 0 : NOPROF);
11693e12c5d1SDavid du Colombier 	p->from.name = D_EXTERN;
11703e12c5d1SDavid du Colombier 	if(s->class == CSTATIC)
11713e12c5d1SDavid du Colombier 		p->from.name = D_STATIC;
11723e12c5d1SDavid du Colombier 	naddr(n, &p->to);
11733e12c5d1SDavid du Colombier 	if(a == ADATA || a == AGLOBL)
11743e12c5d1SDavid du Colombier 		pc--;
11753e12c5d1SDavid du Colombier }
11763e12c5d1SDavid du Colombier 
11773e12c5d1SDavid du Colombier int
sval(long v)11783e12c5d1SDavid du Colombier sval(long v)
11793e12c5d1SDavid du Colombier {
11803e12c5d1SDavid du Colombier 
11813e12c5d1SDavid du Colombier 	if(v >= -(1<<12) && v < (1<<12))
11823e12c5d1SDavid du Colombier 		return 1;
11833e12c5d1SDavid du Colombier 	return 0;
11843e12c5d1SDavid du Colombier }
11853e12c5d1SDavid du Colombier 
11863e12c5d1SDavid du Colombier int
sconst(Node * n)11873e12c5d1SDavid du Colombier sconst(Node *n)
11883e12c5d1SDavid du Colombier {
1189219b2ee8SDavid du Colombier 	vlong vv;
11903e12c5d1SDavid du Colombier 
1191219b2ee8SDavid du Colombier 	if(n->op == OCONST) {
1192219b2ee8SDavid du Colombier 		if(!typefd[n->type->etype]) {
1193219b2ee8SDavid du Colombier 			vv = n->vconst;
1194375daca8SDavid du Colombier 			if(vv >= -(vlong)(1<<12) && vv < (vlong)(1<<12))
11953e12c5d1SDavid du Colombier 				return 1;
11963e12c5d1SDavid du Colombier 		}
1197219b2ee8SDavid du Colombier 	}
11983e12c5d1SDavid du Colombier 	return 0;
11993e12c5d1SDavid du Colombier }
12003e12c5d1SDavid du Colombier 
12013e12c5d1SDavid du Colombier long
exreg(Type * t)12023e12c5d1SDavid du Colombier exreg(Type *t)
12033e12c5d1SDavid du Colombier {
12043e12c5d1SDavid du Colombier 	long o;
12053e12c5d1SDavid du Colombier 
12063e12c5d1SDavid du Colombier 	if(typechlp[t->etype]) {
12073e12c5d1SDavid du Colombier 		if(exregoffset <= 3)
12083e12c5d1SDavid du Colombier 			return 0;
12093e12c5d1SDavid du Colombier 		o = exregoffset;
12103e12c5d1SDavid du Colombier 		exregoffset--;
12113e12c5d1SDavid du Colombier 		return o;
12123e12c5d1SDavid du Colombier 	}
1213219b2ee8SDavid du Colombier 	if(typefd[t->etype]) {
12143e12c5d1SDavid du Colombier 		if(exfregoffset <= 16)
12153e12c5d1SDavid du Colombier 			return 0;
12163e12c5d1SDavid du Colombier 		o = exfregoffset + NREG;
12173e12c5d1SDavid du Colombier 		exfregoffset--;
12183e12c5d1SDavid du Colombier 		return o;
12193e12c5d1SDavid du Colombier 	}
12203e12c5d1SDavid du Colombier 	return 0;
12213e12c5d1SDavid du Colombier }
12223e12c5d1SDavid du Colombier 
12237dd7cddfSDavid du Colombier schar	ewidth[NTYPE] =
12243e12c5d1SDavid du Colombier {
12257dd7cddfSDavid du Colombier 	-1,		/* [TXXX] */
12267dd7cddfSDavid du Colombier 	SZ_CHAR,	/* [TCHAR] */
12277dd7cddfSDavid du Colombier 	SZ_CHAR,	/* [TUCHAR] */
12287dd7cddfSDavid du Colombier 	SZ_SHORT,	/* [TSHORT] */
12297dd7cddfSDavid du Colombier 	SZ_SHORT,	/* [TUSHORT] */
12307dd7cddfSDavid du Colombier 	SZ_INT,		/* [TINT] */
12317dd7cddfSDavid du Colombier 	SZ_INT,		/* [TUINT] */
12327dd7cddfSDavid du Colombier 	SZ_LONG,	/* [TLONG] */
12337dd7cddfSDavid du Colombier 	SZ_LONG,	/* [TULONG] */
12347dd7cddfSDavid du Colombier 	SZ_VLONG,	/* [TVLONG] */
12357dd7cddfSDavid du Colombier 	SZ_VLONG,	/* [TUVLONG] */
12367dd7cddfSDavid du Colombier 	SZ_FLOAT,	/* [TFLOAT] */
12377dd7cddfSDavid du Colombier 	SZ_DOUBLE,	/* [TDOUBLE] */
12387dd7cddfSDavid du Colombier 	SZ_IND,		/* [TIND] */
12397dd7cddfSDavid du Colombier 	0,		/* [TFUNC] */
12407dd7cddfSDavid du Colombier 	-1,		/* [TARRAY] */
12417dd7cddfSDavid du Colombier 	0,		/* [TVOID] */
12427dd7cddfSDavid du Colombier 	-1,		/* [TSTRUCT] */
12437dd7cddfSDavid du Colombier 	-1,		/* [TUNION] */
12447dd7cddfSDavid du Colombier 	SZ_INT,		/* [TENUM] */
12453e12c5d1SDavid du Colombier };
12467dd7cddfSDavid du Colombier 
12477dd7cddfSDavid du Colombier long	ncast[NTYPE] =
12483e12c5d1SDavid du Colombier {
12497dd7cddfSDavid du Colombier 	0,				/* [TXXX] */
12507dd7cddfSDavid du Colombier 	BCHAR|BUCHAR,			/* [TCHAR] */
12517dd7cddfSDavid du Colombier 	BCHAR|BUCHAR,			/* [TUCHAR] */
12527dd7cddfSDavid du Colombier 	BSHORT|BUSHORT,			/* [TSHORT] */
12537dd7cddfSDavid du Colombier 	BSHORT|BUSHORT,			/* [TUSHORT] */
12547dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TINT] */
12557dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TUINT] */
12567dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TLONG] */
12577dd7cddfSDavid du Colombier 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TULONG] */
12587dd7cddfSDavid du Colombier 	BVLONG|BUVLONG,			/* [TVLONG] */
12597dd7cddfSDavid du Colombier 	BVLONG|BUVLONG,			/* [TUVLONG] */
12607dd7cddfSDavid du Colombier 	BFLOAT,				/* [TFLOAT] */
12617dd7cddfSDavid du Colombier 	BDOUBLE,			/* [TDOUBLE] */
12627dd7cddfSDavid du Colombier 	BLONG|BULONG|BIND,		/* [TIND] */
12637dd7cddfSDavid du Colombier 	0,				/* [TFUNC] */
12647dd7cddfSDavid du Colombier 	0,				/* [TARRAY] */
12657dd7cddfSDavid du Colombier 	0,				/* [TVOID] */
12667dd7cddfSDavid du Colombier 	BSTRUCT,			/* [TSTRUCT] */
12677dd7cddfSDavid du Colombier 	BUNION,				/* [TUNION] */
12687dd7cddfSDavid du Colombier 	0,				/* [TENUM] */
12693e12c5d1SDavid du Colombier };
1270