xref: /inferno-os/utils/8c/txt.c (revision 45a20ab721a513710138340faff3d59a31c3e01e)
174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth void
ginit(void)474a4d8c2SCharles.Forsyth ginit(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 	int i;
774a4d8c2SCharles.Forsyth 	Type *t;
874a4d8c2SCharles.Forsyth 
974a4d8c2SCharles.Forsyth 	thechar = '8';
1074a4d8c2SCharles.Forsyth 	thestring = "386";
1174a4d8c2SCharles.Forsyth 	exregoffset = 0;
1274a4d8c2SCharles.Forsyth 	exfregoffset = 0;
1374a4d8c2SCharles.Forsyth 	listinit();
1474a4d8c2SCharles.Forsyth 	nstring = 0;
1574a4d8c2SCharles.Forsyth 	mnstring = 0;
1674a4d8c2SCharles.Forsyth 	nrathole = 0;
1774a4d8c2SCharles.Forsyth 	pc = 0;
1874a4d8c2SCharles.Forsyth 	breakpc = -1;
1974a4d8c2SCharles.Forsyth 	continpc = -1;
2074a4d8c2SCharles.Forsyth 	cases = C;
2174a4d8c2SCharles.Forsyth 	firstp = P;
2274a4d8c2SCharles.Forsyth 	lastp = P;
2374a4d8c2SCharles.Forsyth 	tfield = types[TLONG];
2474a4d8c2SCharles.Forsyth 
25*45a20ab7Sforsyth 	typeswitch = typechlv;
26*45a20ab7Sforsyth 
2774a4d8c2SCharles.Forsyth 	zprog.link = P;
2874a4d8c2SCharles.Forsyth 	zprog.as = AGOK;
2974a4d8c2SCharles.Forsyth 	zprog.from.type = D_NONE;
3074a4d8c2SCharles.Forsyth 	zprog.from.index = D_NONE;
3174a4d8c2SCharles.Forsyth 	zprog.from.scale = 0;
3274a4d8c2SCharles.Forsyth 	zprog.to = zprog.from;
3374a4d8c2SCharles.Forsyth 
3474a4d8c2SCharles.Forsyth 	regnode.op = OREGISTER;
3574a4d8c2SCharles.Forsyth 	regnode.class = CEXREG;
3674a4d8c2SCharles.Forsyth 	regnode.reg = REGTMP;
3774a4d8c2SCharles.Forsyth 	regnode.complex = 0;
3874a4d8c2SCharles.Forsyth 	regnode.addable = 11;
3974a4d8c2SCharles.Forsyth 	regnode.type = types[TLONG];
4074a4d8c2SCharles.Forsyth 
4174a4d8c2SCharles.Forsyth 	fregnode0 = regnode;
4274a4d8c2SCharles.Forsyth 	fregnode0.reg = D_F0;
4374a4d8c2SCharles.Forsyth 	fregnode0.type = types[TDOUBLE];
4474a4d8c2SCharles.Forsyth 
4574a4d8c2SCharles.Forsyth 	fregnode1 = fregnode0;
4674a4d8c2SCharles.Forsyth 	fregnode1.reg = D_F0+1;
4774a4d8c2SCharles.Forsyth 
4874a4d8c2SCharles.Forsyth 	constnode.op = OCONST;
4974a4d8c2SCharles.Forsyth 	constnode.class = CXXX;
5074a4d8c2SCharles.Forsyth 	constnode.complex = 0;
5174a4d8c2SCharles.Forsyth 	constnode.addable = 20;
5274a4d8c2SCharles.Forsyth 	constnode.type = types[TLONG];
5374a4d8c2SCharles.Forsyth 
5474a4d8c2SCharles.Forsyth 	fconstnode.op = OCONST;
5574a4d8c2SCharles.Forsyth 	fconstnode.class = CXXX;
5674a4d8c2SCharles.Forsyth 	fconstnode.complex = 0;
5774a4d8c2SCharles.Forsyth 	fconstnode.addable = 20;
5874a4d8c2SCharles.Forsyth 	fconstnode.type = types[TDOUBLE];
5974a4d8c2SCharles.Forsyth 
6074a4d8c2SCharles.Forsyth 	nodsafe = new(ONAME, Z, Z);
6174a4d8c2SCharles.Forsyth 	nodsafe->sym = slookup(".safe");
6274a4d8c2SCharles.Forsyth 	nodsafe->type = types[TINT];
6374a4d8c2SCharles.Forsyth 	nodsafe->etype = types[TINT]->etype;
6474a4d8c2SCharles.Forsyth 	nodsafe->class = CAUTO;
6574a4d8c2SCharles.Forsyth 	complex(nodsafe);
6674a4d8c2SCharles.Forsyth 
6774a4d8c2SCharles.Forsyth 	t = typ(TARRAY, types[TCHAR]);
6874a4d8c2SCharles.Forsyth 	symrathole = slookup(".rathole");
6974a4d8c2SCharles.Forsyth 	symrathole->class = CGLOBL;
7074a4d8c2SCharles.Forsyth 	symrathole->type = t;
7174a4d8c2SCharles.Forsyth 
7274a4d8c2SCharles.Forsyth 	nodrat = new(ONAME, Z, Z);
7374a4d8c2SCharles.Forsyth 	nodrat->sym = symrathole;
7474a4d8c2SCharles.Forsyth 	nodrat->type = types[TIND];
7574a4d8c2SCharles.Forsyth 	nodrat->etype = TVOID;
7674a4d8c2SCharles.Forsyth 	nodrat->class = CGLOBL;
7774a4d8c2SCharles.Forsyth 	complex(nodrat);
7874a4d8c2SCharles.Forsyth 	nodrat->type = t;
7974a4d8c2SCharles.Forsyth 
8074a4d8c2SCharles.Forsyth 	nodret = new(ONAME, Z, Z);
8174a4d8c2SCharles.Forsyth 	nodret->sym = slookup(".ret");
8274a4d8c2SCharles.Forsyth 	nodret->type = types[TIND];
8374a4d8c2SCharles.Forsyth 	nodret->etype = TIND;
8474a4d8c2SCharles.Forsyth 	nodret->class = CPARAM;
8574a4d8c2SCharles.Forsyth 	nodret = new(OIND, nodret, Z);
8674a4d8c2SCharles.Forsyth 	complex(nodret);
8774a4d8c2SCharles.Forsyth 
8874a4d8c2SCharles.Forsyth 	com64init();
8974a4d8c2SCharles.Forsyth 
9074a4d8c2SCharles.Forsyth 	for(i=0; i<nelem(reg); i++) {
9174a4d8c2SCharles.Forsyth 		reg[i] = 1;
9274a4d8c2SCharles.Forsyth 		if(i >= D_AX && i <= D_DI && i != D_SP)
9374a4d8c2SCharles.Forsyth 			reg[i] = 0;
9474a4d8c2SCharles.Forsyth 	}
9574a4d8c2SCharles.Forsyth }
9674a4d8c2SCharles.Forsyth 
9774a4d8c2SCharles.Forsyth void
gclean(void)9874a4d8c2SCharles.Forsyth gclean(void)
9974a4d8c2SCharles.Forsyth {
10074a4d8c2SCharles.Forsyth 	int i;
10174a4d8c2SCharles.Forsyth 	Sym *s;
10274a4d8c2SCharles.Forsyth 
10374a4d8c2SCharles.Forsyth 	reg[D_SP]--;
10474a4d8c2SCharles.Forsyth 	for(i=D_AX; i<=D_DI; i++)
10574a4d8c2SCharles.Forsyth 		if(reg[i])
10674a4d8c2SCharles.Forsyth 			diag(Z, "reg %R left allocated", i);
10774a4d8c2SCharles.Forsyth 	while(mnstring)
10874a4d8c2SCharles.Forsyth 		outstring("", 1L);
10974a4d8c2SCharles.Forsyth 	symstring->type->width = nstring;
11074a4d8c2SCharles.Forsyth 	symrathole->type->width = nrathole;
11174a4d8c2SCharles.Forsyth 	for(i=0; i<NHASH; i++)
11274a4d8c2SCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link) {
11374a4d8c2SCharles.Forsyth 		if(s->type == T)
11474a4d8c2SCharles.Forsyth 			continue;
11574a4d8c2SCharles.Forsyth 		if(s->type->width == 0)
11674a4d8c2SCharles.Forsyth 			continue;
11774a4d8c2SCharles.Forsyth 		if(s->class != CGLOBL && s->class != CSTATIC)
11874a4d8c2SCharles.Forsyth 			continue;
11974a4d8c2SCharles.Forsyth 		if(s->type == types[TENUM])
12074a4d8c2SCharles.Forsyth 			continue;
12174a4d8c2SCharles.Forsyth 		gpseudo(AGLOBL, s, nodconst(s->type->width));
12274a4d8c2SCharles.Forsyth 	}
12374a4d8c2SCharles.Forsyth 	nextpc();
12474a4d8c2SCharles.Forsyth 	p->as = AEND;
12574a4d8c2SCharles.Forsyth 	outcode();
12674a4d8c2SCharles.Forsyth }
12774a4d8c2SCharles.Forsyth 
12874a4d8c2SCharles.Forsyth void
nextpc(void)12974a4d8c2SCharles.Forsyth nextpc(void)
13074a4d8c2SCharles.Forsyth {
13174a4d8c2SCharles.Forsyth 
13274a4d8c2SCharles.Forsyth 	p = alloc(sizeof(*p));
13374a4d8c2SCharles.Forsyth 	*p = zprog;
13474a4d8c2SCharles.Forsyth 	p->lineno = nearln;
13574a4d8c2SCharles.Forsyth 	pc++;
13674a4d8c2SCharles.Forsyth 	if(firstp == P) {
13774a4d8c2SCharles.Forsyth 		firstp = p;
13874a4d8c2SCharles.Forsyth 		lastp = p;
13974a4d8c2SCharles.Forsyth 		return;
14074a4d8c2SCharles.Forsyth 	}
14174a4d8c2SCharles.Forsyth 	lastp->link = p;
14274a4d8c2SCharles.Forsyth 	lastp = p;
14374a4d8c2SCharles.Forsyth }
14474a4d8c2SCharles.Forsyth 
14574a4d8c2SCharles.Forsyth void
gargs(Node * n,Node * tn1,Node * tn2)14674a4d8c2SCharles.Forsyth gargs(Node *n, Node *tn1, Node *tn2)
14774a4d8c2SCharles.Forsyth {
14874a4d8c2SCharles.Forsyth 	long regs;
14974a4d8c2SCharles.Forsyth 	Node fnxargs[20], *fnxp;
15074a4d8c2SCharles.Forsyth 
15174a4d8c2SCharles.Forsyth 	regs = cursafe;
15274a4d8c2SCharles.Forsyth 
15374a4d8c2SCharles.Forsyth 	fnxp = fnxargs;
15474a4d8c2SCharles.Forsyth 	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
15574a4d8c2SCharles.Forsyth 
15674a4d8c2SCharles.Forsyth 	curarg = 0;
15774a4d8c2SCharles.Forsyth 	fnxp = fnxargs;
15874a4d8c2SCharles.Forsyth 	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
15974a4d8c2SCharles.Forsyth 
16074a4d8c2SCharles.Forsyth 	cursafe = regs;
16174a4d8c2SCharles.Forsyth }
16274a4d8c2SCharles.Forsyth 
163*45a20ab7Sforsyth int
nareg(int notbp)164*45a20ab7Sforsyth nareg(int notbp)
16574a4d8c2SCharles.Forsyth {
16674a4d8c2SCharles.Forsyth 	int i, n;
16774a4d8c2SCharles.Forsyth 
16874a4d8c2SCharles.Forsyth 	n = 0;
16974a4d8c2SCharles.Forsyth 	for(i=D_AX; i<=D_DI; i++)
17074a4d8c2SCharles.Forsyth 		if(reg[i] == 0)
17174a4d8c2SCharles.Forsyth 			n++;
172*45a20ab7Sforsyth 	if(notbp && reg[D_BP] == 0)
173*45a20ab7Sforsyth 		n--;
17474a4d8c2SCharles.Forsyth 	return n;
17574a4d8c2SCharles.Forsyth }
17674a4d8c2SCharles.Forsyth 
17774a4d8c2SCharles.Forsyth void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)17874a4d8c2SCharles.Forsyth garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
17974a4d8c2SCharles.Forsyth {
18074a4d8c2SCharles.Forsyth 	Node nod;
18174a4d8c2SCharles.Forsyth 
18274a4d8c2SCharles.Forsyth 	if(n == Z)
18374a4d8c2SCharles.Forsyth 		return;
18474a4d8c2SCharles.Forsyth 	if(n->op == OLIST) {
18574a4d8c2SCharles.Forsyth 		garg1(n->left, tn1, tn2, f, fnxp);
18674a4d8c2SCharles.Forsyth 		garg1(n->right, tn1, tn2, f, fnxp);
18774a4d8c2SCharles.Forsyth 		return;
18874a4d8c2SCharles.Forsyth 	}
18974a4d8c2SCharles.Forsyth 	if(f == 0) {
19074a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
19174a4d8c2SCharles.Forsyth 			regsalloc(*fnxp, n);
19274a4d8c2SCharles.Forsyth 			nod = znode;
19374a4d8c2SCharles.Forsyth 			nod.op = OAS;
19474a4d8c2SCharles.Forsyth 			nod.left = *fnxp;
19574a4d8c2SCharles.Forsyth 			nod.right = n;
19674a4d8c2SCharles.Forsyth 			nod.type = n->type;
19774a4d8c2SCharles.Forsyth 			cgen(&nod, Z);
19874a4d8c2SCharles.Forsyth 			(*fnxp)++;
19974a4d8c2SCharles.Forsyth 		}
20074a4d8c2SCharles.Forsyth 		return;
20174a4d8c2SCharles.Forsyth 	}
20274a4d8c2SCharles.Forsyth 	if(typesu[n->type->etype] || typev[n->type->etype]) {
20374a4d8c2SCharles.Forsyth 		regaalloc(tn2, n);
20474a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
20574a4d8c2SCharles.Forsyth 			sugen(*fnxp, tn2, n->type->width);
20674a4d8c2SCharles.Forsyth 			(*fnxp)++;
20774a4d8c2SCharles.Forsyth 		} else
20874a4d8c2SCharles.Forsyth 			sugen(n, tn2, n->type->width);
20974a4d8c2SCharles.Forsyth 		return;
21074a4d8c2SCharles.Forsyth 	}
211c0927006Sforsyth 	if(REGARG>=0 && curarg == 0 && typeilp[n->type->etype]) {
21274a4d8c2SCharles.Forsyth 		regaalloc1(tn1, n);
21374a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
21474a4d8c2SCharles.Forsyth 			cgen(*fnxp, tn1);
21574a4d8c2SCharles.Forsyth 			(*fnxp)++;
21674a4d8c2SCharles.Forsyth 		} else
21774a4d8c2SCharles.Forsyth 			cgen(n, tn1);
21874a4d8c2SCharles.Forsyth 		return;
21974a4d8c2SCharles.Forsyth 	}
22074a4d8c2SCharles.Forsyth 	if(vconst(n) == 0) {
22174a4d8c2SCharles.Forsyth 		regaalloc(tn2, n);
22274a4d8c2SCharles.Forsyth 		gmove(n, tn2);
22374a4d8c2SCharles.Forsyth 		return;
22474a4d8c2SCharles.Forsyth 	}
22574a4d8c2SCharles.Forsyth 	regalloc(tn1, n, Z);
22674a4d8c2SCharles.Forsyth 	if(n->complex >= FNX) {
22774a4d8c2SCharles.Forsyth 		cgen(*fnxp, tn1);
22874a4d8c2SCharles.Forsyth 		(*fnxp)++;
22974a4d8c2SCharles.Forsyth 	} else
23074a4d8c2SCharles.Forsyth 		cgen(n, tn1);
23174a4d8c2SCharles.Forsyth 	regaalloc(tn2, n);
23274a4d8c2SCharles.Forsyth 	gmove(tn1, tn2);
23374a4d8c2SCharles.Forsyth 	regfree(tn1);
23474a4d8c2SCharles.Forsyth }
23574a4d8c2SCharles.Forsyth 
23674a4d8c2SCharles.Forsyth Node*
nodconst(long v)23774a4d8c2SCharles.Forsyth nodconst(long v)
23874a4d8c2SCharles.Forsyth {
23974a4d8c2SCharles.Forsyth 	constnode.vconst = v;
24074a4d8c2SCharles.Forsyth 	return &constnode;
24174a4d8c2SCharles.Forsyth }
24274a4d8c2SCharles.Forsyth 
24374a4d8c2SCharles.Forsyth Node*
nodfconst(double d)24474a4d8c2SCharles.Forsyth nodfconst(double d)
24574a4d8c2SCharles.Forsyth {
24674a4d8c2SCharles.Forsyth 	fconstnode.fconst = d;
24774a4d8c2SCharles.Forsyth 	return &fconstnode;
24874a4d8c2SCharles.Forsyth }
24974a4d8c2SCharles.Forsyth 
25074a4d8c2SCharles.Forsyth int
isreg(Node * n,int r)25174a4d8c2SCharles.Forsyth isreg(Node *n, int r)
25274a4d8c2SCharles.Forsyth {
25374a4d8c2SCharles.Forsyth 
25474a4d8c2SCharles.Forsyth 	if(n->op == OREGISTER)
25574a4d8c2SCharles.Forsyth 		if(n->reg == r)
25674a4d8c2SCharles.Forsyth 			return 1;
25774a4d8c2SCharles.Forsyth 	return 0;
25874a4d8c2SCharles.Forsyth }
25974a4d8c2SCharles.Forsyth 
26074a4d8c2SCharles.Forsyth int
nodreg(Node * n,Node * nn,int r)26174a4d8c2SCharles.Forsyth nodreg(Node *n, Node *nn, int r)
26274a4d8c2SCharles.Forsyth {
26374a4d8c2SCharles.Forsyth 
26474a4d8c2SCharles.Forsyth 	*n = regnode;
26574a4d8c2SCharles.Forsyth 	n->reg = r;
26674a4d8c2SCharles.Forsyth 	if(reg[r] == 0)
26774a4d8c2SCharles.Forsyth 		return 0;
26874a4d8c2SCharles.Forsyth 	if(nn != Z) {
26974a4d8c2SCharles.Forsyth 		n->type = nn->type;
27074a4d8c2SCharles.Forsyth 		n->lineno = nn->lineno;
27174a4d8c2SCharles.Forsyth 		if(nn->op == OREGISTER)
27274a4d8c2SCharles.Forsyth 		if(nn->reg == r)
27374a4d8c2SCharles.Forsyth 			return 0;
27474a4d8c2SCharles.Forsyth 	}
27574a4d8c2SCharles.Forsyth 	return 1;
27674a4d8c2SCharles.Forsyth }
27774a4d8c2SCharles.Forsyth 
27874a4d8c2SCharles.Forsyth void
regret(Node * n,Node * nn)27974a4d8c2SCharles.Forsyth regret(Node *n, Node *nn)
28074a4d8c2SCharles.Forsyth {
28174a4d8c2SCharles.Forsyth 	int r;
28274a4d8c2SCharles.Forsyth 
28374a4d8c2SCharles.Forsyth 	r = REGRET;
28474a4d8c2SCharles.Forsyth 	if(typefd[nn->type->etype])
28574a4d8c2SCharles.Forsyth 		r = FREGRET;
28674a4d8c2SCharles.Forsyth 	nodreg(n, nn, r);
28774a4d8c2SCharles.Forsyth 	reg[r]++;
28874a4d8c2SCharles.Forsyth }
28974a4d8c2SCharles.Forsyth 
29074a4d8c2SCharles.Forsyth void
regalloc(Node * n,Node * tn,Node * o)29174a4d8c2SCharles.Forsyth regalloc(Node *n, Node *tn, Node *o)
29274a4d8c2SCharles.Forsyth {
29374a4d8c2SCharles.Forsyth 	int i;
29474a4d8c2SCharles.Forsyth 
29574a4d8c2SCharles.Forsyth 	switch(tn->type->etype) {
29674a4d8c2SCharles.Forsyth 	case TCHAR:
29774a4d8c2SCharles.Forsyth 	case TUCHAR:
29874a4d8c2SCharles.Forsyth 	case TSHORT:
29974a4d8c2SCharles.Forsyth 	case TUSHORT:
30074a4d8c2SCharles.Forsyth 	case TINT:
30174a4d8c2SCharles.Forsyth 	case TUINT:
30274a4d8c2SCharles.Forsyth 	case TLONG:
30374a4d8c2SCharles.Forsyth 	case TULONG:
30474a4d8c2SCharles.Forsyth 	case TIND:
30574a4d8c2SCharles.Forsyth 		if(o != Z && o->op == OREGISTER) {
30674a4d8c2SCharles.Forsyth 			i = o->reg;
30774a4d8c2SCharles.Forsyth 			if(i >= D_AX && i <= D_DI)
30874a4d8c2SCharles.Forsyth 				goto out;
30974a4d8c2SCharles.Forsyth 		}
31074a4d8c2SCharles.Forsyth 		for(i=D_AX; i<=D_DI; i++)
31174a4d8c2SCharles.Forsyth 			if(reg[i] == 0)
31274a4d8c2SCharles.Forsyth 				goto out;
31374a4d8c2SCharles.Forsyth 		diag(tn, "out of fixed registers");
314c0927006Sforsyth abort();
31574a4d8c2SCharles.Forsyth 		goto err;
31674a4d8c2SCharles.Forsyth 
31774a4d8c2SCharles.Forsyth 	case TFLOAT:
31874a4d8c2SCharles.Forsyth 	case TDOUBLE:
31974a4d8c2SCharles.Forsyth 		i = D_F0;
32074a4d8c2SCharles.Forsyth 		goto out;
321*45a20ab7Sforsyth 
322*45a20ab7Sforsyth 	case TVLONG:
323*45a20ab7Sforsyth 	case TUVLONG:
324*45a20ab7Sforsyth 		n->op = OREGPAIR;
325*45a20ab7Sforsyth 		n->complex = 0; /* already in registers */
326*45a20ab7Sforsyth 		n->addable = 11;
327*45a20ab7Sforsyth 		n->type = tn->type;
328*45a20ab7Sforsyth 		n->lineno = nearln;
329*45a20ab7Sforsyth 		n->left = alloc(sizeof(Node));
330*45a20ab7Sforsyth 		n->right = alloc(sizeof(Node));
331*45a20ab7Sforsyth 		if(o != Z && o->op == OREGPAIR) {
332*45a20ab7Sforsyth 			regalloc(n->left, &regnode, o->left);
333*45a20ab7Sforsyth 			regalloc(n->right, &regnode, o->right);
334*45a20ab7Sforsyth 		} else {
335*45a20ab7Sforsyth 			regalloc(n->left, &regnode, Z);
336*45a20ab7Sforsyth 			regalloc(n->right, &regnode, Z);
337*45a20ab7Sforsyth 		}
338*45a20ab7Sforsyth 		n->right->type = types[TULONG];
339*45a20ab7Sforsyth 		if(tn->type->etype == TUVLONG)
340*45a20ab7Sforsyth 			n->left->type = types[TULONG];
341*45a20ab7Sforsyth 		return;
34274a4d8c2SCharles.Forsyth 	}
34374a4d8c2SCharles.Forsyth 	diag(tn, "unknown type in regalloc: %T", tn->type);
34474a4d8c2SCharles.Forsyth err:
34574a4d8c2SCharles.Forsyth 	i = 0;
34674a4d8c2SCharles.Forsyth out:
34774a4d8c2SCharles.Forsyth 	if(i)
34874a4d8c2SCharles.Forsyth 		reg[i]++;
34974a4d8c2SCharles.Forsyth 	nodreg(n, tn, i);
350c0927006Sforsyth //print("+ %R %d\n", i, reg[i]);
35174a4d8c2SCharles.Forsyth }
35274a4d8c2SCharles.Forsyth 
35374a4d8c2SCharles.Forsyth void
regialloc(Node * n,Node * tn,Node * o)35474a4d8c2SCharles.Forsyth regialloc(Node *n, Node *tn, Node *o)
35574a4d8c2SCharles.Forsyth {
35674a4d8c2SCharles.Forsyth 	Node nod;
35774a4d8c2SCharles.Forsyth 
35874a4d8c2SCharles.Forsyth 	nod = *tn;
35974a4d8c2SCharles.Forsyth 	nod.type = types[TIND];
36074a4d8c2SCharles.Forsyth 	regalloc(n, &nod, o);
36174a4d8c2SCharles.Forsyth }
36274a4d8c2SCharles.Forsyth 
36374a4d8c2SCharles.Forsyth void
regfree(Node * n)36474a4d8c2SCharles.Forsyth regfree(Node *n)
36574a4d8c2SCharles.Forsyth {
36674a4d8c2SCharles.Forsyth 	int i;
36774a4d8c2SCharles.Forsyth 
368*45a20ab7Sforsyth 	if(n->op == OREGPAIR) {
369*45a20ab7Sforsyth 		regfree(n->left);
370*45a20ab7Sforsyth 		regfree(n->right);
371*45a20ab7Sforsyth 		return;
372*45a20ab7Sforsyth 	}
373*45a20ab7Sforsyth 
37474a4d8c2SCharles.Forsyth 	i = 0;
37574a4d8c2SCharles.Forsyth 	if(n->op != OREGISTER && n->op != OINDREG)
37674a4d8c2SCharles.Forsyth 		goto err;
37774a4d8c2SCharles.Forsyth 	i = n->reg;
37874a4d8c2SCharles.Forsyth 	if(i < 0 || i >= sizeof(reg))
37974a4d8c2SCharles.Forsyth 		goto err;
38074a4d8c2SCharles.Forsyth 	if(reg[i] <= 0)
38174a4d8c2SCharles.Forsyth 		goto err;
38274a4d8c2SCharles.Forsyth 	reg[i]--;
383c0927006Sforsyth //print("- %R %d\n", i, reg[i]);
38474a4d8c2SCharles.Forsyth 	return;
38574a4d8c2SCharles.Forsyth err:
38674a4d8c2SCharles.Forsyth 	diag(n, "error in regfree: %R", i);
38774a4d8c2SCharles.Forsyth }
38874a4d8c2SCharles.Forsyth 
38974a4d8c2SCharles.Forsyth void
regsalloc(Node * n,Node * nn)39074a4d8c2SCharles.Forsyth regsalloc(Node *n, Node *nn)
39174a4d8c2SCharles.Forsyth {
39274a4d8c2SCharles.Forsyth 	cursafe = align(cursafe, nn->type, Aaut3);
39374a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
39474a4d8c2SCharles.Forsyth 	*n = *nodsafe;
39574a4d8c2SCharles.Forsyth 	n->xoffset = -(stkoff + cursafe);
39674a4d8c2SCharles.Forsyth 	n->type = nn->type;
39774a4d8c2SCharles.Forsyth 	n->etype = nn->type->etype;
39874a4d8c2SCharles.Forsyth 	n->lineno = nn->lineno;
39974a4d8c2SCharles.Forsyth }
40074a4d8c2SCharles.Forsyth 
40174a4d8c2SCharles.Forsyth void
regaalloc1(Node * n,Node * nn)40274a4d8c2SCharles.Forsyth regaalloc1(Node *n, Node *nn)
40374a4d8c2SCharles.Forsyth {
404c0927006Sforsyth 	USED(nn);
405c0927006Sforsyth 
406c0927006Sforsyth 	if(REGARG < 0) {
407c0927006Sforsyth 		diag(n, "regaalloc1");
408c0927006Sforsyth 		return;
409c0927006Sforsyth 	}
410c0927006Sforsyth /* not reached
41174a4d8c2SCharles.Forsyth 	nodreg(n, nn, REGARG);
41274a4d8c2SCharles.Forsyth 	reg[REGARG]++;
41374a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg1);
41474a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg2);
41574a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
416c0927006Sforsyth */
41774a4d8c2SCharles.Forsyth }
41874a4d8c2SCharles.Forsyth 
41974a4d8c2SCharles.Forsyth void
regaalloc(Node * n,Node * nn)42074a4d8c2SCharles.Forsyth regaalloc(Node *n, Node *nn)
42174a4d8c2SCharles.Forsyth {
42274a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg1);
42374a4d8c2SCharles.Forsyth 	*n = *nn;
42474a4d8c2SCharles.Forsyth 	n->op = OINDREG;
42574a4d8c2SCharles.Forsyth 	n->reg = REGSP;
42674a4d8c2SCharles.Forsyth 	n->xoffset = curarg;
42774a4d8c2SCharles.Forsyth 	n->complex = 0;
42874a4d8c2SCharles.Forsyth 	n->addable = 20;
42974a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg2);
43074a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
43174a4d8c2SCharles.Forsyth }
43274a4d8c2SCharles.Forsyth 
43374a4d8c2SCharles.Forsyth void
regind(Node * n,Node * nn)43474a4d8c2SCharles.Forsyth regind(Node *n, Node *nn)
43574a4d8c2SCharles.Forsyth {
43674a4d8c2SCharles.Forsyth 
43774a4d8c2SCharles.Forsyth 	if(n->op != OREGISTER) {
43874a4d8c2SCharles.Forsyth 		diag(n, "regind not OREGISTER");
43974a4d8c2SCharles.Forsyth 		return;
44074a4d8c2SCharles.Forsyth 	}
44174a4d8c2SCharles.Forsyth 	n->op = OINDREG;
44274a4d8c2SCharles.Forsyth 	n->type = nn->type;
44374a4d8c2SCharles.Forsyth }
44474a4d8c2SCharles.Forsyth 
44574a4d8c2SCharles.Forsyth void
naddr(Node * n,Adr * a)44674a4d8c2SCharles.Forsyth naddr(Node *n, Adr *a)
44774a4d8c2SCharles.Forsyth {
44874a4d8c2SCharles.Forsyth 	long v;
44974a4d8c2SCharles.Forsyth 
45074a4d8c2SCharles.Forsyth 	a->type = D_NONE;
45174a4d8c2SCharles.Forsyth 	if(n == Z)
45274a4d8c2SCharles.Forsyth 		return;
45374a4d8c2SCharles.Forsyth 	switch(n->op) {
45474a4d8c2SCharles.Forsyth 	default:
45574a4d8c2SCharles.Forsyth 	bad:
45674a4d8c2SCharles.Forsyth 		diag(n, "bad in naddr: %O %D", n->op, a);
457c0927006Sforsyth //prtree(n, "naddr");
45874a4d8c2SCharles.Forsyth 		break;
45974a4d8c2SCharles.Forsyth 
46074a4d8c2SCharles.Forsyth 	case OREGISTER:
46174a4d8c2SCharles.Forsyth 		a->type = n->reg;
46274a4d8c2SCharles.Forsyth 		a->sym = S;
46374a4d8c2SCharles.Forsyth 		break;
46474a4d8c2SCharles.Forsyth 
465*45a20ab7Sforsyth 	case OEXREG:
466*45a20ab7Sforsyth 		a->type = D_INDIR + D_GS;
467*45a20ab7Sforsyth 		a->offset = n->reg - 1;
468*45a20ab7Sforsyth 		a->etype = n->etype;
469*45a20ab7Sforsyth 		break;
47074a4d8c2SCharles.Forsyth 
47174a4d8c2SCharles.Forsyth 	case OIND:
47274a4d8c2SCharles.Forsyth 		naddr(n->left, a);
47374a4d8c2SCharles.Forsyth 		if(a->type >= D_AX && a->type <= D_DI)
47474a4d8c2SCharles.Forsyth 			a->type += D_INDIR;
47574a4d8c2SCharles.Forsyth 		else
47674a4d8c2SCharles.Forsyth 		if(a->type == D_CONST)
47774a4d8c2SCharles.Forsyth 			a->type = D_NONE+D_INDIR;
47874a4d8c2SCharles.Forsyth 		else
47974a4d8c2SCharles.Forsyth 		if(a->type == D_ADDR) {
48074a4d8c2SCharles.Forsyth 			a->type = a->index;
48174a4d8c2SCharles.Forsyth 			a->index = D_NONE;
48274a4d8c2SCharles.Forsyth 		} else
48374a4d8c2SCharles.Forsyth 			goto bad;
48474a4d8c2SCharles.Forsyth 		break;
48574a4d8c2SCharles.Forsyth 
48674a4d8c2SCharles.Forsyth 	case OINDEX:
48774a4d8c2SCharles.Forsyth 		a->type = idx.ptr;
48874a4d8c2SCharles.Forsyth 		if(n->left->op == OADDR || n->left->op == OCONST)
48974a4d8c2SCharles.Forsyth 			naddr(n->left, a);
49074a4d8c2SCharles.Forsyth 		if(a->type >= D_AX && a->type <= D_DI)
49174a4d8c2SCharles.Forsyth 			a->type += D_INDIR;
49274a4d8c2SCharles.Forsyth 		else
49374a4d8c2SCharles.Forsyth 		if(a->type == D_CONST)
49474a4d8c2SCharles.Forsyth 			a->type = D_NONE+D_INDIR;
49574a4d8c2SCharles.Forsyth 		else
49674a4d8c2SCharles.Forsyth 		if(a->type == D_ADDR) {
49774a4d8c2SCharles.Forsyth 			a->type = a->index;
49874a4d8c2SCharles.Forsyth 			a->index = D_NONE;
49974a4d8c2SCharles.Forsyth 		} else
50074a4d8c2SCharles.Forsyth 			goto bad;
50174a4d8c2SCharles.Forsyth 		a->index = idx.reg;
50274a4d8c2SCharles.Forsyth 		a->scale = n->scale;
50374a4d8c2SCharles.Forsyth 		a->offset += n->xoffset;
50474a4d8c2SCharles.Forsyth 		break;
50574a4d8c2SCharles.Forsyth 
50674a4d8c2SCharles.Forsyth 	case OINDREG:
50774a4d8c2SCharles.Forsyth 		a->type = n->reg+D_INDIR;
50874a4d8c2SCharles.Forsyth 		a->sym = S;
50974a4d8c2SCharles.Forsyth 		a->offset = n->xoffset;
51074a4d8c2SCharles.Forsyth 		break;
51174a4d8c2SCharles.Forsyth 
51274a4d8c2SCharles.Forsyth 	case ONAME:
51374a4d8c2SCharles.Forsyth 		a->etype = n->etype;
51474a4d8c2SCharles.Forsyth 		a->type = D_STATIC;
51574a4d8c2SCharles.Forsyth 		a->sym = n->sym;
51674a4d8c2SCharles.Forsyth 		a->offset = n->xoffset;
51774a4d8c2SCharles.Forsyth 		if(n->class == CSTATIC)
51874a4d8c2SCharles.Forsyth 			break;
51974a4d8c2SCharles.Forsyth 		if(n->class == CEXTERN || n->class == CGLOBL) {
52074a4d8c2SCharles.Forsyth 			a->type = D_EXTERN;
52174a4d8c2SCharles.Forsyth 			break;
52274a4d8c2SCharles.Forsyth 		}
52374a4d8c2SCharles.Forsyth 		if(n->class == CAUTO) {
52474a4d8c2SCharles.Forsyth 			a->type = D_AUTO;
52574a4d8c2SCharles.Forsyth 			break;
52674a4d8c2SCharles.Forsyth 		}
52774a4d8c2SCharles.Forsyth 		if(n->class == CPARAM) {
52874a4d8c2SCharles.Forsyth 			a->type = D_PARAM;
52974a4d8c2SCharles.Forsyth 			break;
53074a4d8c2SCharles.Forsyth 		}
53174a4d8c2SCharles.Forsyth 		goto bad;
53274a4d8c2SCharles.Forsyth 
53374a4d8c2SCharles.Forsyth 	case OCONST:
53474a4d8c2SCharles.Forsyth 		if(typefd[n->type->etype]) {
53574a4d8c2SCharles.Forsyth 			a->type = D_FCONST;
53674a4d8c2SCharles.Forsyth 			a->dval = n->fconst;
53774a4d8c2SCharles.Forsyth 			break;
53874a4d8c2SCharles.Forsyth 		}
53974a4d8c2SCharles.Forsyth 		a->sym = S;
54074a4d8c2SCharles.Forsyth 		a->type = D_CONST;
54174a4d8c2SCharles.Forsyth 		a->offset = n->vconst;
54274a4d8c2SCharles.Forsyth 		break;
54374a4d8c2SCharles.Forsyth 
54474a4d8c2SCharles.Forsyth 	case OADDR:
54574a4d8c2SCharles.Forsyth 		naddr(n->left, a);
54674a4d8c2SCharles.Forsyth 		if(a->type >= D_INDIR) {
54774a4d8c2SCharles.Forsyth 			a->type -= D_INDIR;
54874a4d8c2SCharles.Forsyth 			break;
54974a4d8c2SCharles.Forsyth 		}
55074a4d8c2SCharles.Forsyth 		if(a->type == D_EXTERN || a->type == D_STATIC ||
55174a4d8c2SCharles.Forsyth 		   a->type == D_AUTO || a->type == D_PARAM)
55274a4d8c2SCharles.Forsyth 			if(a->index == D_NONE) {
55374a4d8c2SCharles.Forsyth 				a->index = a->type;
55474a4d8c2SCharles.Forsyth 				a->type = D_ADDR;
55574a4d8c2SCharles.Forsyth 				break;
55674a4d8c2SCharles.Forsyth 			}
55774a4d8c2SCharles.Forsyth 		goto bad;
55874a4d8c2SCharles.Forsyth 
55974a4d8c2SCharles.Forsyth 	case OADD:
56074a4d8c2SCharles.Forsyth 		if(n->right->op == OCONST) {
56174a4d8c2SCharles.Forsyth 			v = n->right->vconst;
56274a4d8c2SCharles.Forsyth 			naddr(n->left, a);
56374a4d8c2SCharles.Forsyth 		} else
56474a4d8c2SCharles.Forsyth 		if(n->left->op == OCONST) {
56574a4d8c2SCharles.Forsyth 			v = n->left->vconst;
56674a4d8c2SCharles.Forsyth 			naddr(n->right, a);
56774a4d8c2SCharles.Forsyth 		} else
56874a4d8c2SCharles.Forsyth 			goto bad;
56974a4d8c2SCharles.Forsyth 		a->offset += v;
57074a4d8c2SCharles.Forsyth 		break;
57174a4d8c2SCharles.Forsyth 
57274a4d8c2SCharles.Forsyth 	}
57374a4d8c2SCharles.Forsyth }
57474a4d8c2SCharles.Forsyth 
57574a4d8c2SCharles.Forsyth #define	CASE(a,b)	((a<<8)|(b<<0))
57674a4d8c2SCharles.Forsyth 
57774a4d8c2SCharles.Forsyth void
gmove(Node * f,Node * t)57874a4d8c2SCharles.Forsyth gmove(Node *f, Node *t)
57974a4d8c2SCharles.Forsyth {
58074a4d8c2SCharles.Forsyth 	int ft, tt, a;
58174a4d8c2SCharles.Forsyth 	Node nod, nod1;
58274a4d8c2SCharles.Forsyth 	Prog *p1;
58374a4d8c2SCharles.Forsyth 
58474a4d8c2SCharles.Forsyth 	ft = f->type->etype;
58574a4d8c2SCharles.Forsyth 	tt = t->type->etype;
58674a4d8c2SCharles.Forsyth 	if(debug['M'])
58774a4d8c2SCharles.Forsyth 		print("gop: %O %O[%s],%O[%s]\n", OAS,
58874a4d8c2SCharles.Forsyth 			f->op, tnames[ft], t->op, tnames[tt]);
58974a4d8c2SCharles.Forsyth 	if(typefd[ft] && f->op == OCONST) {
59074a4d8c2SCharles.Forsyth 		if(f->fconst == 0)
59174a4d8c2SCharles.Forsyth 			gins(AFLDZ, Z, Z);
59274a4d8c2SCharles.Forsyth 		else
59374a4d8c2SCharles.Forsyth 		if(f->fconst == 1)
59474a4d8c2SCharles.Forsyth 			gins(AFLD1, Z, Z);
59574a4d8c2SCharles.Forsyth 		else
59674a4d8c2SCharles.Forsyth 			gins(AFMOVD, f, &fregnode0);
59774a4d8c2SCharles.Forsyth 		gmove(&fregnode0, t);
59874a4d8c2SCharles.Forsyth 		return;
59974a4d8c2SCharles.Forsyth 	}
60074a4d8c2SCharles.Forsyth /*
60174a4d8c2SCharles.Forsyth  * load
60274a4d8c2SCharles.Forsyth  */
60374a4d8c2SCharles.Forsyth 	if(f->op == ONAME || f->op == OINDREG ||
60474a4d8c2SCharles.Forsyth 	   f->op == OIND || f->op == OINDEX)
60574a4d8c2SCharles.Forsyth 	switch(ft) {
60674a4d8c2SCharles.Forsyth 	case TCHAR:
60774a4d8c2SCharles.Forsyth 		a = AMOVBLSX;
60874a4d8c2SCharles.Forsyth 		goto ld;
60974a4d8c2SCharles.Forsyth 	case TUCHAR:
61074a4d8c2SCharles.Forsyth 		a = AMOVBLZX;
61174a4d8c2SCharles.Forsyth 		goto ld;
61274a4d8c2SCharles.Forsyth 	case TSHORT:
61374a4d8c2SCharles.Forsyth 		if(typefd[tt]) {
61474a4d8c2SCharles.Forsyth 			gins(AFMOVW, f, &fregnode0);
61574a4d8c2SCharles.Forsyth 			gmove(&fregnode0, t);
61674a4d8c2SCharles.Forsyth 			return;
61774a4d8c2SCharles.Forsyth 		}
61874a4d8c2SCharles.Forsyth 		a = AMOVWLSX;
61974a4d8c2SCharles.Forsyth 		goto ld;
62074a4d8c2SCharles.Forsyth 	case TUSHORT:
62174a4d8c2SCharles.Forsyth 		a = AMOVWLZX;
62274a4d8c2SCharles.Forsyth 		goto ld;
62374a4d8c2SCharles.Forsyth 	case TINT:
62474a4d8c2SCharles.Forsyth 	case TUINT:
62574a4d8c2SCharles.Forsyth 	case TLONG:
62674a4d8c2SCharles.Forsyth 	case TULONG:
62774a4d8c2SCharles.Forsyth 	case TIND:
62874a4d8c2SCharles.Forsyth 		if(typefd[tt]) {
62974a4d8c2SCharles.Forsyth 			gins(AFMOVL, f, &fregnode0);
63074a4d8c2SCharles.Forsyth 			gmove(&fregnode0, t);
63174a4d8c2SCharles.Forsyth 			return;
63274a4d8c2SCharles.Forsyth 		}
63374a4d8c2SCharles.Forsyth 		a = AMOVL;
63474a4d8c2SCharles.Forsyth 
63574a4d8c2SCharles.Forsyth 	ld:
63674a4d8c2SCharles.Forsyth 		regalloc(&nod, f, t);
63774a4d8c2SCharles.Forsyth 		nod.type = types[TLONG];
63874a4d8c2SCharles.Forsyth 		gins(a, f, &nod);
63974a4d8c2SCharles.Forsyth 		gmove(&nod, t);
64074a4d8c2SCharles.Forsyth 		regfree(&nod);
64174a4d8c2SCharles.Forsyth 		return;
64274a4d8c2SCharles.Forsyth 
64374a4d8c2SCharles.Forsyth 	case TFLOAT:
64474a4d8c2SCharles.Forsyth 		gins(AFMOVF, f, t);
64574a4d8c2SCharles.Forsyth 		return;
64674a4d8c2SCharles.Forsyth 	case TDOUBLE:
64774a4d8c2SCharles.Forsyth 		gins(AFMOVD, f, t);
64874a4d8c2SCharles.Forsyth 		return;
64974a4d8c2SCharles.Forsyth 	}
65074a4d8c2SCharles.Forsyth 
65174a4d8c2SCharles.Forsyth /*
65274a4d8c2SCharles.Forsyth  * store
65374a4d8c2SCharles.Forsyth  */
65474a4d8c2SCharles.Forsyth 	if(t->op == ONAME || t->op == OINDREG ||
65574a4d8c2SCharles.Forsyth 	   t->op == OIND || t->op == OINDEX)
65674a4d8c2SCharles.Forsyth 	switch(tt) {
65774a4d8c2SCharles.Forsyth 	case TCHAR:
65874a4d8c2SCharles.Forsyth 	case TUCHAR:
65974a4d8c2SCharles.Forsyth 		a = AMOVB;	goto st;
66074a4d8c2SCharles.Forsyth 	case TSHORT:
66174a4d8c2SCharles.Forsyth 	case TUSHORT:
66274a4d8c2SCharles.Forsyth 		a = AMOVW;	goto st;
66374a4d8c2SCharles.Forsyth 	case TINT:
66474a4d8c2SCharles.Forsyth 	case TUINT:
66574a4d8c2SCharles.Forsyth 	case TLONG:
66674a4d8c2SCharles.Forsyth 	case TULONG:
66774a4d8c2SCharles.Forsyth 	case TIND:
66874a4d8c2SCharles.Forsyth 		a = AMOVL;	goto st;
66974a4d8c2SCharles.Forsyth 
67074a4d8c2SCharles.Forsyth 	st:
67174a4d8c2SCharles.Forsyth 		if(f->op == OCONST) {
67274a4d8c2SCharles.Forsyth 			gins(a, f, t);
67374a4d8c2SCharles.Forsyth 			return;
67474a4d8c2SCharles.Forsyth 		}
67574a4d8c2SCharles.Forsyth 		regalloc(&nod, t, f);
67674a4d8c2SCharles.Forsyth 		gmove(f, &nod);
67774a4d8c2SCharles.Forsyth 		gins(a, &nod, t);
67874a4d8c2SCharles.Forsyth 		regfree(&nod);
67974a4d8c2SCharles.Forsyth 		return;
68074a4d8c2SCharles.Forsyth 
68174a4d8c2SCharles.Forsyth 	case TFLOAT:
68274a4d8c2SCharles.Forsyth 		gins(AFMOVFP, f, t);
68374a4d8c2SCharles.Forsyth 		return;
68474a4d8c2SCharles.Forsyth 	case TDOUBLE:
68574a4d8c2SCharles.Forsyth 		gins(AFMOVDP, f, t);
68674a4d8c2SCharles.Forsyth 		return;
68774a4d8c2SCharles.Forsyth 	}
68874a4d8c2SCharles.Forsyth 
68974a4d8c2SCharles.Forsyth /*
69074a4d8c2SCharles.Forsyth  * convert
69174a4d8c2SCharles.Forsyth  */
69274a4d8c2SCharles.Forsyth 	switch(CASE(ft,tt)) {
69374a4d8c2SCharles.Forsyth 	default:
69474a4d8c2SCharles.Forsyth /*
69574a4d8c2SCharles.Forsyth  * integer to integer
69674a4d8c2SCharles.Forsyth  ********
69774a4d8c2SCharles.Forsyth 		a = AGOK;	break;
69874a4d8c2SCharles.Forsyth 
69974a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TCHAR):
70074a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TCHAR):
70174a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TCHAR):
70274a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TCHAR):
70374a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TCHAR):
70474a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TCHAR):
70574a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TCHAR):
70674a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TCHAR):
70774a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TCHAR):
70874a4d8c2SCharles.Forsyth 
70974a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TUCHAR):
71074a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TUCHAR):
71174a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TUCHAR):
71274a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TUCHAR):
71374a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TUCHAR):
71474a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TUCHAR):
71574a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TUCHAR):
71674a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TUCHAR):
71774a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TUCHAR):
71874a4d8c2SCharles.Forsyth 
71974a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TSHORT):
72074a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TSHORT):
72174a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TSHORT):
72274a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TSHORT):
72374a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TSHORT):
72474a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TSHORT):
72574a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TSHORT):
72674a4d8c2SCharles.Forsyth 
72774a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TUSHORT):
72874a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TUSHORT):
72974a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TUSHORT):
73074a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TUSHORT):
73174a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TUSHORT):
73274a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TUSHORT):
73374a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TUSHORT):
73474a4d8c2SCharles.Forsyth 
73574a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TINT):
73674a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TINT):
73774a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TINT):
73874a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TINT):
73974a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TINT):
74074a4d8c2SCharles.Forsyth 
74174a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TUINT):
74274a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TUINT):
74374a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TUINT):
74474a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TUINT):
74574a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TUINT):
74674a4d8c2SCharles.Forsyth 
74774a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TLONG):
74874a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TLONG):
74974a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TLONG):
75074a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TLONG):
75174a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TLONG):
75274a4d8c2SCharles.Forsyth 
75374a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TULONG):
75474a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TULONG):
75574a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TULONG):
75674a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TULONG):
75774a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TULONG):
75874a4d8c2SCharles.Forsyth 
75974a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TIND):
76074a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TIND):
76174a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TIND):
76274a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TIND):
76374a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TIND):
76474a4d8c2SCharles.Forsyth  *****/
76574a4d8c2SCharles.Forsyth 		a = AMOVL;
76674a4d8c2SCharles.Forsyth 		break;
76774a4d8c2SCharles.Forsyth 
76874a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TINT):
76974a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TUINT):
77074a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TLONG):
77174a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TULONG):
77274a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TIND):
77374a4d8c2SCharles.Forsyth 		a = AMOVWLSX;
77474a4d8c2SCharles.Forsyth 		if(f->op == OCONST) {
77574a4d8c2SCharles.Forsyth 			f->vconst &= 0xffff;
77674a4d8c2SCharles.Forsyth 			if(f->vconst & 0x8000)
77774a4d8c2SCharles.Forsyth 				f->vconst |= 0xffff0000;
77874a4d8c2SCharles.Forsyth 			a = AMOVL;
77974a4d8c2SCharles.Forsyth 		}
78074a4d8c2SCharles.Forsyth 		break;
78174a4d8c2SCharles.Forsyth 
78274a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TINT):
78374a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TUINT):
78474a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TLONG):
78574a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TULONG):
78674a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TIND):
78774a4d8c2SCharles.Forsyth 		a = AMOVWLZX;
78874a4d8c2SCharles.Forsyth 		if(f->op == OCONST) {
78974a4d8c2SCharles.Forsyth 			f->vconst &= 0xffff;
79074a4d8c2SCharles.Forsyth 			a = AMOVL;
79174a4d8c2SCharles.Forsyth 		}
79274a4d8c2SCharles.Forsyth 		break;
79374a4d8c2SCharles.Forsyth 
79474a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TSHORT):
79574a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TUSHORT):
79674a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TINT):
79774a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TUINT):
79874a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TLONG):
79974a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TULONG):
80074a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TIND):
80174a4d8c2SCharles.Forsyth 		a = AMOVBLSX;
80274a4d8c2SCharles.Forsyth 		if(f->op == OCONST) {
80374a4d8c2SCharles.Forsyth 			f->vconst &= 0xff;
80474a4d8c2SCharles.Forsyth 			if(f->vconst & 0x80)
80574a4d8c2SCharles.Forsyth 				f->vconst |= 0xffffff00;
80674a4d8c2SCharles.Forsyth 			a = AMOVL;
80774a4d8c2SCharles.Forsyth 		}
80874a4d8c2SCharles.Forsyth 		break;
80974a4d8c2SCharles.Forsyth 
81074a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TSHORT):
81174a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TUSHORT):
81274a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TINT):
81374a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TUINT):
81474a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TLONG):
81574a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TULONG):
81674a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TIND):
81774a4d8c2SCharles.Forsyth 		a = AMOVBLZX;
81874a4d8c2SCharles.Forsyth 		if(f->op == OCONST) {
81974a4d8c2SCharles.Forsyth 			f->vconst &= 0xff;
82074a4d8c2SCharles.Forsyth 			a = AMOVL;
82174a4d8c2SCharles.Forsyth 		}
82274a4d8c2SCharles.Forsyth 		break;
82374a4d8c2SCharles.Forsyth 
82474a4d8c2SCharles.Forsyth /*
82574a4d8c2SCharles.Forsyth  * float to fix
82674a4d8c2SCharles.Forsyth  */
82774a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TCHAR):
82874a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TUCHAR):
82974a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TSHORT):
83074a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TUSHORT):
83174a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TINT):
83274a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TLONG):
83374a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TIND):
83474a4d8c2SCharles.Forsyth 
83574a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TCHAR):
83674a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TUCHAR):
83774a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TSHORT):
83874a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TUSHORT):
83974a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TINT):
84074a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TLONG):
84174a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TIND):
84274a4d8c2SCharles.Forsyth 		if(fproundflg) {
84374a4d8c2SCharles.Forsyth 			regsalloc(&nod, &regnode);
84474a4d8c2SCharles.Forsyth 			gins(AFMOVLP, f, &nod);
84574a4d8c2SCharles.Forsyth 			gmove(&nod, t);
84674a4d8c2SCharles.Forsyth 			return;
84774a4d8c2SCharles.Forsyth 		}
84874a4d8c2SCharles.Forsyth 		regsalloc(&nod, &regnode);
84974a4d8c2SCharles.Forsyth 		regsalloc(&nod1, &regnode);
85074a4d8c2SCharles.Forsyth 		gins(AFSTCW, Z, &nod1);
85174a4d8c2SCharles.Forsyth 		nod1.xoffset += 2;
85274a4d8c2SCharles.Forsyth 		gins(AMOVW, nodconst(0xf7f), &nod1);
85374a4d8c2SCharles.Forsyth 		gins(AFLDCW, &nod1, Z);
85474a4d8c2SCharles.Forsyth 		gins(AFMOVLP, f, &nod);
85574a4d8c2SCharles.Forsyth 		nod1.xoffset -= 2;
85674a4d8c2SCharles.Forsyth 		gins(AFLDCW, &nod1, Z);
85774a4d8c2SCharles.Forsyth 		gmove(&nod, t);
85874a4d8c2SCharles.Forsyth 		return;
85974a4d8c2SCharles.Forsyth 
86074a4d8c2SCharles.Forsyth /*
861c0927006Sforsyth  * float to ulong
862c0927006Sforsyth  */
863c0927006Sforsyth 	case CASE(	TDOUBLE,	TULONG):
864c0927006Sforsyth 	case CASE(	TFLOAT,	TULONG):
865c0927006Sforsyth 	case CASE(	TDOUBLE,	TUINT):
866c0927006Sforsyth 	case CASE(	TFLOAT,	TUINT):
867c0927006Sforsyth 		regsalloc(&nod, &regnode);
868c0927006Sforsyth 		gmove(f, &fregnode0);
869c0927006Sforsyth 		gins(AFADDD, nodfconst(-2147483648.), &fregnode0);
870c0927006Sforsyth 		gins(AFMOVLP, f, &nod);
871*45a20ab7Sforsyth 		gins(ASUBL, nodconst(-2147483648u), &nod);
872c0927006Sforsyth 		gmove(&nod, t);
873c0927006Sforsyth 		return;
874c0927006Sforsyth 
875c0927006Sforsyth /*
87674a4d8c2SCharles.Forsyth  * ulong to float
87774a4d8c2SCharles.Forsyth  */
87874a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TDOUBLE):
87974a4d8c2SCharles.Forsyth 	case CASE(	TULONG,	TFLOAT):
88074a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TDOUBLE):
88174a4d8c2SCharles.Forsyth 	case CASE(	TUINT,	TFLOAT):
88274a4d8c2SCharles.Forsyth 		regalloc(&nod, f, f);
88374a4d8c2SCharles.Forsyth 		gmove(f, &nod);
88474a4d8c2SCharles.Forsyth 		regsalloc(&nod1, &regnode);
88574a4d8c2SCharles.Forsyth 		gmove(&nod, &nod1);
88674a4d8c2SCharles.Forsyth 		gins(AFMOVL, &nod1, &fregnode0);
88774a4d8c2SCharles.Forsyth 		gins(ACMPL, &nod, nodconst(0));
88874a4d8c2SCharles.Forsyth 		gins(AJGE, Z, Z);
88974a4d8c2SCharles.Forsyth 		p1 = p;
89074a4d8c2SCharles.Forsyth 		gins(AFADDD, nodfconst(4294967296.), &fregnode0);
89174a4d8c2SCharles.Forsyth 		patch(p1, pc);
89274a4d8c2SCharles.Forsyth 		regfree(&nod);
89374a4d8c2SCharles.Forsyth 		return;
89474a4d8c2SCharles.Forsyth 
89574a4d8c2SCharles.Forsyth /*
89674a4d8c2SCharles.Forsyth  * fix to float
89774a4d8c2SCharles.Forsyth  */
89874a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TFLOAT):
89974a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TFLOAT):
90074a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TFLOAT):
90174a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TFLOAT):
90274a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TFLOAT):
90374a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TFLOAT):
90474a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TFLOAT):
90574a4d8c2SCharles.Forsyth 
90674a4d8c2SCharles.Forsyth 	case CASE(	TCHAR,	TDOUBLE):
90774a4d8c2SCharles.Forsyth 	case CASE(	TUCHAR,	TDOUBLE):
90874a4d8c2SCharles.Forsyth 	case CASE(	TSHORT,	TDOUBLE):
90974a4d8c2SCharles.Forsyth 	case CASE(	TUSHORT,TDOUBLE):
91074a4d8c2SCharles.Forsyth 	case CASE(	TINT,	TDOUBLE):
91174a4d8c2SCharles.Forsyth 	case CASE(	TLONG,	TDOUBLE):
91274a4d8c2SCharles.Forsyth 	case CASE(	TIND,	TDOUBLE):
91374a4d8c2SCharles.Forsyth 		regsalloc(&nod, &regnode);
91474a4d8c2SCharles.Forsyth 		gmove(f, &nod);
91574a4d8c2SCharles.Forsyth 		gins(AFMOVL, &nod, &fregnode0);
91674a4d8c2SCharles.Forsyth 		return;
91774a4d8c2SCharles.Forsyth 
91874a4d8c2SCharles.Forsyth /*
91974a4d8c2SCharles.Forsyth  * float to float
92074a4d8c2SCharles.Forsyth  */
92174a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TFLOAT):
92274a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TFLOAT):
92374a4d8c2SCharles.Forsyth 
92474a4d8c2SCharles.Forsyth 	case CASE(	TFLOAT,	TDOUBLE):
92574a4d8c2SCharles.Forsyth 	case CASE(	TDOUBLE,TDOUBLE):
92674a4d8c2SCharles.Forsyth 		a = AFMOVD;	break;
92774a4d8c2SCharles.Forsyth 	}
92874a4d8c2SCharles.Forsyth 	if(a == AMOVL || a == AFMOVD)
92974a4d8c2SCharles.Forsyth 	if(samaddr(f, t))
93074a4d8c2SCharles.Forsyth 		return;
93174a4d8c2SCharles.Forsyth 	gins(a, f, t);
93274a4d8c2SCharles.Forsyth }
93374a4d8c2SCharles.Forsyth 
93474a4d8c2SCharles.Forsyth void
doindex(Node * n)93574a4d8c2SCharles.Forsyth doindex(Node *n)
93674a4d8c2SCharles.Forsyth {
93774a4d8c2SCharles.Forsyth 	Node nod, nod1;
93874a4d8c2SCharles.Forsyth 	long v;
93974a4d8c2SCharles.Forsyth 
94074a4d8c2SCharles.Forsyth if(debug['Y'])
94174a4d8c2SCharles.Forsyth prtree(n, "index");
94274a4d8c2SCharles.Forsyth 
94374a4d8c2SCharles.Forsyth if(n->left->complex >= FNX)
94474a4d8c2SCharles.Forsyth print("botch in doindex\n");
94574a4d8c2SCharles.Forsyth 
94674a4d8c2SCharles.Forsyth 	regalloc(&nod, &regnode, Z);
94774a4d8c2SCharles.Forsyth 	v = constnode.vconst;
94874a4d8c2SCharles.Forsyth 	cgen(n->right, &nod);
94974a4d8c2SCharles.Forsyth 	idx.ptr = D_NONE;
95074a4d8c2SCharles.Forsyth 	if(n->left->op == OCONST)
95174a4d8c2SCharles.Forsyth 		idx.ptr = D_CONST;
95274a4d8c2SCharles.Forsyth 	else if(n->left->op == OREGISTER)
953c0927006Sforsyth //	else if(n->left->op == OREGISTER && typeil[n->left->type->etype])
95474a4d8c2SCharles.Forsyth 		idx.ptr = n->left->reg;
95574a4d8c2SCharles.Forsyth 	else if(n->left->op != OADDR) {
95674a4d8c2SCharles.Forsyth 		reg[D_BP]++;	// cant be used as a base
95774a4d8c2SCharles.Forsyth 		regalloc(&nod1, &regnode, Z);
95874a4d8c2SCharles.Forsyth 		cgen(n->left, &nod1);
95974a4d8c2SCharles.Forsyth 		idx.ptr = nod1.reg;
96074a4d8c2SCharles.Forsyth 		regfree(&nod1);
96174a4d8c2SCharles.Forsyth 		reg[D_BP]--;
96274a4d8c2SCharles.Forsyth 	}
96374a4d8c2SCharles.Forsyth 	idx.reg = nod.reg;
96474a4d8c2SCharles.Forsyth 	regfree(&nod);
96574a4d8c2SCharles.Forsyth 	constnode.vconst = v;
96674a4d8c2SCharles.Forsyth }
96774a4d8c2SCharles.Forsyth 
96874a4d8c2SCharles.Forsyth void
gins(int a,Node * f,Node * t)96974a4d8c2SCharles.Forsyth gins(int a, Node *f, Node *t)
97074a4d8c2SCharles.Forsyth {
97174a4d8c2SCharles.Forsyth 
97274a4d8c2SCharles.Forsyth 	if(f != Z && f->op == OINDEX)
97374a4d8c2SCharles.Forsyth 		doindex(f);
97474a4d8c2SCharles.Forsyth 	if(t != Z && t->op == OINDEX)
97574a4d8c2SCharles.Forsyth 		doindex(t);
97674a4d8c2SCharles.Forsyth 	nextpc();
97774a4d8c2SCharles.Forsyth 	p->as = a;
97874a4d8c2SCharles.Forsyth 	if(f != Z)
97974a4d8c2SCharles.Forsyth 		naddr(f, &p->from);
98074a4d8c2SCharles.Forsyth 	if(t != Z)
98174a4d8c2SCharles.Forsyth 		naddr(t, &p->to);
98274a4d8c2SCharles.Forsyth 	if(debug['g'])
98374a4d8c2SCharles.Forsyth 		print("%P\n", p);
98474a4d8c2SCharles.Forsyth }
98574a4d8c2SCharles.Forsyth 
98674a4d8c2SCharles.Forsyth void
fgopcode(int o,Node * f,Node * t,int pop,int rev)98774a4d8c2SCharles.Forsyth fgopcode(int o, Node *f, Node *t, int pop, int rev)
98874a4d8c2SCharles.Forsyth {
98974a4d8c2SCharles.Forsyth 	int a, et;
99074a4d8c2SCharles.Forsyth 	Node nod;
99174a4d8c2SCharles.Forsyth 
99274a4d8c2SCharles.Forsyth 	et = TLONG;
99374a4d8c2SCharles.Forsyth 	if(f != Z && f->type != T)
99474a4d8c2SCharles.Forsyth 		et = f->type->etype;
99574a4d8c2SCharles.Forsyth 	if(!typefd[et]) {
99674a4d8c2SCharles.Forsyth 		diag(f, "fop: integer %O", o);
99774a4d8c2SCharles.Forsyth 		return;
99874a4d8c2SCharles.Forsyth 	}
99974a4d8c2SCharles.Forsyth 	if(debug['M']) {
100074a4d8c2SCharles.Forsyth 		if(t != Z && t->type != T)
100174a4d8c2SCharles.Forsyth 			print("gop: %O %O-%s Z\n", o, f->op, tnames[et]);
100274a4d8c2SCharles.Forsyth 		else
100374a4d8c2SCharles.Forsyth 			print("gop: %O %O-%s %O-%s\n", o,
100474a4d8c2SCharles.Forsyth 				f->op, tnames[et], t->op, tnames[t->type->etype]);
100574a4d8c2SCharles.Forsyth 	}
100674a4d8c2SCharles.Forsyth 	a = AGOK;
100774a4d8c2SCharles.Forsyth 	switch(o) {
100874a4d8c2SCharles.Forsyth 
100974a4d8c2SCharles.Forsyth 	case OASADD:
101074a4d8c2SCharles.Forsyth 	case OADD:
101174a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
101274a4d8c2SCharles.Forsyth 			a = AFADDF;
101374a4d8c2SCharles.Forsyth 		else
1014*45a20ab7Sforsyth 		if(et == TDOUBLE) {
101574a4d8c2SCharles.Forsyth 			a = AFADDD;
101674a4d8c2SCharles.Forsyth 			if(pop)
101774a4d8c2SCharles.Forsyth 				a = AFADDDP;
101874a4d8c2SCharles.Forsyth 		}
101974a4d8c2SCharles.Forsyth 		break;
102074a4d8c2SCharles.Forsyth 
102174a4d8c2SCharles.Forsyth 	case OASSUB:
102274a4d8c2SCharles.Forsyth 	case OSUB:
102374a4d8c2SCharles.Forsyth 		if(et == TFLOAT) {
102474a4d8c2SCharles.Forsyth 			a = AFSUBF;
102574a4d8c2SCharles.Forsyth 			if(rev)
102674a4d8c2SCharles.Forsyth 				a = AFSUBRF;
102774a4d8c2SCharles.Forsyth 		} else
1028*45a20ab7Sforsyth 		if(et == TDOUBLE) {
102974a4d8c2SCharles.Forsyth 			a = AFSUBD;
103074a4d8c2SCharles.Forsyth 			if(pop)
103174a4d8c2SCharles.Forsyth 				a = AFSUBDP;
103274a4d8c2SCharles.Forsyth 			if(rev) {
103374a4d8c2SCharles.Forsyth 				a = AFSUBRD;
103474a4d8c2SCharles.Forsyth 				if(pop)
103574a4d8c2SCharles.Forsyth 					a = AFSUBRDP;
103674a4d8c2SCharles.Forsyth 			}
103774a4d8c2SCharles.Forsyth 		}
103874a4d8c2SCharles.Forsyth 		break;
103974a4d8c2SCharles.Forsyth 
104074a4d8c2SCharles.Forsyth 	case OASMUL:
104174a4d8c2SCharles.Forsyth 	case OMUL:
104274a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
104374a4d8c2SCharles.Forsyth 			a = AFMULF;
104474a4d8c2SCharles.Forsyth 		else
1045*45a20ab7Sforsyth 		if(et == TDOUBLE) {
104674a4d8c2SCharles.Forsyth 			a = AFMULD;
104774a4d8c2SCharles.Forsyth 			if(pop)
104874a4d8c2SCharles.Forsyth 				a = AFMULDP;
104974a4d8c2SCharles.Forsyth 		}
105074a4d8c2SCharles.Forsyth 		break;
105174a4d8c2SCharles.Forsyth 
105274a4d8c2SCharles.Forsyth 	case OASMOD:
105374a4d8c2SCharles.Forsyth 	case OMOD:
105474a4d8c2SCharles.Forsyth 	case OASDIV:
105574a4d8c2SCharles.Forsyth 	case ODIV:
105674a4d8c2SCharles.Forsyth 		if(et == TFLOAT) {
105774a4d8c2SCharles.Forsyth 			a = AFDIVF;
105874a4d8c2SCharles.Forsyth 			if(rev)
105974a4d8c2SCharles.Forsyth 				a = AFDIVRF;
106074a4d8c2SCharles.Forsyth 		} else
1061*45a20ab7Sforsyth 		if(et == TDOUBLE) {
106274a4d8c2SCharles.Forsyth 			a = AFDIVD;
106374a4d8c2SCharles.Forsyth 			if(pop)
106474a4d8c2SCharles.Forsyth 				a = AFDIVDP;
106574a4d8c2SCharles.Forsyth 			if(rev) {
106674a4d8c2SCharles.Forsyth 				a = AFDIVRD;
106774a4d8c2SCharles.Forsyth 				if(pop)
106874a4d8c2SCharles.Forsyth 					a = AFDIVRDP;
106974a4d8c2SCharles.Forsyth 			}
107074a4d8c2SCharles.Forsyth 		}
107174a4d8c2SCharles.Forsyth 		break;
107274a4d8c2SCharles.Forsyth 
107374a4d8c2SCharles.Forsyth 	case OEQ:
107474a4d8c2SCharles.Forsyth 	case ONE:
107574a4d8c2SCharles.Forsyth 	case OLT:
107674a4d8c2SCharles.Forsyth 	case OLE:
107774a4d8c2SCharles.Forsyth 	case OGE:
107874a4d8c2SCharles.Forsyth 	case OGT:
107974a4d8c2SCharles.Forsyth 		pop += rev;
108074a4d8c2SCharles.Forsyth 		if(et == TFLOAT) {
108174a4d8c2SCharles.Forsyth 			a = AFCOMF;
108274a4d8c2SCharles.Forsyth 			if(pop) {
108374a4d8c2SCharles.Forsyth 				a = AFCOMFP;
108474a4d8c2SCharles.Forsyth 				if(pop > 1)
108574a4d8c2SCharles.Forsyth 					a = AGOK;
108674a4d8c2SCharles.Forsyth 			}
108774a4d8c2SCharles.Forsyth 		} else
1088*45a20ab7Sforsyth 		if(et == TDOUBLE) {
108974a4d8c2SCharles.Forsyth 			a = AFCOMF;
109074a4d8c2SCharles.Forsyth 			if(pop) {
109174a4d8c2SCharles.Forsyth 				a = AFCOMDP;
109274a4d8c2SCharles.Forsyth 				if(pop > 1)
109374a4d8c2SCharles.Forsyth 					a = AFCOMDPP;
109474a4d8c2SCharles.Forsyth 			}
109574a4d8c2SCharles.Forsyth 		}
109674a4d8c2SCharles.Forsyth 		gins(a, f, t);
109774a4d8c2SCharles.Forsyth 		regalloc(&nod, &regnode, Z);
109874a4d8c2SCharles.Forsyth 		if(nod.reg != D_AX) {
109974a4d8c2SCharles.Forsyth 			regfree(&nod);
110074a4d8c2SCharles.Forsyth 			nod.reg = D_AX;
110174a4d8c2SCharles.Forsyth 			gins(APUSHL, &nod, Z);
110274a4d8c2SCharles.Forsyth 			gins(AWAIT, Z, Z);
110374a4d8c2SCharles.Forsyth 			gins(AFSTSW, Z, &nod);
110474a4d8c2SCharles.Forsyth 			gins(ASAHF, Z, Z);
110574a4d8c2SCharles.Forsyth 			gins(APOPL, Z, &nod);
110674a4d8c2SCharles.Forsyth 		} else {
110774a4d8c2SCharles.Forsyth 			gins(AWAIT, Z, Z);
110874a4d8c2SCharles.Forsyth 			gins(AFSTSW, Z, &nod);
110974a4d8c2SCharles.Forsyth 			gins(ASAHF, Z, Z);
111074a4d8c2SCharles.Forsyth 			regfree(&nod);
111174a4d8c2SCharles.Forsyth 		}
111274a4d8c2SCharles.Forsyth 		switch(o) {
111374a4d8c2SCharles.Forsyth 		case OEQ:	a = AJEQ; break;
111474a4d8c2SCharles.Forsyth 		case ONE:	a = AJNE; break;
111574a4d8c2SCharles.Forsyth 		case OLT:	a = AJCS; break;
111674a4d8c2SCharles.Forsyth 		case OLE:	a = AJLS; break;
111774a4d8c2SCharles.Forsyth 		case OGE:	a = AJCC; break;
111874a4d8c2SCharles.Forsyth 		case OGT:	a = AJHI; break;
111974a4d8c2SCharles.Forsyth 		}
112074a4d8c2SCharles.Forsyth 		gins(a, Z, Z);
112174a4d8c2SCharles.Forsyth 		return;
112274a4d8c2SCharles.Forsyth 	}
112374a4d8c2SCharles.Forsyth 	if(a == AGOK)
112474a4d8c2SCharles.Forsyth 		diag(Z, "bad in gopcode %O", o);
112574a4d8c2SCharles.Forsyth 	gins(a, f, t);
112674a4d8c2SCharles.Forsyth }
112774a4d8c2SCharles.Forsyth 
112874a4d8c2SCharles.Forsyth void
gopcode(int o,Type * ty,Node * f,Node * t)112974a4d8c2SCharles.Forsyth gopcode(int o, Type *ty, Node *f, Node *t)
113074a4d8c2SCharles.Forsyth {
113174a4d8c2SCharles.Forsyth 	int a, et;
113274a4d8c2SCharles.Forsyth 
113374a4d8c2SCharles.Forsyth 	et = TLONG;
113474a4d8c2SCharles.Forsyth 	if(ty != T)
113574a4d8c2SCharles.Forsyth 		et = ty->etype;
113674a4d8c2SCharles.Forsyth 	if(typefd[et] && o != OADDR && o != OFUNC) {
113774a4d8c2SCharles.Forsyth 		diag(f, "gop: float %O", o);
113874a4d8c2SCharles.Forsyth 		return;
113974a4d8c2SCharles.Forsyth 	}
114074a4d8c2SCharles.Forsyth 	if(debug['M']) {
114174a4d8c2SCharles.Forsyth 		if(f != Z && f->type != T)
114274a4d8c2SCharles.Forsyth 			print("gop: %O %O[%s],", o, f->op, tnames[et]);
114374a4d8c2SCharles.Forsyth 		else
114474a4d8c2SCharles.Forsyth 			print("gop: %O Z,", o);
114574a4d8c2SCharles.Forsyth 		if(t != Z && t->type != T)
114674a4d8c2SCharles.Forsyth 			print("%O[%s]\n", t->op, tnames[t->type->etype]);
114774a4d8c2SCharles.Forsyth 		else
114874a4d8c2SCharles.Forsyth 			print("Z\n");
114974a4d8c2SCharles.Forsyth 	}
115074a4d8c2SCharles.Forsyth 	a = AGOK;
115174a4d8c2SCharles.Forsyth 	switch(o) {
115274a4d8c2SCharles.Forsyth 	case OCOM:
115374a4d8c2SCharles.Forsyth 		a = ANOTL;
115474a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
115574a4d8c2SCharles.Forsyth 			a = ANOTB;
115674a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
115774a4d8c2SCharles.Forsyth 			a = ANOTW;
115874a4d8c2SCharles.Forsyth 		break;
115974a4d8c2SCharles.Forsyth 
116074a4d8c2SCharles.Forsyth 	case ONEG:
116174a4d8c2SCharles.Forsyth 		a = ANEGL;
116274a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
116374a4d8c2SCharles.Forsyth 			a = ANEGB;
116474a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
116574a4d8c2SCharles.Forsyth 			a = ANEGW;
116674a4d8c2SCharles.Forsyth 		break;
116774a4d8c2SCharles.Forsyth 
116874a4d8c2SCharles.Forsyth 	case OADDR:
116974a4d8c2SCharles.Forsyth 		a = ALEAL;
117074a4d8c2SCharles.Forsyth 		break;
117174a4d8c2SCharles.Forsyth 
117274a4d8c2SCharles.Forsyth 	case OASADD:
117374a4d8c2SCharles.Forsyth 	case OADD:
117474a4d8c2SCharles.Forsyth 		a = AADDL;
117574a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
117674a4d8c2SCharles.Forsyth 			a = AADDB;
117774a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
117874a4d8c2SCharles.Forsyth 			a = AADDW;
117974a4d8c2SCharles.Forsyth 		break;
118074a4d8c2SCharles.Forsyth 
118174a4d8c2SCharles.Forsyth 	case OASSUB:
118274a4d8c2SCharles.Forsyth 	case OSUB:
118374a4d8c2SCharles.Forsyth 		a = ASUBL;
118474a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
118574a4d8c2SCharles.Forsyth 			a = ASUBB;
118674a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
118774a4d8c2SCharles.Forsyth 			a = ASUBW;
118874a4d8c2SCharles.Forsyth 		break;
118974a4d8c2SCharles.Forsyth 
119074a4d8c2SCharles.Forsyth 	case OASOR:
119174a4d8c2SCharles.Forsyth 	case OOR:
119274a4d8c2SCharles.Forsyth 		a = AORL;
119374a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
119474a4d8c2SCharles.Forsyth 			a = AORB;
119574a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
119674a4d8c2SCharles.Forsyth 			a = AORW;
119774a4d8c2SCharles.Forsyth 		break;
119874a4d8c2SCharles.Forsyth 
119974a4d8c2SCharles.Forsyth 	case OASAND:
120074a4d8c2SCharles.Forsyth 	case OAND:
120174a4d8c2SCharles.Forsyth 		a = AANDL;
120274a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
120374a4d8c2SCharles.Forsyth 			a = AANDB;
120474a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
120574a4d8c2SCharles.Forsyth 			a = AANDW;
120674a4d8c2SCharles.Forsyth 		break;
120774a4d8c2SCharles.Forsyth 
120874a4d8c2SCharles.Forsyth 	case OASXOR:
120974a4d8c2SCharles.Forsyth 	case OXOR:
121074a4d8c2SCharles.Forsyth 		a = AXORL;
121174a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
121274a4d8c2SCharles.Forsyth 			a = AXORB;
121374a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
121474a4d8c2SCharles.Forsyth 			a = AXORW;
121574a4d8c2SCharles.Forsyth 		break;
121674a4d8c2SCharles.Forsyth 
121774a4d8c2SCharles.Forsyth 	case OASLSHR:
121874a4d8c2SCharles.Forsyth 	case OLSHR:
121974a4d8c2SCharles.Forsyth 		a = ASHRL;
122074a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
122174a4d8c2SCharles.Forsyth 			a = ASHRB;
122274a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
122374a4d8c2SCharles.Forsyth 			a = ASHRW;
122474a4d8c2SCharles.Forsyth 		break;
122574a4d8c2SCharles.Forsyth 
122674a4d8c2SCharles.Forsyth 	case OASASHR:
122774a4d8c2SCharles.Forsyth 	case OASHR:
122874a4d8c2SCharles.Forsyth 		a = ASARL;
122974a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
123074a4d8c2SCharles.Forsyth 			a = ASARB;
123174a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
123274a4d8c2SCharles.Forsyth 			a = ASARW;
123374a4d8c2SCharles.Forsyth 		break;
123474a4d8c2SCharles.Forsyth 
123574a4d8c2SCharles.Forsyth 	case OASASHL:
123674a4d8c2SCharles.Forsyth 	case OASHL:
123774a4d8c2SCharles.Forsyth 		a = ASALL;
123874a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
123974a4d8c2SCharles.Forsyth 			a = ASALB;
124074a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
124174a4d8c2SCharles.Forsyth 			a = ASALW;
124274a4d8c2SCharles.Forsyth 		break;
124374a4d8c2SCharles.Forsyth 
124474a4d8c2SCharles.Forsyth 	case OFUNC:
124574a4d8c2SCharles.Forsyth 		a = ACALL;
124674a4d8c2SCharles.Forsyth 		break;
124774a4d8c2SCharles.Forsyth 
124874a4d8c2SCharles.Forsyth 	case OASMUL:
124974a4d8c2SCharles.Forsyth 	case OMUL:
125074a4d8c2SCharles.Forsyth 		if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
125174a4d8c2SCharles.Forsyth 			t = Z;
125274a4d8c2SCharles.Forsyth 		a = AIMULL;
125374a4d8c2SCharles.Forsyth 		break;
125474a4d8c2SCharles.Forsyth 
125574a4d8c2SCharles.Forsyth 	case OASMOD:
125674a4d8c2SCharles.Forsyth 	case OMOD:
125774a4d8c2SCharles.Forsyth 	case OASDIV:
125874a4d8c2SCharles.Forsyth 	case ODIV:
125974a4d8c2SCharles.Forsyth 		a = AIDIVL;
126074a4d8c2SCharles.Forsyth 		break;
126174a4d8c2SCharles.Forsyth 
126274a4d8c2SCharles.Forsyth 	case OASLMUL:
126374a4d8c2SCharles.Forsyth 	case OLMUL:
126474a4d8c2SCharles.Forsyth 		a = AMULL;
126574a4d8c2SCharles.Forsyth 		break;
126674a4d8c2SCharles.Forsyth 
126774a4d8c2SCharles.Forsyth 	case OASLMOD:
126874a4d8c2SCharles.Forsyth 	case OLMOD:
126974a4d8c2SCharles.Forsyth 	case OASLDIV:
127074a4d8c2SCharles.Forsyth 	case OLDIV:
127174a4d8c2SCharles.Forsyth 		a = ADIVL;
127274a4d8c2SCharles.Forsyth 		break;
127374a4d8c2SCharles.Forsyth 
127474a4d8c2SCharles.Forsyth 	case OEQ:
127574a4d8c2SCharles.Forsyth 	case ONE:
127674a4d8c2SCharles.Forsyth 	case OLT:
127774a4d8c2SCharles.Forsyth 	case OLE:
127874a4d8c2SCharles.Forsyth 	case OGE:
127974a4d8c2SCharles.Forsyth 	case OGT:
128074a4d8c2SCharles.Forsyth 	case OLO:
128174a4d8c2SCharles.Forsyth 	case OLS:
128274a4d8c2SCharles.Forsyth 	case OHS:
128374a4d8c2SCharles.Forsyth 	case OHI:
128474a4d8c2SCharles.Forsyth 		a = ACMPL;
128574a4d8c2SCharles.Forsyth 		if(et == TCHAR || et == TUCHAR)
128674a4d8c2SCharles.Forsyth 			a = ACMPB;
128774a4d8c2SCharles.Forsyth 		if(et == TSHORT || et == TUSHORT)
128874a4d8c2SCharles.Forsyth 			a = ACMPW;
128974a4d8c2SCharles.Forsyth 		gins(a, f, t);
129074a4d8c2SCharles.Forsyth 		switch(o) {
129174a4d8c2SCharles.Forsyth 		case OEQ:	a = AJEQ; break;
129274a4d8c2SCharles.Forsyth 		case ONE:	a = AJNE; break;
129374a4d8c2SCharles.Forsyth 		case OLT:	a = AJLT; break;
129474a4d8c2SCharles.Forsyth 		case OLE:	a = AJLE; break;
129574a4d8c2SCharles.Forsyth 		case OGE:	a = AJGE; break;
129674a4d8c2SCharles.Forsyth 		case OGT:	a = AJGT; break;
129774a4d8c2SCharles.Forsyth 		case OLO:	a = AJCS; break;
129874a4d8c2SCharles.Forsyth 		case OLS:	a = AJLS; break;
129974a4d8c2SCharles.Forsyth 		case OHS:	a = AJCC; break;
130074a4d8c2SCharles.Forsyth 		case OHI:	a = AJHI; break;
130174a4d8c2SCharles.Forsyth 		}
130274a4d8c2SCharles.Forsyth 		gins(a, Z, Z);
130374a4d8c2SCharles.Forsyth 		return;
130474a4d8c2SCharles.Forsyth 	}
130574a4d8c2SCharles.Forsyth 	if(a == AGOK)
130674a4d8c2SCharles.Forsyth 		diag(Z, "bad in gopcode %O", o);
130774a4d8c2SCharles.Forsyth 	gins(a, f, t);
130874a4d8c2SCharles.Forsyth }
130974a4d8c2SCharles.Forsyth 
131074a4d8c2SCharles.Forsyth int
samaddr(Node * f,Node * t)131174a4d8c2SCharles.Forsyth samaddr(Node *f, Node *t)
131274a4d8c2SCharles.Forsyth {
131374a4d8c2SCharles.Forsyth 
131474a4d8c2SCharles.Forsyth 	if(f->op != t->op)
131574a4d8c2SCharles.Forsyth 		return 0;
131674a4d8c2SCharles.Forsyth 	switch(f->op) {
131774a4d8c2SCharles.Forsyth 
131874a4d8c2SCharles.Forsyth 	case OREGISTER:
131974a4d8c2SCharles.Forsyth 		if(f->reg != t->reg)
132074a4d8c2SCharles.Forsyth 			break;
132174a4d8c2SCharles.Forsyth 		return 1;
132274a4d8c2SCharles.Forsyth 	}
132374a4d8c2SCharles.Forsyth 	return 0;
132474a4d8c2SCharles.Forsyth }
132574a4d8c2SCharles.Forsyth 
132674a4d8c2SCharles.Forsyth void
gbranch(int o)132774a4d8c2SCharles.Forsyth gbranch(int o)
132874a4d8c2SCharles.Forsyth {
132974a4d8c2SCharles.Forsyth 	int a;
133074a4d8c2SCharles.Forsyth 
133174a4d8c2SCharles.Forsyth 	a = AGOK;
133274a4d8c2SCharles.Forsyth 	switch(o) {
133374a4d8c2SCharles.Forsyth 	case ORETURN:
133474a4d8c2SCharles.Forsyth 		a = ARET;
133574a4d8c2SCharles.Forsyth 		break;
133674a4d8c2SCharles.Forsyth 	case OGOTO:
133774a4d8c2SCharles.Forsyth 		a = AJMP;
133874a4d8c2SCharles.Forsyth 		break;
133974a4d8c2SCharles.Forsyth 	}
134074a4d8c2SCharles.Forsyth 	nextpc();
134174a4d8c2SCharles.Forsyth 	if(a == AGOK) {
134274a4d8c2SCharles.Forsyth 		diag(Z, "bad in gbranch %O",  o);
134374a4d8c2SCharles.Forsyth 		nextpc();
134474a4d8c2SCharles.Forsyth 	}
134574a4d8c2SCharles.Forsyth 	p->as = a;
134674a4d8c2SCharles.Forsyth }
134774a4d8c2SCharles.Forsyth 
134874a4d8c2SCharles.Forsyth void
patch(Prog * op,long pc)134974a4d8c2SCharles.Forsyth patch(Prog *op, long pc)
135074a4d8c2SCharles.Forsyth {
135174a4d8c2SCharles.Forsyth 
135274a4d8c2SCharles.Forsyth 	op->to.offset = pc;
135374a4d8c2SCharles.Forsyth 	op->to.type = D_BRANCH;
135474a4d8c2SCharles.Forsyth }
135574a4d8c2SCharles.Forsyth 
135674a4d8c2SCharles.Forsyth void
gpseudo(int a,Sym * s,Node * n)135774a4d8c2SCharles.Forsyth gpseudo(int a, Sym *s, Node *n)
135874a4d8c2SCharles.Forsyth {
135974a4d8c2SCharles.Forsyth 
136074a4d8c2SCharles.Forsyth 	nextpc();
136174a4d8c2SCharles.Forsyth 	p->as = a;
136274a4d8c2SCharles.Forsyth 	p->from.type = D_EXTERN;
136374a4d8c2SCharles.Forsyth 	p->from.sym = s;
136474a4d8c2SCharles.Forsyth 	p->from.scale = (profileflg ? 0 : NOPROF);
136574a4d8c2SCharles.Forsyth 	if(s->class == CSTATIC)
136674a4d8c2SCharles.Forsyth 		p->from.type = D_STATIC;
136774a4d8c2SCharles.Forsyth 	naddr(n, &p->to);
136874a4d8c2SCharles.Forsyth 	if(a == ADATA || a == AGLOBL)
136974a4d8c2SCharles.Forsyth 		pc--;
137074a4d8c2SCharles.Forsyth }
137174a4d8c2SCharles.Forsyth 
137274a4d8c2SCharles.Forsyth int
sconst(Node * n)137374a4d8c2SCharles.Forsyth sconst(Node *n)
137474a4d8c2SCharles.Forsyth {
137574a4d8c2SCharles.Forsyth 	long v;
137674a4d8c2SCharles.Forsyth 
137774a4d8c2SCharles.Forsyth 	if(n->op == OCONST && !typefd[n->type->etype]) {
137874a4d8c2SCharles.Forsyth 		v = n->vconst;
137974a4d8c2SCharles.Forsyth 		if(v >= -32766L && v < 32766L)
138074a4d8c2SCharles.Forsyth 			return 1;
138174a4d8c2SCharles.Forsyth 	}
138274a4d8c2SCharles.Forsyth 	return 0;
138374a4d8c2SCharles.Forsyth }
138474a4d8c2SCharles.Forsyth 
138574a4d8c2SCharles.Forsyth long
exreg(Type * t)138674a4d8c2SCharles.Forsyth exreg(Type *t)
138774a4d8c2SCharles.Forsyth {
138874a4d8c2SCharles.Forsyth 
1389*45a20ab7Sforsyth 	int o;
1390*45a20ab7Sforsyth 
1391*45a20ab7Sforsyth 	if(typechlp[t->etype]){
1392*45a20ab7Sforsyth 		if(exregoffset >= 32)
1393*45a20ab7Sforsyth 			return 0;
1394*45a20ab7Sforsyth 		o = exregoffset;
1395*45a20ab7Sforsyth 		exregoffset += 4;
1396*45a20ab7Sforsyth 		return o+1;	/* +1 to avoid 0 == failure; naddr case OEXREG will -1. */
1397*45a20ab7Sforsyth 	}
139874a4d8c2SCharles.Forsyth 	return 0;
139974a4d8c2SCharles.Forsyth }
140074a4d8c2SCharles.Forsyth 
140174a4d8c2SCharles.Forsyth schar	ewidth[NTYPE] =
140274a4d8c2SCharles.Forsyth {
140374a4d8c2SCharles.Forsyth 	-1,		/*[TXXX]*/
140474a4d8c2SCharles.Forsyth 	SZ_CHAR,	/*[TCHAR]*/
140574a4d8c2SCharles.Forsyth 	SZ_CHAR,	/*[TUCHAR]*/
140674a4d8c2SCharles.Forsyth 	SZ_SHORT,	/*[TSHORT]*/
140774a4d8c2SCharles.Forsyth 	SZ_SHORT,	/*[TUSHORT]*/
140874a4d8c2SCharles.Forsyth 	SZ_INT,		/*[TINT]*/
140974a4d8c2SCharles.Forsyth 	SZ_INT,		/*[TUINT]*/
141074a4d8c2SCharles.Forsyth 	SZ_LONG,	/*[TLONG]*/
141174a4d8c2SCharles.Forsyth 	SZ_LONG,	/*[TULONG]*/
141274a4d8c2SCharles.Forsyth 	SZ_VLONG,	/*[TVLONG]*/
141374a4d8c2SCharles.Forsyth 	SZ_VLONG,	/*[TUVLONG]*/
141474a4d8c2SCharles.Forsyth 	SZ_FLOAT,	/*[TFLOAT]*/
141574a4d8c2SCharles.Forsyth 	SZ_DOUBLE,	/*[TDOUBLE]*/
141674a4d8c2SCharles.Forsyth 	SZ_IND,		/*[TIND]*/
141774a4d8c2SCharles.Forsyth 	0,		/*[TFUNC]*/
141874a4d8c2SCharles.Forsyth 	-1,		/*[TARRAY]*/
141974a4d8c2SCharles.Forsyth 	0,		/*[TVOID]*/
142074a4d8c2SCharles.Forsyth 	-1,		/*[TSTRUCT]*/
142174a4d8c2SCharles.Forsyth 	-1,		/*[TUNION]*/
142274a4d8c2SCharles.Forsyth 	SZ_INT,		/*[TENUM]*/
142374a4d8c2SCharles.Forsyth };
142474a4d8c2SCharles.Forsyth long	ncast[NTYPE] =
142574a4d8c2SCharles.Forsyth {
142674a4d8c2SCharles.Forsyth 	0,				/*[TXXX]*/
142774a4d8c2SCharles.Forsyth 	BCHAR|BUCHAR,			/*[TCHAR]*/
142874a4d8c2SCharles.Forsyth 	BCHAR|BUCHAR,			/*[TUCHAR]*/
142974a4d8c2SCharles.Forsyth 	BSHORT|BUSHORT,			/*[TSHORT]*/
143074a4d8c2SCharles.Forsyth 	BSHORT|BUSHORT,			/*[TUSHORT]*/
143174a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TINT]*/
143274a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TUINT]*/
143374a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TLONG]*/
143474a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/*[TULONG]*/
143574a4d8c2SCharles.Forsyth 	BVLONG|BUVLONG,			/*[TVLONG]*/
143674a4d8c2SCharles.Forsyth 	BVLONG|BUVLONG,			/*[TUVLONG]*/
143774a4d8c2SCharles.Forsyth 	BFLOAT,				/*[TFLOAT]*/
143874a4d8c2SCharles.Forsyth 	BDOUBLE,			/*[TDOUBLE]*/
143974a4d8c2SCharles.Forsyth 	BLONG|BULONG|BIND,		/*[TIND]*/
144074a4d8c2SCharles.Forsyth 	0,				/*[TFUNC]*/
144174a4d8c2SCharles.Forsyth 	0,				/*[TARRAY]*/
144274a4d8c2SCharles.Forsyth 	0,				/*[TVOID]*/
144374a4d8c2SCharles.Forsyth 	BSTRUCT,			/*[TSTRUCT]*/
144474a4d8c2SCharles.Forsyth 	BUNION,				/*[TUNION]*/
144574a4d8c2SCharles.Forsyth 	0,				/*[TENUM]*/
144674a4d8c2SCharles.Forsyth };
1447