xref: /inferno-os/utils/tc/txt.c (revision 45a20ab721a513710138340faff3d59a31c3e01e)
174a4d8c2SCharles.Forsyth #include "gc.h"
274a4d8c2SCharles.Forsyth 
374a4d8c2SCharles.Forsyth void
ginit(void)474a4d8c2SCharles.Forsyth ginit(void)
574a4d8c2SCharles.Forsyth {
674a4d8c2SCharles.Forsyth 	Type *t;
774a4d8c2SCharles.Forsyth 
874a4d8c2SCharles.Forsyth 	thechar = 't';
974a4d8c2SCharles.Forsyth 	thestring = "arm";
1074a4d8c2SCharles.Forsyth 	exregoffset = REGEXT;
1174a4d8c2SCharles.Forsyth 	exfregoffset = FREGEXT;
1274a4d8c2SCharles.Forsyth 	listinit();
1374a4d8c2SCharles.Forsyth 	nstring = 0;
1474a4d8c2SCharles.Forsyth 	mnstring = 0;
1574a4d8c2SCharles.Forsyth 	nrathole = 0;
1674a4d8c2SCharles.Forsyth 	pc = 0;
1774a4d8c2SCharles.Forsyth 	breakpc = -1;
1874a4d8c2SCharles.Forsyth 	continpc = -1;
1974a4d8c2SCharles.Forsyth 	cases = C;
2074a4d8c2SCharles.Forsyth 	firstp = P;
2174a4d8c2SCharles.Forsyth 	lastp = P;
2274a4d8c2SCharles.Forsyth 	tfield = types[TLONG];
2374a4d8c2SCharles.Forsyth 
2474a4d8c2SCharles.Forsyth 	zprog.link = P;
2574a4d8c2SCharles.Forsyth 	zprog.as = AGOK;
2674a4d8c2SCharles.Forsyth 	zprog.reg = NREG;
2774a4d8c2SCharles.Forsyth 	zprog.from.type = D_NONE;
2874a4d8c2SCharles.Forsyth 	zprog.from.name = D_NONE;
2974a4d8c2SCharles.Forsyth 	zprog.from.reg = NREG;
3074a4d8c2SCharles.Forsyth 	zprog.to = zprog.from;
3174a4d8c2SCharles.Forsyth 
3274a4d8c2SCharles.Forsyth 	regnode.op = OREGISTER;
3374a4d8c2SCharles.Forsyth 	regnode.class = CEXREG;
3474a4d8c2SCharles.Forsyth 	regnode.reg = REGTMPT;
3574a4d8c2SCharles.Forsyth 	regnode.complex = 0;
3674a4d8c2SCharles.Forsyth 	regnode.addable = 11;
3774a4d8c2SCharles.Forsyth 	regnode.type = types[TLONG];
3874a4d8c2SCharles.Forsyth 
3974a4d8c2SCharles.Forsyth 	constnode.op = OCONST;
4074a4d8c2SCharles.Forsyth 	constnode.class = CXXX;
4174a4d8c2SCharles.Forsyth 	constnode.complex = 0;
4274a4d8c2SCharles.Forsyth 	constnode.addable = 20;
4374a4d8c2SCharles.Forsyth 	constnode.type = types[TLONG];
4474a4d8c2SCharles.Forsyth 
4574a4d8c2SCharles.Forsyth 	fconstnode.op = OCONST;
4674a4d8c2SCharles.Forsyth 	fconstnode.class = CXXX;
4774a4d8c2SCharles.Forsyth 	fconstnode.complex = 0;
4874a4d8c2SCharles.Forsyth 	fconstnode.addable = 20;
4974a4d8c2SCharles.Forsyth 	fconstnode.type = types[TDOUBLE];
5074a4d8c2SCharles.Forsyth 
5174a4d8c2SCharles.Forsyth 	nodsafe = new(ONAME, Z, Z);
5274a4d8c2SCharles.Forsyth 	nodsafe->sym = slookup(".safe");
5374a4d8c2SCharles.Forsyth 	nodsafe->type = types[TINT];
5474a4d8c2SCharles.Forsyth 	nodsafe->etype = types[TINT]->etype;
5574a4d8c2SCharles.Forsyth 	nodsafe->class = CAUTO;
5674a4d8c2SCharles.Forsyth 	complex(nodsafe);
5774a4d8c2SCharles.Forsyth 
5874a4d8c2SCharles.Forsyth 	t = typ(TARRAY, types[TCHAR]);
5974a4d8c2SCharles.Forsyth 	symrathole = slookup(".rathole");
6074a4d8c2SCharles.Forsyth 	symrathole->class = CGLOBL;
6174a4d8c2SCharles.Forsyth 	symrathole->type = t;
6274a4d8c2SCharles.Forsyth 
6374a4d8c2SCharles.Forsyth 	nodrat = new(ONAME, Z, Z);
6474a4d8c2SCharles.Forsyth 	nodrat->sym = symrathole;
6574a4d8c2SCharles.Forsyth 	nodrat->type = types[TIND];
6674a4d8c2SCharles.Forsyth 	nodrat->etype = TVOID;
6774a4d8c2SCharles.Forsyth 	nodrat->class = CGLOBL;
6874a4d8c2SCharles.Forsyth 	complex(nodrat);
6974a4d8c2SCharles.Forsyth 	nodrat->type = t;
7074a4d8c2SCharles.Forsyth 
7174a4d8c2SCharles.Forsyth 	nodret = new(ONAME, Z, Z);
7274a4d8c2SCharles.Forsyth 	nodret->sym = slookup(".ret");
7374a4d8c2SCharles.Forsyth 	nodret->type = types[TIND];
7474a4d8c2SCharles.Forsyth 	nodret->etype = TIND;
7574a4d8c2SCharles.Forsyth 	nodret->class = CPARAM;
7674a4d8c2SCharles.Forsyth 	nodret = new(OIND, nodret, Z);
7774a4d8c2SCharles.Forsyth 	complex(nodret);
7874a4d8c2SCharles.Forsyth 
7974a4d8c2SCharles.Forsyth 	com64init();
8074a4d8c2SCharles.Forsyth 
8174a4d8c2SCharles.Forsyth 	memset(reg, 0, sizeof(reg));
8274a4d8c2SCharles.Forsyth 	// reg[REGTMPT] = 1;
8374a4d8c2SCharles.Forsyth }
8474a4d8c2SCharles.Forsyth 
8574a4d8c2SCharles.Forsyth void
gclean(void)8674a4d8c2SCharles.Forsyth gclean(void)
8774a4d8c2SCharles.Forsyth {
8874a4d8c2SCharles.Forsyth 	int i;
8974a4d8c2SCharles.Forsyth 	Sym *s;
9074a4d8c2SCharles.Forsyth 
9174a4d8c2SCharles.Forsyth 	for(i=0; i<NREG; i++)
9274a4d8c2SCharles.Forsyth 		if(reg[i])
9374a4d8c2SCharles.Forsyth 			diag(Z, "reg %d left allocated", i);
9474a4d8c2SCharles.Forsyth 	for(i=NREG; i<NREG+NFREG; i++)
9574a4d8c2SCharles.Forsyth 		if(reg[i])
9674a4d8c2SCharles.Forsyth 			diag(Z, "freg %d left allocated", i-NREG);
9774a4d8c2SCharles.Forsyth 	while(mnstring)
9874a4d8c2SCharles.Forsyth 		outstring("", 1L);
9974a4d8c2SCharles.Forsyth 	symstring->type->width = nstring;
10074a4d8c2SCharles.Forsyth 	symrathole->type->width = nrathole;
10174a4d8c2SCharles.Forsyth 	for(i=0; i<NHASH; i++)
10274a4d8c2SCharles.Forsyth 	for(s = hash[i]; s != S; s = s->link) {
10374a4d8c2SCharles.Forsyth 		if(s->type == T)
10474a4d8c2SCharles.Forsyth 			continue;
10574a4d8c2SCharles.Forsyth 		if(s->type->width == 0)
10674a4d8c2SCharles.Forsyth 			continue;
10774a4d8c2SCharles.Forsyth 		if(s->class != CGLOBL && s->class != CSTATIC)
10874a4d8c2SCharles.Forsyth 			continue;
10974a4d8c2SCharles.Forsyth 		if(s->type == types[TENUM])
11074a4d8c2SCharles.Forsyth 			continue;
11174a4d8c2SCharles.Forsyth 		gpseudo(AGLOBL, s, nodconst(s->type->width));
11274a4d8c2SCharles.Forsyth 	}
11374a4d8c2SCharles.Forsyth 	nextpc();
11474a4d8c2SCharles.Forsyth 	p->as = AEND;
11574a4d8c2SCharles.Forsyth 	outcode();
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth 
11874a4d8c2SCharles.Forsyth void
nextpc(void)11974a4d8c2SCharles.Forsyth nextpc(void)
12074a4d8c2SCharles.Forsyth {
12174a4d8c2SCharles.Forsyth 
12274a4d8c2SCharles.Forsyth 	p = alloc(sizeof(*p));
12374a4d8c2SCharles.Forsyth 	*p = zprog;
12474a4d8c2SCharles.Forsyth 	p->lineno = nearln;
12574a4d8c2SCharles.Forsyth 	pc++;
12674a4d8c2SCharles.Forsyth 	if(firstp == P) {
12774a4d8c2SCharles.Forsyth 		firstp = p;
12874a4d8c2SCharles.Forsyth 		lastp = p;
12974a4d8c2SCharles.Forsyth 		return;
13074a4d8c2SCharles.Forsyth 	}
13174a4d8c2SCharles.Forsyth 	lastp->link = p;
13274a4d8c2SCharles.Forsyth 	lastp = p;
13374a4d8c2SCharles.Forsyth }
13474a4d8c2SCharles.Forsyth 
13574a4d8c2SCharles.Forsyth void
gargs(Node * n,Node * tn1,Node * tn2)13674a4d8c2SCharles.Forsyth gargs(Node *n, Node *tn1, Node *tn2)
13774a4d8c2SCharles.Forsyth {
13874a4d8c2SCharles.Forsyth 	long regs;
13974a4d8c2SCharles.Forsyth 	Node fnxargs[20], *fnxp;
14074a4d8c2SCharles.Forsyth 
14174a4d8c2SCharles.Forsyth 	regs = cursafe;
14274a4d8c2SCharles.Forsyth 
14374a4d8c2SCharles.Forsyth 	fnxp = fnxargs;
14474a4d8c2SCharles.Forsyth 	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
14574a4d8c2SCharles.Forsyth 
14674a4d8c2SCharles.Forsyth 	curarg = 0;
14774a4d8c2SCharles.Forsyth 	fnxp = fnxargs;
14874a4d8c2SCharles.Forsyth 	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
14974a4d8c2SCharles.Forsyth 
15074a4d8c2SCharles.Forsyth 	cursafe = regs;
15174a4d8c2SCharles.Forsyth }
15274a4d8c2SCharles.Forsyth 
15374a4d8c2SCharles.Forsyth void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)15474a4d8c2SCharles.Forsyth garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
15574a4d8c2SCharles.Forsyth {
15674a4d8c2SCharles.Forsyth 	Node nod;
15774a4d8c2SCharles.Forsyth 
15874a4d8c2SCharles.Forsyth 	if(n == Z)
15974a4d8c2SCharles.Forsyth 		return;
16074a4d8c2SCharles.Forsyth 	if(n->op == OLIST) {
16174a4d8c2SCharles.Forsyth 		garg1(n->left, tn1, tn2, f, fnxp);
16274a4d8c2SCharles.Forsyth 		garg1(n->right, tn1, tn2, f, fnxp);
16374a4d8c2SCharles.Forsyth 		return;
16474a4d8c2SCharles.Forsyth 	}
16574a4d8c2SCharles.Forsyth 	if(f == 0) {
16674a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
16774a4d8c2SCharles.Forsyth 			regsalloc(*fnxp, n);
16874a4d8c2SCharles.Forsyth 			nod = znode;
16974a4d8c2SCharles.Forsyth 			nod.op = OAS;
17074a4d8c2SCharles.Forsyth 			nod.left = *fnxp;
17174a4d8c2SCharles.Forsyth 			nod.right = n;
17274a4d8c2SCharles.Forsyth 			nod.type = n->type;
17374a4d8c2SCharles.Forsyth 			cgen(&nod, Z);
17474a4d8c2SCharles.Forsyth 			(*fnxp)++;
17574a4d8c2SCharles.Forsyth 		}
17674a4d8c2SCharles.Forsyth 		return;
17774a4d8c2SCharles.Forsyth 	}
17874a4d8c2SCharles.Forsyth 	if(typesuv[n->type->etype]) {
17974a4d8c2SCharles.Forsyth 		regaalloc(tn2, n);
18074a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
18174a4d8c2SCharles.Forsyth 			sugen(*fnxp, tn2, n->type->width);
18274a4d8c2SCharles.Forsyth 			(*fnxp)++;
18374a4d8c2SCharles.Forsyth 		} else
18474a4d8c2SCharles.Forsyth 			sugen(n, tn2, n->type->width);
18574a4d8c2SCharles.Forsyth 		return;
18674a4d8c2SCharles.Forsyth 	}
18774a4d8c2SCharles.Forsyth 	if(REGARG >= 0 && curarg == 0 && typechlp[n->type->etype]) {
18874a4d8c2SCharles.Forsyth 		regaalloc1(tn1, n);
18974a4d8c2SCharles.Forsyth 		if(n->complex >= FNX) {
19074a4d8c2SCharles.Forsyth 			cgen(*fnxp, tn1);
19174a4d8c2SCharles.Forsyth 			(*fnxp)++;
19274a4d8c2SCharles.Forsyth 		} else
19374a4d8c2SCharles.Forsyth 			cgen(n, tn1);
19474a4d8c2SCharles.Forsyth 		return;
19574a4d8c2SCharles.Forsyth 	}
19674a4d8c2SCharles.Forsyth 	regalloc(tn1, n, Z);
19774a4d8c2SCharles.Forsyth 	if(n->complex >= FNX) {
19874a4d8c2SCharles.Forsyth 		cgen(*fnxp, tn1);
19974a4d8c2SCharles.Forsyth 		(*fnxp)++;
20074a4d8c2SCharles.Forsyth 	} else
20174a4d8c2SCharles.Forsyth 		cgen(n, tn1);
20274a4d8c2SCharles.Forsyth 	regaalloc(tn2, n);
20374a4d8c2SCharles.Forsyth 	gopcode(OAS, tn1, Z, tn2);
20474a4d8c2SCharles.Forsyth 	regfree(tn1);
20574a4d8c2SCharles.Forsyth }
20674a4d8c2SCharles.Forsyth 
20774a4d8c2SCharles.Forsyth Node*
nodconst(long v)20874a4d8c2SCharles.Forsyth nodconst(long v)
20974a4d8c2SCharles.Forsyth {
21074a4d8c2SCharles.Forsyth 	constnode.vconst = v;
21174a4d8c2SCharles.Forsyth 	return &constnode;
21274a4d8c2SCharles.Forsyth }
21374a4d8c2SCharles.Forsyth 
21474a4d8c2SCharles.Forsyth Node*
nod32const(vlong v)21574a4d8c2SCharles.Forsyth nod32const(vlong v)
21674a4d8c2SCharles.Forsyth {
21774a4d8c2SCharles.Forsyth 	constnode.vconst = v & MASK(32);
21874a4d8c2SCharles.Forsyth 	return &constnode;
21974a4d8c2SCharles.Forsyth }
22074a4d8c2SCharles.Forsyth 
22174a4d8c2SCharles.Forsyth Node*
nodfconst(double d)22274a4d8c2SCharles.Forsyth nodfconst(double d)
22374a4d8c2SCharles.Forsyth {
22474a4d8c2SCharles.Forsyth 	fconstnode.fconst = d;
22574a4d8c2SCharles.Forsyth 	return &fconstnode;
22674a4d8c2SCharles.Forsyth }
22774a4d8c2SCharles.Forsyth 
22874a4d8c2SCharles.Forsyth void
nodreg(Node * n,Node * nn,int reg)22974a4d8c2SCharles.Forsyth nodreg(Node *n, Node *nn, int reg)
23074a4d8c2SCharles.Forsyth {
23174a4d8c2SCharles.Forsyth 	*n = regnode;
23274a4d8c2SCharles.Forsyth 	n->reg = reg;
23374a4d8c2SCharles.Forsyth 	n->type = nn->type;
23474a4d8c2SCharles.Forsyth 	n->lineno = nn->lineno;
23574a4d8c2SCharles.Forsyth }
23674a4d8c2SCharles.Forsyth 
23774a4d8c2SCharles.Forsyth void
regret(Node * n,Node * nn)23874a4d8c2SCharles.Forsyth regret(Node *n, Node *nn)
23974a4d8c2SCharles.Forsyth {
24074a4d8c2SCharles.Forsyth 	int r;
24174a4d8c2SCharles.Forsyth 
24274a4d8c2SCharles.Forsyth 	r = REGRET;
24374a4d8c2SCharles.Forsyth 	if(typefd[nn->type->etype])
24474a4d8c2SCharles.Forsyth 		r = FREGRET+NREG;
24574a4d8c2SCharles.Forsyth 	nodreg(n, nn, r);
24674a4d8c2SCharles.Forsyth 	reg[r]++;
24774a4d8c2SCharles.Forsyth }
24874a4d8c2SCharles.Forsyth 
24974a4d8c2SCharles.Forsyth int
tmpreg(void)25074a4d8c2SCharles.Forsyth tmpreg(void)
25174a4d8c2SCharles.Forsyth {
25274a4d8c2SCharles.Forsyth 	int i;
25374a4d8c2SCharles.Forsyth 
25474a4d8c2SCharles.Forsyth 	for(i=REGRET+1; i<NREG; i++)
25574a4d8c2SCharles.Forsyth 		if(reg[i] == 0)
25674a4d8c2SCharles.Forsyth 			return i;
25774a4d8c2SCharles.Forsyth 	diag(Z, "out of fixed tmp registers");
25874a4d8c2SCharles.Forsyth 	return 0;
25974a4d8c2SCharles.Forsyth }
26074a4d8c2SCharles.Forsyth 
26174a4d8c2SCharles.Forsyth void
regalloc(Node * n,Node * tn,Node * o)26274a4d8c2SCharles.Forsyth regalloc(Node *n, Node *tn, Node *o)
26374a4d8c2SCharles.Forsyth {
26474a4d8c2SCharles.Forsyth 	int i, j;
26574a4d8c2SCharles.Forsyth 	static int lasti;
26674a4d8c2SCharles.Forsyth 
26774a4d8c2SCharles.Forsyth 	switch(tn->type->etype) {
26874a4d8c2SCharles.Forsyth 	case TCHAR:
26974a4d8c2SCharles.Forsyth 	case TUCHAR:
27074a4d8c2SCharles.Forsyth 	case TSHORT:
27174a4d8c2SCharles.Forsyth 	case TUSHORT:
27274a4d8c2SCharles.Forsyth 	case TINT:
27374a4d8c2SCharles.Forsyth 	case TUINT:
27474a4d8c2SCharles.Forsyth 	case TLONG:
27574a4d8c2SCharles.Forsyth 	case TULONG:
27674a4d8c2SCharles.Forsyth 	case TIND:
27774a4d8c2SCharles.Forsyth 		if(o != Z && o->op == OREGISTER) {
27874a4d8c2SCharles.Forsyth 			i = o->reg;
27974a4d8c2SCharles.Forsyth 			if(i >= 0 && i < NREG)
28074a4d8c2SCharles.Forsyth 				goto out;
28174a4d8c2SCharles.Forsyth 		}
28274a4d8c2SCharles.Forsyth 		j = lasti + REGRET+1;
28374a4d8c2SCharles.Forsyth 		for(i=REGRET+1; i<REGTMPT; i++) {
28474a4d8c2SCharles.Forsyth 			if(j >= REGTMPT)
28574a4d8c2SCharles.Forsyth 				j = REGRET+1;
28674a4d8c2SCharles.Forsyth 			if(reg[j] == 0) {
28774a4d8c2SCharles.Forsyth 				i = j;
28874a4d8c2SCharles.Forsyth 				goto out;
28974a4d8c2SCharles.Forsyth 			}
29074a4d8c2SCharles.Forsyth 			j++;
29174a4d8c2SCharles.Forsyth 		}
29274a4d8c2SCharles.Forsyth 		diag(tn, "out of fixed registers");
29374a4d8c2SCharles.Forsyth 		goto err;
29474a4d8c2SCharles.Forsyth 
29574a4d8c2SCharles.Forsyth 	case TFLOAT:
29674a4d8c2SCharles.Forsyth 	case TDOUBLE:
29774a4d8c2SCharles.Forsyth 	case TVLONG:
29874a4d8c2SCharles.Forsyth 		if(o != Z && o->op == OREGISTER) {
29974a4d8c2SCharles.Forsyth 			i = o->reg;
30074a4d8c2SCharles.Forsyth 			if(i >= NREG && i < NREG+NFREG)
30174a4d8c2SCharles.Forsyth 				goto out;
30274a4d8c2SCharles.Forsyth 		}
30374a4d8c2SCharles.Forsyth 		j = 0*2 + NREG;
30474a4d8c2SCharles.Forsyth 		for(i=NREG; i<NREG+NFREG; i++) {
30574a4d8c2SCharles.Forsyth 			if(j >= NREG+NFREG)
30674a4d8c2SCharles.Forsyth 				j = NREG;
30774a4d8c2SCharles.Forsyth 			if(reg[j] == 0) {
30874a4d8c2SCharles.Forsyth 				i = j;
30974a4d8c2SCharles.Forsyth 				goto out;
31074a4d8c2SCharles.Forsyth 			}
31174a4d8c2SCharles.Forsyth 			j++;
31274a4d8c2SCharles.Forsyth 		}
31374a4d8c2SCharles.Forsyth 		diag(tn, "out of float registers");
31474a4d8c2SCharles.Forsyth 		goto err;
31574a4d8c2SCharles.Forsyth 	}
31674a4d8c2SCharles.Forsyth 	diag(tn, "unknown type in regalloc: %T", tn->type);
31774a4d8c2SCharles.Forsyth err:
31874a4d8c2SCharles.Forsyth 	nodreg(n, tn, 0);
31974a4d8c2SCharles.Forsyth 	return;
32074a4d8c2SCharles.Forsyth out:
32174a4d8c2SCharles.Forsyth 	reg[i]++;
32274a4d8c2SCharles.Forsyth /* 	lasti++;	*** StrongARM does register forwarding */
32374a4d8c2SCharles.Forsyth /*
32474a4d8c2SCharles.Forsyth 	if(lasti >= 5)
32574a4d8c2SCharles.Forsyth 		lasti = 0;
32674a4d8c2SCharles.Forsyth */
32774a4d8c2SCharles.Forsyth 	nodreg(n, tn, i);
32874a4d8c2SCharles.Forsyth }
32974a4d8c2SCharles.Forsyth 
33074a4d8c2SCharles.Forsyth void
regialloc(Node * n,Node * tn,Node * o)33174a4d8c2SCharles.Forsyth regialloc(Node *n, Node *tn, Node *o)
33274a4d8c2SCharles.Forsyth {
33374a4d8c2SCharles.Forsyth 	Node nod;
33474a4d8c2SCharles.Forsyth 
33574a4d8c2SCharles.Forsyth 	nod = *tn;
33674a4d8c2SCharles.Forsyth 	nod.type = types[TIND];
33774a4d8c2SCharles.Forsyth 	regalloc(n, &nod, o);
33874a4d8c2SCharles.Forsyth }
33974a4d8c2SCharles.Forsyth 
34074a4d8c2SCharles.Forsyth void
regfree(Node * n)34174a4d8c2SCharles.Forsyth regfree(Node *n)
34274a4d8c2SCharles.Forsyth {
34374a4d8c2SCharles.Forsyth 	int i;
34474a4d8c2SCharles.Forsyth 
34574a4d8c2SCharles.Forsyth 	i = 0;
34674a4d8c2SCharles.Forsyth 	if(n->op != OREGISTER && n->op != OINDREG)
34774a4d8c2SCharles.Forsyth 		goto err;
34874a4d8c2SCharles.Forsyth 	i = n->reg;
34974a4d8c2SCharles.Forsyth 	if(i < 0 || i >= sizeof(reg))
35074a4d8c2SCharles.Forsyth 		goto err;
35174a4d8c2SCharles.Forsyth 	if(reg[i] <= 0)
35274a4d8c2SCharles.Forsyth 		goto err;
35374a4d8c2SCharles.Forsyth 	reg[i]--;
35474a4d8c2SCharles.Forsyth 	return;
35574a4d8c2SCharles.Forsyth err:
35674a4d8c2SCharles.Forsyth 	diag(n, "error in regfree: %d", i);
35774a4d8c2SCharles.Forsyth }
35874a4d8c2SCharles.Forsyth 
35974a4d8c2SCharles.Forsyth void
regsalloc(Node * n,Node * nn)36074a4d8c2SCharles.Forsyth regsalloc(Node *n, Node *nn)
36174a4d8c2SCharles.Forsyth {
36274a4d8c2SCharles.Forsyth 	cursafe = align(cursafe, nn->type, Aaut3);
36374a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
36474a4d8c2SCharles.Forsyth 	*n = *nodsafe;
36574a4d8c2SCharles.Forsyth 	n->xoffset = -(stkoff + cursafe);
36674a4d8c2SCharles.Forsyth 	n->type = nn->type;
36774a4d8c2SCharles.Forsyth 	n->etype = nn->type->etype;
36874a4d8c2SCharles.Forsyth 	n->lineno = nn->lineno;
36974a4d8c2SCharles.Forsyth }
37074a4d8c2SCharles.Forsyth 
37174a4d8c2SCharles.Forsyth void
regaalloc1(Node * n,Node * nn)37274a4d8c2SCharles.Forsyth regaalloc1(Node *n, Node *nn)
37374a4d8c2SCharles.Forsyth {
37474a4d8c2SCharles.Forsyth 	nodreg(n, nn, REGARG);
37574a4d8c2SCharles.Forsyth 	reg[REGARG]++;
37674a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg1);
37774a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg2);
37874a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
37974a4d8c2SCharles.Forsyth }
38074a4d8c2SCharles.Forsyth 
38174a4d8c2SCharles.Forsyth void
regaalloc(Node * n,Node * nn)38274a4d8c2SCharles.Forsyth regaalloc(Node *n, Node *nn)
38374a4d8c2SCharles.Forsyth {
38474a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg1);
38574a4d8c2SCharles.Forsyth 	*n = *nn;
38674a4d8c2SCharles.Forsyth 	n->op = OINDREG;
38774a4d8c2SCharles.Forsyth 	n->reg = REGSP;
38874a4d8c2SCharles.Forsyth 	n->xoffset = curarg + SZ_LONG;
38974a4d8c2SCharles.Forsyth 	n->complex = 0;
39074a4d8c2SCharles.Forsyth 	n->addable = 20;
39174a4d8c2SCharles.Forsyth 	curarg = align(curarg, nn->type, Aarg2);
39274a4d8c2SCharles.Forsyth 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
39374a4d8c2SCharles.Forsyth }
39474a4d8c2SCharles.Forsyth 
39574a4d8c2SCharles.Forsyth void
regind(Node * n,Node * nn)39674a4d8c2SCharles.Forsyth regind(Node *n, Node *nn)
39774a4d8c2SCharles.Forsyth {
39874a4d8c2SCharles.Forsyth 
39974a4d8c2SCharles.Forsyth 	if(n->op != OREGISTER) {
40074a4d8c2SCharles.Forsyth 		diag(n, "regind not OREGISTER");
40174a4d8c2SCharles.Forsyth 		return;
40274a4d8c2SCharles.Forsyth 	}
40374a4d8c2SCharles.Forsyth 	n->op = OINDREG;
40474a4d8c2SCharles.Forsyth 	n->type = nn->type;
40574a4d8c2SCharles.Forsyth }
40674a4d8c2SCharles.Forsyth 
40774a4d8c2SCharles.Forsyth void
raddr(Node * n,Prog * p)40874a4d8c2SCharles.Forsyth raddr(Node *n, Prog *p)
40974a4d8c2SCharles.Forsyth {
41074a4d8c2SCharles.Forsyth 	Adr a;
41174a4d8c2SCharles.Forsyth 
41274a4d8c2SCharles.Forsyth 	naddr(n, &a);
41374a4d8c2SCharles.Forsyth 	if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
41474a4d8c2SCharles.Forsyth 		a.type = D_REG;
41574a4d8c2SCharles.Forsyth 		a.reg = 0;
41674a4d8c2SCharles.Forsyth 	}
41774a4d8c2SCharles.Forsyth 	if(a.type != D_REG && a.type != D_FREG) {
41874a4d8c2SCharles.Forsyth 		if(n)
41974a4d8c2SCharles.Forsyth 			diag(n, "bad in raddr: %O", n->op);
42074a4d8c2SCharles.Forsyth 		else
42174a4d8c2SCharles.Forsyth 			diag(n, "bad in raddr: <null>");
42274a4d8c2SCharles.Forsyth 		p->reg = NREG;
42374a4d8c2SCharles.Forsyth 	} else
42474a4d8c2SCharles.Forsyth 		p->reg = a.reg;
42574a4d8c2SCharles.Forsyth }
42674a4d8c2SCharles.Forsyth 
42774a4d8c2SCharles.Forsyth void
naddr(Node * n,Adr * a)42874a4d8c2SCharles.Forsyth naddr(Node *n, Adr *a)
42974a4d8c2SCharles.Forsyth {
43074a4d8c2SCharles.Forsyth 	long v;
43174a4d8c2SCharles.Forsyth 
43274a4d8c2SCharles.Forsyth 	a->type = D_NONE;
43374a4d8c2SCharles.Forsyth 	if(n == Z)
43474a4d8c2SCharles.Forsyth 		return;
43574a4d8c2SCharles.Forsyth 	switch(n->op) {
43674a4d8c2SCharles.Forsyth 	default:
43774a4d8c2SCharles.Forsyth 	bad:
43874a4d8c2SCharles.Forsyth 		diag(n, "bad in naddr: %O", n->op);
43974a4d8c2SCharles.Forsyth 		break;
44074a4d8c2SCharles.Forsyth 
44174a4d8c2SCharles.Forsyth 	case OREGISTER:
44274a4d8c2SCharles.Forsyth 		a->type = D_REG;
44374a4d8c2SCharles.Forsyth 		a->sym = S;
44474a4d8c2SCharles.Forsyth 		a->reg = n->reg;
44574a4d8c2SCharles.Forsyth 		if(a->reg >= NREG) {
44674a4d8c2SCharles.Forsyth 			a->type = D_FREG;
44774a4d8c2SCharles.Forsyth 			a->reg -= NREG;
44874a4d8c2SCharles.Forsyth 		}
44974a4d8c2SCharles.Forsyth 		break;
45074a4d8c2SCharles.Forsyth 
45174a4d8c2SCharles.Forsyth 	case OIND:
45274a4d8c2SCharles.Forsyth 		naddr(n->left, a);
45374a4d8c2SCharles.Forsyth 		if(a->type == D_REG) {
45474a4d8c2SCharles.Forsyth 			a->type = D_OREG;
45574a4d8c2SCharles.Forsyth 			break;
45674a4d8c2SCharles.Forsyth 		}
45774a4d8c2SCharles.Forsyth 		if(a->type == D_CONST) {
45874a4d8c2SCharles.Forsyth 			a->type = D_OREG;
45974a4d8c2SCharles.Forsyth 			break;
46074a4d8c2SCharles.Forsyth 		}
46174a4d8c2SCharles.Forsyth 		goto bad;
46274a4d8c2SCharles.Forsyth 
46374a4d8c2SCharles.Forsyth 	case OINDREG:
46474a4d8c2SCharles.Forsyth 		a->type = D_OREG;
46574a4d8c2SCharles.Forsyth 		a->sym = S;
46674a4d8c2SCharles.Forsyth 		a->offset = n->xoffset;
46774a4d8c2SCharles.Forsyth 		a->reg = n->reg;
46874a4d8c2SCharles.Forsyth 		break;
46974a4d8c2SCharles.Forsyth 
47074a4d8c2SCharles.Forsyth 	case ONAME:
47174a4d8c2SCharles.Forsyth 		a->etype = n->etype;
47274a4d8c2SCharles.Forsyth 		a->type = D_OREG;
47374a4d8c2SCharles.Forsyth 		a->name = D_STATIC;
47474a4d8c2SCharles.Forsyth 		a->sym = n->sym;
47574a4d8c2SCharles.Forsyth 		a->offset = n->xoffset;
47674a4d8c2SCharles.Forsyth 		if(n->class == CSTATIC)
47774a4d8c2SCharles.Forsyth 			break;
47874a4d8c2SCharles.Forsyth 		if(n->class == CEXTERN || n->class == CGLOBL) {
47974a4d8c2SCharles.Forsyth 			a->name = D_EXTERN;
48074a4d8c2SCharles.Forsyth 			break;
48174a4d8c2SCharles.Forsyth 		}
48274a4d8c2SCharles.Forsyth 		if(n->class == CAUTO) {
48374a4d8c2SCharles.Forsyth 			a->name = D_AUTO;
48474a4d8c2SCharles.Forsyth 			break;
48574a4d8c2SCharles.Forsyth 		}
48674a4d8c2SCharles.Forsyth 		if(n->class == CPARAM) {
48774a4d8c2SCharles.Forsyth 			a->name = D_PARAM;
48874a4d8c2SCharles.Forsyth 			break;
48974a4d8c2SCharles.Forsyth 		}
49074a4d8c2SCharles.Forsyth 		goto bad;
49174a4d8c2SCharles.Forsyth 
49274a4d8c2SCharles.Forsyth 	case OCONST:
49374a4d8c2SCharles.Forsyth 		a->sym = S;
49474a4d8c2SCharles.Forsyth 		a->reg = NREG;
49574a4d8c2SCharles.Forsyth 		if(typefd[n->type->etype]) {
49674a4d8c2SCharles.Forsyth 			a->type = D_FCONST;
49774a4d8c2SCharles.Forsyth 			a->dval = n->fconst;
49874a4d8c2SCharles.Forsyth 		} else {
49974a4d8c2SCharles.Forsyth 			a->type = D_CONST;
50074a4d8c2SCharles.Forsyth 			a->offset = n->vconst;
50174a4d8c2SCharles.Forsyth 		}
50274a4d8c2SCharles.Forsyth 		break;
50374a4d8c2SCharles.Forsyth 
50474a4d8c2SCharles.Forsyth 	case OADDR:
50574a4d8c2SCharles.Forsyth 		naddr(n->left, a);
50674a4d8c2SCharles.Forsyth 		if(a->type == D_OREG) {
50774a4d8c2SCharles.Forsyth 			a->type = D_CONST;
50874a4d8c2SCharles.Forsyth 			break;
50974a4d8c2SCharles.Forsyth 		}
51074a4d8c2SCharles.Forsyth 		goto bad;
51174a4d8c2SCharles.Forsyth 
51274a4d8c2SCharles.Forsyth 	case OADD:
51374a4d8c2SCharles.Forsyth 		if(n->left->op == OCONST) {
51474a4d8c2SCharles.Forsyth 			naddr(n->left, a);
51574a4d8c2SCharles.Forsyth 			v = a->offset;
51674a4d8c2SCharles.Forsyth 			naddr(n->right, a);
51774a4d8c2SCharles.Forsyth 		} else {
51874a4d8c2SCharles.Forsyth 			naddr(n->right, a);
51974a4d8c2SCharles.Forsyth 			v = a->offset;
52074a4d8c2SCharles.Forsyth 			naddr(n->left, a);
52174a4d8c2SCharles.Forsyth 		}
52274a4d8c2SCharles.Forsyth 		a->offset += v;
52374a4d8c2SCharles.Forsyth 		break;
52474a4d8c2SCharles.Forsyth 
52574a4d8c2SCharles.Forsyth 	}
52674a4d8c2SCharles.Forsyth }
52774a4d8c2SCharles.Forsyth 
52874a4d8c2SCharles.Forsyth void
gmovm(Node * f,Node * t)52974a4d8c2SCharles.Forsyth gmovm(Node *f, Node *t)
53074a4d8c2SCharles.Forsyth {
53174a4d8c2SCharles.Forsyth 	gins(AMOVM, f, t);	// always sets base register now
53274a4d8c2SCharles.Forsyth }
53374a4d8c2SCharles.Forsyth 
53474a4d8c2SCharles.Forsyth void
gmove(Node * f,Node * t)53574a4d8c2SCharles.Forsyth gmove(Node *f, Node *t)
53674a4d8c2SCharles.Forsyth {
53774a4d8c2SCharles.Forsyth 	int ft, tt, a;
53874a4d8c2SCharles.Forsyth 	Node nod;
53974a4d8c2SCharles.Forsyth 
54074a4d8c2SCharles.Forsyth // prtree(f, "gmove src");
54174a4d8c2SCharles.Forsyth // prtree(t, "gmove dst");
54274a4d8c2SCharles.Forsyth 	ft = f->type->etype;
54374a4d8c2SCharles.Forsyth 	tt = t->type->etype;
54474a4d8c2SCharles.Forsyth 
54574a4d8c2SCharles.Forsyth 	if(ft == TDOUBLE && f->op == OCONST) {
54674a4d8c2SCharles.Forsyth 	}
54774a4d8c2SCharles.Forsyth 	if(ft == TFLOAT && f->op == OCONST) {
54874a4d8c2SCharles.Forsyth 	}
54974a4d8c2SCharles.Forsyth 
55074a4d8c2SCharles.Forsyth 	/*
55174a4d8c2SCharles.Forsyth 	 * a load --
55274a4d8c2SCharles.Forsyth 	 * put it into a register then
55374a4d8c2SCharles.Forsyth 	 * worry what to do with it.
55474a4d8c2SCharles.Forsyth 	 */
55574a4d8c2SCharles.Forsyth 	if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
55674a4d8c2SCharles.Forsyth 		switch(ft) {
55774a4d8c2SCharles.Forsyth 		default:
55874a4d8c2SCharles.Forsyth 			a = AMOVW;
55974a4d8c2SCharles.Forsyth 			break;
56074a4d8c2SCharles.Forsyth 		case TFLOAT:
56174a4d8c2SCharles.Forsyth 			a = AMOVF;
56274a4d8c2SCharles.Forsyth 			break;
56374a4d8c2SCharles.Forsyth 		case TDOUBLE:
56474a4d8c2SCharles.Forsyth 			a = AMOVD;
56574a4d8c2SCharles.Forsyth 			break;
56674a4d8c2SCharles.Forsyth 		case TCHAR:
56774a4d8c2SCharles.Forsyth 			a = AMOVB;
56874a4d8c2SCharles.Forsyth 			break;
56974a4d8c2SCharles.Forsyth 		case TUCHAR:
57074a4d8c2SCharles.Forsyth 			a = AMOVBU;
57174a4d8c2SCharles.Forsyth 			break;
57274a4d8c2SCharles.Forsyth 		case TSHORT:
57374a4d8c2SCharles.Forsyth 			a = AMOVH;
57474a4d8c2SCharles.Forsyth 			break;
57574a4d8c2SCharles.Forsyth 		case TUSHORT:
57674a4d8c2SCharles.Forsyth 			a = AMOVHU;
57774a4d8c2SCharles.Forsyth 			break;
57874a4d8c2SCharles.Forsyth 		}
57974a4d8c2SCharles.Forsyth 		if(typechlp[ft] && typeilp[tt])
58074a4d8c2SCharles.Forsyth 			regalloc(&nod, t, t);
58174a4d8c2SCharles.Forsyth 		else
58274a4d8c2SCharles.Forsyth 			regalloc(&nod, f, t);
58374a4d8c2SCharles.Forsyth 		gins(a, f, &nod);
58474a4d8c2SCharles.Forsyth 		gmove(&nod, t);
58574a4d8c2SCharles.Forsyth 		regfree(&nod);
58674a4d8c2SCharles.Forsyth 		return;
58774a4d8c2SCharles.Forsyth 	}
58874a4d8c2SCharles.Forsyth 
58974a4d8c2SCharles.Forsyth 	/*
59074a4d8c2SCharles.Forsyth 	 * a store --
59174a4d8c2SCharles.Forsyth 	 * put it into a register then
59274a4d8c2SCharles.Forsyth 	 * store it.
59374a4d8c2SCharles.Forsyth 	 */
59474a4d8c2SCharles.Forsyth 	if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
59574a4d8c2SCharles.Forsyth 		switch(tt) {
59674a4d8c2SCharles.Forsyth 		default:
59774a4d8c2SCharles.Forsyth 			a = AMOVW;
59874a4d8c2SCharles.Forsyth 			break;
59974a4d8c2SCharles.Forsyth 		case TUCHAR:
60074a4d8c2SCharles.Forsyth 			a = AMOVBU;
60174a4d8c2SCharles.Forsyth 			break;
60274a4d8c2SCharles.Forsyth 		case TCHAR:
60374a4d8c2SCharles.Forsyth 			a = AMOVB;
60474a4d8c2SCharles.Forsyth 			break;
60574a4d8c2SCharles.Forsyth 		case TUSHORT:
60674a4d8c2SCharles.Forsyth 			a = AMOVHU;
60774a4d8c2SCharles.Forsyth 			break;
60874a4d8c2SCharles.Forsyth 		case TSHORT:
60974a4d8c2SCharles.Forsyth 			a = AMOVH;
61074a4d8c2SCharles.Forsyth 			break;
61174a4d8c2SCharles.Forsyth 		case TFLOAT:
61274a4d8c2SCharles.Forsyth 			a = AMOVF;
61374a4d8c2SCharles.Forsyth 			break;
61474a4d8c2SCharles.Forsyth 		case TVLONG:
61574a4d8c2SCharles.Forsyth 		case TDOUBLE:
61674a4d8c2SCharles.Forsyth 			a = AMOVD;
61774a4d8c2SCharles.Forsyth 			break;
61874a4d8c2SCharles.Forsyth 		}
61974a4d8c2SCharles.Forsyth 		if(ft == tt)
62074a4d8c2SCharles.Forsyth 			regalloc(&nod, t, f);
62174a4d8c2SCharles.Forsyth 		else
62274a4d8c2SCharles.Forsyth 			regalloc(&nod, t, Z);
62374a4d8c2SCharles.Forsyth 		gmove(f, &nod);
62474a4d8c2SCharles.Forsyth 		gins(a, &nod, t);
62574a4d8c2SCharles.Forsyth 		regfree(&nod);
62674a4d8c2SCharles.Forsyth 		return;
62774a4d8c2SCharles.Forsyth 	}
62874a4d8c2SCharles.Forsyth 
62974a4d8c2SCharles.Forsyth 	/*
63074a4d8c2SCharles.Forsyth 	 * type x type cross table
63174a4d8c2SCharles.Forsyth 	 */
63274a4d8c2SCharles.Forsyth 	a = AGOK;
63374a4d8c2SCharles.Forsyth 	switch(ft) {
63474a4d8c2SCharles.Forsyth 	case TDOUBLE:
63574a4d8c2SCharles.Forsyth 	case TVLONG:
63674a4d8c2SCharles.Forsyth 	case TFLOAT:
63774a4d8c2SCharles.Forsyth 		switch(tt) {
63874a4d8c2SCharles.Forsyth 		case TDOUBLE:
63974a4d8c2SCharles.Forsyth 		case TVLONG:
64074a4d8c2SCharles.Forsyth 			a = AMOVD;
64174a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
64274a4d8c2SCharles.Forsyth 				a = AMOVFD;
64374a4d8c2SCharles.Forsyth 			break;
64474a4d8c2SCharles.Forsyth 		case TFLOAT:
64574a4d8c2SCharles.Forsyth 			a = AMOVDF;
64674a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
64774a4d8c2SCharles.Forsyth 				a = AMOVF;
64874a4d8c2SCharles.Forsyth 			break;
64974a4d8c2SCharles.Forsyth 		case TINT:
65074a4d8c2SCharles.Forsyth 		case TUINT:
65174a4d8c2SCharles.Forsyth 		case TLONG:
65274a4d8c2SCharles.Forsyth 		case TULONG:
65374a4d8c2SCharles.Forsyth 		case TIND:
65474a4d8c2SCharles.Forsyth 		case TSHORT:
65574a4d8c2SCharles.Forsyth 		case TUSHORT:
65674a4d8c2SCharles.Forsyth 		case TCHAR:
65774a4d8c2SCharles.Forsyth 		case TUCHAR:
65874a4d8c2SCharles.Forsyth 			a = AMOVDW;
65974a4d8c2SCharles.Forsyth 			if(ft == TFLOAT)
66074a4d8c2SCharles.Forsyth 				a = AMOVFW;
66174a4d8c2SCharles.Forsyth 			break;
66274a4d8c2SCharles.Forsyth 		}
66374a4d8c2SCharles.Forsyth 		break;
66474a4d8c2SCharles.Forsyth 	case TUINT:
66574a4d8c2SCharles.Forsyth 	case TINT:
66674a4d8c2SCharles.Forsyth 	case TULONG:
66774a4d8c2SCharles.Forsyth 	case TLONG:
66874a4d8c2SCharles.Forsyth 	case TIND:
66974a4d8c2SCharles.Forsyth 		switch(tt) {
67074a4d8c2SCharles.Forsyth 		case TDOUBLE:
67174a4d8c2SCharles.Forsyth 		case TVLONG:
67274a4d8c2SCharles.Forsyth 			gins(AMOVWD, f, t);
67374a4d8c2SCharles.Forsyth 			if(ft == TULONG) {
67474a4d8c2SCharles.Forsyth 			}
67574a4d8c2SCharles.Forsyth 			return;
67674a4d8c2SCharles.Forsyth 		case TFLOAT:
67774a4d8c2SCharles.Forsyth 			gins(AMOVWF, f, t);
67874a4d8c2SCharles.Forsyth 			if(ft == TULONG) {
67974a4d8c2SCharles.Forsyth 			}
68074a4d8c2SCharles.Forsyth 			return;
68174a4d8c2SCharles.Forsyth 		case TINT:
68274a4d8c2SCharles.Forsyth 		case TUINT:
68374a4d8c2SCharles.Forsyth 		case TLONG:
68474a4d8c2SCharles.Forsyth 		case TULONG:
68574a4d8c2SCharles.Forsyth 		case TIND:
68674a4d8c2SCharles.Forsyth 		case TSHORT:
68774a4d8c2SCharles.Forsyth 		case TUSHORT:
68874a4d8c2SCharles.Forsyth 		case TCHAR:
68974a4d8c2SCharles.Forsyth 		case TUCHAR:
69074a4d8c2SCharles.Forsyth 			a = AMOVW;
69174a4d8c2SCharles.Forsyth 			break;
69274a4d8c2SCharles.Forsyth 		}
69374a4d8c2SCharles.Forsyth 		break;
69474a4d8c2SCharles.Forsyth 	case TSHORT:
69574a4d8c2SCharles.Forsyth 		switch(tt) {
69674a4d8c2SCharles.Forsyth 		case TDOUBLE:
69774a4d8c2SCharles.Forsyth 		case TVLONG:
69874a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
69974a4d8c2SCharles.Forsyth 			gins(AMOVH, f, &nod);
70074a4d8c2SCharles.Forsyth 			gins(AMOVWD, &nod, t);
70174a4d8c2SCharles.Forsyth 			regfree(&nod);
70274a4d8c2SCharles.Forsyth 			return;
70374a4d8c2SCharles.Forsyth 		case TFLOAT:
70474a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
70574a4d8c2SCharles.Forsyth 			gins(AMOVH, f, &nod);
70674a4d8c2SCharles.Forsyth 			gins(AMOVWF, &nod, t);
70774a4d8c2SCharles.Forsyth 			regfree(&nod);
70874a4d8c2SCharles.Forsyth 			return;
70974a4d8c2SCharles.Forsyth 		case TUINT:
71074a4d8c2SCharles.Forsyth 		case TINT:
71174a4d8c2SCharles.Forsyth 		case TULONG:
71274a4d8c2SCharles.Forsyth 		case TLONG:
71374a4d8c2SCharles.Forsyth 		case TIND:
71474a4d8c2SCharles.Forsyth 			a = AMOVH;
71574a4d8c2SCharles.Forsyth 			break;
71674a4d8c2SCharles.Forsyth 		case TSHORT:
71774a4d8c2SCharles.Forsyth 		case TUSHORT:
71874a4d8c2SCharles.Forsyth 		case TCHAR:
71974a4d8c2SCharles.Forsyth 		case TUCHAR:
72074a4d8c2SCharles.Forsyth 			a = AMOVW;
72174a4d8c2SCharles.Forsyth 			break;
72274a4d8c2SCharles.Forsyth 		}
72374a4d8c2SCharles.Forsyth 		break;
72474a4d8c2SCharles.Forsyth 	case TUSHORT:
72574a4d8c2SCharles.Forsyth 		switch(tt) {
72674a4d8c2SCharles.Forsyth 		case TDOUBLE:
72774a4d8c2SCharles.Forsyth 		case TVLONG:
72874a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
72974a4d8c2SCharles.Forsyth 			gins(AMOVHU, f, &nod);
73074a4d8c2SCharles.Forsyth 			gins(AMOVWD, &nod, t);
73174a4d8c2SCharles.Forsyth 			regfree(&nod);
73274a4d8c2SCharles.Forsyth 			return;
73374a4d8c2SCharles.Forsyth 		case TFLOAT:
73474a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
73574a4d8c2SCharles.Forsyth 			gins(AMOVHU, f, &nod);
73674a4d8c2SCharles.Forsyth 			gins(AMOVWF, &nod, t);
73774a4d8c2SCharles.Forsyth 			regfree(&nod);
73874a4d8c2SCharles.Forsyth 			return;
73974a4d8c2SCharles.Forsyth 		case TINT:
74074a4d8c2SCharles.Forsyth 		case TUINT:
74174a4d8c2SCharles.Forsyth 		case TLONG:
74274a4d8c2SCharles.Forsyth 		case TULONG:
74374a4d8c2SCharles.Forsyth 		case TIND:
74474a4d8c2SCharles.Forsyth 			a = AMOVHU;
74574a4d8c2SCharles.Forsyth 			break;
74674a4d8c2SCharles.Forsyth 		case TSHORT:
74774a4d8c2SCharles.Forsyth 		case TUSHORT:
74874a4d8c2SCharles.Forsyth 		case TCHAR:
74974a4d8c2SCharles.Forsyth 		case TUCHAR:
75074a4d8c2SCharles.Forsyth 			a = AMOVW;
75174a4d8c2SCharles.Forsyth 			break;
75274a4d8c2SCharles.Forsyth 		}
75374a4d8c2SCharles.Forsyth 		break;
75474a4d8c2SCharles.Forsyth 	case TCHAR:
75574a4d8c2SCharles.Forsyth 		switch(tt) {
75674a4d8c2SCharles.Forsyth 		case TDOUBLE:
75774a4d8c2SCharles.Forsyth 		case TVLONG:
75874a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
75974a4d8c2SCharles.Forsyth 			gins(AMOVB, f, &nod);
76074a4d8c2SCharles.Forsyth 			gins(AMOVWD, &nod, t);
76174a4d8c2SCharles.Forsyth 			regfree(&nod);
76274a4d8c2SCharles.Forsyth 			return;
76374a4d8c2SCharles.Forsyth 		case TFLOAT:
76474a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
76574a4d8c2SCharles.Forsyth 			gins(AMOVB, f, &nod);
76674a4d8c2SCharles.Forsyth 			gins(AMOVWF, &nod, t);
76774a4d8c2SCharles.Forsyth 			regfree(&nod);
76874a4d8c2SCharles.Forsyth 			return;
76974a4d8c2SCharles.Forsyth 		case TINT:
77074a4d8c2SCharles.Forsyth 		case TUINT:
77174a4d8c2SCharles.Forsyth 		case TLONG:
77274a4d8c2SCharles.Forsyth 		case TULONG:
77374a4d8c2SCharles.Forsyth 		case TIND:
77474a4d8c2SCharles.Forsyth 		case TSHORT:
77574a4d8c2SCharles.Forsyth 		case TUSHORT:
77674a4d8c2SCharles.Forsyth 			a = AMOVB;
77774a4d8c2SCharles.Forsyth 			break;
77874a4d8c2SCharles.Forsyth 		case TCHAR:
77974a4d8c2SCharles.Forsyth 		case TUCHAR:
78074a4d8c2SCharles.Forsyth 			a = AMOVW;
78174a4d8c2SCharles.Forsyth 			break;
78274a4d8c2SCharles.Forsyth 		}
78374a4d8c2SCharles.Forsyth 		break;
78474a4d8c2SCharles.Forsyth 	case TUCHAR:
78574a4d8c2SCharles.Forsyth 		switch(tt) {
78674a4d8c2SCharles.Forsyth 		case TDOUBLE:
78774a4d8c2SCharles.Forsyth 		case TVLONG:
78874a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
78974a4d8c2SCharles.Forsyth 			gins(AMOVBU, f, &nod);
79074a4d8c2SCharles.Forsyth 			gins(AMOVWD, &nod, t);
79174a4d8c2SCharles.Forsyth 			regfree(&nod);
79274a4d8c2SCharles.Forsyth 			return;
79374a4d8c2SCharles.Forsyth 		case TFLOAT:
79474a4d8c2SCharles.Forsyth 			regalloc(&nod, f, Z);
79574a4d8c2SCharles.Forsyth 			gins(AMOVBU, f, &nod);
79674a4d8c2SCharles.Forsyth 			gins(AMOVWF, &nod, t);
79774a4d8c2SCharles.Forsyth 			regfree(&nod);
79874a4d8c2SCharles.Forsyth 			return;
79974a4d8c2SCharles.Forsyth 		case TINT:
80074a4d8c2SCharles.Forsyth 		case TUINT:
80174a4d8c2SCharles.Forsyth 		case TLONG:
80274a4d8c2SCharles.Forsyth 		case TULONG:
80374a4d8c2SCharles.Forsyth 		case TIND:
80474a4d8c2SCharles.Forsyth 		case TSHORT:
80574a4d8c2SCharles.Forsyth 		case TUSHORT:
80674a4d8c2SCharles.Forsyth 			a = AMOVBU;
80774a4d8c2SCharles.Forsyth 			break;
80874a4d8c2SCharles.Forsyth 		case TCHAR:
80974a4d8c2SCharles.Forsyth 		case TUCHAR:
81074a4d8c2SCharles.Forsyth 			a = AMOVW;
81174a4d8c2SCharles.Forsyth 			break;
81274a4d8c2SCharles.Forsyth 		}
81374a4d8c2SCharles.Forsyth 		break;
81474a4d8c2SCharles.Forsyth 	}
81574a4d8c2SCharles.Forsyth 	if(a == AGOK)
81674a4d8c2SCharles.Forsyth 		diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
81774a4d8c2SCharles.Forsyth 	if(a == AMOVW || a == AMOVF || a == AMOVD)
81874a4d8c2SCharles.Forsyth 	if(samaddr(f, t))
81974a4d8c2SCharles.Forsyth 		return;
82074a4d8c2SCharles.Forsyth 	gins(a, f, t);
82174a4d8c2SCharles.Forsyth }
82274a4d8c2SCharles.Forsyth 
82374a4d8c2SCharles.Forsyth void
gins(int a,Node * f,Node * t)82474a4d8c2SCharles.Forsyth gins(int a, Node *f, Node *t)
82574a4d8c2SCharles.Forsyth {
82674a4d8c2SCharles.Forsyth 
82774a4d8c2SCharles.Forsyth 	nextpc();
82874a4d8c2SCharles.Forsyth 	p->as = a;
82974a4d8c2SCharles.Forsyth 	if(f != Z)
83074a4d8c2SCharles.Forsyth 		naddr(f, &p->from);
83174a4d8c2SCharles.Forsyth 	if(t != Z)
83274a4d8c2SCharles.Forsyth 		naddr(t, &p->to);
83374a4d8c2SCharles.Forsyth 	if(debug['g'])
83474a4d8c2SCharles.Forsyth 		print("%P\n", p);
83574a4d8c2SCharles.Forsyth }
83674a4d8c2SCharles.Forsyth 
83774a4d8c2SCharles.Forsyth void
gopcode(int o,Node * f1,Node * f2,Node * t)83874a4d8c2SCharles.Forsyth gopcode(int o, Node *f1, Node *f2, Node *t)
83974a4d8c2SCharles.Forsyth {
84074a4d8c2SCharles.Forsyth 	int a, et;
84174a4d8c2SCharles.Forsyth 	Adr ta;
84274a4d8c2SCharles.Forsyth 
84374a4d8c2SCharles.Forsyth 	et = TLONG;
84474a4d8c2SCharles.Forsyth 	if(f1 != Z && f1->type != T)
84574a4d8c2SCharles.Forsyth 		et = f1->type->etype;
84674a4d8c2SCharles.Forsyth 	a = AGOK;
84774a4d8c2SCharles.Forsyth 	switch(o) {
84874a4d8c2SCharles.Forsyth 	case OAS:
84974a4d8c2SCharles.Forsyth 		gmove(f1, t);
85074a4d8c2SCharles.Forsyth 		return;
85174a4d8c2SCharles.Forsyth 
85274a4d8c2SCharles.Forsyth 	case OASADD:
85374a4d8c2SCharles.Forsyth 	case OADD:
85474a4d8c2SCharles.Forsyth 		a = AADD;
85574a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
85674a4d8c2SCharles.Forsyth 			a = AADDF;
85774a4d8c2SCharles.Forsyth 		else
85874a4d8c2SCharles.Forsyth 		if(et == TDOUBLE || et == TVLONG)
85974a4d8c2SCharles.Forsyth 			a = AADDD;
86074a4d8c2SCharles.Forsyth 		break;
86174a4d8c2SCharles.Forsyth 
86274a4d8c2SCharles.Forsyth 	case OASSUB:
86374a4d8c2SCharles.Forsyth 	case OSUB:
86474a4d8c2SCharles.Forsyth 		a = ASUB;
86574a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
86674a4d8c2SCharles.Forsyth 			a = ASUBF;
86774a4d8c2SCharles.Forsyth 		else
86874a4d8c2SCharles.Forsyth 		if(et == TDOUBLE || et == TVLONG)
86974a4d8c2SCharles.Forsyth 			a = ASUBD;
87074a4d8c2SCharles.Forsyth 		break;
87174a4d8c2SCharles.Forsyth 
87274a4d8c2SCharles.Forsyth 	case OASOR:
87374a4d8c2SCharles.Forsyth 	case OOR:
87474a4d8c2SCharles.Forsyth 		a = AORR;
87574a4d8c2SCharles.Forsyth 		break;
87674a4d8c2SCharles.Forsyth 
87774a4d8c2SCharles.Forsyth 	case OASAND:
87874a4d8c2SCharles.Forsyth 	case OAND:
87974a4d8c2SCharles.Forsyth 		a = AAND;
88074a4d8c2SCharles.Forsyth 		break;
88174a4d8c2SCharles.Forsyth 
88274a4d8c2SCharles.Forsyth 	case OASXOR:
88374a4d8c2SCharles.Forsyth 	case OXOR:
88474a4d8c2SCharles.Forsyth 		a = AEOR;
88574a4d8c2SCharles.Forsyth 		break;
88674a4d8c2SCharles.Forsyth 
88774a4d8c2SCharles.Forsyth 	case OASLSHR:
88874a4d8c2SCharles.Forsyth 	case OLSHR:
88974a4d8c2SCharles.Forsyth 		a = ASRL;
89074a4d8c2SCharles.Forsyth 		break;
89174a4d8c2SCharles.Forsyth 
89274a4d8c2SCharles.Forsyth 	case OASASHR:
89374a4d8c2SCharles.Forsyth 	case OASHR:
89474a4d8c2SCharles.Forsyth 		a = ASRA;
89574a4d8c2SCharles.Forsyth 		break;
89674a4d8c2SCharles.Forsyth 
89774a4d8c2SCharles.Forsyth 	case OASASHL:
89874a4d8c2SCharles.Forsyth 	case OASHL:
89974a4d8c2SCharles.Forsyth 		a = ASLL;
90074a4d8c2SCharles.Forsyth 		break;
90174a4d8c2SCharles.Forsyth 
90274a4d8c2SCharles.Forsyth 	case OFUNC:
90374a4d8c2SCharles.Forsyth 		a = ABL;
90474a4d8c2SCharles.Forsyth 		break;
90574a4d8c2SCharles.Forsyth 
90674a4d8c2SCharles.Forsyth 	case OASMUL:
90774a4d8c2SCharles.Forsyth 	case OMUL:
90874a4d8c2SCharles.Forsyth 		a = AMUL;
90974a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
91074a4d8c2SCharles.Forsyth 			a = AMULF;
91174a4d8c2SCharles.Forsyth 		else
91274a4d8c2SCharles.Forsyth 		if(et == TDOUBLE || et == TVLONG)
91374a4d8c2SCharles.Forsyth 			a = AMULD;
91474a4d8c2SCharles.Forsyth 		break;
91574a4d8c2SCharles.Forsyth 
91674a4d8c2SCharles.Forsyth 	case OASDIV:
91774a4d8c2SCharles.Forsyth 	case ODIV:
91874a4d8c2SCharles.Forsyth 		a = ADIV;
91974a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
92074a4d8c2SCharles.Forsyth 			a = ADIVF;
92174a4d8c2SCharles.Forsyth 		else
92274a4d8c2SCharles.Forsyth 		if(et == TDOUBLE || et == TVLONG)
92374a4d8c2SCharles.Forsyth 			a = ADIVD;
92474a4d8c2SCharles.Forsyth 		break;
92574a4d8c2SCharles.Forsyth 
92674a4d8c2SCharles.Forsyth 	case OASMOD:
92774a4d8c2SCharles.Forsyth 	case OMOD:
92874a4d8c2SCharles.Forsyth 		a = AMOD;
92974a4d8c2SCharles.Forsyth 		break;
93074a4d8c2SCharles.Forsyth 
93174a4d8c2SCharles.Forsyth 	case OASLMUL:
93274a4d8c2SCharles.Forsyth 	case OLMUL:
93374a4d8c2SCharles.Forsyth 		a = AMULU;
93474a4d8c2SCharles.Forsyth 		break;
93574a4d8c2SCharles.Forsyth 
93674a4d8c2SCharles.Forsyth 	case OASLMOD:
93774a4d8c2SCharles.Forsyth 	case OLMOD:
93874a4d8c2SCharles.Forsyth 		a = AMODU;
93974a4d8c2SCharles.Forsyth 		break;
94074a4d8c2SCharles.Forsyth 
94174a4d8c2SCharles.Forsyth 	case OASLDIV:
94274a4d8c2SCharles.Forsyth 	case OLDIV:
94374a4d8c2SCharles.Forsyth 		a = ADIVU;
94474a4d8c2SCharles.Forsyth 		break;
94574a4d8c2SCharles.Forsyth 
94674a4d8c2SCharles.Forsyth 	case OEQ:
94774a4d8c2SCharles.Forsyth 	case ONE:
94874a4d8c2SCharles.Forsyth 	case OLT:
94974a4d8c2SCharles.Forsyth 	case OLE:
95074a4d8c2SCharles.Forsyth 	case OGE:
95174a4d8c2SCharles.Forsyth 	case OGT:
95274a4d8c2SCharles.Forsyth 	case OLO:
95374a4d8c2SCharles.Forsyth 	case OLS:
95474a4d8c2SCharles.Forsyth 	case OHS:
95574a4d8c2SCharles.Forsyth 	case OHI:
95674a4d8c2SCharles.Forsyth 		a = ACMP;
95774a4d8c2SCharles.Forsyth 		if(et == TFLOAT)
95874a4d8c2SCharles.Forsyth 			a = ACMPF;
95974a4d8c2SCharles.Forsyth 		else
96074a4d8c2SCharles.Forsyth 		if(et == TDOUBLE || et == TVLONG)
96174a4d8c2SCharles.Forsyth 			a = ACMPD;
96274a4d8c2SCharles.Forsyth 		nextpc();
96374a4d8c2SCharles.Forsyth 		p->as = a;
96474a4d8c2SCharles.Forsyth 		naddr(f1, &p->from);
96574a4d8c2SCharles.Forsyth /*
96674a4d8c2SCharles.Forsyth 		if(a == ACMP && f1->op == OCONST && p->from.offset < 0) {
96774a4d8c2SCharles.Forsyth 			p->as = ACMN;
96874a4d8c2SCharles.Forsyth 			p->from.offset = -p->from.offset;
96974a4d8c2SCharles.Forsyth 		}
97074a4d8c2SCharles.Forsyth */
97174a4d8c2SCharles.Forsyth 		raddr(f2, p);	// expects it to be a register
97274a4d8c2SCharles.Forsyth 		switch(o) {
97374a4d8c2SCharles.Forsyth 		case OEQ:
97474a4d8c2SCharles.Forsyth 			a = ABEQ;
97574a4d8c2SCharles.Forsyth 			break;
97674a4d8c2SCharles.Forsyth 		case ONE:
97774a4d8c2SCharles.Forsyth 			a = ABNE;
97874a4d8c2SCharles.Forsyth 			break;
97974a4d8c2SCharles.Forsyth 		case OLT:
98074a4d8c2SCharles.Forsyth 			a = ABLT;
98174a4d8c2SCharles.Forsyth 			break;
98274a4d8c2SCharles.Forsyth 		case OLE:
98374a4d8c2SCharles.Forsyth 			a = ABLE;
98474a4d8c2SCharles.Forsyth 			break;
98574a4d8c2SCharles.Forsyth 		case OGE:
98674a4d8c2SCharles.Forsyth 			a = ABGE;
98774a4d8c2SCharles.Forsyth 			break;
98874a4d8c2SCharles.Forsyth 		case OGT:
98974a4d8c2SCharles.Forsyth 			a = ABGT;
99074a4d8c2SCharles.Forsyth 			break;
99174a4d8c2SCharles.Forsyth 		case OLO:
99274a4d8c2SCharles.Forsyth 			a = ABLO;
99374a4d8c2SCharles.Forsyth 			break;
99474a4d8c2SCharles.Forsyth 		case OLS:
99574a4d8c2SCharles.Forsyth 			a = ABLS;
99674a4d8c2SCharles.Forsyth 			break;
99774a4d8c2SCharles.Forsyth 		case OHS:
99874a4d8c2SCharles.Forsyth 			a = ABHS;
99974a4d8c2SCharles.Forsyth 			break;
100074a4d8c2SCharles.Forsyth 		case OHI:
100174a4d8c2SCharles.Forsyth 			a = ABHI;
100274a4d8c2SCharles.Forsyth 			break;
100374a4d8c2SCharles.Forsyth 		}
100474a4d8c2SCharles.Forsyth 		f1 = Z;
100574a4d8c2SCharles.Forsyth 		f2 = Z;
100674a4d8c2SCharles.Forsyth 		break;
100774a4d8c2SCharles.Forsyth 	}
100874a4d8c2SCharles.Forsyth 	if(a == AGOK)
100974a4d8c2SCharles.Forsyth 		diag(Z, "bad in gopcode %O", o);
101074a4d8c2SCharles.Forsyth 	nextpc();
101174a4d8c2SCharles.Forsyth 	p->as = a;
101274a4d8c2SCharles.Forsyth 	if(f1 != Z)
101374a4d8c2SCharles.Forsyth 		naddr(f1, &p->from);
101474a4d8c2SCharles.Forsyth 	if(f2 != Z) {
101574a4d8c2SCharles.Forsyth 		naddr(f2, &ta);
101674a4d8c2SCharles.Forsyth 		p->reg = ta.reg;
101774a4d8c2SCharles.Forsyth 	}
101874a4d8c2SCharles.Forsyth 	if(t != Z)
101974a4d8c2SCharles.Forsyth 		naddr(t, &p->to);
102074a4d8c2SCharles.Forsyth 	if(debug['g'])
102174a4d8c2SCharles.Forsyth 		print("%P\n", p);
102274a4d8c2SCharles.Forsyth }
102374a4d8c2SCharles.Forsyth 
102474a4d8c2SCharles.Forsyth /* put f1 in a register first */
102574a4d8c2SCharles.Forsyth void
gopcode2(int o,Node * f1,Node * f2,Node * t)102674a4d8c2SCharles.Forsyth gopcode2(int o, Node *f1, Node *f2, Node *t)
102774a4d8c2SCharles.Forsyth {
102874a4d8c2SCharles.Forsyth 	Node nod;
102974a4d8c2SCharles.Forsyth 
103074a4d8c2SCharles.Forsyth 	if(f2 != Z)
103174a4d8c2SCharles.Forsyth 		diag(Z, "bad parameter in gopcode2");
103274a4d8c2SCharles.Forsyth 	// regalloc(&nod, t, Z);
103374a4d8c2SCharles.Forsyth 	nodreg(&nod, t, REGTMPT);
103474a4d8c2SCharles.Forsyth 	gopcode(OAS, f1, Z, &nod);
103574a4d8c2SCharles.Forsyth 	gopcode(o, &nod, Z, t);
103674a4d8c2SCharles.Forsyth 	// regfree(&nod);
103774a4d8c2SCharles.Forsyth }
103874a4d8c2SCharles.Forsyth 
1039*45a20ab7Sforsyth int
samaddr(Node * f,Node * t)104074a4d8c2SCharles.Forsyth samaddr(Node *f, Node *t)
104174a4d8c2SCharles.Forsyth {
104274a4d8c2SCharles.Forsyth 
104374a4d8c2SCharles.Forsyth 	if(f->op != t->op)
104474a4d8c2SCharles.Forsyth 		return 0;
104574a4d8c2SCharles.Forsyth 	switch(f->op) {
104674a4d8c2SCharles.Forsyth 
104774a4d8c2SCharles.Forsyth 	case OREGISTER:
104874a4d8c2SCharles.Forsyth 		if(f->reg != t->reg)
104974a4d8c2SCharles.Forsyth 			break;
105074a4d8c2SCharles.Forsyth 		return 1;
105174a4d8c2SCharles.Forsyth 	}
105274a4d8c2SCharles.Forsyth 	return 0;
105374a4d8c2SCharles.Forsyth }
105474a4d8c2SCharles.Forsyth 
105574a4d8c2SCharles.Forsyth void
gbranch(int o)105674a4d8c2SCharles.Forsyth gbranch(int o)
105774a4d8c2SCharles.Forsyth {
105874a4d8c2SCharles.Forsyth 	int a;
105974a4d8c2SCharles.Forsyth 
106074a4d8c2SCharles.Forsyth 	a = AGOK;
106174a4d8c2SCharles.Forsyth 	switch(o) {
106274a4d8c2SCharles.Forsyth 	case ORETURN:
106374a4d8c2SCharles.Forsyth 		a = ARET;
106474a4d8c2SCharles.Forsyth 		break;
106574a4d8c2SCharles.Forsyth 	case OGOTO:
106674a4d8c2SCharles.Forsyth 		a = AB;
106774a4d8c2SCharles.Forsyth 		break;
106874a4d8c2SCharles.Forsyth 	}
106974a4d8c2SCharles.Forsyth 	nextpc();
107074a4d8c2SCharles.Forsyth 	if(a == AGOK) {
107174a4d8c2SCharles.Forsyth 		diag(Z, "bad in gbranch %O",  o);
107274a4d8c2SCharles.Forsyth 		nextpc();
107374a4d8c2SCharles.Forsyth 	}
107474a4d8c2SCharles.Forsyth 	p->as = a;
107574a4d8c2SCharles.Forsyth }
107674a4d8c2SCharles.Forsyth 
107774a4d8c2SCharles.Forsyth void
patch(Prog * op,long pc)107874a4d8c2SCharles.Forsyth patch(Prog *op, long pc)
107974a4d8c2SCharles.Forsyth {
108074a4d8c2SCharles.Forsyth 
108174a4d8c2SCharles.Forsyth 	op->to.offset = pc;
108274a4d8c2SCharles.Forsyth 	op->to.type = D_BRANCH;
108374a4d8c2SCharles.Forsyth }
108474a4d8c2SCharles.Forsyth 
108574a4d8c2SCharles.Forsyth void
gpseudo(int a,Sym * s,Node * n)108674a4d8c2SCharles.Forsyth gpseudo(int a, Sym *s, Node *n)
108774a4d8c2SCharles.Forsyth {
108874a4d8c2SCharles.Forsyth 
108974a4d8c2SCharles.Forsyth 	nextpc();
109074a4d8c2SCharles.Forsyth 	p->as = a;
109174a4d8c2SCharles.Forsyth 	p->from.type = D_OREG;
109274a4d8c2SCharles.Forsyth 	p->from.sym = s;
109374a4d8c2SCharles.Forsyth 	p->from.name = D_EXTERN;
109474a4d8c2SCharles.Forsyth 	if(a == ATEXT)
109574a4d8c2SCharles.Forsyth 		p->reg = (profileflg ? 0 : NOPROF);
109674a4d8c2SCharles.Forsyth 	if(s->class == CSTATIC)
109774a4d8c2SCharles.Forsyth 		p->from.name = D_STATIC;
109874a4d8c2SCharles.Forsyth 	naddr(n, &p->to);
109974a4d8c2SCharles.Forsyth 	if(a == ADATA || a == AGLOBL)
110074a4d8c2SCharles.Forsyth 		pc--;
110174a4d8c2SCharles.Forsyth }
110274a4d8c2SCharles.Forsyth 
110374a4d8c2SCharles.Forsyth int
sconst(Node * n)110474a4d8c2SCharles.Forsyth sconst(Node *n)
110574a4d8c2SCharles.Forsyth {
110674a4d8c2SCharles.Forsyth 	vlong vv;
110774a4d8c2SCharles.Forsyth 
110874a4d8c2SCharles.Forsyth 	if(n->op == OCONST) {
110974a4d8c2SCharles.Forsyth 		if(!typefd[n->type->etype]) {
111074a4d8c2SCharles.Forsyth 			vv = n->vconst;
111174a4d8c2SCharles.Forsyth 			if(vv >= (vlong)0 && vv < (vlong)256)
111274a4d8c2SCharles.Forsyth 				return 1;
111374a4d8c2SCharles.Forsyth 			/*
111474a4d8c2SCharles.Forsyth 			 * should be specialised for constant values which will
111574a4d8c2SCharles.Forsyth 			 * fit in different instructionsl; for now, let 5l
111674a4d8c2SCharles.Forsyth 			 * sort it out
111774a4d8c2SCharles.Forsyth 			 */
111874a4d8c2SCharles.Forsyth 			return 1;
111974a4d8c2SCharles.Forsyth 		}
112074a4d8c2SCharles.Forsyth 	}
112174a4d8c2SCharles.Forsyth 	return 0;
112274a4d8c2SCharles.Forsyth }
112374a4d8c2SCharles.Forsyth 
112474a4d8c2SCharles.Forsyth int
sval(long v)112574a4d8c2SCharles.Forsyth sval(long v)
112674a4d8c2SCharles.Forsyth {
112774a4d8c2SCharles.Forsyth 	if(v >= -32768 && v < 32768)
112874a4d8c2SCharles.Forsyth 		return 1;
112974a4d8c2SCharles.Forsyth 	return 0;
113074a4d8c2SCharles.Forsyth }
113174a4d8c2SCharles.Forsyth 
113274a4d8c2SCharles.Forsyth long
exreg(Type * t)113374a4d8c2SCharles.Forsyth exreg(Type *t)
113474a4d8c2SCharles.Forsyth {
113574a4d8c2SCharles.Forsyth 	long o;
113674a4d8c2SCharles.Forsyth 
113774a4d8c2SCharles.Forsyth 	if(typechlp[t->etype]) {
113874a4d8c2SCharles.Forsyth 		if(exregoffset <= NREG-1)
113974a4d8c2SCharles.Forsyth 			return 0;
114074a4d8c2SCharles.Forsyth 		o = exregoffset;
114174a4d8c2SCharles.Forsyth 		exregoffset--;
114274a4d8c2SCharles.Forsyth 		return o;
114374a4d8c2SCharles.Forsyth 	}
114474a4d8c2SCharles.Forsyth 	if(typefd[t->etype]) {
114574a4d8c2SCharles.Forsyth 		if(exfregoffset <= NFREG-1)
114674a4d8c2SCharles.Forsyth 			return 0;
114774a4d8c2SCharles.Forsyth 		o = exfregoffset + NREG;
114874a4d8c2SCharles.Forsyth 		exfregoffset--;
114974a4d8c2SCharles.Forsyth 		return o;
115074a4d8c2SCharles.Forsyth 	}
115174a4d8c2SCharles.Forsyth 	return 0;
115274a4d8c2SCharles.Forsyth }
115374a4d8c2SCharles.Forsyth 
115474a4d8c2SCharles.Forsyth schar	ewidth[NTYPE] =
115574a4d8c2SCharles.Forsyth {
115674a4d8c2SCharles.Forsyth 	-1,		/* [TXXX] */
115774a4d8c2SCharles.Forsyth 	SZ_CHAR,	/* [TCHAR] */
115874a4d8c2SCharles.Forsyth 	SZ_CHAR,	/* [TUCHAR] */
115974a4d8c2SCharles.Forsyth 	SZ_SHORT,	/* [TSHORT] */
116074a4d8c2SCharles.Forsyth 	SZ_SHORT,	/* [TUSHORT] */
116174a4d8c2SCharles.Forsyth 	SZ_INT,		/* [TINT] */
116274a4d8c2SCharles.Forsyth 	SZ_INT,		/* [TUINT] */
116374a4d8c2SCharles.Forsyth 	SZ_LONG,	/* [TLONG] */
116474a4d8c2SCharles.Forsyth 	SZ_LONG,	/* [TULONG] */
116574a4d8c2SCharles.Forsyth 	SZ_VLONG,	/* [TVLONG] */
116674a4d8c2SCharles.Forsyth 	SZ_VLONG,	/* [TUVLONG] */
116774a4d8c2SCharles.Forsyth 	SZ_FLOAT,	/* [TFLOAT] */
116874a4d8c2SCharles.Forsyth 	SZ_DOUBLE,	/* [TDOUBLE] */
116974a4d8c2SCharles.Forsyth 	SZ_IND,		/* [TIND] */
117074a4d8c2SCharles.Forsyth 	0,		/* [TFUNC] */
117174a4d8c2SCharles.Forsyth 	-1,		/* [TARRAY] */
117274a4d8c2SCharles.Forsyth 	0,		/* [TVOID] */
117374a4d8c2SCharles.Forsyth 	-1,		/* [TSTRUCT] */
117474a4d8c2SCharles.Forsyth 	-1,		/* [TUNION] */
117574a4d8c2SCharles.Forsyth 	SZ_INT,		/* [TENUM] */
117674a4d8c2SCharles.Forsyth };
117774a4d8c2SCharles.Forsyth 
117874a4d8c2SCharles.Forsyth long	ncast[NTYPE] =
117974a4d8c2SCharles.Forsyth {
118074a4d8c2SCharles.Forsyth 	0,				/* [TXXX] */
118174a4d8c2SCharles.Forsyth 	BCHAR|BUCHAR,			/* [TCHAR] */
118274a4d8c2SCharles.Forsyth 	BCHAR|BUCHAR,			/* [TUCHAR] */
118374a4d8c2SCharles.Forsyth 	BSHORT|BUSHORT,			/* [TSHORT] */
118474a4d8c2SCharles.Forsyth 	BSHORT|BUSHORT,			/* [TUSHORT] */
118574a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TINT] */
118674a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TUINT] */
118774a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TLONG] */
118874a4d8c2SCharles.Forsyth 	BINT|BUINT|BLONG|BULONG|BIND,	/* [TULONG] */
118974a4d8c2SCharles.Forsyth 	BVLONG|BUVLONG,			/* [TVLONG] */
119074a4d8c2SCharles.Forsyth 	BVLONG|BUVLONG,			/* [TUVLONG] */
119174a4d8c2SCharles.Forsyth 	BFLOAT,				/* [TFLOAT] */
119274a4d8c2SCharles.Forsyth 	BDOUBLE,			/* [TDOUBLE] */
119374a4d8c2SCharles.Forsyth 	BLONG|BULONG|BIND,		/* [TIND] */
119474a4d8c2SCharles.Forsyth 	0,				/* [TFUNC] */
119574a4d8c2SCharles.Forsyth 	0,				/* [TARRAY] */
119674a4d8c2SCharles.Forsyth 	0,				/* [TVOID] */
119774a4d8c2SCharles.Forsyth 	BSTRUCT,			/* [TSTRUCT] */
119874a4d8c2SCharles.Forsyth 	BUNION,				/* [TUNION] */
119974a4d8c2SCharles.Forsyth 	0,				/* [TENUM] */
120074a4d8c2SCharles.Forsyth };
1201