xref: /plan9-contrib/sys/src/cmd/4c/txt.c (revision f8bc6aaf8056e137bcdfb6117a990ac3eff62cc9)
17edc7532SDavid du Colombier #include "gc.h"
27edc7532SDavid du Colombier 
37edc7532SDavid du Colombier void
ginit(void)47edc7532SDavid du Colombier ginit(void)
57edc7532SDavid du Colombier {
67edc7532SDavid du Colombier 	int i;
77edc7532SDavid du Colombier 	Type *t;
87edc7532SDavid du Colombier 
97edc7532SDavid du Colombier 	thechar = '4';
107edc7532SDavid du Colombier 	thestring = "mips64";
117edc7532SDavid du Colombier 	exregoffset = REGEXT;
127edc7532SDavid du Colombier 	exfregoffset = FREGEXT;
137edc7532SDavid du Colombier 	listinit();
147edc7532SDavid du Colombier 	nstring = 0;
157edc7532SDavid du Colombier 	mnstring = 0;
167edc7532SDavid du Colombier 	nrathole = 0;
177edc7532SDavid du Colombier 	pc = 0;
187edc7532SDavid du Colombier 	breakpc = -1;
197edc7532SDavid du Colombier 	continpc = -1;
207edc7532SDavid du Colombier 	cases = C;
217edc7532SDavid du Colombier 	firstp = P;
227edc7532SDavid du Colombier 	lastp = P;
237edc7532SDavid du Colombier 	tfield = types[TLONG];
247edc7532SDavid du Colombier 
25*f8bc6aafSDavid du Colombier 	/* 64-bit machine */
26*f8bc6aafSDavid du Colombier 	typeword = typechlvp;
27*f8bc6aafSDavid du Colombier 	typeswitch = typechlv;
28*f8bc6aafSDavid du Colombier 	typecmplx = typesu;
29*f8bc6aafSDavid du Colombier 
307edc7532SDavid du Colombier 	zprog.link = P;
317edc7532SDavid du Colombier 	zprog.as = AGOK;
327edc7532SDavid du Colombier 	zprog.reg = NREG;
337edc7532SDavid du Colombier 	zprog.from.type = D_NONE;
347edc7532SDavid du Colombier 	zprog.from.name = D_NONE;
357edc7532SDavid du Colombier 	zprog.from.reg = NREG;
367edc7532SDavid du Colombier 	zprog.to = zprog.from;
377edc7532SDavid du Colombier 
387edc7532SDavid du Colombier 	regnode.op = OREGISTER;
397edc7532SDavid du Colombier 	regnode.class = CEXREG;
407edc7532SDavid du Colombier 	regnode.reg = REGTMP;
417edc7532SDavid du Colombier 	regnode.complex = 0;
427edc7532SDavid du Colombier 	regnode.addable = 11;
437edc7532SDavid du Colombier 	regnode.type = types[TLONG];
447edc7532SDavid du Colombier 
457edc7532SDavid du Colombier 	constnode.op = OCONST;
467edc7532SDavid du Colombier 	constnode.class = CXXX;
477edc7532SDavid du Colombier 	constnode.complex = 0;
487edc7532SDavid du Colombier 	constnode.addable = 20;
497edc7532SDavid du Colombier 	constnode.type = types[TLONG];
507edc7532SDavid du Colombier 
517edc7532SDavid du Colombier 	fconstnode.op = OCONST;
527edc7532SDavid du Colombier 	fconstnode.class = CXXX;
537edc7532SDavid du Colombier 	fconstnode.complex = 0;
547edc7532SDavid du Colombier 	fconstnode.addable = 20;
557edc7532SDavid du Colombier 	fconstnode.type = types[TDOUBLE];
567edc7532SDavid du Colombier 
577edc7532SDavid du Colombier 	nodsafe = new(ONAME, Z, Z);
587edc7532SDavid du Colombier 	nodsafe->sym = slookup(".safe");
597edc7532SDavid du Colombier 	nodsafe->type = types[TINT];
607edc7532SDavid du Colombier 	nodsafe->etype = types[TINT]->etype;
617edc7532SDavid du Colombier 	nodsafe->class = CAUTO;
627edc7532SDavid du Colombier 	complex(nodsafe);
637edc7532SDavid du Colombier 
647edc7532SDavid du Colombier 	t = typ(TARRAY, types[TCHAR]);
657edc7532SDavid du Colombier 	symrathole = slookup(".rathole");
667edc7532SDavid du Colombier 	symrathole->class = CGLOBL;
677edc7532SDavid du Colombier 	symrathole->type = t;
687edc7532SDavid du Colombier 
697edc7532SDavid du Colombier 	nodrat = new(ONAME, Z, Z);
707edc7532SDavid du Colombier 	nodrat->sym = symrathole;
717edc7532SDavid du Colombier 	nodrat->type = types[TIND];
727edc7532SDavid du Colombier 	nodrat->etype = TVOID;
737edc7532SDavid du Colombier 	nodrat->class = CGLOBL;
747edc7532SDavid du Colombier 	complex(nodrat);
757edc7532SDavid du Colombier 	nodrat->type = t;
767edc7532SDavid du Colombier 
777edc7532SDavid du Colombier 	nodret = new(ONAME, Z, Z);
787edc7532SDavid du Colombier 	nodret->sym = slookup(".ret");
797edc7532SDavid du Colombier 	nodret->type = types[TIND];
807edc7532SDavid du Colombier 	nodret->etype = TIND;
817edc7532SDavid du Colombier 	nodret->class = CPARAM;
827edc7532SDavid du Colombier 	nodret = new(OIND, nodret, Z);
837edc7532SDavid du Colombier 	complex(nodret);
847edc7532SDavid du Colombier 
85*f8bc6aafSDavid du Colombier 	for(i=0; i<nelem(reg); i++) {
86*f8bc6aafSDavid du Colombier 		reg[i] = 0;
87*f8bc6aafSDavid du Colombier 		if(i == REGZERO ||
88*f8bc6aafSDavid du Colombier 		  (i >= NREG && ((i-NREG)&1)))
89*f8bc6aafSDavid du Colombier 			reg[i] = 1;
90*f8bc6aafSDavid du Colombier 	}
917edc7532SDavid du Colombier }
927edc7532SDavid du Colombier 
937edc7532SDavid du Colombier void
gclean(void)947edc7532SDavid du Colombier gclean(void)
957edc7532SDavid du Colombier {
967edc7532SDavid du Colombier 	int i;
977edc7532SDavid du Colombier 	Sym *s;
987edc7532SDavid du Colombier 
997edc7532SDavid du Colombier 	for(i=0; i<NREG; i++)
1007edc7532SDavid du Colombier 		if(i != REGZERO)
1017edc7532SDavid du Colombier 			if(reg[i])
1027edc7532SDavid du Colombier 				diag(Z, "reg %d left allocated", i);
1037edc7532SDavid du Colombier 	for(i=NREG; i<NREG+NREG; i+=2)
1047edc7532SDavid du Colombier 		if(reg[i])
1057edc7532SDavid du Colombier 			diag(Z, "freg %d left allocated", i-NREG);
1067edc7532SDavid du Colombier 	while(mnstring)
1077edc7532SDavid du Colombier 		outstring("", 1L);
1087edc7532SDavid du Colombier 	symstring->type->width = nstring;
1097edc7532SDavid du Colombier 	symrathole->type->width = nrathole;
1107edc7532SDavid du Colombier 	for(i=0; i<NHASH; i++)
1117edc7532SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link) {
1127edc7532SDavid du Colombier 		if(s->type == T)
1137edc7532SDavid du Colombier 			continue;
1147edc7532SDavid du Colombier 		if(s->type->width == 0)
1157edc7532SDavid du Colombier 			continue;
1167edc7532SDavid du Colombier 		if(s->class != CGLOBL && s->class != CSTATIC)
1177edc7532SDavid du Colombier 			continue;
1187edc7532SDavid du Colombier 		if(s->type == types[TENUM])
1197edc7532SDavid du Colombier 			continue;
1207edc7532SDavid du Colombier 		gpseudo(AGLOBL, s, nodconst(s->type->width));
1217edc7532SDavid du Colombier 	}
1227edc7532SDavid du Colombier 	nextpc();
1237edc7532SDavid du Colombier 	p->as = AEND;
1247edc7532SDavid du Colombier 	outcode();
1257edc7532SDavid du Colombier }
1267edc7532SDavid du Colombier 
1277edc7532SDavid du Colombier void
nextpc(void)1287edc7532SDavid du Colombier nextpc(void)
1297edc7532SDavid du Colombier {
1307edc7532SDavid du Colombier 
1317edc7532SDavid du Colombier 	p = alloc(sizeof(*p));
1327edc7532SDavid du Colombier 	*p = zprog;
1337edc7532SDavid du Colombier 	p->lineno = nearln;
1347edc7532SDavid du Colombier 	pc++;
1357edc7532SDavid du Colombier 	if(firstp == P) {
1367edc7532SDavid du Colombier 		firstp = p;
1377edc7532SDavid du Colombier 		lastp = p;
1387edc7532SDavid du Colombier 		return;
1397edc7532SDavid du Colombier 	}
1407edc7532SDavid du Colombier 	lastp->link = p;
1417edc7532SDavid du Colombier 	lastp = p;
1427edc7532SDavid du Colombier }
1437edc7532SDavid du Colombier 
1447edc7532SDavid du Colombier void
gargs(Node * n,Node * tn1,Node * tn2)1457edc7532SDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2)
1467edc7532SDavid du Colombier {
1477edc7532SDavid du Colombier 	long regs;
1487edc7532SDavid du Colombier 	Node fnxargs[20], *fnxp;
1497edc7532SDavid du Colombier 
1507edc7532SDavid du Colombier 	regs = cursafe;
1517edc7532SDavid du Colombier 
1527edc7532SDavid du Colombier 	fnxp = fnxargs;
1537edc7532SDavid du Colombier 	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
1547edc7532SDavid du Colombier 
1557edc7532SDavid du Colombier 	curarg = 0;
1567edc7532SDavid du Colombier 	fnxp = fnxargs;
1577edc7532SDavid du Colombier 	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
1587edc7532SDavid du Colombier 
1597edc7532SDavid du Colombier 	cursafe = regs;
1607edc7532SDavid du Colombier }
1617edc7532SDavid du Colombier 
1627edc7532SDavid du Colombier void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)1637edc7532SDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
1647edc7532SDavid du Colombier {
1657edc7532SDavid du Colombier 	Node nod;
1667edc7532SDavid du Colombier 
1677edc7532SDavid du Colombier 	if(n == Z)
1687edc7532SDavid du Colombier 		return;
1697edc7532SDavid du Colombier 	if(n->op == OLIST) {
1707edc7532SDavid du Colombier 		garg1(n->left, tn1, tn2, f, fnxp);
1717edc7532SDavid du Colombier 		garg1(n->right, tn1, tn2, f, fnxp);
1727edc7532SDavid du Colombier 		return;
1737edc7532SDavid du Colombier 	}
1747edc7532SDavid du Colombier 	if(f == 0) {
1757edc7532SDavid du Colombier 		if(n->complex >= FNX) {
1767edc7532SDavid du Colombier 			regsalloc(*fnxp, n);
1777edc7532SDavid du Colombier 			nod = znode;
1787edc7532SDavid du Colombier 			nod.op = OAS;
1797edc7532SDavid du Colombier 			nod.left = *fnxp;
1807edc7532SDavid du Colombier 			nod.right = n;
1817edc7532SDavid du Colombier 			nod.type = n->type;
1827edc7532SDavid du Colombier 			cgen(&nod, Z);
1837edc7532SDavid du Colombier 			(*fnxp)++;
1847edc7532SDavid du Colombier 		}
1857edc7532SDavid du Colombier 		return;
1867edc7532SDavid du Colombier 	}
1877edc7532SDavid du Colombier 	if(typesu[n->type->etype]) {
1887edc7532SDavid du Colombier 		regaalloc(tn2, n);
1897edc7532SDavid du Colombier 		if(n->complex >= FNX) {
1907edc7532SDavid du Colombier 			sugen(*fnxp, tn2, n->type->width);
1917edc7532SDavid du Colombier 			(*fnxp)++;
1927edc7532SDavid du Colombier 		} else
1937edc7532SDavid du Colombier 			sugen(n, tn2, n->type->width);
1947edc7532SDavid du Colombier 		return;
1957edc7532SDavid du Colombier 	}
196*f8bc6aafSDavid du Colombier 	if(REGARG && curarg == 0 && typeword[n->type->etype]) {
1977edc7532SDavid du Colombier 		regaalloc1(tn1, n);
1987edc7532SDavid du Colombier 		if(n->complex >= FNX) {
1997edc7532SDavid du Colombier 			cgen(*fnxp, tn1);
2007edc7532SDavid du Colombier 			(*fnxp)++;
2017edc7532SDavid du Colombier 		} else
2027edc7532SDavid du Colombier 			cgen(n, tn1);
2037edc7532SDavid du Colombier 		return;
2047edc7532SDavid du Colombier 	}
2057edc7532SDavid du Colombier 	if(vconst(n) == 0) {
2067edc7532SDavid du Colombier 		regaalloc(tn2, n);
2077edc7532SDavid du Colombier 		gopcode(OAS, n, Z, tn2);
2087edc7532SDavid du Colombier 		return;
2097edc7532SDavid du Colombier 	}
2107edc7532SDavid du Colombier 	regalloc(tn1, n, Z);
2117edc7532SDavid du Colombier 	if(n->complex >= FNX) {
2127edc7532SDavid du Colombier 		cgen(*fnxp, tn1);
2137edc7532SDavid du Colombier 		(*fnxp)++;
2147edc7532SDavid du Colombier 	} else
2157edc7532SDavid du Colombier 		cgen(n, tn1);
2167edc7532SDavid du Colombier 	regaalloc(tn2, n);
2177edc7532SDavid du Colombier 	gopcode(OAS, tn1, Z, tn2);
2187edc7532SDavid du Colombier 	regfree(tn1);
2197edc7532SDavid du Colombier }
2207edc7532SDavid du Colombier 
2217edc7532SDavid du Colombier Node*
nodconst(long v)2227edc7532SDavid du Colombier nodconst(long v)
2237edc7532SDavid du Colombier {
2247edc7532SDavid du Colombier 	constnode.vconst = v;
2257edc7532SDavid du Colombier 	return &constnode;
2267edc7532SDavid du Colombier }
2277edc7532SDavid du Colombier 
2287edc7532SDavid du Colombier Node*
nod32const(vlong v)229*f8bc6aafSDavid du Colombier nod32const(vlong v)
230*f8bc6aafSDavid du Colombier {
231*f8bc6aafSDavid du Colombier 	constnode.vconst = v & MASK(32);
232*f8bc6aafSDavid du Colombier 	return &constnode;
233*f8bc6aafSDavid du Colombier }
234*f8bc6aafSDavid du Colombier 
235*f8bc6aafSDavid du Colombier Node*
nodfconst(double d)2367edc7532SDavid du Colombier nodfconst(double d)
2377edc7532SDavid du Colombier {
2387edc7532SDavid du Colombier 	fconstnode.fconst = d;
2397edc7532SDavid du Colombier 	return &fconstnode;
2407edc7532SDavid du Colombier }
2417edc7532SDavid du Colombier 
2427edc7532SDavid du Colombier void
nodreg(Node * n,Node * nn,int reg)2437edc7532SDavid du Colombier nodreg(Node *n, Node *nn, int reg)
2447edc7532SDavid du Colombier {
2457edc7532SDavid du Colombier 	*n = regnode;
2467edc7532SDavid du Colombier 	n->reg = reg;
2477edc7532SDavid du Colombier 	n->type = nn->type;
2487edc7532SDavid du Colombier 	n->lineno = nn->lineno;
2497edc7532SDavid du Colombier }
2507edc7532SDavid du Colombier 
2517edc7532SDavid du Colombier void
regret(Node * n,Node * nn)2527edc7532SDavid du Colombier regret(Node *n, Node *nn)
2537edc7532SDavid du Colombier {
2547edc7532SDavid du Colombier 	int r;
2557edc7532SDavid du Colombier 
2567edc7532SDavid du Colombier 	r = REGRET;
2577edc7532SDavid du Colombier 	if(typefd[nn->type->etype])
2587edc7532SDavid du Colombier 		r = FREGRET+NREG;
2597edc7532SDavid du Colombier 	nodreg(n, nn, r);
2607edc7532SDavid du Colombier 	reg[r]++;
2617edc7532SDavid du Colombier }
2627edc7532SDavid du Colombier 
2637edc7532SDavid du Colombier int
tmpreg(void)2647edc7532SDavid du Colombier tmpreg(void)
2657edc7532SDavid du Colombier {
2667edc7532SDavid du Colombier 	int i;
2677edc7532SDavid du Colombier 
2687edc7532SDavid du Colombier 	for(i=REGRET+1; i<NREG; i++)
2697edc7532SDavid du Colombier 		if(reg[i] == 0)
2707edc7532SDavid du Colombier 			return i;
2717edc7532SDavid du Colombier 	diag(Z, "out of fixed registers");
2727edc7532SDavid du Colombier 	return 0;
2737edc7532SDavid du Colombier }
2747edc7532SDavid du Colombier 
2757edc7532SDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)2767edc7532SDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
2777edc7532SDavid du Colombier {
2787edc7532SDavid du Colombier 	int i, j;
279*f8bc6aafSDavid du Colombier 	static int lasti;
2807edc7532SDavid du Colombier 
2817edc7532SDavid du Colombier 	switch(tn->type->etype) {
2827edc7532SDavid du Colombier 	case TCHAR:
2837edc7532SDavid du Colombier 	case TUCHAR:
2847edc7532SDavid du Colombier 	case TSHORT:
2857edc7532SDavid du Colombier 	case TUSHORT:
2867edc7532SDavid du Colombier 	case TINT:
2877edc7532SDavid du Colombier 	case TUINT:
2887edc7532SDavid du Colombier 	case TLONG:
2897edc7532SDavid du Colombier 	case TULONG:
2907edc7532SDavid du Colombier 	case TIND:
2917edc7532SDavid du Colombier 	case TUVLONG:
2927edc7532SDavid du Colombier 	case TVLONG:
2937edc7532SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
2947edc7532SDavid du Colombier 			i = o->reg;
2957edc7532SDavid du Colombier 			if(i > 0 && i < NREG)
2967edc7532SDavid du Colombier 				goto out;
2977edc7532SDavid du Colombier 		}
2987edc7532SDavid du Colombier 		j = lasti + REGRET+1;
2997edc7532SDavid du Colombier 		for(i=REGRET+1; i<NREG; i++) {
3007edc7532SDavid du Colombier 			if(j >= NREG)
3017edc7532SDavid du Colombier 				j = REGRET+1;
3027edc7532SDavid du Colombier 			if(reg[j] == 0) {
3037edc7532SDavid du Colombier 				i = j;
3047edc7532SDavid du Colombier 				goto out;
3057edc7532SDavid du Colombier 			}
3067edc7532SDavid du Colombier 			j++;
3077edc7532SDavid du Colombier 		}
3087edc7532SDavid du Colombier 		diag(tn, "out of fixed registers");
3097edc7532SDavid du Colombier 		goto err;
3107edc7532SDavid du Colombier 
3117edc7532SDavid du Colombier 	case TFLOAT:
3127edc7532SDavid du Colombier 	case TDOUBLE:
3137edc7532SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
3147edc7532SDavid du Colombier 			i = o->reg;
3157edc7532SDavid du Colombier 			if(i >= NREG && i < NREG+NREG)
3167edc7532SDavid du Colombier 				goto out;
3177edc7532SDavid du Colombier 		}
3187edc7532SDavid du Colombier 		j = 0*2 + NREG;
3197edc7532SDavid du Colombier 		for(i=NREG; i<NREG+NREG; i+=2) {
3207edc7532SDavid du Colombier 			if(j >= NREG+NREG)
3217edc7532SDavid du Colombier 				j = NREG;
3227edc7532SDavid du Colombier 			if(reg[j] == 0) {
3237edc7532SDavid du Colombier 				i = j;
3247edc7532SDavid du Colombier 				goto out;
3257edc7532SDavid du Colombier 			}
3267edc7532SDavid du Colombier 			j += 2;
3277edc7532SDavid du Colombier 		}
3287edc7532SDavid du Colombier 		diag(tn, "out of float registers");
3297edc7532SDavid du Colombier 		goto err;
3307edc7532SDavid du Colombier 	}
3317edc7532SDavid du Colombier 	diag(tn, "unknown type in regalloc: %T", tn->type);
3327edc7532SDavid du Colombier err:
333*f8bc6aafSDavid du Colombier 	nodreg(n, tn, 0);
334*f8bc6aafSDavid du Colombier 	return;
3357edc7532SDavid du Colombier out:
3367edc7532SDavid du Colombier 	reg[i]++;
3377edc7532SDavid du Colombier 	lasti++;
3387edc7532SDavid du Colombier 	if(lasti >= 5)
3397edc7532SDavid du Colombier 		lasti = 0;
3407edc7532SDavid du Colombier 	nodreg(n, tn, i);
3417edc7532SDavid du Colombier }
3427edc7532SDavid du Colombier 
3437edc7532SDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)3447edc7532SDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
3457edc7532SDavid du Colombier {
3467edc7532SDavid du Colombier 	Node nod;
3477edc7532SDavid du Colombier 
3487edc7532SDavid du Colombier 	nod = *tn;
3497edc7532SDavid du Colombier 	nod.type = types[TIND];
3507edc7532SDavid du Colombier 	regalloc(n, &nod, o);
3517edc7532SDavid du Colombier }
3527edc7532SDavid du Colombier 
3537edc7532SDavid du Colombier void
regfree(Node * n)3547edc7532SDavid du Colombier regfree(Node *n)
3557edc7532SDavid du Colombier {
3567edc7532SDavid du Colombier 	int i;
3577edc7532SDavid du Colombier 
3587edc7532SDavid du Colombier 	i = 0;
3597edc7532SDavid du Colombier 	if(n->op != OREGISTER && n->op != OINDREG)
3607edc7532SDavid du Colombier 		goto err;
3617edc7532SDavid du Colombier 	i = n->reg;
3627edc7532SDavid du Colombier 	if(i < 0 || i >= sizeof(reg))
3637edc7532SDavid du Colombier 		goto err;
3647edc7532SDavid du Colombier 	if(reg[i] <= 0)
3657edc7532SDavid du Colombier 		goto err;
3667edc7532SDavid du Colombier 	reg[i]--;
3677edc7532SDavid du Colombier 	return;
3687edc7532SDavid du Colombier err:
3697edc7532SDavid du Colombier 	diag(n, "error in regfree: %d", i);
3707edc7532SDavid du Colombier }
3717edc7532SDavid du Colombier 
3727edc7532SDavid du Colombier void
regsalloc(Node * n,Node * nn)3737edc7532SDavid du Colombier regsalloc(Node *n, Node *nn)
3747edc7532SDavid du Colombier {
3757edc7532SDavid du Colombier 	cursafe = align(cursafe, nn->type, Aaut3);
3767edc7532SDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3777edc7532SDavid du Colombier 	*n = *nodsafe;
3787edc7532SDavid du Colombier 	n->xoffset = -(stkoff + cursafe);
3797edc7532SDavid du Colombier 	n->type = nn->type;
3807edc7532SDavid du Colombier 	n->etype = nn->type->etype;
3817edc7532SDavid du Colombier 	n->lineno = nn->lineno;
3827edc7532SDavid du Colombier }
3837edc7532SDavid du Colombier 
3847edc7532SDavid du Colombier void
regaalloc1(Node * n,Node * nn)3857edc7532SDavid du Colombier regaalloc1(Node *n, Node *nn)
3867edc7532SDavid du Colombier {
3877edc7532SDavid du Colombier 	nodreg(n, nn, REGARG);
3887edc7532SDavid du Colombier 	reg[REGARG]++;
3897edc7532SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
3907edc7532SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
3917edc7532SDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
3927edc7532SDavid du Colombier }
3937edc7532SDavid du Colombier 
3947edc7532SDavid du Colombier void
regaalloc(Node * n,Node * nn)3957edc7532SDavid du Colombier regaalloc(Node *n, Node *nn)
3967edc7532SDavid du Colombier {
3977edc7532SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
3987edc7532SDavid du Colombier 	*n = *nn;
3997edc7532SDavid du Colombier 	n->op = OINDREG;
4007edc7532SDavid du Colombier 	n->reg = REGSP;
4017edc7532SDavid du Colombier 	n->xoffset = curarg + SZ_VLONG;
4027edc7532SDavid du Colombier 	n->complex = 0;
4037edc7532SDavid du Colombier 	n->addable = 20;
4047edc7532SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
4057edc7532SDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
4067edc7532SDavid du Colombier }
4077edc7532SDavid du Colombier 
4087edc7532SDavid du Colombier void
regind(Node * n,Node * nn)4097edc7532SDavid du Colombier regind(Node *n, Node *nn)
4107edc7532SDavid du Colombier {
4117edc7532SDavid du Colombier 
4127edc7532SDavid du Colombier 	if(n->op != OREGISTER) {
4137edc7532SDavid du Colombier 		diag(n, "regind not OREGISTER");
4147edc7532SDavid du Colombier 		return;
4157edc7532SDavid du Colombier 	}
4167edc7532SDavid du Colombier 	n->op = OINDREG;
4177edc7532SDavid du Colombier 	n->type = nn->type;
4187edc7532SDavid du Colombier }
4197edc7532SDavid du Colombier 
4207edc7532SDavid du Colombier void
raddr(Node * n,Prog * p)4217edc7532SDavid du Colombier raddr(Node *n, Prog *p)
4227edc7532SDavid du Colombier {
4237edc7532SDavid du Colombier 	Adr a;
4247edc7532SDavid du Colombier 
4257edc7532SDavid du Colombier 	naddr(n, &a);
4267edc7532SDavid du Colombier 	if(a.type == D_CONST && a.offset == 0) {
4277edc7532SDavid du Colombier 		a.type = D_REG;
4287edc7532SDavid du Colombier 		a.reg = 0;
4297edc7532SDavid du Colombier 	}
4307edc7532SDavid du Colombier 	if(a.type != D_REG && a.type != D_FREG) {
4317edc7532SDavid du Colombier 		if(n)
4327edc7532SDavid du Colombier 			diag(n, "bad in raddr: %O", n->op);
4337edc7532SDavid du Colombier 		else
4347edc7532SDavid du Colombier 			diag(n, "bad in raddr: <null>");
4357edc7532SDavid du Colombier 		p->reg = NREG;
4367edc7532SDavid du Colombier 	} else
4377edc7532SDavid du Colombier 		p->reg = a.reg;
4387edc7532SDavid du Colombier }
4397edc7532SDavid du Colombier 
4407edc7532SDavid du Colombier void
naddr(Node * n,Adr * a)4417edc7532SDavid du Colombier naddr(Node *n, Adr *a)
4427edc7532SDavid du Colombier {
4437edc7532SDavid du Colombier 	long v;
4447edc7532SDavid du Colombier 
4457edc7532SDavid du Colombier 	a->type = D_NONE;
4467edc7532SDavid du Colombier 	if(n == Z)
4477edc7532SDavid du Colombier 		return;
4487edc7532SDavid du Colombier 	switch(n->op) {
4497edc7532SDavid du Colombier 	default:
4507edc7532SDavid du Colombier 	bad:
4517edc7532SDavid du Colombier 		diag(n, "bad in naddr: %O", n->op);
4527edc7532SDavid du Colombier 		break;
4537edc7532SDavid du Colombier 
4547edc7532SDavid du Colombier 	case OREGISTER:
4557edc7532SDavid du Colombier 		a->type = D_REG;
4567edc7532SDavid du Colombier 		a->sym = S;
4577edc7532SDavid du Colombier 		a->reg = n->reg;
4587edc7532SDavid du Colombier 		if(a->reg >= NREG) {
4597edc7532SDavid du Colombier 			a->type = D_FREG;
4607edc7532SDavid du Colombier 			a->reg -= NREG;
4617edc7532SDavid du Colombier 		}
4627edc7532SDavid du Colombier 		break;
4637edc7532SDavid du Colombier 
4647edc7532SDavid du Colombier 	case OIND:
4657edc7532SDavid du Colombier 		naddr(n->left, a);
4667edc7532SDavid du Colombier 		if(a->type == D_REG) {
4677edc7532SDavid du Colombier 			a->type = D_OREG;
4687edc7532SDavid du Colombier 			break;
4697edc7532SDavid du Colombier 		}
4707edc7532SDavid du Colombier 		if(a->type == D_CONST) {
4717edc7532SDavid du Colombier 			a->type = D_OREG;
4727edc7532SDavid du Colombier 			break;
4737edc7532SDavid du Colombier 		}
4747edc7532SDavid du Colombier 		goto bad;
4757edc7532SDavid du Colombier 
4767edc7532SDavid du Colombier 	case OINDREG:
4777edc7532SDavid du Colombier 		a->type = D_OREG;
4787edc7532SDavid du Colombier 		a->sym = S;
4797edc7532SDavid du Colombier 		a->offset = n->xoffset;
4807edc7532SDavid du Colombier 		a->reg = n->reg;
4817edc7532SDavid du Colombier 		break;
4827edc7532SDavid du Colombier 
4837edc7532SDavid du Colombier 	case ONAME:
4847edc7532SDavid du Colombier 		a->etype = n->etype;
4857edc7532SDavid du Colombier 		a->type = D_OREG;
4867edc7532SDavid du Colombier 		a->name = D_STATIC;
4877edc7532SDavid du Colombier 		a->sym = n->sym;
4887edc7532SDavid du Colombier 		a->offset = n->xoffset;
4897edc7532SDavid du Colombier 		if(n->class == CSTATIC)
4907edc7532SDavid du Colombier 			break;
4917edc7532SDavid du Colombier 		if(n->class == CEXTERN || n->class == CGLOBL) {
4927edc7532SDavid du Colombier 			a->name = D_EXTERN;
4937edc7532SDavid du Colombier 			break;
4947edc7532SDavid du Colombier 		}
4957edc7532SDavid du Colombier 		if(n->class == CAUTO) {
4967edc7532SDavid du Colombier 			a->name = D_AUTO;
4977edc7532SDavid du Colombier 			break;
4987edc7532SDavid du Colombier 		}
4997edc7532SDavid du Colombier 		if(n->class == CPARAM) {
5007edc7532SDavid du Colombier 			a->name = D_PARAM;
5017edc7532SDavid du Colombier 			break;
5027edc7532SDavid du Colombier 		}
5037edc7532SDavid du Colombier 		goto bad;
5047edc7532SDavid du Colombier 
5057edc7532SDavid du Colombier 	case OCONST:
5067edc7532SDavid du Colombier 		a->sym = S;
5077edc7532SDavid du Colombier 		a->reg = NREG;
5087edc7532SDavid du Colombier 		if(typefd[n->type->etype]) {
5097edc7532SDavid du Colombier 			a->type = D_FCONST;
5107edc7532SDavid du Colombier 			a->dval = n->fconst;
5117edc7532SDavid du Colombier 		} else {
5127edc7532SDavid du Colombier 			a->type = D_CONST;
5137edc7532SDavid du Colombier 			a->offset = n->vconst;
5147edc7532SDavid du Colombier 		}
5157edc7532SDavid du Colombier 		break;
5167edc7532SDavid du Colombier 
5177edc7532SDavid du Colombier 	case OADDR:
5187edc7532SDavid du Colombier 		naddr(n->left, a);
5197edc7532SDavid du Colombier 		if(a->type == D_OREG) {
5207edc7532SDavid du Colombier 			a->type = D_CONST;
5217edc7532SDavid du Colombier 			break;
5227edc7532SDavid du Colombier 		}
5237edc7532SDavid du Colombier 		goto bad;
5247edc7532SDavid du Colombier 
5257edc7532SDavid du Colombier 	case OADD:
5267edc7532SDavid du Colombier 		if(n->left->op == OCONST) {
5277edc7532SDavid du Colombier 			naddr(n->left, a);
5287edc7532SDavid du Colombier 			v = a->offset;
5297edc7532SDavid du Colombier 			naddr(n->right, a);
5307edc7532SDavid du Colombier 		} else {
5317edc7532SDavid du Colombier 			naddr(n->right, a);
5327edc7532SDavid du Colombier 			v = a->offset;
5337edc7532SDavid du Colombier 			naddr(n->left, a);
5347edc7532SDavid du Colombier 		}
5357edc7532SDavid du Colombier 		a->offset += v;
5367edc7532SDavid du Colombier 		break;
5377edc7532SDavid du Colombier 
5387edc7532SDavid du Colombier 	}
5397edc7532SDavid du Colombier }
5407edc7532SDavid du Colombier 
5417edc7532SDavid du Colombier void
fop(int as,int f1,int f2,Node * t)5427edc7532SDavid du Colombier fop(int as, int f1, int f2, Node *t)
5437edc7532SDavid du Colombier {
5447edc7532SDavid du Colombier 	Node nod1, nod2, nod3;
5457edc7532SDavid du Colombier 
5467edc7532SDavid du Colombier 	nodreg(&nod1, t, NREG+f1);
5477edc7532SDavid du Colombier 	nodreg(&nod2, t, NREG+f2);
5487edc7532SDavid du Colombier 	regalloc(&nod3, t, t);
5497edc7532SDavid du Colombier 	gopcode(as, &nod1, &nod2, &nod3);
5507edc7532SDavid du Colombier 	gmove(&nod3, t);
5517edc7532SDavid du Colombier 	regfree(&nod3);
5527edc7532SDavid du Colombier }
5537edc7532SDavid du Colombier 
5547edc7532SDavid du Colombier void
gmove(Node * f,Node * t)5557edc7532SDavid du Colombier gmove(Node *f, Node *t)
5567edc7532SDavid du Colombier {
5577edc7532SDavid du Colombier 	int ft, tt, a;
5587edc7532SDavid du Colombier 	Node nod;
5597edc7532SDavid du Colombier 	Prog *p1;
5607edc7532SDavid du Colombier 	double d;
5617edc7532SDavid du Colombier 
5627edc7532SDavid du Colombier 	ft = f->type->etype;
5637edc7532SDavid du Colombier 	tt = t->type->etype;
5647edc7532SDavid du Colombier 
5657edc7532SDavid du Colombier 	if(ft == TDOUBLE && f->op == OCONST) {
5667edc7532SDavid du Colombier 		d = f->fconst;
5677edc7532SDavid du Colombier 		if(d == 0.0) {
5687edc7532SDavid du Colombier 			a = FREGZERO;
5697edc7532SDavid du Colombier 			goto ffreg;
5707edc7532SDavid du Colombier 		}
5717edc7532SDavid du Colombier 		if(d == 0.5) {
5727edc7532SDavid du Colombier 			a = FREGHALF;
5737edc7532SDavid du Colombier 			goto ffreg;
5747edc7532SDavid du Colombier 		}
5757edc7532SDavid du Colombier 		if(d == 1.0) {
5767edc7532SDavid du Colombier 			a = FREGONE;
5777edc7532SDavid du Colombier 			goto ffreg;
5787edc7532SDavid du Colombier 		}
5797edc7532SDavid du Colombier 		if(d == 2.0) {
5807edc7532SDavid du Colombier 			a = FREGTWO;
5817edc7532SDavid du Colombier 			goto ffreg;
5827edc7532SDavid du Colombier 		}
5837edc7532SDavid du Colombier 		if(d == -.5) {
5847edc7532SDavid du Colombier 			fop(OSUB, FREGHALF, FREGZERO, t);
5857edc7532SDavid du Colombier 			return;
5867edc7532SDavid du Colombier 		}
5877edc7532SDavid du Colombier 		if(d == -1.0) {
5887edc7532SDavid du Colombier 			fop(OSUB, FREGONE, FREGZERO, t);
5897edc7532SDavid du Colombier 			return;
5907edc7532SDavid du Colombier 		}
5917edc7532SDavid du Colombier 		if(d == -2.0) {
5927edc7532SDavid du Colombier 			fop(OSUB, FREGTWO, FREGZERO, t);
5937edc7532SDavid du Colombier 			return;
5947edc7532SDavid du Colombier 		}
5957edc7532SDavid du Colombier 		if(d == 1.5) {
5967edc7532SDavid du Colombier 			fop(OADD, FREGONE, FREGHALF, t);
5977edc7532SDavid du Colombier 			return;
5987edc7532SDavid du Colombier 		}
5997edc7532SDavid du Colombier 		if(d == 2.5) {
6007edc7532SDavid du Colombier 			fop(OADD, FREGTWO, FREGHALF, t);
6017edc7532SDavid du Colombier 			return;
6027edc7532SDavid du Colombier 		}
6037edc7532SDavid du Colombier 		if(d == 3.0) {
6047edc7532SDavid du Colombier 			fop(OADD, FREGTWO, FREGONE, t);
6057edc7532SDavid du Colombier 			return;
6067edc7532SDavid du Colombier 		}
6077edc7532SDavid du Colombier 	}
6087edc7532SDavid du Colombier 	if(ft == TFLOAT && f->op == OCONST) {
6097edc7532SDavid du Colombier 		d = f->fconst;
6107edc7532SDavid du Colombier 		if(d == 0) {
6117edc7532SDavid du Colombier 			a = FREGZERO;
6127edc7532SDavid du Colombier 		ffreg:
6137edc7532SDavid du Colombier 			nodreg(&nod, f, NREG+a);
6147edc7532SDavid du Colombier 			gmove(&nod, t);
6157edc7532SDavid du Colombier 			return;
6167edc7532SDavid du Colombier 		}
6177edc7532SDavid du Colombier 	}
6187edc7532SDavid du Colombier 	/*
6197edc7532SDavid du Colombier 	 * a load --
6207edc7532SDavid du Colombier 	 * put it into a register then
6217edc7532SDavid du Colombier 	 * worry what to do with it.
6227edc7532SDavid du Colombier 	 */
6237edc7532SDavid du Colombier 	if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
6247edc7532SDavid du Colombier 		switch(ft) {
6257edc7532SDavid du Colombier 		default:
6267edc7532SDavid du Colombier 			if(typefd[tt]) {
6277edc7532SDavid du Colombier 				/* special case can load mem to Freg */
6287edc7532SDavid du Colombier 				regalloc(&nod, t, t);
6297edc7532SDavid du Colombier 				gins(AMOVW, f, &nod);
6307edc7532SDavid du Colombier 				a = AMOVWD;
6317edc7532SDavid du Colombier 				if(tt == TFLOAT)
6327edc7532SDavid du Colombier 					a = AMOVWF;
6337edc7532SDavid du Colombier 				gins(a, &nod, &nod);
6347edc7532SDavid du Colombier 				gmove(&nod, t);
6357edc7532SDavid du Colombier 				regfree(&nod);
6367edc7532SDavid du Colombier 				return;
6377edc7532SDavid du Colombier 			}
6387edc7532SDavid du Colombier 			a = AMOVW;
6397edc7532SDavid du Colombier 			break;
6407edc7532SDavid du Colombier 		case TCHAR:
6417edc7532SDavid du Colombier 			a = AMOVB;
6427edc7532SDavid du Colombier 			break;
6437edc7532SDavid du Colombier 		case TUCHAR:
6447edc7532SDavid du Colombier 			a = AMOVBU;
6457edc7532SDavid du Colombier 			break;
6467edc7532SDavid du Colombier 		case TSHORT:
6477edc7532SDavid du Colombier 			a = AMOVH;
6487edc7532SDavid du Colombier 			break;
6497edc7532SDavid du Colombier 		case TUSHORT:
6507edc7532SDavid du Colombier 			a = AMOVHU;
6517edc7532SDavid du Colombier 			break;
6527edc7532SDavid du Colombier 		case TFLOAT:
6537edc7532SDavid du Colombier 			a = AMOVF;
6547edc7532SDavid du Colombier 			break;
6557edc7532SDavid du Colombier 		case TDOUBLE:
6567edc7532SDavid du Colombier 			a = AMOVD;
6577edc7532SDavid du Colombier 			break;
6587edc7532SDavid du Colombier 		case TUVLONG:
6597edc7532SDavid du Colombier 		case TVLONG:
6607edc7532SDavid du Colombier 		case TIND:
6617edc7532SDavid du Colombier 			a = AMOVV;
6627edc7532SDavid du Colombier 			break;
6637edc7532SDavid du Colombier 		}
6647edc7532SDavid du Colombier 		if(typechlp[ft] && typeilp[tt])
6657edc7532SDavid du Colombier 			regalloc(&nod, t, t);
6667edc7532SDavid du Colombier 		else
6677edc7532SDavid du Colombier 			regalloc(&nod, f, t);
6687edc7532SDavid du Colombier 		gins(a, f, &nod);
6697edc7532SDavid du Colombier 		gmove(&nod, t);
6707edc7532SDavid du Colombier 		regfree(&nod);
6717edc7532SDavid du Colombier 		return;
6727edc7532SDavid du Colombier 	}
6737edc7532SDavid du Colombier 
6747edc7532SDavid du Colombier 	/*
6757edc7532SDavid du Colombier 	 * a store --
6767edc7532SDavid du Colombier 	 * put it into a register then
6777edc7532SDavid du Colombier 	 * store it.
6787edc7532SDavid du Colombier 	 */
6797edc7532SDavid du Colombier 	if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
6807edc7532SDavid du Colombier 		switch(tt) {
6817edc7532SDavid du Colombier 		default:
6827edc7532SDavid du Colombier 			a = AMOVW;
6837edc7532SDavid du Colombier 			break;
6847edc7532SDavid du Colombier 		case TUCHAR:
685*f8bc6aafSDavid du Colombier 			a = AMOVBU;
686*f8bc6aafSDavid du Colombier 			break;
6877edc7532SDavid du Colombier 		case TCHAR:
6887edc7532SDavid du Colombier 			a = AMOVB;
6897edc7532SDavid du Colombier 			break;
6907edc7532SDavid du Colombier 		case TUSHORT:
691*f8bc6aafSDavid du Colombier 			a = AMOVHU;
692*f8bc6aafSDavid du Colombier 			break;
6937edc7532SDavid du Colombier 		case TSHORT:
6947edc7532SDavid du Colombier 			a = AMOVH;
6957edc7532SDavid du Colombier 			break;
6967edc7532SDavid du Colombier 		case TFLOAT:
6977edc7532SDavid du Colombier 			a = AMOVF;
6987edc7532SDavid du Colombier 			break;
6997edc7532SDavid du Colombier 		case TDOUBLE:
7007edc7532SDavid du Colombier 			a = AMOVD;
7017edc7532SDavid du Colombier 			break;
7027edc7532SDavid du Colombier 		case TUVLONG:
7037edc7532SDavid du Colombier 		case TVLONG:
7047edc7532SDavid du Colombier 		case TIND:
7057edc7532SDavid du Colombier 			a = AMOVV;
7067edc7532SDavid du Colombier 			break;
7077edc7532SDavid du Colombier 		}
7087edc7532SDavid du Colombier 		if(!typefd[ft] && vconst(f) == 0) {
7097edc7532SDavid du Colombier 			gins(a, f, t);
7107edc7532SDavid du Colombier 			return;
7117edc7532SDavid du Colombier 		}
7127edc7532SDavid du Colombier 		if(ft == tt)
7137edc7532SDavid du Colombier 			regalloc(&nod, t, f);
7147edc7532SDavid du Colombier 		else
7157edc7532SDavid du Colombier 			regalloc(&nod, t, Z);
7167edc7532SDavid du Colombier 		gmove(f, &nod);
7177edc7532SDavid du Colombier 		gins(a, &nod, t);
7187edc7532SDavid du Colombier 		regfree(&nod);
7197edc7532SDavid du Colombier 		return;
7207edc7532SDavid du Colombier 	}
7217edc7532SDavid du Colombier 
7227edc7532SDavid du Colombier 	/*
7237edc7532SDavid du Colombier 	 * type x type cross table
7247edc7532SDavid du Colombier 	 */
7257edc7532SDavid du Colombier 	a = AGOK;
7267edc7532SDavid du Colombier 	switch(ft) {
7277edc7532SDavid du Colombier 	case TUVLONG:
7287edc7532SDavid du Colombier 	case TVLONG:
7297edc7532SDavid du Colombier 	case TIND:
7307edc7532SDavid du Colombier 		switch(tt) {
7317edc7532SDavid du Colombier 		case TUVLONG:
7327edc7532SDavid du Colombier 		case TVLONG:
7337edc7532SDavid du Colombier 		case TIND:
7347edc7532SDavid du Colombier 			a = AMOVV;
7357edc7532SDavid du Colombier 			break;
7367edc7532SDavid du Colombier 		case TINT:
7377edc7532SDavid du Colombier 		case TUINT:
7387edc7532SDavid du Colombier 		case TLONG:
7397edc7532SDavid du Colombier 		case TULONG:
7407edc7532SDavid du Colombier 		case TSHORT:
7417edc7532SDavid du Colombier 		case TUSHORT:
7427edc7532SDavid du Colombier 		case TCHAR:
7437edc7532SDavid du Colombier 		case TUCHAR:
7447edc7532SDavid du Colombier 			a = AMOVW;
7457edc7532SDavid du Colombier 			break;
7467edc7532SDavid du Colombier 		case TDOUBLE:
747*f8bc6aafSDavid du Colombier 			gins(AMOVV, f, t);
748*f8bc6aafSDavid du Colombier 			gins(AMOVVD, t, t);
7497edc7532SDavid du Colombier 			return;
7507edc7532SDavid du Colombier 		case TFLOAT:
751*f8bc6aafSDavid du Colombier 			gins(AMOVV, f, t);
752*f8bc6aafSDavid du Colombier 			gins(AMOVVF, t, t);
7537edc7532SDavid du Colombier 			return;
7547edc7532SDavid du Colombier 		}
7557edc7532SDavid du Colombier 		break;
7567edc7532SDavid du Colombier 	case TDOUBLE:
7577edc7532SDavid du Colombier 	case TFLOAT:
7587edc7532SDavid du Colombier 		switch(tt) {
7597edc7532SDavid du Colombier 		case TDOUBLE:
7607edc7532SDavid du Colombier 			a = AMOVD;
7617edc7532SDavid du Colombier 			if(ft == TFLOAT)
7627edc7532SDavid du Colombier 				a = AMOVFD;
7637edc7532SDavid du Colombier 			break;
7647edc7532SDavid du Colombier 		case TFLOAT:
7657edc7532SDavid du Colombier 			a = AMOVDF;
7667edc7532SDavid du Colombier 			if(ft == TFLOAT)
7677edc7532SDavid du Colombier 				a = AMOVF;
7687edc7532SDavid du Colombier 			break;
7697edc7532SDavid du Colombier 		case TINT:
7707edc7532SDavid du Colombier 		case TUINT:
7717edc7532SDavid du Colombier 		case TLONG:
7727edc7532SDavid du Colombier 		case TULONG:
7737edc7532SDavid du Colombier 		case TSHORT:
7747edc7532SDavid du Colombier 		case TUSHORT:
7757edc7532SDavid du Colombier 		case TCHAR:
7767edc7532SDavid du Colombier 		case TUCHAR:
7777edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
7787edc7532SDavid du Colombier 			gins(ATRUNCDW, f, &nod);
7797edc7532SDavid du Colombier 			if(ft == TFLOAT)
7807edc7532SDavid du Colombier 				p->as = ATRUNCFW;
7817edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
7827edc7532SDavid du Colombier 			regfree(&nod);
7837edc7532SDavid du Colombier 			return;
7847edc7532SDavid du Colombier 		case TUVLONG:
7857edc7532SDavid du Colombier 		case TVLONG:
7867edc7532SDavid du Colombier 		case TIND:
7877edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
7887edc7532SDavid du Colombier 			gins(ATRUNCDV, f, &nod);
7897edc7532SDavid du Colombier 			if(ft == TFLOAT)
7907edc7532SDavid du Colombier 				p->as = ATRUNCFV;
7917edc7532SDavid du Colombier 			gins(AMOVV, &nod, t);
7927edc7532SDavid du Colombier 			regfree(&nod);
7937edc7532SDavid du Colombier 			return;
7947edc7532SDavid du Colombier 		}
7957edc7532SDavid du Colombier 		break;
7967edc7532SDavid du Colombier 	case TINT:
7977edc7532SDavid du Colombier 	case TUINT:
7987edc7532SDavid du Colombier 	case TLONG:
7997edc7532SDavid du Colombier 	case TULONG:
8007edc7532SDavid du Colombier 		switch(tt) {
8017edc7532SDavid du Colombier 		case TDOUBLE:
8027edc7532SDavid du Colombier 			gins(AMOVW, f, t);
8037edc7532SDavid du Colombier 			gins(AMOVWD, t, t);
8047edc7532SDavid du Colombier 			if(ft == TULONG || ft == TUINT) {
8057edc7532SDavid du Colombier 				regalloc(&nod, t, Z);
8067edc7532SDavid du Colombier 				gins(ACMPGED, t, Z);
8077edc7532SDavid du Colombier 				p->reg = FREGZERO;
8087edc7532SDavid du Colombier 				gins(ABFPT, Z, Z);
8097edc7532SDavid du Colombier 				p1 = p;
8107edc7532SDavid du Colombier 				gins(AMOVD, nodfconst(4294967296.), &nod);
8117edc7532SDavid du Colombier 				gins(AADDD, &nod, t);
8127edc7532SDavid du Colombier 				patch(p1, pc);
8137edc7532SDavid du Colombier 				regfree(&nod);
8147edc7532SDavid du Colombier 			}
8157edc7532SDavid du Colombier 			return;
8167edc7532SDavid du Colombier 		case TFLOAT:
8177edc7532SDavid du Colombier 			gins(AMOVW, f, t);
8187edc7532SDavid du Colombier 			gins(AMOVWF, t, t);
8197edc7532SDavid du Colombier 			if(ft == TULONG || ft == TUINT) {
8207edc7532SDavid du Colombier 				regalloc(&nod, t, Z);
8217edc7532SDavid du Colombier 				gins(ACMPGEF, t, Z);
8227edc7532SDavid du Colombier 				p->reg = FREGZERO;
8237edc7532SDavid du Colombier 				gins(ABFPT, Z, Z);
8247edc7532SDavid du Colombier 				p1 = p;
8257edc7532SDavid du Colombier 				gins(AMOVF, nodfconst(4294967296.), &nod);
8267edc7532SDavid du Colombier 				gins(AADDF, &nod, t);
8277edc7532SDavid du Colombier 				patch(p1, pc);
8287edc7532SDavid du Colombier 				regfree(&nod);
8297edc7532SDavid du Colombier 			}
8307edc7532SDavid du Colombier 			return;
8317edc7532SDavid du Colombier 		case TUVLONG:
8327edc7532SDavid du Colombier 		case TVLONG:
8337edc7532SDavid du Colombier 		case TIND:
8347edc7532SDavid du Colombier 			if(ft == TULONG || ft == TUINT) {
8357edc7532SDavid du Colombier 				a = AMOVWU;
8367edc7532SDavid du Colombier 				break;
8377edc7532SDavid du Colombier 			}
8387edc7532SDavid du Colombier 		case TINT:
8397edc7532SDavid du Colombier 		case TUINT:
8407edc7532SDavid du Colombier 		case TLONG:
8417edc7532SDavid du Colombier 		case TULONG:
8427edc7532SDavid du Colombier 		case TSHORT:
8437edc7532SDavid du Colombier 		case TUSHORT:
8447edc7532SDavid du Colombier 		case TCHAR:
8457edc7532SDavid du Colombier 		case TUCHAR:
8467edc7532SDavid du Colombier 			a = AMOVW;
8477edc7532SDavid du Colombier 			break;
8487edc7532SDavid du Colombier 		}
8497edc7532SDavid du Colombier 		break;
8507edc7532SDavid du Colombier 	case TSHORT:
8517edc7532SDavid du Colombier 		switch(tt) {
8527edc7532SDavid du Colombier 		case TDOUBLE:
8537edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
8547edc7532SDavid du Colombier 			gins(AMOVH, f, &nod);
8557edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
8567edc7532SDavid du Colombier 			gins(AMOVWD, t, t);
8577edc7532SDavid du Colombier 			regfree(&nod);
8587edc7532SDavid du Colombier 			return;
8597edc7532SDavid du Colombier 		case TFLOAT:
8607edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
8617edc7532SDavid du Colombier 			gins(AMOVH, f, &nod);
8627edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
8637edc7532SDavid du Colombier 			gins(AMOVWF, t, t);
8647edc7532SDavid du Colombier 			regfree(&nod);
8657edc7532SDavid du Colombier 			return;
8667edc7532SDavid du Colombier 		case TINT:
8677edc7532SDavid du Colombier 		case TUINT:
8687edc7532SDavid du Colombier 		case TLONG:
8697edc7532SDavid du Colombier 		case TULONG:
8707edc7532SDavid du Colombier 		case TVLONG:
8717edc7532SDavid du Colombier 		case TUVLONG:
8727edc7532SDavid du Colombier 		case TIND:
8737edc7532SDavid du Colombier 			a = AMOVH;
8747edc7532SDavid du Colombier 			break;
8757edc7532SDavid du Colombier 		case TSHORT:
8767edc7532SDavid du Colombier 		case TUSHORT:
8777edc7532SDavid du Colombier 		case TCHAR:
8787edc7532SDavid du Colombier 		case TUCHAR:
879*f8bc6aafSDavid du Colombier 			a = AMOVV;
8807edc7532SDavid du Colombier 			break;
8817edc7532SDavid du Colombier 		}
8827edc7532SDavid du Colombier 		break;
8837edc7532SDavid du Colombier 	case TUSHORT:
8847edc7532SDavid du Colombier 		switch(tt) {
8857edc7532SDavid du Colombier 		case TDOUBLE:
8867edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
8877edc7532SDavid du Colombier 			gins(AMOVHU, f, &nod);
8887edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
8897edc7532SDavid du Colombier 			gins(AMOVWD, t, t);
8907edc7532SDavid du Colombier 			regfree(&nod);
8917edc7532SDavid du Colombier 			return;
8927edc7532SDavid du Colombier 		case TFLOAT:
8937edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
8947edc7532SDavid du Colombier 			gins(AMOVHU, f, &nod);
8957edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
8967edc7532SDavid du Colombier 			gins(AMOVWF, t, t);
8977edc7532SDavid du Colombier 			regfree(&nod);
8987edc7532SDavid du Colombier 			return;
8997edc7532SDavid du Colombier 		case TINT:
9007edc7532SDavid du Colombier 		case TUINT:
9017edc7532SDavid du Colombier 		case TLONG:
9027edc7532SDavid du Colombier 		case TULONG:
9037edc7532SDavid du Colombier 		case TVLONG:
9047edc7532SDavid du Colombier 		case TUVLONG:
9057edc7532SDavid du Colombier 		case TIND:
9067edc7532SDavid du Colombier 			a = AMOVHU;
9077edc7532SDavid du Colombier 			break;
9087edc7532SDavid du Colombier 		case TSHORT:
9097edc7532SDavid du Colombier 		case TUSHORT:
9107edc7532SDavid du Colombier 		case TCHAR:
9117edc7532SDavid du Colombier 		case TUCHAR:
912*f8bc6aafSDavid du Colombier 			a = AMOVV;
9137edc7532SDavid du Colombier 			break;
9147edc7532SDavid du Colombier 		}
9157edc7532SDavid du Colombier 		break;
9167edc7532SDavid du Colombier 	case TCHAR:
9177edc7532SDavid du Colombier 		switch(tt) {
9187edc7532SDavid du Colombier 		case TDOUBLE:
9197edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
9207edc7532SDavid du Colombier 			gins(AMOVB, f, &nod);
9217edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
9227edc7532SDavid du Colombier 			gins(AMOVWD, t, t);
9237edc7532SDavid du Colombier 			regfree(&nod);
9247edc7532SDavid du Colombier 			return;
9257edc7532SDavid du Colombier 		case TFLOAT:
9267edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
9277edc7532SDavid du Colombier 			gins(AMOVB, f, &nod);
9287edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
9297edc7532SDavid du Colombier 			gins(AMOVWF, t, t);
9307edc7532SDavid du Colombier 			regfree(&nod);
9317edc7532SDavid du Colombier 			return;
9327edc7532SDavid du Colombier 		case TINT:
9337edc7532SDavid du Colombier 		case TUINT:
9347edc7532SDavid du Colombier 		case TLONG:
9357edc7532SDavid du Colombier 		case TULONG:
9367edc7532SDavid du Colombier 		case TVLONG:
9377edc7532SDavid du Colombier 		case TUVLONG:
9387edc7532SDavid du Colombier 		case TIND:
9397edc7532SDavid du Colombier 		case TSHORT:
9407edc7532SDavid du Colombier 		case TUSHORT:
9417edc7532SDavid du Colombier 			a = AMOVB;
9427edc7532SDavid du Colombier 			break;
9437edc7532SDavid du Colombier 		case TCHAR:
9447edc7532SDavid du Colombier 		case TUCHAR:
945*f8bc6aafSDavid du Colombier 			a = AMOVV;
9467edc7532SDavid du Colombier 			break;
9477edc7532SDavid du Colombier 		}
9487edc7532SDavid du Colombier 		break;
9497edc7532SDavid du Colombier 	case TUCHAR:
9507edc7532SDavid du Colombier 		switch(tt) {
9517edc7532SDavid du Colombier 		case TDOUBLE:
9527edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
9537edc7532SDavid du Colombier 			gins(AMOVBU, f, &nod);
9547edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
9557edc7532SDavid du Colombier 			gins(AMOVWD, t, t);
9567edc7532SDavid du Colombier 			regfree(&nod);
9577edc7532SDavid du Colombier 			return;
9587edc7532SDavid du Colombier 		case TFLOAT:
9597edc7532SDavid du Colombier 			regalloc(&nod, f, Z);
9607edc7532SDavid du Colombier 			gins(AMOVBU, f, &nod);
9617edc7532SDavid du Colombier 			gins(AMOVW, &nod, t);
9627edc7532SDavid du Colombier 			gins(AMOVWF, t, t);
9637edc7532SDavid du Colombier 			regfree(&nod);
9647edc7532SDavid du Colombier 			return;
9657edc7532SDavid du Colombier 		case TINT:
9667edc7532SDavid du Colombier 		case TUINT:
9677edc7532SDavid du Colombier 		case TLONG:
9687edc7532SDavid du Colombier 		case TULONG:
9697edc7532SDavid du Colombier 		case TVLONG:
9707edc7532SDavid du Colombier 		case TUVLONG:
9717edc7532SDavid du Colombier 		case TIND:
9727edc7532SDavid du Colombier 		case TSHORT:
9737edc7532SDavid du Colombier 		case TUSHORT:
9747edc7532SDavid du Colombier 			a = AMOVBU;
9757edc7532SDavid du Colombier 			break;
9767edc7532SDavid du Colombier 		case TCHAR:
9777edc7532SDavid du Colombier 		case TUCHAR:
978*f8bc6aafSDavid du Colombier 			a = AMOVV;
9797edc7532SDavid du Colombier 			break;
9807edc7532SDavid du Colombier 		}
9817edc7532SDavid du Colombier 		break;
9827edc7532SDavid du Colombier 	}
9837edc7532SDavid du Colombier 	if(a == AGOK)
9847edc7532SDavid du Colombier 		diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
985*f8bc6aafSDavid du Colombier 	if((a == AMOVW && ewidth[ft] == ewidth[tt]) || a == AMOVF || a == AMOVD || a == AMOVV)
9867edc7532SDavid du Colombier 	if(samaddr(f, t))
9877edc7532SDavid du Colombier 		return;
9887edc7532SDavid du Colombier 	gins(a, f, t);
9897edc7532SDavid du Colombier }
9907edc7532SDavid du Colombier 
9917edc7532SDavid du Colombier void
gins(int a,Node * f,Node * t)9927edc7532SDavid du Colombier gins(int a, Node *f, Node *t)
9937edc7532SDavid du Colombier {
9947edc7532SDavid du Colombier 
9957edc7532SDavid du Colombier 	nextpc();
9967edc7532SDavid du Colombier 	p->as = a;
9977edc7532SDavid du Colombier 	if(f != Z)
9987edc7532SDavid du Colombier 		naddr(f, &p->from);
9997edc7532SDavid du Colombier 	if(t != Z)
10007edc7532SDavid du Colombier 		naddr(t, &p->to);
10017edc7532SDavid du Colombier 	if(debug['g'])
10027edc7532SDavid du Colombier 		print("%P\n", p);
10037edc7532SDavid du Colombier }
10047edc7532SDavid du Colombier 
10057edc7532SDavid du Colombier void
gopcode(int o,Node * f1,Node * f2,Node * t)10067edc7532SDavid du Colombier gopcode(int o, Node *f1, Node *f2, Node *t)
10077edc7532SDavid du Colombier {
10087edc7532SDavid du Colombier 	int a, et, ett;
10097edc7532SDavid du Colombier 	Adr ta;
10107edc7532SDavid du Colombier 	Node nod;
10117edc7532SDavid du Colombier 
10127edc7532SDavid du Colombier 	et = TLONG;
10137edc7532SDavid du Colombier 	if(f1 != Z && f1->type != T)
1014*f8bc6aafSDavid du Colombier 		if(f1-> op == OCONST && t != Z && t->type != T)
1015*f8bc6aafSDavid du Colombier 			et = t->type->etype;
1016*f8bc6aafSDavid du Colombier 		else
10177edc7532SDavid du Colombier 			et = f1->type->etype;
10187edc7532SDavid du Colombier 	ett = TLONG;
10197edc7532SDavid du Colombier 	if(t != Z && t->type != T)
10207edc7532SDavid du Colombier 		ett = t->type->etype;
10217edc7532SDavid du Colombier 	if(llconst(f1) && o != OAS) {
10227edc7532SDavid du Colombier 		regalloc(&nod, f1, Z);
10237edc7532SDavid du Colombier 		gmove(f1, &nod);
10247edc7532SDavid du Colombier 		gopcode(o, &nod, f2, t);
10257edc7532SDavid du Colombier 		regfree(&nod);
10267edc7532SDavid du Colombier 		return;
10277edc7532SDavid du Colombier 	}
10287edc7532SDavid du Colombier 	a = AGOK;
10297edc7532SDavid du Colombier 	switch(o) {
10307edc7532SDavid du Colombier 	case OAS:
10317edc7532SDavid du Colombier 		gmove(f1, t);
10327edc7532SDavid du Colombier 		return;
10337edc7532SDavid du Colombier 
10347edc7532SDavid du Colombier 	case OASADD:
10357edc7532SDavid du Colombier 	case OADD:
10367edc7532SDavid du Colombier 		a = AADDU;
10377edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
10387edc7532SDavid du Colombier 			a = AADDVU;
10397edc7532SDavid du Colombier 		else
10407edc7532SDavid du Colombier 		if(et == TFLOAT)
10417edc7532SDavid du Colombier 			a = AADDF;
10427edc7532SDavid du Colombier 		else
10437edc7532SDavid du Colombier 		if(et == TDOUBLE)
10447edc7532SDavid du Colombier 			a = AADDD;
10457edc7532SDavid du Colombier 		break;
10467edc7532SDavid du Colombier 
10477edc7532SDavid du Colombier 	case OASSUB:
10487edc7532SDavid du Colombier 	case OSUB:
10497edc7532SDavid du Colombier 		a = ASUBU;
10507edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
10517edc7532SDavid du Colombier 			a = ASUBVU;
10527edc7532SDavid du Colombier 		else
10537edc7532SDavid du Colombier 		if(et == TFLOAT)
10547edc7532SDavid du Colombier 			a = ASUBF;
10557edc7532SDavid du Colombier 		else
10567edc7532SDavid du Colombier 		if(et == TDOUBLE)
10577edc7532SDavid du Colombier 			a = ASUBD;
10587edc7532SDavid du Colombier 		break;
10597edc7532SDavid du Colombier 
10607edc7532SDavid du Colombier 	case OASOR:
10617edc7532SDavid du Colombier 	case OOR:
10627edc7532SDavid du Colombier 		a = AOR;
10637edc7532SDavid du Colombier 		break;
10647edc7532SDavid du Colombier 
10657edc7532SDavid du Colombier 	case OASAND:
10667edc7532SDavid du Colombier 	case OAND:
10677edc7532SDavid du Colombier 		a = AAND;
10687edc7532SDavid du Colombier 		break;
10697edc7532SDavid du Colombier 
10707edc7532SDavid du Colombier 	case OASXOR:
10717edc7532SDavid du Colombier 	case OXOR:
10727edc7532SDavid du Colombier 		a = AXOR;
10737edc7532SDavid du Colombier 		break;
10747edc7532SDavid du Colombier 
10757edc7532SDavid du Colombier 	case OASLSHR:
10767edc7532SDavid du Colombier 	case OLSHR:
10777edc7532SDavid du Colombier 		a = ASRL;
10787edc7532SDavid du Colombier 		if(ett == TVLONG || ett == TUVLONG || et == TIND)
10797edc7532SDavid du Colombier 			a = ASRLV;
10807edc7532SDavid du Colombier 		break;
10817edc7532SDavid du Colombier 
10827edc7532SDavid du Colombier 	case OASASHR:
10837edc7532SDavid du Colombier 	case OASHR:
10847edc7532SDavid du Colombier 		a = ASRA;
10857edc7532SDavid du Colombier 		if(ett == TVLONG || ett == TUVLONG || et == TIND)
10867edc7532SDavid du Colombier 			a = ASRAV;
10877edc7532SDavid du Colombier 		break;
10887edc7532SDavid du Colombier 
10897edc7532SDavid du Colombier 	case OASASHL:
10907edc7532SDavid du Colombier 	case OASHL:
10917edc7532SDavid du Colombier 		a = ASLL;
10927edc7532SDavid du Colombier 		if(ett == TVLONG || ett == TUVLONG || et == TIND)
10937edc7532SDavid du Colombier 			a = ASLLV;
10947edc7532SDavid du Colombier 		break;
10957edc7532SDavid du Colombier 
10967edc7532SDavid du Colombier 	case OFUNC:
10977edc7532SDavid du Colombier 		a = AJAL;
10987edc7532SDavid du Colombier 		break;
10997edc7532SDavid du Colombier 
11007edc7532SDavid du Colombier 	case OCOND:
11017edc7532SDavid du Colombier 		a = ASGTU;
11027edc7532SDavid du Colombier 		break;
11037edc7532SDavid du Colombier 
11047edc7532SDavid du Colombier 	case OCOMMA:
11057edc7532SDavid du Colombier 		a = ASGT;
11067edc7532SDavid du Colombier 		break;
11077edc7532SDavid du Colombier 
11087edc7532SDavid du Colombier 	case OASMUL:
11097edc7532SDavid du Colombier 	case OMUL:
11107edc7532SDavid du Colombier 		if(et == TFLOAT) {
11117edc7532SDavid du Colombier 			a = AMULF;
11127edc7532SDavid du Colombier 			break;
11137edc7532SDavid du Colombier 		} else
11147edc7532SDavid du Colombier 		if(et == TDOUBLE) {
11157edc7532SDavid du Colombier 			a = AMULD;
11167edc7532SDavid du Colombier 			break;
11177edc7532SDavid du Colombier 		}
11187edc7532SDavid du Colombier 		a = AMUL;
11197edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
11207edc7532SDavid du Colombier 			a = AMULV;
11217edc7532SDavid du Colombier 		goto muldiv;
11227edc7532SDavid du Colombier 
11237edc7532SDavid du Colombier 	case OASDIV:
11247edc7532SDavid du Colombier 	case ODIV:
11257edc7532SDavid du Colombier 		if(et == TFLOAT) {
11267edc7532SDavid du Colombier 			a = ADIVF;
11277edc7532SDavid du Colombier 			break;
11287edc7532SDavid du Colombier 		} else
11297edc7532SDavid du Colombier 		if(et == TDOUBLE) {
11307edc7532SDavid du Colombier 			a = ADIVD;
11317edc7532SDavid du Colombier 			break;
11327edc7532SDavid du Colombier 		}
11337edc7532SDavid du Colombier 		a = ADIV;
11347edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
11357edc7532SDavid du Colombier 			a = ADIVV;
11367edc7532SDavid du Colombier 		goto muldiv;
11377edc7532SDavid du Colombier 
11387edc7532SDavid du Colombier 	case OASMOD:
11397edc7532SDavid du Colombier 	case OMOD:
11407edc7532SDavid du Colombier 		a = ADIV;
11417edc7532SDavid du Colombier 		o = OMOD;
11427edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
11437edc7532SDavid du Colombier 			a = ADIVV;
11447edc7532SDavid du Colombier 		goto muldiv;
11457edc7532SDavid du Colombier 
11467edc7532SDavid du Colombier 	case OASLMUL:
11477edc7532SDavid du Colombier 	case OLMUL:
11487edc7532SDavid du Colombier 		a = AMULU;
11497edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
11507edc7532SDavid du Colombier 			a = AMULVU;
11517edc7532SDavid du Colombier 		goto muldiv;
11527edc7532SDavid du Colombier 
11537edc7532SDavid du Colombier 	case OASLMOD:
11547edc7532SDavid du Colombier 	case OLMOD:
11557edc7532SDavid du Colombier 		o = OMOD;
11567edc7532SDavid du Colombier 
11577edc7532SDavid du Colombier 	case OASLDIV:
11587edc7532SDavid du Colombier 	case OLDIV:
11597edc7532SDavid du Colombier 		a = ADIVU;
11607edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
11617edc7532SDavid du Colombier 			a = ADIVVU;
11627edc7532SDavid du Colombier 		goto muldiv;
11637edc7532SDavid du Colombier 
11647edc7532SDavid du Colombier 	muldiv:
11657edc7532SDavid du Colombier 		nextpc();
11667edc7532SDavid du Colombier 		naddr(f1, &p->from);
11677edc7532SDavid du Colombier 		if(f2 == Z)
11687edc7532SDavid du Colombier 			raddr(t, p);
11697edc7532SDavid du Colombier 		else
11707edc7532SDavid du Colombier 			raddr(f2, p);
11717edc7532SDavid du Colombier 		p->as = a;
11727edc7532SDavid du Colombier 		if(debug['g'])
11737edc7532SDavid du Colombier 			print("%P\n", p);
11747edc7532SDavid du Colombier 		nextpc();
11757edc7532SDavid du Colombier 		p->as = AMOVW;
11767edc7532SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
11777edc7532SDavid du Colombier 			p->as = AMOVV;
11787edc7532SDavid du Colombier 		a = D_LO;
11797edc7532SDavid du Colombier 		if(o == OMOD)
11807edc7532SDavid du Colombier 			a = D_HI;
11817edc7532SDavid du Colombier 		p->from.type = a;
11827edc7532SDavid du Colombier 		naddr(t, &p->to);
11837edc7532SDavid du Colombier 		if(debug['g'])
11847edc7532SDavid du Colombier 			print("%P\n", p);
11857edc7532SDavid du Colombier 		return;
11867edc7532SDavid du Colombier 
11877edc7532SDavid du Colombier 	case OEQ:
11887edc7532SDavid du Colombier 		if(!typefd[et]) {
11897edc7532SDavid du Colombier 			a = ABEQ;
11907edc7532SDavid du Colombier 			break;
11917edc7532SDavid du Colombier 		}
11927edc7532SDavid du Colombier 
11937edc7532SDavid du Colombier 	case ONE:
11947edc7532SDavid du Colombier 		if(!typefd[et]) {
11957edc7532SDavid du Colombier 			a = ABNE;
11967edc7532SDavid du Colombier 			break;
11977edc7532SDavid du Colombier 		}
11987edc7532SDavid du Colombier 
11997edc7532SDavid du Colombier 	case OLT:
12007edc7532SDavid du Colombier 	case OLE:
12017edc7532SDavid du Colombier 	case OGE:
12027edc7532SDavid du Colombier 	case OGT:
12037edc7532SDavid du Colombier 		if(typefd[et]) {
12047edc7532SDavid du Colombier 			nextpc();
12057edc7532SDavid du Colombier 			if(et == TFLOAT) {
12067edc7532SDavid du Colombier 				a = ACMPGTF;
12077edc7532SDavid du Colombier 				if(o == OEQ || o == ONE)
12087edc7532SDavid du Colombier 					a = ACMPEQF;
12097edc7532SDavid du Colombier 				else
12107edc7532SDavid du Colombier 				if(o == OLT || o == OGE)
12117edc7532SDavid du Colombier 					a = ACMPGEF;
12127edc7532SDavid du Colombier 			} else {
12137edc7532SDavid du Colombier 				a = ACMPGTD;
12147edc7532SDavid du Colombier 				if(o == OEQ || o == ONE)
12157edc7532SDavid du Colombier 					a = ACMPEQD;
12167edc7532SDavid du Colombier 				else
12177edc7532SDavid du Colombier 				if(o == OLT || o == OGE)
12187edc7532SDavid du Colombier 					a = ACMPGED;
12197edc7532SDavid du Colombier 			}
12207edc7532SDavid du Colombier 			p->as = a;
12217edc7532SDavid du Colombier 			naddr(f1, &p->from);
12227edc7532SDavid du Colombier 			raddr(f2, p);
12237edc7532SDavid du Colombier 			if(debug['g'])
12247edc7532SDavid du Colombier 				print("%P\n", p);
12257edc7532SDavid du Colombier 			nextpc();
12267edc7532SDavid du Colombier 			a = ABFPF;
12277edc7532SDavid du Colombier 			if(o == OEQ || o == OGE || o == OGT)
12287edc7532SDavid du Colombier 				a = ABFPT;
12297edc7532SDavid du Colombier 			p->as = a;
12307edc7532SDavid du Colombier 			if(debug['g'])
12317edc7532SDavid du Colombier 				print("%P\n", p);
12327edc7532SDavid du Colombier 			return;
12337edc7532SDavid du Colombier 		}
12347edc7532SDavid du Colombier 		if(vconst(f1) == 0 || vconst(f2) == 0) {
12357edc7532SDavid du Colombier 			if(vconst(f1) == 0) {
12367edc7532SDavid du Colombier 				o = invrel[relindex(o)];
12377edc7532SDavid du Colombier 				f1 = f2;
12387edc7532SDavid du Colombier 			}
12397edc7532SDavid du Colombier 			switch(o) {
12407edc7532SDavid du Colombier 			case OLT:
12417edc7532SDavid du Colombier 				a = ABLTZ;
12427edc7532SDavid du Colombier 				break;
12437edc7532SDavid du Colombier 			case OLE:
12447edc7532SDavid du Colombier 				a = ABLEZ;
12457edc7532SDavid du Colombier 				break;
12467edc7532SDavid du Colombier 			case OGE:
12477edc7532SDavid du Colombier 				a = ABGEZ;
12487edc7532SDavid du Colombier 				break;
12497edc7532SDavid du Colombier 			case OGT:
12507edc7532SDavid du Colombier 				a = ABGTZ;
12517edc7532SDavid du Colombier 				break;
12527edc7532SDavid du Colombier 			}
12537edc7532SDavid du Colombier 			f2 = Z;
12547edc7532SDavid du Colombier 			break;
12557edc7532SDavid du Colombier 		}
12567edc7532SDavid du Colombier 
12577edc7532SDavid du Colombier 	case OLO:
12587edc7532SDavid du Colombier 	case OLS:
12597edc7532SDavid du Colombier 	case OHS:
12607edc7532SDavid du Colombier 	case OHI:
12617edc7532SDavid du Colombier 		nextpc();
12627edc7532SDavid du Colombier 		if(o == OLE || o == OGT || o == OLS || o == OHI) {
12637edc7532SDavid du Colombier 			naddr(f1, &p->from);
12647edc7532SDavid du Colombier 			raddr(f2, p);
12657edc7532SDavid du Colombier 		} else {
12667edc7532SDavid du Colombier 			naddr(f2, &p->from);
12677edc7532SDavid du Colombier 			raddr(f1, p);
12687edc7532SDavid du Colombier 		}
12697edc7532SDavid du Colombier 		naddr(&regnode, &p->to);
12707edc7532SDavid du Colombier 		p->to.reg = tmpreg();
12717edc7532SDavid du Colombier 		a = ASGT;
12727edc7532SDavid du Colombier 		if(o == OLO || o == OLS || o == OHS || o == OHI)
12737edc7532SDavid du Colombier 			a = ASGTU;
12747edc7532SDavid du Colombier 		p->as = a;
12757edc7532SDavid du Colombier 		if(debug['g'])
12767edc7532SDavid du Colombier 			print("%P\n", p);
12777edc7532SDavid du Colombier 
12787edc7532SDavid du Colombier 		nextpc();
12797edc7532SDavid du Colombier 		naddr(&regnode, &p->from);
12807edc7532SDavid du Colombier 		p->from.reg = tmpreg();
12817edc7532SDavid du Colombier 		a = ABEQ;
12827edc7532SDavid du Colombier 		if(o == OLT || o == OGT || o == OLO || o == OHI)
12837edc7532SDavid du Colombier 			a = ABNE;
12847edc7532SDavid du Colombier 		p->as = a;
12857edc7532SDavid du Colombier 		if(debug['g'])
12867edc7532SDavid du Colombier 			print("%P\n", p);
12877edc7532SDavid du Colombier 		return;
12887edc7532SDavid du Colombier 	}
12897edc7532SDavid du Colombier 	if(a == AGOK)
12907edc7532SDavid du Colombier 		diag(Z, "bad in gopcode %O", o);
12917edc7532SDavid du Colombier 	nextpc();
12927edc7532SDavid du Colombier 	p->as = a;
12937edc7532SDavid du Colombier 	if(f1 != Z)
12947edc7532SDavid du Colombier 		naddr(f1, &p->from);
12957edc7532SDavid du Colombier 	if(f2 != Z) {
12967edc7532SDavid du Colombier 		naddr(f2, &ta);
12977edc7532SDavid du Colombier 		p->reg = ta.reg;
12987edc7532SDavid du Colombier 		if(ta.type == D_CONST && ta.offset == 0)
12997edc7532SDavid du Colombier 			p->reg = REGZERO;
13007edc7532SDavid du Colombier 	}
13017edc7532SDavid du Colombier 	if(t != Z)
13027edc7532SDavid du Colombier 		naddr(t, &p->to);
13037edc7532SDavid du Colombier 	if(debug['g'])
13047edc7532SDavid du Colombier 		print("%P\n", p);
13057edc7532SDavid du Colombier }
13067edc7532SDavid du Colombier 
13077edc7532SDavid du Colombier int
samaddr(Node * f,Node * t)13087edc7532SDavid du Colombier samaddr(Node *f, Node *t)
13097edc7532SDavid du Colombier {
13107edc7532SDavid du Colombier 
13117edc7532SDavid du Colombier 	if(f->op != t->op)
13127edc7532SDavid du Colombier 		return 0;
13137edc7532SDavid du Colombier 	switch(f->op) {
13147edc7532SDavid du Colombier 
13157edc7532SDavid du Colombier 	case OREGISTER:
13167edc7532SDavid du Colombier 		if(f->reg != t->reg)
13177edc7532SDavid du Colombier 			break;
13187edc7532SDavid du Colombier 		return 1;
13197edc7532SDavid du Colombier 	}
13207edc7532SDavid du Colombier 	return 0;
13217edc7532SDavid du Colombier }
13227edc7532SDavid du Colombier 
13237edc7532SDavid du Colombier void
gbranch(int o)13247edc7532SDavid du Colombier gbranch(int o)
13257edc7532SDavid du Colombier {
13267edc7532SDavid du Colombier 	int a;
13277edc7532SDavid du Colombier 
13287edc7532SDavid du Colombier 	a = AGOK;
13297edc7532SDavid du Colombier 	switch(o) {
13307edc7532SDavid du Colombier 	case ORETURN:
13317edc7532SDavid du Colombier 		a = ARET;
13327edc7532SDavid du Colombier 		break;
13337edc7532SDavid du Colombier 	case OGOTO:
13347edc7532SDavid du Colombier 		a = AJMP;
13357edc7532SDavid du Colombier 		break;
13367edc7532SDavid du Colombier 	}
13377edc7532SDavid du Colombier 	nextpc();
13387edc7532SDavid du Colombier 	if(a == AGOK) {
13397edc7532SDavid du Colombier 		diag(Z, "bad in gbranch %O",  o);
13407edc7532SDavid du Colombier 		nextpc();
13417edc7532SDavid du Colombier 	}
13427edc7532SDavid du Colombier 	p->as = a;
13437edc7532SDavid du Colombier }
13447edc7532SDavid du Colombier 
13457edc7532SDavid du Colombier void
patch(Prog * op,vlong pc)13467edc7532SDavid du Colombier patch(Prog *op, vlong pc)
13477edc7532SDavid du Colombier {
13487edc7532SDavid du Colombier 
13497edc7532SDavid du Colombier 	op->to.offset = pc;
13507edc7532SDavid du Colombier 	op->to.type = D_BRANCH;
13517edc7532SDavid du Colombier }
13527edc7532SDavid du Colombier 
13537edc7532SDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)13547edc7532SDavid du Colombier gpseudo(int a, Sym *s, Node *n)
13557edc7532SDavid du Colombier {
13567edc7532SDavid du Colombier 
13577edc7532SDavid du Colombier 	nextpc();
13587edc7532SDavid du Colombier 	p->as = a;
13597edc7532SDavid du Colombier 	p->from.type = D_OREG;
13607edc7532SDavid du Colombier 	p->from.sym = s;
1361*f8bc6aafSDavid du Colombier 	if(a == ATEXT)
13627edc7532SDavid du Colombier 		p->reg = (profileflg ? 0 : NOPROF);
13637edc7532SDavid du Colombier 	p->from.name = D_EXTERN;
13647edc7532SDavid du Colombier 	if(s->class == CSTATIC)
13657edc7532SDavid du Colombier 		p->from.name = D_STATIC;
13667edc7532SDavid du Colombier 	naddr(n, &p->to);
13677edc7532SDavid du Colombier 	if(a == ADATA || a == AGLOBL)
13687edc7532SDavid du Colombier 		pc--;
13697edc7532SDavid du Colombier }
13707edc7532SDavid du Colombier 
13717edc7532SDavid du Colombier int
sconst(Node * n)13727edc7532SDavid du Colombier sconst(Node *n)
13737edc7532SDavid du Colombier {
13747edc7532SDavid du Colombier 	vlong vv;
13757edc7532SDavid du Colombier 
13767edc7532SDavid du Colombier 	if(n->op == OCONST) {
13777edc7532SDavid du Colombier 		if(!typefd[n->type->etype]) {
13787edc7532SDavid du Colombier 			vv = n->vconst;
1379*f8bc6aafSDavid du Colombier 			if(vv >= (vlong)(-32766) && vv < (vlong)32766)
13807edc7532SDavid du Colombier 				return 1;
13817edc7532SDavid du Colombier 		}
13827edc7532SDavid du Colombier 	}
13837edc7532SDavid du Colombier 	return 0;
13847edc7532SDavid du Colombier }
13857edc7532SDavid du Colombier 
13867edc7532SDavid du Colombier int
llconst(Node * n)13877edc7532SDavid du Colombier llconst(Node *n)
13887edc7532SDavid du Colombier {
1389*f8bc6aafSDavid du Colombier 	long l;
13907edc7532SDavid du Colombier 
13917edc7532SDavid du Colombier 	if(n != Z && n->op == OCONST) {
13927edc7532SDavid du Colombier 		if(typev[n->type->etype] || n->type->etype == TIND) {
1393*f8bc6aafSDavid du Colombier 			l = n->vconst;
1394*f8bc6aafSDavid du Colombier 			return (vlong)l != n->vconst;
13957edc7532SDavid du Colombier 		}
13967edc7532SDavid du Colombier 	}
13977edc7532SDavid du Colombier 	return 0;
13987edc7532SDavid du Colombier }
13997edc7532SDavid du Colombier 
14007edc7532SDavid du Colombier int
sval(long v)14017edc7532SDavid du Colombier sval(long v)
14027edc7532SDavid du Colombier {
14037edc7532SDavid du Colombier 	if(v >= -32766L && v < 32766L)
14047edc7532SDavid du Colombier 		return 1;
14057edc7532SDavid du Colombier 	return 0;
14067edc7532SDavid du Colombier }
14077edc7532SDavid du Colombier 
14087edc7532SDavid du Colombier long
exreg(Type * t)14097edc7532SDavid du Colombier exreg(Type *t)
14107edc7532SDavid du Colombier {
14117edc7532SDavid du Colombier 	long o;
14127edc7532SDavid du Colombier 
14137edc7532SDavid du Colombier 	if(typechlp[t->etype]) {
14147edc7532SDavid du Colombier 		if(exregoffset <= 16)
14157edc7532SDavid du Colombier 			return 0;
14167edc7532SDavid du Colombier 		o = exregoffset;
14177edc7532SDavid du Colombier 		exregoffset--;
14187edc7532SDavid du Colombier 		return o;
14197edc7532SDavid du Colombier 	}
14207edc7532SDavid du Colombier 	if(typefd[t->etype]) {
14217edc7532SDavid du Colombier 		if(exfregoffset <= 16)
14227edc7532SDavid du Colombier 			return 0;
14237edc7532SDavid du Colombier 		o = exfregoffset + NREG;
14247edc7532SDavid du Colombier 		exfregoffset--;
14257edc7532SDavid du Colombier 		return o;
14267edc7532SDavid du Colombier 	}
14277edc7532SDavid du Colombier 	return 0;
14287edc7532SDavid du Colombier }
14297edc7532SDavid du Colombier 
14307edc7532SDavid du Colombier schar	ewidth[NTYPE] =
14317edc7532SDavid du Colombier {
14327edc7532SDavid du Colombier 	-1,		/* [TXXX] */
14337edc7532SDavid du Colombier 	SZ_CHAR,	/* [TCHAR] */
14347edc7532SDavid du Colombier 	SZ_CHAR,	/* [TUCHAR] */
14357edc7532SDavid du Colombier 	SZ_SHORT,	/* [TSHORT] */
14367edc7532SDavid du Colombier 	SZ_SHORT,	/* [TUSHORT] */
14377edc7532SDavid du Colombier 	SZ_INT,		/* [TINT] */
14387edc7532SDavid du Colombier 	SZ_INT,		/* [TUINT] */
14397edc7532SDavid du Colombier 	SZ_LONG,	/* [TLONG] */
14407edc7532SDavid du Colombier 	SZ_LONG,	/* [TULONG] */
14417edc7532SDavid du Colombier 	SZ_VLONG,	/* [TVLONG] */
14427edc7532SDavid du Colombier 	SZ_VLONG,	/* [TUVLONG] */
14437edc7532SDavid du Colombier 	SZ_FLOAT,	/* [TFLOAT] */
14447edc7532SDavid du Colombier 	SZ_DOUBLE,	/* [TDOUBLE] */
14457edc7532SDavid du Colombier 	SZ_IND,		/* [TIND] */
14467edc7532SDavid du Colombier 	0,		/* [TFUNC] */
14477edc7532SDavid du Colombier 	-1,		/* [TARRAY] */
14487edc7532SDavid du Colombier 	0,		/* [TVOID] */
14497edc7532SDavid du Colombier 	-1,		/* [TSTRUCT] */
14507edc7532SDavid du Colombier 	-1,		/* [TUNION] */
14517edc7532SDavid du Colombier 	SZ_INT,		/* [TENUM] */
14527edc7532SDavid du Colombier };
14537edc7532SDavid du Colombier 
14547edc7532SDavid du Colombier long	ncast[NTYPE] =
14557edc7532SDavid du Colombier {
14567edc7532SDavid du Colombier 	0,				/* [TXXX] */
14577edc7532SDavid du Colombier 	BCHAR|BUCHAR,			/* [TCHAR] */
14587edc7532SDavid du Colombier 	BCHAR|BUCHAR,			/* [TUCHAR] */
14597edc7532SDavid du Colombier 	BSHORT|BUSHORT,			/* [TSHORT] */
14607edc7532SDavid du Colombier 	BSHORT|BUSHORT,			/* [TUSHORT] */
14617edc7532SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/* [TINT] */
14627edc7532SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/* [TUINT] */
14637edc7532SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/* [TLONG] */
14647edc7532SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/* [TULONG] */
14657edc7532SDavid du Colombier 	BVLONG|BUVLONG|BIND,		/* [TVLONG] */
14667edc7532SDavid du Colombier 	BVLONG|BUVLONG|BIND,		/* [TUVLONG] */
14677edc7532SDavid du Colombier 	BFLOAT,				/* [TFLOAT] */
14687edc7532SDavid du Colombier 	BDOUBLE,			/* [TDOUBLE] */
14697edc7532SDavid du Colombier 	BVLONG|BUVLONG|BIND,		/* [TIND] */
14707edc7532SDavid du Colombier 	0,				/* [TFUNC] */
14717edc7532SDavid du Colombier 	0,				/* [TARRAY] */
14727edc7532SDavid du Colombier 	0,				/* [TVOID] */
14737edc7532SDavid du Colombier 	BSTRUCT,			/* [TSTRUCT] */
14747edc7532SDavid du Colombier 	BUNION,				/* [TUNION] */
14757edc7532SDavid du Colombier 	0,				/* [TENUM] */
14767edc7532SDavid du Colombier };
1477