xref: /plan9-contrib/sys/src/cmd/6c/txt.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
1e887ea33SDavid du Colombier #include "gc.h"
2e887ea33SDavid du Colombier 
3b94bb474SDavid du Colombier static	int	resvreg[nelem(reg)];
4b94bb474SDavid du Colombier 
5e887ea33SDavid du Colombier void
ginit(void)6e887ea33SDavid du Colombier ginit(void)
7e887ea33SDavid du Colombier {
8e887ea33SDavid du Colombier 	int i;
9e887ea33SDavid du Colombier 	Type *t;
10e887ea33SDavid du Colombier 
11e887ea33SDavid du Colombier 	thechar = '6';
12e887ea33SDavid du Colombier 	thestring = "amd64";
13e887ea33SDavid du Colombier 	exregoffset = REGEXT;
14e887ea33SDavid du Colombier 	exfregoffset = FREGEXT;
15e887ea33SDavid du Colombier 	listinit();
16e887ea33SDavid du Colombier 	nstring = 0;
17e887ea33SDavid du Colombier 	mnstring = 0;
18e887ea33SDavid du Colombier 	nrathole = 0;
19e887ea33SDavid du Colombier 	pc = 0;
20e887ea33SDavid du Colombier 	breakpc = -1;
21e887ea33SDavid du Colombier 	continpc = -1;
22e887ea33SDavid du Colombier 	cases = C;
23e887ea33SDavid du Colombier 	firstp = P;
24e887ea33SDavid du Colombier 	lastp = P;
25e887ea33SDavid du Colombier 	tfield = types[TINT];
26e887ea33SDavid du Colombier 
27e887ea33SDavid du Colombier 	typeword = typechlvp;
283a276d32SDavid du Colombier 	typeswitch = typechlv;
29e887ea33SDavid du Colombier 	typecmplx = typesu;
30e887ea33SDavid du Colombier 
31e887ea33SDavid du Colombier 	/* TO DO */
32e887ea33SDavid du Colombier 	memmove(typechlpv, typechlp, sizeof(typechlpv));
33e887ea33SDavid du Colombier 	typechlpv[TVLONG] = 1;
34e887ea33SDavid du Colombier 	typechlpv[TUVLONG] = 1;
35e887ea33SDavid du Colombier 
36e887ea33SDavid du Colombier 	zprog.link = P;
37e887ea33SDavid du Colombier 	zprog.as = AGOK;
38e887ea33SDavid du Colombier 	zprog.from.type = D_NONE;
39e887ea33SDavid du Colombier 	zprog.from.index = D_NONE;
40e887ea33SDavid du Colombier 	zprog.from.scale = 0;
41e887ea33SDavid du Colombier 	zprog.to = zprog.from;
42e887ea33SDavid du Colombier 
43e887ea33SDavid du Colombier 	lregnode.op = OREGISTER;
44e887ea33SDavid du Colombier 	lregnode.class = CEXREG;
45e887ea33SDavid du Colombier 	lregnode.reg = REGTMP;
46e887ea33SDavid du Colombier 	lregnode.complex = 0;
47e887ea33SDavid du Colombier 	lregnode.addable = 11;
48e887ea33SDavid du Colombier 	lregnode.type = types[TLONG];
49e887ea33SDavid du Colombier 
50e887ea33SDavid du Colombier 	qregnode = lregnode;
51e887ea33SDavid du Colombier 	qregnode.type = types[TVLONG];
52e887ea33SDavid du Colombier 
53e887ea33SDavid du Colombier 	constnode.op = OCONST;
54e887ea33SDavid du Colombier 	constnode.class = CXXX;
55e887ea33SDavid du Colombier 	constnode.complex = 0;
56e887ea33SDavid du Colombier 	constnode.addable = 20;
57e887ea33SDavid du Colombier 	constnode.type = types[TLONG];
58e887ea33SDavid du Colombier 
59e887ea33SDavid du Colombier 	vconstnode = constnode;
60e887ea33SDavid du Colombier 	vconstnode.type = types[TVLONG];
61e887ea33SDavid du Colombier 
62e887ea33SDavid du Colombier 	fconstnode.op = OCONST;
63e887ea33SDavid du Colombier 	fconstnode.class = CXXX;
64e887ea33SDavid du Colombier 	fconstnode.complex = 0;
65e887ea33SDavid du Colombier 	fconstnode.addable = 20;
66e887ea33SDavid du Colombier 	fconstnode.type = types[TDOUBLE];
67e887ea33SDavid du Colombier 
68e887ea33SDavid du Colombier 	nodsafe = new(ONAME, Z, Z);
69e887ea33SDavid du Colombier 	nodsafe->sym = slookup(".safe");
70e887ea33SDavid du Colombier 	nodsafe->type = types[TINT];
71e887ea33SDavid du Colombier 	nodsafe->etype = types[TINT]->etype;
72e887ea33SDavid du Colombier 	nodsafe->class = CAUTO;
73e887ea33SDavid du Colombier 	complex(nodsafe);
74e887ea33SDavid du Colombier 
75e887ea33SDavid du Colombier 	t = typ(TARRAY, types[TCHAR]);
76e887ea33SDavid du Colombier 	symrathole = slookup(".rathole");
77e887ea33SDavid du Colombier 	symrathole->class = CGLOBL;
78e887ea33SDavid du Colombier 	symrathole->type = t;
79e887ea33SDavid du Colombier 
80e887ea33SDavid du Colombier 	nodrat = new(ONAME, Z, Z);
81e887ea33SDavid du Colombier 	nodrat->sym = symrathole;
82e887ea33SDavid du Colombier 	nodrat->type = types[TIND];
83e887ea33SDavid du Colombier 	nodrat->etype = TVOID;
84e887ea33SDavid du Colombier 	nodrat->class = CGLOBL;
85e887ea33SDavid du Colombier 	complex(nodrat);
86e887ea33SDavid du Colombier 	nodrat->type = t;
87e887ea33SDavid du Colombier 
88e887ea33SDavid du Colombier 	nodret = new(ONAME, Z, Z);
89e887ea33SDavid du Colombier 	nodret->sym = slookup(".ret");
90e887ea33SDavid du Colombier 	nodret->type = types[TIND];
91e887ea33SDavid du Colombier 	nodret->etype = TIND;
92e887ea33SDavid du Colombier 	nodret->class = CPARAM;
93e887ea33SDavid du Colombier 	nodret = new(OIND, nodret, Z);
94e887ea33SDavid du Colombier 	complex(nodret);
95e887ea33SDavid du Colombier 
96b94bb474SDavid du Colombier 	memset(reg, 0, sizeof(reg));
97e887ea33SDavid du Colombier 	for(i=0; i<nelem(reg); i++) {
98e887ea33SDavid du Colombier 		reg[i] = 1;
99e887ea33SDavid du Colombier 		if(i >= D_AX && i <= D_R15 && i != D_SP)
100e887ea33SDavid du Colombier 			reg[i] = 0;
101e887ea33SDavid du Colombier 		if(i >= D_X0 && i <= D_X7)
102e887ea33SDavid du Colombier 			reg[i] = 0;
103e887ea33SDavid du Colombier 	}
104b94bb474SDavid du Colombier 	/* keep two external registers */
105b94bb474SDavid du Colombier 	reg[REGEXT] = 1;
106b94bb474SDavid du Colombier 	reg[REGEXT-1] = 1;
107b94bb474SDavid du Colombier 	memmove(resvreg, reg, sizeof(resvreg));
108e887ea33SDavid du Colombier }
109e887ea33SDavid du Colombier 
110e887ea33SDavid du Colombier void
gclean(void)111e887ea33SDavid du Colombier gclean(void)
112e887ea33SDavid du Colombier {
113e887ea33SDavid du Colombier 	int i;
114e887ea33SDavid du Colombier 	Sym *s;
115e887ea33SDavid du Colombier 
116e887ea33SDavid du Colombier 	reg[D_SP]--;
117e887ea33SDavid du Colombier 	for(i=D_AX; i<=D_R15; i++)
118b94bb474SDavid du Colombier 		if(reg[i] && !resvreg[i])
119e887ea33SDavid du Colombier 			diag(Z, "reg %R left allocated", i);
120e887ea33SDavid du Colombier 	for(i=D_X0; i<=D_X7; i++)
121b94bb474SDavid du Colombier 		if(reg[i] && !resvreg[i])
122e887ea33SDavid du Colombier 			diag(Z, "reg %R left allocated", i);
123e887ea33SDavid du Colombier 	while(mnstring)
124e887ea33SDavid du Colombier 		outstring("", 1L);
125e887ea33SDavid du Colombier 	symstring->type->width = nstring;
126e887ea33SDavid du Colombier 	symrathole->type->width = nrathole;
127e887ea33SDavid du Colombier 	for(i=0; i<NHASH; i++)
128e887ea33SDavid du Colombier 	for(s = hash[i]; s != S; s = s->link) {
129e887ea33SDavid du Colombier 		if(s->type == T)
130e887ea33SDavid du Colombier 			continue;
131e887ea33SDavid du Colombier 		if(s->type->width == 0)
132e887ea33SDavid du Colombier 			continue;
133e887ea33SDavid du Colombier 		if(s->class != CGLOBL && s->class != CSTATIC)
134e887ea33SDavid du Colombier 			continue;
135e887ea33SDavid du Colombier 		if(s->type == types[TENUM])
136e887ea33SDavid du Colombier 			continue;
137e887ea33SDavid du Colombier 		gpseudo(AGLOBL, s, nodconst(s->type->width));
138e887ea33SDavid du Colombier 	}
139e887ea33SDavid du Colombier 	nextpc();
140e887ea33SDavid du Colombier 	p->as = AEND;
141e887ea33SDavid du Colombier 	outcode();
142e887ea33SDavid du Colombier }
143e887ea33SDavid du Colombier 
144e887ea33SDavid du Colombier void
nextpc(void)145e887ea33SDavid du Colombier nextpc(void)
146e887ea33SDavid du Colombier {
147e887ea33SDavid du Colombier 
148e887ea33SDavid du Colombier 	p = alloc(sizeof(*p));
149e887ea33SDavid du Colombier 	*p = zprog;
150e887ea33SDavid du Colombier 	p->lineno = nearln;
151e887ea33SDavid du Colombier 	pc++;
152e887ea33SDavid du Colombier 	if(firstp == P) {
153e887ea33SDavid du Colombier 		firstp = p;
154e887ea33SDavid du Colombier 		lastp = p;
155e887ea33SDavid du Colombier 		return;
156e887ea33SDavid du Colombier 	}
157e887ea33SDavid du Colombier 	lastp->link = p;
158e887ea33SDavid du Colombier 	lastp = p;
159e887ea33SDavid du Colombier }
160e887ea33SDavid du Colombier 
161e887ea33SDavid du Colombier void
gargs(Node * n,Node * tn1,Node * tn2)162e887ea33SDavid du Colombier gargs(Node *n, Node *tn1, Node *tn2)
163e887ea33SDavid du Colombier {
164e887ea33SDavid du Colombier 	long regs;
165e887ea33SDavid du Colombier 	Node fnxargs[20], *fnxp;
166e887ea33SDavid du Colombier 
167e887ea33SDavid du Colombier 	regs = cursafe;
168e887ea33SDavid du Colombier 
169e887ea33SDavid du Colombier 	fnxp = fnxargs;
170e887ea33SDavid du Colombier 	garg1(n, tn1, tn2, 0, &fnxp);	/* compile fns to temps */
171e887ea33SDavid du Colombier 
172e887ea33SDavid du Colombier 	curarg = 0;
173e887ea33SDavid du Colombier 	fnxp = fnxargs;
174e887ea33SDavid du Colombier 	garg1(n, tn1, tn2, 1, &fnxp);	/* compile normal args and temps */
175e887ea33SDavid du Colombier 
176e887ea33SDavid du Colombier 	cursafe = regs;
177e887ea33SDavid du Colombier }
178e887ea33SDavid du Colombier 
179e887ea33SDavid du Colombier int
nareg(void)180e887ea33SDavid du Colombier nareg(void)
181e887ea33SDavid du Colombier {
182e887ea33SDavid du Colombier 	int i, n;
183e887ea33SDavid du Colombier 
184e887ea33SDavid du Colombier 	n = 0;
185e887ea33SDavid du Colombier 	for(i=D_AX; i<=D_R15; i++)
186b94bb474SDavid du Colombier 		if(reg[i] == 0 && !resvreg[i])
187e887ea33SDavid du Colombier 			n++;
188e887ea33SDavid du Colombier 	return n;
189e887ea33SDavid du Colombier }
190e887ea33SDavid du Colombier 
191e887ea33SDavid du Colombier void
garg1(Node * n,Node * tn1,Node * tn2,int f,Node ** fnxp)192e887ea33SDavid du Colombier garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
193e887ea33SDavid du Colombier {
194e887ea33SDavid du Colombier 	Node nod;
195e887ea33SDavid du Colombier 
196e887ea33SDavid du Colombier 	if(n == Z)
197e887ea33SDavid du Colombier 		return;
198e887ea33SDavid du Colombier 	if(n->op == OLIST) {
199e887ea33SDavid du Colombier 		garg1(n->left, tn1, tn2, f, fnxp);
200e887ea33SDavid du Colombier 		garg1(n->right, tn1, tn2, f, fnxp);
201e887ea33SDavid du Colombier 		return;
202e887ea33SDavid du Colombier 	}
203e887ea33SDavid du Colombier 	if(f == 0) {
204e887ea33SDavid du Colombier 		if(n->complex >= FNX) {
205e887ea33SDavid du Colombier 			regsalloc(*fnxp, n);
206e887ea33SDavid du Colombier 			nod = znode;
207e887ea33SDavid du Colombier 			nod.op = OAS;
208e887ea33SDavid du Colombier 			nod.left = *fnxp;
209e887ea33SDavid du Colombier 			nod.right = n;
210e887ea33SDavid du Colombier 			nod.type = n->type;
211e887ea33SDavid du Colombier 			cgen(&nod, Z);
212e887ea33SDavid du Colombier 			(*fnxp)++;
213e887ea33SDavid du Colombier 		}
214e887ea33SDavid du Colombier 		return;
215e887ea33SDavid du Colombier 	}
216e887ea33SDavid du Colombier 	if(typesu[n->type->etype]) {
217e887ea33SDavid du Colombier 		regaalloc(tn2, n);
218e887ea33SDavid du Colombier 		if(n->complex >= FNX) {
219e887ea33SDavid du Colombier 			sugen(*fnxp, tn2, n->type->width);
220e887ea33SDavid du Colombier 			(*fnxp)++;
221e887ea33SDavid du Colombier 		} else
222e887ea33SDavid du Colombier 			sugen(n, tn2, n->type->width);
223e887ea33SDavid du Colombier 		return;
224e887ea33SDavid du Colombier 	}
225e887ea33SDavid du Colombier 	if(REGARG && curarg == 0 && typechlpv[n->type->etype]) {
226e887ea33SDavid du Colombier 		regaalloc1(tn1, n);
227e887ea33SDavid du Colombier 		if(n->complex >= FNX) {
228e887ea33SDavid du Colombier 			cgen(*fnxp, tn1);
229e887ea33SDavid du Colombier 			(*fnxp)++;
230e887ea33SDavid du Colombier 		} else
231e887ea33SDavid du Colombier 			cgen(n, tn1);
232e887ea33SDavid du Colombier 		return;
233e887ea33SDavid du Colombier 	}
234e887ea33SDavid du Colombier 	if(vconst(n) == 0) {
235e887ea33SDavid du Colombier 		regaalloc(tn2, n);
236e887ea33SDavid du Colombier 		gmove(n, tn2);
237e887ea33SDavid du Colombier 		return;
238e887ea33SDavid du Colombier 	}
239e887ea33SDavid du Colombier 	regalloc(tn1, n, Z);
240e887ea33SDavid du Colombier 	if(n->complex >= FNX) {
241e887ea33SDavid du Colombier 		cgen(*fnxp, tn1);
242e887ea33SDavid du Colombier 		(*fnxp)++;
243e887ea33SDavid du Colombier 	} else
244e887ea33SDavid du Colombier 		cgen(n, tn1);
245e887ea33SDavid du Colombier 	regaalloc(tn2, n);
246e887ea33SDavid du Colombier 	gmove(tn1, tn2);
247e887ea33SDavid du Colombier 	regfree(tn1);
248e887ea33SDavid du Colombier }
249e887ea33SDavid du Colombier 
250e887ea33SDavid du Colombier Node*
nodgconst(vlong v,Type * t)251e887ea33SDavid du Colombier nodgconst(vlong v, Type *t)
252e887ea33SDavid du Colombier {
253e887ea33SDavid du Colombier 	if(!typev[t->etype])
254e887ea33SDavid du Colombier 		return nodconst((long)v);
255e887ea33SDavid du Colombier 	vconstnode.vconst = v;
256e887ea33SDavid du Colombier 	return &vconstnode;
257e887ea33SDavid du Colombier }
258e887ea33SDavid du Colombier 
259e887ea33SDavid du Colombier Node*
nodconst(long v)260e887ea33SDavid du Colombier nodconst(long v)
261e887ea33SDavid du Colombier {
262e887ea33SDavid du Colombier 	constnode.vconst = v;
263e887ea33SDavid du Colombier 	return &constnode;
264e887ea33SDavid du Colombier }
265e887ea33SDavid du Colombier 
266e887ea33SDavid du Colombier Node*
nodfconst(double d)267e887ea33SDavid du Colombier nodfconst(double d)
268e887ea33SDavid du Colombier {
269e887ea33SDavid du Colombier 	fconstnode.fconst = d;
270e887ea33SDavid du Colombier 	return &fconstnode;
271e887ea33SDavid du Colombier }
272e887ea33SDavid du Colombier 
273e887ea33SDavid du Colombier int
isreg(Node * n,int r)274e887ea33SDavid du Colombier isreg(Node *n, int r)
275e887ea33SDavid du Colombier {
276e887ea33SDavid du Colombier 
277e887ea33SDavid du Colombier 	if(n->op == OREGISTER)
278e887ea33SDavid du Colombier 		if(n->reg == r)
279e887ea33SDavid du Colombier 			return 1;
280e887ea33SDavid du Colombier 	return 0;
281e887ea33SDavid du Colombier }
282e887ea33SDavid du Colombier 
283e887ea33SDavid du Colombier int
nodreg(Node * n,Node * nn,int r)284e887ea33SDavid du Colombier nodreg(Node *n, Node *nn, int r)
285e887ea33SDavid du Colombier {
286e887ea33SDavid du Colombier 	int et;
287e887ea33SDavid du Colombier 
288e887ea33SDavid du Colombier 	*n = qregnode;
289e887ea33SDavid du Colombier 	n->reg = r;
290e887ea33SDavid du Colombier 	if(nn != Z){
291e887ea33SDavid du Colombier 		et = nn->type->etype;
292e887ea33SDavid du Colombier 		if(!typefd[et] && nn->type->width <= SZ_LONG && 0)
293e887ea33SDavid du Colombier 			n->type = typeu[et]? types[TUINT]: types[TINT];
294e887ea33SDavid du Colombier 		else
295e887ea33SDavid du Colombier 			n->type = nn->type;
296e887ea33SDavid du Colombier //print("nodreg %s [%s]\n", tnames[et], tnames[n->type->etype]);
297e887ea33SDavid du Colombier 		n->lineno = nn->lineno;
298e887ea33SDavid du Colombier 	}
299e887ea33SDavid du Colombier 	if(reg[r] == 0)
300e887ea33SDavid du Colombier 		return 0;
301e887ea33SDavid du Colombier 	if(nn != Z) {
302e887ea33SDavid du Colombier 		if(nn->op == OREGISTER)
303e887ea33SDavid du Colombier 		if(nn->reg == r)
304e887ea33SDavid du Colombier 			return 0;
305e887ea33SDavid du Colombier 	}
306e887ea33SDavid du Colombier 	return 1;
307e887ea33SDavid du Colombier }
308e887ea33SDavid du Colombier 
309e887ea33SDavid du Colombier void
regret(Node * n,Node * nn)310e887ea33SDavid du Colombier regret(Node *n, Node *nn)
311e887ea33SDavid du Colombier {
312e887ea33SDavid du Colombier 	int r;
313e887ea33SDavid du Colombier 
314e887ea33SDavid du Colombier 	r = REGRET;
315e887ea33SDavid du Colombier 	if(typefd[nn->type->etype])
316e887ea33SDavid du Colombier 		r = FREGRET;
317e887ea33SDavid du Colombier 	nodreg(n, nn, r);
318e887ea33SDavid du Colombier 	reg[r]++;
319e887ea33SDavid du Colombier }
320e887ea33SDavid du Colombier 
321e887ea33SDavid du Colombier void
regalloc(Node * n,Node * tn,Node * o)322e887ea33SDavid du Colombier regalloc(Node *n, Node *tn, Node *o)
323e887ea33SDavid du Colombier {
324e887ea33SDavid du Colombier 	int i;
325e887ea33SDavid du Colombier 
326e887ea33SDavid du Colombier 	switch(tn->type->etype) {
327e887ea33SDavid du Colombier 	case TCHAR:
328e887ea33SDavid du Colombier 	case TUCHAR:
329e887ea33SDavid du Colombier 	case TSHORT:
330e887ea33SDavid du Colombier 	case TUSHORT:
331e887ea33SDavid du Colombier 	case TINT:
332e887ea33SDavid du Colombier 	case TUINT:
333e887ea33SDavid du Colombier 	case TLONG:
334e887ea33SDavid du Colombier 	case TULONG:
335e887ea33SDavid du Colombier 	case TVLONG:
336e887ea33SDavid du Colombier 	case TUVLONG:
337e887ea33SDavid du Colombier 	case TIND:
338e887ea33SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
339e887ea33SDavid du Colombier 			i = o->reg;
340e887ea33SDavid du Colombier 			if(i >= D_AX && i <= D_R15)
341e887ea33SDavid du Colombier 				goto out;
342e887ea33SDavid du Colombier 		}
343e887ea33SDavid du Colombier 		for(i=D_AX; i<=D_R15; i++)
344b94bb474SDavid du Colombier 			if(reg[i] == 0 && !resvreg[i])
345e887ea33SDavid du Colombier 				goto out;
346e887ea33SDavid du Colombier 		diag(tn, "out of fixed registers");
347e887ea33SDavid du Colombier 		goto err;
348e887ea33SDavid du Colombier 
349e887ea33SDavid du Colombier 	case TFLOAT:
350e887ea33SDavid du Colombier 	case TDOUBLE:
351e887ea33SDavid du Colombier 		if(o != Z && o->op == OREGISTER) {
352e887ea33SDavid du Colombier 			i = o->reg;
353e887ea33SDavid du Colombier 			if(i >= D_X0 && i <= D_X7)
354e887ea33SDavid du Colombier 				goto out;
355e887ea33SDavid du Colombier 		}
356e887ea33SDavid du Colombier 		for(i=D_X0; i<=D_X7; i++)
357b94bb474SDavid du Colombier 			if(reg[i] == 0 && !resvreg[i])
358e887ea33SDavid du Colombier 				goto out;
359e887ea33SDavid du Colombier 		diag(tn, "out of float registers");
360e887ea33SDavid du Colombier 		goto out;
361e887ea33SDavid du Colombier 	}
362e887ea33SDavid du Colombier 	diag(tn, "unknown type in regalloc: %T", tn->type);
363e887ea33SDavid du Colombier err:
364e887ea33SDavid du Colombier 	i = 0;
365e887ea33SDavid du Colombier out:
366e887ea33SDavid du Colombier 	if(i)
367e887ea33SDavid du Colombier 		reg[i]++;
368e887ea33SDavid du Colombier 	nodreg(n, tn, i);
369e887ea33SDavid du Colombier }
370e887ea33SDavid du Colombier 
371e887ea33SDavid du Colombier void
regialloc(Node * n,Node * tn,Node * o)372e887ea33SDavid du Colombier regialloc(Node *n, Node *tn, Node *o)
373e887ea33SDavid du Colombier {
374e887ea33SDavid du Colombier 	Node nod;
375e887ea33SDavid du Colombier 
376e887ea33SDavid du Colombier 	nod = *tn;
377e887ea33SDavid du Colombier 	nod.type = types[TIND];
378e887ea33SDavid du Colombier 	regalloc(n, &nod, o);
379e887ea33SDavid du Colombier }
380e887ea33SDavid du Colombier 
381e887ea33SDavid du Colombier void
regfree(Node * n)382e887ea33SDavid du Colombier regfree(Node *n)
383e887ea33SDavid du Colombier {
384e887ea33SDavid du Colombier 	int i;
385e887ea33SDavid du Colombier 
386e887ea33SDavid du Colombier 	i = 0;
387e887ea33SDavid du Colombier 	if(n->op != OREGISTER && n->op != OINDREG)
388e887ea33SDavid du Colombier 		goto err;
389e887ea33SDavid du Colombier 	i = n->reg;
390e887ea33SDavid du Colombier 	if(i < 0 || i >= sizeof(reg))
391e887ea33SDavid du Colombier 		goto err;
392e887ea33SDavid du Colombier 	if(reg[i] <= 0)
393e887ea33SDavid du Colombier 		goto err;
394e887ea33SDavid du Colombier 	reg[i]--;
395e887ea33SDavid du Colombier 	return;
396e887ea33SDavid du Colombier err:
397e887ea33SDavid du Colombier 	diag(n, "error in regfree: %R", i);
398e887ea33SDavid du Colombier }
399e887ea33SDavid du Colombier 
400e887ea33SDavid du Colombier void
regsalloc(Node * n,Node * nn)401e887ea33SDavid du Colombier regsalloc(Node *n, Node *nn)
402e887ea33SDavid du Colombier {
403e887ea33SDavid du Colombier 	cursafe = align(cursafe, nn->type, Aaut3);
404e887ea33SDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
405e887ea33SDavid du Colombier 	*n = *nodsafe;
406e887ea33SDavid du Colombier 	n->xoffset = -(stkoff + cursafe);
407e887ea33SDavid du Colombier 	n->type = nn->type;
408e887ea33SDavid du Colombier 	n->etype = nn->type->etype;
409e887ea33SDavid du Colombier 	n->lineno = nn->lineno;
410e887ea33SDavid du Colombier }
411e887ea33SDavid du Colombier 
412e887ea33SDavid du Colombier void
regaalloc1(Node * n,Node * nn)413e887ea33SDavid du Colombier regaalloc1(Node *n, Node *nn)
414e887ea33SDavid du Colombier {
415e887ea33SDavid du Colombier 	nodreg(n, nn, REGARG);
416e887ea33SDavid du Colombier 	reg[REGARG]++;
417e887ea33SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
418e887ea33SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
419e887ea33SDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
420e887ea33SDavid du Colombier }
421e887ea33SDavid du Colombier 
422e887ea33SDavid du Colombier void
regaalloc(Node * n,Node * nn)423e887ea33SDavid du Colombier regaalloc(Node *n, Node *nn)
424e887ea33SDavid du Colombier {
425e887ea33SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg1);
426e887ea33SDavid du Colombier 	*n = *nn;
427e887ea33SDavid du Colombier 	n->op = OINDREG;
428e887ea33SDavid du Colombier 	n->reg = REGSP;
429e887ea33SDavid du Colombier 	n->xoffset = curarg;
430e887ea33SDavid du Colombier 	n->complex = 0;
431e887ea33SDavid du Colombier 	n->addable = 20;
432e887ea33SDavid du Colombier 	curarg = align(curarg, nn->type, Aarg2);
433e887ea33SDavid du Colombier 	maxargsafe = maxround(maxargsafe, cursafe+curarg);
434e887ea33SDavid du Colombier }
435e887ea33SDavid du Colombier 
436e887ea33SDavid du Colombier void
regind(Node * n,Node * nn)437e887ea33SDavid du Colombier regind(Node *n, Node *nn)
438e887ea33SDavid du Colombier {
439e887ea33SDavid du Colombier 
440e887ea33SDavid du Colombier 	if(n->op != OREGISTER) {
441e887ea33SDavid du Colombier 		diag(n, "regind not OREGISTER");
442e887ea33SDavid du Colombier 		return;
443e887ea33SDavid du Colombier 	}
444e887ea33SDavid du Colombier 	n->op = OINDREG;
445e887ea33SDavid du Colombier 	n->type = nn->type;
446e887ea33SDavid du Colombier }
447e887ea33SDavid du Colombier 
448e887ea33SDavid du Colombier void
naddr(Node * n,Adr * a)449e887ea33SDavid du Colombier naddr(Node *n, Adr *a)
450e887ea33SDavid du Colombier {
451e887ea33SDavid du Colombier 	long v;
452e887ea33SDavid du Colombier 
453e887ea33SDavid du Colombier 	a->type = D_NONE;
454e887ea33SDavid du Colombier 	if(n == Z)
455e887ea33SDavid du Colombier 		return;
456e887ea33SDavid du Colombier 	switch(n->op) {
457e887ea33SDavid du Colombier 	default:
458e887ea33SDavid du Colombier 	bad:
459e887ea33SDavid du Colombier 		diag(n, "bad in naddr: %O %D", n->op, a);
460e887ea33SDavid du Colombier 		break;
461e887ea33SDavid du Colombier 
462e887ea33SDavid du Colombier 	case OREGISTER:
463e887ea33SDavid du Colombier 		a->type = n->reg;
464e887ea33SDavid du Colombier 		a->sym = S;
465e887ea33SDavid du Colombier 		break;
466e887ea33SDavid du Colombier 
467e887ea33SDavid du Colombier 
468e887ea33SDavid du Colombier 	case OIND:
469e887ea33SDavid du Colombier 		naddr(n->left, a);
470e887ea33SDavid du Colombier 		if(a->type >= D_AX && a->type <= D_R15)
471e887ea33SDavid du Colombier 			a->type += D_INDIR;
472e887ea33SDavid du Colombier 		else
473e887ea33SDavid du Colombier 		if(a->type == D_CONST)
474e887ea33SDavid du Colombier 			a->type = D_NONE+D_INDIR;
475e887ea33SDavid du Colombier 		else
476e887ea33SDavid du Colombier 		if(a->type == D_ADDR) {
477e887ea33SDavid du Colombier 			a->type = a->index;
478e887ea33SDavid du Colombier 			a->index = D_NONE;
479e887ea33SDavid du Colombier 		} else
480e887ea33SDavid du Colombier 			goto bad;
481e887ea33SDavid du Colombier 		break;
482e887ea33SDavid du Colombier 
483e887ea33SDavid du Colombier 	case OINDEX:
484e887ea33SDavid du Colombier 		a->type = idx.ptr;
485e887ea33SDavid du Colombier 		if(n->left->op == OADDR || n->left->op == OCONST)
486e887ea33SDavid du Colombier 			naddr(n->left, a);
487e887ea33SDavid du Colombier 		if(a->type >= D_AX && a->type <= D_R15)
488e887ea33SDavid du Colombier 			a->type += D_INDIR;
489e887ea33SDavid du Colombier 		else
490e887ea33SDavid du Colombier 		if(a->type == D_CONST)
491e887ea33SDavid du Colombier 			a->type = D_NONE+D_INDIR;
492e887ea33SDavid du Colombier 		else
493e887ea33SDavid du Colombier 		if(a->type == D_ADDR) {
494e887ea33SDavid du Colombier 			a->type = a->index;
495e887ea33SDavid du Colombier 			a->index = D_NONE;
496e887ea33SDavid du Colombier 		} else
497e887ea33SDavid du Colombier 			goto bad;
498e887ea33SDavid du Colombier 		a->index = idx.reg;
499e887ea33SDavid du Colombier 		a->scale = n->scale;
500e887ea33SDavid du Colombier 		a->offset += n->xoffset;
501e887ea33SDavid du Colombier 		break;
502e887ea33SDavid du Colombier 
503e887ea33SDavid du Colombier 	case OINDREG:
504e887ea33SDavid du Colombier 		a->type = n->reg+D_INDIR;
505e887ea33SDavid du Colombier 		a->sym = S;
506e887ea33SDavid du Colombier 		a->offset = n->xoffset;
507e887ea33SDavid du Colombier 		break;
508e887ea33SDavid du Colombier 
509e887ea33SDavid du Colombier 	case ONAME:
510e887ea33SDavid du Colombier 		a->etype = n->etype;
511e887ea33SDavid du Colombier 		a->type = D_STATIC;
512e887ea33SDavid du Colombier 		a->sym = n->sym;
513e887ea33SDavid du Colombier 		a->offset = n->xoffset;
514e887ea33SDavid du Colombier 		if(n->class == CSTATIC)
515e887ea33SDavid du Colombier 			break;
516e887ea33SDavid du Colombier 		if(n->class == CEXTERN || n->class == CGLOBL) {
517e887ea33SDavid du Colombier 			a->type = D_EXTERN;
518e887ea33SDavid du Colombier 			break;
519e887ea33SDavid du Colombier 		}
520e887ea33SDavid du Colombier 		if(n->class == CAUTO) {
521e887ea33SDavid du Colombier 			a->type = D_AUTO;
522e887ea33SDavid du Colombier 			break;
523e887ea33SDavid du Colombier 		}
524e887ea33SDavid du Colombier 		if(n->class == CPARAM) {
525e887ea33SDavid du Colombier 			a->type = D_PARAM;
526e887ea33SDavid du Colombier 			break;
527e887ea33SDavid du Colombier 		}
528e887ea33SDavid du Colombier 		goto bad;
529e887ea33SDavid du Colombier 
530e887ea33SDavid du Colombier 	case OCONST:
531e887ea33SDavid du Colombier 		if(typefd[n->type->etype]) {
532e887ea33SDavid du Colombier 			a->type = D_FCONST;
533e887ea33SDavid du Colombier 			a->dval = n->fconst;
534e887ea33SDavid du Colombier 			break;
535e887ea33SDavid du Colombier 		}
536e887ea33SDavid du Colombier 		a->sym = S;
537e887ea33SDavid du Colombier 		a->type = D_CONST;
538e887ea33SDavid du Colombier 		if(typev[n->type->etype] || n->type->etype == TIND)
539e887ea33SDavid du Colombier 			a->offset = n->vconst;
540e887ea33SDavid du Colombier 		else
541e887ea33SDavid du Colombier 			a->offset = convvtox(n->vconst, typeu[n->type->etype]? TULONG: TLONG);
542e887ea33SDavid du Colombier 		break;
543e887ea33SDavid du Colombier 
544e887ea33SDavid du Colombier 	case OADDR:
545e887ea33SDavid du Colombier 		naddr(n->left, a);
546e887ea33SDavid du Colombier 		if(a->type >= D_INDIR) {
547e887ea33SDavid du Colombier 			a->type -= D_INDIR;
548e887ea33SDavid du Colombier 			break;
549e887ea33SDavid du Colombier 		}
550e887ea33SDavid du Colombier 		if(a->type == D_EXTERN || a->type == D_STATIC ||
551e887ea33SDavid du Colombier 		   a->type == D_AUTO || a->type == D_PARAM)
552e887ea33SDavid du Colombier 			if(a->index == D_NONE) {
553e887ea33SDavid du Colombier 				a->index = a->type;
554e887ea33SDavid du Colombier 				a->type = D_ADDR;
555e887ea33SDavid du Colombier 				break;
556e887ea33SDavid du Colombier 			}
557e887ea33SDavid du Colombier 		goto bad;
558e887ea33SDavid du Colombier 
559e887ea33SDavid du Colombier 	case OADD:
560e887ea33SDavid du Colombier 		if(n->right->op == OCONST) {
561e887ea33SDavid du Colombier 			v = n->right->vconst;
562e887ea33SDavid du Colombier 			naddr(n->left, a);
563e887ea33SDavid du Colombier 		} else
564e887ea33SDavid du Colombier 		if(n->left->op == OCONST) {
565e887ea33SDavid du Colombier 			v = n->left->vconst;
566e887ea33SDavid du Colombier 			naddr(n->right, a);
567e887ea33SDavid du Colombier 		} else
568e887ea33SDavid du Colombier 			goto bad;
569e887ea33SDavid du Colombier 		a->offset += v;
570e887ea33SDavid du Colombier 		break;
571e887ea33SDavid du Colombier 
572e887ea33SDavid du Colombier 	}
573e887ea33SDavid du Colombier }
574e887ea33SDavid du Colombier 
575e887ea33SDavid du Colombier void
gcmp(int op,Node * n,vlong val)576e887ea33SDavid du Colombier gcmp(int op, Node *n, vlong val)
577e887ea33SDavid du Colombier {
578e887ea33SDavid du Colombier 	Node *cn, nod;
579e887ea33SDavid du Colombier 
580e887ea33SDavid du Colombier 	cn = nodgconst(val, n->type);
581e887ea33SDavid du Colombier 	if(!immconst(cn)){
582e887ea33SDavid du Colombier 		regalloc(&nod, n, Z);
583e887ea33SDavid du Colombier 		gmove(cn, &nod);
584e887ea33SDavid du Colombier 		gopcode(op, n->type, n, &nod);
585e887ea33SDavid du Colombier 		regfree(&nod);
586e887ea33SDavid du Colombier 	}else
587e887ea33SDavid du Colombier 		gopcode(op, n->type, n, cn);
588e887ea33SDavid du Colombier }
589e887ea33SDavid du Colombier 
590e887ea33SDavid du Colombier #define	CASE(a,b)	((a<<8)|(b<<0))
591e887ea33SDavid du Colombier 
592e887ea33SDavid du Colombier void
gmove(Node * f,Node * t)593e887ea33SDavid du Colombier gmove(Node *f, Node *t)
594e887ea33SDavid du Colombier {
595e887ea33SDavid du Colombier 	int ft, tt, t64, a;
596e887ea33SDavid du Colombier 	Node nod, nod1, nod2, nod3;
597e887ea33SDavid du Colombier 	Prog *p1, *p2;
598e887ea33SDavid du Colombier 
599e887ea33SDavid du Colombier 	ft = f->type->etype;
600e887ea33SDavid du Colombier 	tt = t->type->etype;
601e887ea33SDavid du Colombier 	t64 = tt == TVLONG || tt == TUVLONG || tt == TIND;
602e887ea33SDavid du Colombier 	if(debug['M'])
603e887ea33SDavid du Colombier 		print("gop: %O %O[%s],%O[%s]\n", OAS,
604e887ea33SDavid du Colombier 			f->op, tnames[ft], t->op, tnames[tt]);
605e887ea33SDavid du Colombier 	if(typefd[ft] && f->op == OCONST) {
606e887ea33SDavid du Colombier 		/* TO DO: pick up special constants, possibly preloaded */
607e887ea33SDavid du Colombier 		if(f->fconst == 0.0){
608e887ea33SDavid du Colombier 			regalloc(&nod, t, t);
609e887ea33SDavid du Colombier 			gins(AXORPD, &nod, &nod);
610e887ea33SDavid du Colombier 			gmove(&nod, t);
611e887ea33SDavid du Colombier 			regfree(&nod);
612e887ea33SDavid du Colombier 			return;
613e887ea33SDavid du Colombier 		}
614e887ea33SDavid du Colombier 	}
615e887ea33SDavid du Colombier /*
616e887ea33SDavid du Colombier  * load
617e887ea33SDavid du Colombier  */
618*40d01547SDavid du Colombier 	if(ft == TVLONG || ft == TUVLONG)
619*40d01547SDavid du Colombier 	if(f->op == OCONST)
620*40d01547SDavid du Colombier 	if(f->vconst > 0x7fffffffLL || f->vconst < -0x7fffffffLL)
621*40d01547SDavid du Colombier 	if(t->op != OREGISTER) {
622*40d01547SDavid du Colombier 		regalloc(&nod, f, Z);
623*40d01547SDavid du Colombier 		gmove(f, &nod);
624*40d01547SDavid du Colombier 		gmove(&nod, t);
625*40d01547SDavid du Colombier 		regfree(&nod);
626*40d01547SDavid du Colombier 		return;
627*40d01547SDavid du Colombier 	}
628*40d01547SDavid du Colombier 
629e887ea33SDavid du Colombier 	if(f->op == ONAME || f->op == OINDREG ||
630e887ea33SDavid du Colombier 	   f->op == OIND || f->op == OINDEX)
631e887ea33SDavid du Colombier 	switch(ft) {
632e887ea33SDavid du Colombier 	case TCHAR:
633e887ea33SDavid du Colombier 		a = AMOVBLSX;
634e887ea33SDavid du Colombier 		if(t64)
635e887ea33SDavid du Colombier 			a = AMOVBQSX;
636e887ea33SDavid du Colombier 		goto ld;
637e887ea33SDavid du Colombier 	case TUCHAR:
638e887ea33SDavid du Colombier 		a = AMOVBLZX;
639e887ea33SDavid du Colombier 		if(t64)
640e887ea33SDavid du Colombier 			a = AMOVBQZX;
641e887ea33SDavid du Colombier 		goto ld;
642e887ea33SDavid du Colombier 	case TSHORT:
643e887ea33SDavid du Colombier 		a = AMOVWLSX;
644e887ea33SDavid du Colombier 		if(t64)
645e887ea33SDavid du Colombier 			a = AMOVWQSX;
646e887ea33SDavid du Colombier 		goto ld;
647e887ea33SDavid du Colombier 	case TUSHORT:
648e887ea33SDavid du Colombier 		a = AMOVWLZX;
649e887ea33SDavid du Colombier 		if(t64)
650e887ea33SDavid du Colombier 			a = AMOVWQZX;
651e887ea33SDavid du Colombier 		goto ld;
652e887ea33SDavid du Colombier 	case TINT:
653e887ea33SDavid du Colombier 	case TLONG:
654e887ea33SDavid du Colombier 		if(typefd[tt]) {
655e887ea33SDavid du Colombier 			regalloc(&nod, t, t);
656e887ea33SDavid du Colombier 			if(tt == TDOUBLE)
657e887ea33SDavid du Colombier 				a = ACVTSL2SD;
658e887ea33SDavid du Colombier 			else
659e887ea33SDavid du Colombier 				a = ACVTSL2SS;
660e887ea33SDavid du Colombier 			gins(a, f, &nod);
661e887ea33SDavid du Colombier 			gmove(&nod, t);
662e887ea33SDavid du Colombier 			regfree(&nod);
663e887ea33SDavid du Colombier 			return;
664e887ea33SDavid du Colombier 		}
665e887ea33SDavid du Colombier 		a = AMOVL;
666e887ea33SDavid du Colombier 		if(t64)
667e887ea33SDavid du Colombier 			a = AMOVLQSX;
668e887ea33SDavid du Colombier 		goto ld;
669e887ea33SDavid du Colombier 	case TUINT:
670e887ea33SDavid du Colombier 	case TULONG:
671e887ea33SDavid du Colombier 		a = AMOVL;
672e887ea33SDavid du Colombier 		if(t64)
673e887ea33SDavid du Colombier 			a = AMOVLQZX;	/* could probably use plain MOVL */
674e887ea33SDavid du Colombier 		goto ld;
675e887ea33SDavid du Colombier 	case TVLONG:
676*40d01547SDavid du Colombier 	case TUVLONG:
677e887ea33SDavid du Colombier 		if(typefd[tt]) {
678e887ea33SDavid du Colombier 			regalloc(&nod, t, t);
679e887ea33SDavid du Colombier 			if(tt == TDOUBLE)
680e887ea33SDavid du Colombier 				a = ACVTSQ2SD;
681e887ea33SDavid du Colombier 			else
682e887ea33SDavid du Colombier 				a = ACVTSQ2SS;
683e887ea33SDavid du Colombier 			gins(a, f, &nod);
684e887ea33SDavid du Colombier 			gmove(&nod, t);
685e887ea33SDavid du Colombier 			regfree(&nod);
686e887ea33SDavid du Colombier 			return;
687e887ea33SDavid du Colombier 		}
688e887ea33SDavid du Colombier 		a = AMOVQ;
689e887ea33SDavid du Colombier 		goto ld;
690e887ea33SDavid du Colombier 	case TIND:
691e887ea33SDavid du Colombier 		a = AMOVQ;
692e887ea33SDavid du Colombier 
693e887ea33SDavid du Colombier 	ld:
694e887ea33SDavid du Colombier 		regalloc(&nod, f, t);
695e887ea33SDavid du Colombier 		nod.type = t64? types[TVLONG]: types[TINT];
696e887ea33SDavid du Colombier 		gins(a, f, &nod);
697e887ea33SDavid du Colombier 		gmove(&nod, t);
698e887ea33SDavid du Colombier 		regfree(&nod);
699e887ea33SDavid du Colombier 		return;
700e887ea33SDavid du Colombier 
701e887ea33SDavid du Colombier 	case TFLOAT:
702e887ea33SDavid du Colombier 		a = AMOVSS;
703e887ea33SDavid du Colombier 		goto fld;
704e887ea33SDavid du Colombier 	case TDOUBLE:
705e887ea33SDavid du Colombier 		a = AMOVSD;
706e887ea33SDavid du Colombier 	fld:
707e887ea33SDavid du Colombier 		regalloc(&nod, f, t);
708e887ea33SDavid du Colombier 		if(tt != TDOUBLE && tt != TFLOAT){	/* TO DO: why is this here */
709e887ea33SDavid du Colombier 			prtree(f, "odd tree");
710e887ea33SDavid du Colombier 			nod.type = t64? types[TVLONG]: types[TINT];
711e887ea33SDavid du Colombier 		}
712e887ea33SDavid du Colombier 		gins(a, f, &nod);
713e887ea33SDavid du Colombier 		gmove(&nod, t);
714e887ea33SDavid du Colombier 		regfree(&nod);
715e887ea33SDavid du Colombier 		return;
716e887ea33SDavid du Colombier 	}
717e887ea33SDavid du Colombier 
718e887ea33SDavid du Colombier /*
719e887ea33SDavid du Colombier  * store
720e887ea33SDavid du Colombier  */
721e887ea33SDavid du Colombier 	if(t->op == ONAME || t->op == OINDREG ||
722e887ea33SDavid du Colombier 	   t->op == OIND || t->op == OINDEX)
723e887ea33SDavid du Colombier 	switch(tt) {
724e887ea33SDavid du Colombier 	case TCHAR:
725e887ea33SDavid du Colombier 	case TUCHAR:
726e887ea33SDavid du Colombier 		a = AMOVB;	goto st;
727e887ea33SDavid du Colombier 	case TSHORT:
728e887ea33SDavid du Colombier 	case TUSHORT:
729e887ea33SDavid du Colombier 		a = AMOVW;	goto st;
730e887ea33SDavid du Colombier 	case TINT:
731e887ea33SDavid du Colombier 	case TUINT:
732e887ea33SDavid du Colombier 	case TLONG:
733e887ea33SDavid du Colombier 	case TULONG:
734e887ea33SDavid du Colombier 		a = AMOVL;	goto st;
735e887ea33SDavid du Colombier 	case TVLONG:
736e887ea33SDavid du Colombier 	case TUVLONG:
737e887ea33SDavid du Colombier 	case TIND:
738e887ea33SDavid du Colombier 		a = AMOVQ;	goto st;
739e887ea33SDavid du Colombier 
740e887ea33SDavid du Colombier 	st:
741e887ea33SDavid du Colombier 		if(f->op == OCONST) {
742e887ea33SDavid du Colombier 			gins(a, f, t);
743e887ea33SDavid du Colombier 			return;
744e887ea33SDavid du Colombier 		}
745e887ea33SDavid du Colombier 	fst:
746e887ea33SDavid du Colombier 		regalloc(&nod, t, f);
747e887ea33SDavid du Colombier 		gmove(f, &nod);
748e887ea33SDavid du Colombier 		gins(a, &nod, t);
749e887ea33SDavid du Colombier 		regfree(&nod);
750e887ea33SDavid du Colombier 		return;
751e887ea33SDavid du Colombier 
752e887ea33SDavid du Colombier 	case TFLOAT:
753e887ea33SDavid du Colombier 		a = AMOVSS;
754e887ea33SDavid du Colombier 		goto fst;
755e887ea33SDavid du Colombier 	case TDOUBLE:
756e887ea33SDavid du Colombier 		a = AMOVSD;
757e887ea33SDavid du Colombier 		goto fst;
758e887ea33SDavid du Colombier 	}
759e887ea33SDavid du Colombier 
760e887ea33SDavid du Colombier /*
761e887ea33SDavid du Colombier  * convert
762e887ea33SDavid du Colombier  */
763e887ea33SDavid du Colombier 	switch(CASE(ft,tt)) {
764e887ea33SDavid du Colombier 	default:
765e887ea33SDavid du Colombier /*
766e887ea33SDavid du Colombier  * integer to integer
767e887ea33SDavid du Colombier  ********
768e887ea33SDavid du Colombier 		a = AGOK;	break;
769e887ea33SDavid du Colombier 
770e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TCHAR):
771e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TCHAR):
772e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TCHAR):
773e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TCHAR):
774e887ea33SDavid du Colombier 	case CASE(	TINT,	TCHAR):
775e887ea33SDavid du Colombier 	case CASE(	TUINT,	TCHAR):
776e887ea33SDavid du Colombier 	case CASE(	TLONG,	TCHAR):
777e887ea33SDavid du Colombier 	case CASE(	TULONG,	TCHAR):
778e887ea33SDavid du Colombier 
779e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TUCHAR):
780e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TUCHAR):
781e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TUCHAR):
782e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TUCHAR):
783e887ea33SDavid du Colombier 	case CASE(	TINT,	TUCHAR):
784e887ea33SDavid du Colombier 	case CASE(	TUINT,	TUCHAR):
785e887ea33SDavid du Colombier 	case CASE(	TLONG,	TUCHAR):
786e887ea33SDavid du Colombier 	case CASE(	TULONG,	TUCHAR):
787e887ea33SDavid du Colombier 
788e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TSHORT):
789e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TSHORT):
790e887ea33SDavid du Colombier 	case CASE(	TINT,	TSHORT):
791e887ea33SDavid du Colombier 	case CASE(	TUINT,	TSHORT):
792e887ea33SDavid du Colombier 	case CASE(	TLONG,	TSHORT):
793e887ea33SDavid du Colombier 	case CASE(	TULONG,	TSHORT):
794e887ea33SDavid du Colombier 
795e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TUSHORT):
796e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TUSHORT):
797e887ea33SDavid du Colombier 	case CASE(	TINT,	TUSHORT):
798e887ea33SDavid du Colombier 	case CASE(	TUINT,	TUSHORT):
799e887ea33SDavid du Colombier 	case CASE(	TLONG,	TUSHORT):
800e887ea33SDavid du Colombier 	case CASE(	TULONG,	TUSHORT):
801e887ea33SDavid du Colombier 
802e887ea33SDavid du Colombier 	case CASE(	TINT,	TINT):
803e887ea33SDavid du Colombier 	case CASE(	TUINT,	TINT):
804e887ea33SDavid du Colombier 	case CASE(	TLONG,	TINT):
805e887ea33SDavid du Colombier 	case CASE(	TULONG,	TINT):
806e887ea33SDavid du Colombier 
807e887ea33SDavid du Colombier 	case CASE(	TINT,	TUINT):
808e887ea33SDavid du Colombier 	case CASE(	TUINT,	TUINT):
809e887ea33SDavid du Colombier 	case CASE(	TLONG,	TUINT):
810e887ea33SDavid du Colombier 	case CASE(	TULONG,	TUINT):
811e887ea33SDavid du Colombier  *****/
812e887ea33SDavid du Colombier 		a = AMOVL;
813e887ea33SDavid du Colombier 		break;
814e887ea33SDavid du Colombier 
815*40d01547SDavid du Colombier 	case CASE(	TINT,	TIND):
816e887ea33SDavid du Colombier 	case CASE(	TINT,	TVLONG):
817e887ea33SDavid du Colombier 	case CASE(	TINT,	TUVLONG):
818e887ea33SDavid du Colombier 	case CASE(	TLONG,	TIND):
819*40d01547SDavid du Colombier 	case CASE(	TLONG,	TVLONG):
820*40d01547SDavid du Colombier 	case CASE(	TLONG,	TUVLONG):
821e887ea33SDavid du Colombier 		a = AMOVLQSX;
822e887ea33SDavid du Colombier 		if(f->op == OCONST) {
823e887ea33SDavid du Colombier 			f->vconst &= (uvlong)0xffffffffU;
824e887ea33SDavid du Colombier 			if(f->vconst & 0x80000000)
825e887ea33SDavid du Colombier 				f->vconst |= (vlong)0xffffffff << 32;
826e887ea33SDavid du Colombier 			a = AMOVQ;
827e887ea33SDavid du Colombier 		}
828e887ea33SDavid du Colombier 		break;
829e887ea33SDavid du Colombier 
830e887ea33SDavid du Colombier 	case CASE(	TUINT,	TIND):
831e887ea33SDavid du Colombier 	case CASE(	TUINT,	TVLONG):
832e887ea33SDavid du Colombier 	case CASE(	TUINT,	TUVLONG):
833e887ea33SDavid du Colombier 	case CASE(	TULONG,	TVLONG):
834e887ea33SDavid du Colombier 	case CASE(	TULONG,	TUVLONG):
835e887ea33SDavid du Colombier 	case CASE(	TULONG,	TIND):
836*40d01547SDavid du Colombier 		a = AMOVLQZX;
837e887ea33SDavid du Colombier 		if(f->op == OCONST) {
838e887ea33SDavid du Colombier 			f->vconst &= (uvlong)0xffffffffU;
839e887ea33SDavid du Colombier 			a = AMOVQ;
840e887ea33SDavid du Colombier 		}
841e887ea33SDavid du Colombier 		break;
842e887ea33SDavid du Colombier 
843*40d01547SDavid du Colombier 	case CASE(	TIND,	TCHAR):
844*40d01547SDavid du Colombier 	case CASE(	TIND,	TUCHAR):
845*40d01547SDavid du Colombier 	case CASE(	TIND,	TSHORT):
846*40d01547SDavid du Colombier 	case CASE(	TIND,	TUSHORT):
847*40d01547SDavid du Colombier 	case CASE(	TIND,	TINT):
848*40d01547SDavid du Colombier 	case CASE(	TIND,	TUINT):
849*40d01547SDavid du Colombier 	case CASE(	TIND,	TLONG):
850*40d01547SDavid du Colombier 	case CASE(	TIND,	TULONG):
851*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TCHAR):
852*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TUCHAR):
853*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TSHORT):
854*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TUSHORT):
855*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TINT):
856*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TUINT):
857*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TLONG):
858*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TULONG):
859*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TCHAR):
860*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TUCHAR):
861*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TSHORT):
862*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TUSHORT):
863*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TINT):
864*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TUINT):
865*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TLONG):
866*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TULONG):
867*40d01547SDavid du Colombier 		a = AMOVQL;
868*40d01547SDavid du Colombier 		if(f->op == OCONST) {
869*40d01547SDavid du Colombier 			f->vconst &= 0xffffffffU;
870*40d01547SDavid du Colombier 			a = AMOVL;
871*40d01547SDavid du Colombier 		}
872*40d01547SDavid du Colombier 		break;
873*40d01547SDavid du Colombier 
874*40d01547SDavid du Colombier 	case CASE(	TIND,	TIND):
875e887ea33SDavid du Colombier 	case CASE(	TIND,	TVLONG):
876e887ea33SDavid du Colombier 	case CASE(	TIND,	TUVLONG):
877e887ea33SDavid du Colombier 	case CASE(	TVLONG,	TIND):
878*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TVLONG):
879*40d01547SDavid du Colombier 	case CASE(	TVLONG,	TUVLONG):
880e887ea33SDavid du Colombier 	case CASE(	TUVLONG,	TIND):
881*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TVLONG):
882*40d01547SDavid du Colombier 	case CASE(	TUVLONG,	TUVLONG):
883e887ea33SDavid du Colombier 		a = AMOVQ;
884e887ea33SDavid du Colombier 		break;
885e887ea33SDavid du Colombier 
886e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TINT):
887e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TUINT):
888e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TLONG):
889e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TULONG):
890e887ea33SDavid du Colombier 		a = AMOVWLSX;
891e887ea33SDavid du Colombier 		if(f->op == OCONST) {
892e887ea33SDavid du Colombier 			f->vconst &= 0xffff;
893e887ea33SDavid du Colombier 			if(f->vconst & 0x8000)
894e887ea33SDavid du Colombier 				f->vconst |= 0xffff0000;
895e887ea33SDavid du Colombier 			a = AMOVL;
896e887ea33SDavid du Colombier 		}
897e887ea33SDavid du Colombier 		break;
898e887ea33SDavid du Colombier 
899e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TVLONG):
900e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TUVLONG):
901e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TIND):
902e887ea33SDavid du Colombier 		a = AMOVWQSX;
903e887ea33SDavid du Colombier 		if(f->op == OCONST) {
904e887ea33SDavid du Colombier 			f->vconst &= 0xffff;
905e887ea33SDavid du Colombier 			if(f->vconst & 0x8000){
906e887ea33SDavid du Colombier 				f->vconst |= 0xffff0000;
907e887ea33SDavid du Colombier 				f->vconst |= (vlong)~0 << 32;
908e887ea33SDavid du Colombier 			}
909e887ea33SDavid du Colombier 			a = AMOVL;
910e887ea33SDavid du Colombier 		}
911e887ea33SDavid du Colombier 		break;
912e887ea33SDavid du Colombier 
913e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TINT):
914e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TUINT):
915e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TLONG):
916e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TULONG):
917e887ea33SDavid du Colombier 		a = AMOVWLZX;
918e887ea33SDavid du Colombier 		if(f->op == OCONST) {
919e887ea33SDavid du Colombier 			f->vconst &= 0xffff;
920e887ea33SDavid du Colombier 			a = AMOVL;
921e887ea33SDavid du Colombier 		}
922e887ea33SDavid du Colombier 		break;
923e887ea33SDavid du Colombier 
924e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TVLONG):
925e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TUVLONG):
926e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TIND):
927e887ea33SDavid du Colombier 		a = AMOVWQZX;
928e887ea33SDavid du Colombier 		if(f->op == OCONST) {
929e887ea33SDavid du Colombier 			f->vconst &= 0xffff;
930e887ea33SDavid du Colombier 			a = AMOVL;	/* MOVL also zero-extends to 64 bits */
931e887ea33SDavid du Colombier 		}
932e887ea33SDavid du Colombier 		break;
933e887ea33SDavid du Colombier 
934e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TSHORT):
935e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TUSHORT):
936e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TINT):
937e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TUINT):
938e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TLONG):
939e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TULONG):
940e887ea33SDavid du Colombier 		a = AMOVBLSX;
941e887ea33SDavid du Colombier 		if(f->op == OCONST) {
942e887ea33SDavid du Colombier 			f->vconst &= 0xff;
943e887ea33SDavid du Colombier 			if(f->vconst & 0x80)
944e887ea33SDavid du Colombier 				f->vconst |= 0xffffff00;
945e887ea33SDavid du Colombier 			a = AMOVL;
946e887ea33SDavid du Colombier 		}
947e887ea33SDavid du Colombier 		break;
948e887ea33SDavid du Colombier 
949e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TVLONG):
950e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TUVLONG):
951e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TIND):
952e887ea33SDavid du Colombier 		a = AMOVBQSX;
953e887ea33SDavid du Colombier 		if(f->op == OCONST) {
954e887ea33SDavid du Colombier 			f->vconst &= 0xff;
955e887ea33SDavid du Colombier 			if(f->vconst & 0x80){
956e887ea33SDavid du Colombier 				f->vconst |= 0xffffff00;
957e887ea33SDavid du Colombier 				f->vconst |= (vlong)~0 << 32;
958e887ea33SDavid du Colombier 			}
959e887ea33SDavid du Colombier 			a = AMOVQ;
960e887ea33SDavid du Colombier 		}
961e887ea33SDavid du Colombier 		break;
962e887ea33SDavid du Colombier 
963e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TSHORT):
964e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TUSHORT):
965e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TINT):
966e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TUINT):
967e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TLONG):
968e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TULONG):
969e887ea33SDavid du Colombier 		a = AMOVBLZX;
970e887ea33SDavid du Colombier 		if(f->op == OCONST) {
971e887ea33SDavid du Colombier 			f->vconst &= 0xff;
972e887ea33SDavid du Colombier 			a = AMOVL;
973e887ea33SDavid du Colombier 		}
974e887ea33SDavid du Colombier 		break;
975e887ea33SDavid du Colombier 
976e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TVLONG):
977e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TUVLONG):
978e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TIND):
979e887ea33SDavid du Colombier 		a = AMOVBQZX;
980e887ea33SDavid du Colombier 		if(f->op == OCONST) {
981e887ea33SDavid du Colombier 			f->vconst &= 0xff;
982e887ea33SDavid du Colombier 			a = AMOVL;	/* zero-extends to 64-bits */
983e887ea33SDavid du Colombier 		}
984e887ea33SDavid du Colombier 		break;
985e887ea33SDavid du Colombier 
986e887ea33SDavid du Colombier /*
987e887ea33SDavid du Colombier  * float to fix
988e887ea33SDavid du Colombier  */
989e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TCHAR):
990e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TUCHAR):
991e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TSHORT):
992e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TUSHORT):
993e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TINT):
994e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TUINT):
995e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TLONG):
996e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TULONG):
997e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TVLONG):
998e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TUVLONG):
999e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TIND):
1000e887ea33SDavid du Colombier 
1001e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TCHAR):
1002e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TUCHAR):
1003e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TSHORT):
1004e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TUSHORT):
1005e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TINT):
1006e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TUINT):
1007e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TLONG):
1008e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TULONG):
1009e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TVLONG):
1010e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TUVLONG):
1011e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TIND):
1012e887ea33SDavid du Colombier 		regalloc(&nod, t, Z);
1013e887ea33SDavid du Colombier 		if(ewidth[tt] == SZ_VLONG || typeu[tt] && ewidth[tt] == SZ_INT){
1014e887ea33SDavid du Colombier 			if(ft == TFLOAT)
1015e887ea33SDavid du Colombier 				a = ACVTTSS2SQ;
1016e887ea33SDavid du Colombier 			else
1017e887ea33SDavid du Colombier 				a = ACVTTSD2SQ;
1018e887ea33SDavid du Colombier 		}else{
1019e887ea33SDavid du Colombier 			if(ft == TFLOAT)
1020e887ea33SDavid du Colombier 				a = ACVTTSS2SL;
1021e887ea33SDavid du Colombier 			else
1022e887ea33SDavid du Colombier 				a = ACVTTSD2SL;
1023e887ea33SDavid du Colombier 		}
1024e887ea33SDavid du Colombier 		gins(a, f, &nod);
1025e887ea33SDavid du Colombier 		gmove(&nod, t);
1026e887ea33SDavid du Colombier 		regfree(&nod);
1027e887ea33SDavid du Colombier 		return;
1028e887ea33SDavid du Colombier 
1029e887ea33SDavid du Colombier /*
1030*40d01547SDavid du Colombier  * uvlong to float
1031e887ea33SDavid du Colombier  */
1032e887ea33SDavid du Colombier 	case CASE(	TUVLONG,	TDOUBLE):
1033e887ea33SDavid du Colombier 	case CASE(	TUVLONG,	TFLOAT):
1034e887ea33SDavid du Colombier 		a = ACVTSQ2SS;
1035e887ea33SDavid du Colombier 		if(tt == TDOUBLE)
1036e887ea33SDavid du Colombier 			a = ACVTSQ2SD;
1037e887ea33SDavid du Colombier 		regalloc(&nod, f, f);
1038e887ea33SDavid du Colombier 		gmove(f, &nod);
1039e887ea33SDavid du Colombier 		regalloc(&nod1, t, t);
1040e887ea33SDavid du Colombier 		gins(ACMPQ, &nod, nodconst(0));
1041e887ea33SDavid du Colombier 		gins(AJLT, Z, Z);
1042e887ea33SDavid du Colombier 		p1 = p;
1043e887ea33SDavid du Colombier 		gins(a, &nod, &nod1);
1044e887ea33SDavid du Colombier 		gins(AJMP, Z, Z);
1045e887ea33SDavid du Colombier 		p2 = p;
1046e887ea33SDavid du Colombier 		patch(p1, pc);
1047e887ea33SDavid du Colombier 		regalloc(&nod2, f, Z);
1048e887ea33SDavid du Colombier 		regalloc(&nod3, f, Z);
1049e887ea33SDavid du Colombier 		gmove(&nod, &nod2);
1050e887ea33SDavid du Colombier 		gins(ASHRQ, nodconst(1), &nod2);
1051e887ea33SDavid du Colombier 		gmove(&nod, &nod3);
1052e887ea33SDavid du Colombier 		gins(AANDL, nodconst(1), &nod3);
1053e887ea33SDavid du Colombier 		gins(AORQ, &nod3, &nod2);
1054e887ea33SDavid du Colombier 		gins(a, &nod2, &nod1);
1055e887ea33SDavid du Colombier 		gins(tt == TDOUBLE? AADDSD: AADDSS, &nod1, &nod1);
1056e887ea33SDavid du Colombier 		regfree(&nod2);
1057e887ea33SDavid du Colombier 		regfree(&nod3);
1058e887ea33SDavid du Colombier 		patch(p2, pc);
1059e887ea33SDavid du Colombier 		regfree(&nod);
1060e887ea33SDavid du Colombier 		regfree(&nod1);
1061e887ea33SDavid du Colombier 		return;
1062e887ea33SDavid du Colombier 
1063e887ea33SDavid du Colombier 	case CASE(	TULONG,	TDOUBLE):
1064e887ea33SDavid du Colombier 	case CASE(	TUINT,	TDOUBLE):
1065e887ea33SDavid du Colombier 	case CASE(	TULONG,	TFLOAT):
1066e887ea33SDavid du Colombier 	case CASE(	TUINT,	TFLOAT):
1067e887ea33SDavid du Colombier 		a = ACVTSQ2SS;
1068e887ea33SDavid du Colombier 		if(tt == TDOUBLE)
1069e887ea33SDavid du Colombier 			a = ACVTSQ2SD;
1070e887ea33SDavid du Colombier 		regalloc(&nod, f, f);
1071e887ea33SDavid du Colombier 		gins(AMOVLQZX, f, &nod);
1072e887ea33SDavid du Colombier 		regalloc(&nod1, t, t);
1073e887ea33SDavid du Colombier 		gins(a, &nod, &nod1);
1074e887ea33SDavid du Colombier 		gmove(&nod1, t);
1075e887ea33SDavid du Colombier 		regfree(&nod);
1076e887ea33SDavid du Colombier 		regfree(&nod1);
1077e887ea33SDavid du Colombier 		return;
1078e887ea33SDavid du Colombier 
1079e887ea33SDavid du Colombier /*
1080e887ea33SDavid du Colombier  * fix to float
1081e887ea33SDavid du Colombier  */
1082e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TFLOAT):
1083e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TFLOAT):
1084e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TFLOAT):
1085e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TFLOAT):
1086e887ea33SDavid du Colombier 	case CASE(	TINT,	TFLOAT):
1087e887ea33SDavid du Colombier 	case CASE(	TLONG,	TFLOAT):
1088e887ea33SDavid du Colombier 	case	CASE(	TVLONG,	TFLOAT):
1089e887ea33SDavid du Colombier 	case CASE(	TIND,	TFLOAT):
1090e887ea33SDavid du Colombier 
1091e887ea33SDavid du Colombier 	case CASE(	TCHAR,	TDOUBLE):
1092e887ea33SDavid du Colombier 	case CASE(	TUCHAR,	TDOUBLE):
1093e887ea33SDavid du Colombier 	case CASE(	TSHORT,	TDOUBLE):
1094e887ea33SDavid du Colombier 	case CASE(	TUSHORT,TDOUBLE):
1095e887ea33SDavid du Colombier 	case CASE(	TINT,	TDOUBLE):
1096e887ea33SDavid du Colombier 	case CASE(	TLONG,	TDOUBLE):
1097e887ea33SDavid du Colombier 	case CASE(	TVLONG,	TDOUBLE):
1098e887ea33SDavid du Colombier 	case CASE(	TIND,	TDOUBLE):
1099e887ea33SDavid du Colombier 		regalloc(&nod, t, t);
1100e887ea33SDavid du Colombier 		if(ewidth[ft] == SZ_VLONG){
1101e887ea33SDavid du Colombier 			if(tt == TFLOAT)
1102e887ea33SDavid du Colombier 				a = ACVTSQ2SS;
1103e887ea33SDavid du Colombier 			else
1104e887ea33SDavid du Colombier 				a = ACVTSQ2SD;
1105e887ea33SDavid du Colombier 		}else{
1106e887ea33SDavid du Colombier 			if(tt == TFLOAT)
1107e887ea33SDavid du Colombier 				a = ACVTSL2SS;
1108e887ea33SDavid du Colombier 			else
1109e887ea33SDavid du Colombier 				a = ACVTSL2SD;
1110e887ea33SDavid du Colombier 		}
1111e887ea33SDavid du Colombier 		gins(a, f, &nod);
1112e887ea33SDavid du Colombier 		gmove(&nod, t);
1113e887ea33SDavid du Colombier 		regfree(&nod);
1114e887ea33SDavid du Colombier 		return;
1115e887ea33SDavid du Colombier 
1116e887ea33SDavid du Colombier /*
1117e887ea33SDavid du Colombier  * float to float
1118e887ea33SDavid du Colombier  */
1119e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TFLOAT):
1120e887ea33SDavid du Colombier 		a = AMOVSS;
1121e887ea33SDavid du Colombier 		break;
1122e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TFLOAT):
1123e887ea33SDavid du Colombier 		a = ACVTSD2SS;
1124e887ea33SDavid du Colombier 		break;
1125e887ea33SDavid du Colombier 	case CASE(	TFLOAT,	TDOUBLE):
1126e887ea33SDavid du Colombier 		a = ACVTSS2SD;
1127e887ea33SDavid du Colombier 		break;
1128e887ea33SDavid du Colombier 	case CASE(	TDOUBLE,TDOUBLE):
1129e887ea33SDavid du Colombier 		a = AMOVSD;
1130e887ea33SDavid du Colombier 		break;
1131e887ea33SDavid du Colombier 	}
1132e887ea33SDavid du Colombier 	if(a == AMOVQ || a == AMOVSD || a == AMOVSS || a == AMOVL && ewidth[ft] == ewidth[tt])	/* TO DO: check AMOVL */
1133e887ea33SDavid du Colombier 	if(samaddr(f, t))
1134e887ea33SDavid du Colombier 		return;
1135e887ea33SDavid du Colombier 	gins(a, f, t);
1136e887ea33SDavid du Colombier }
1137e887ea33SDavid du Colombier 
1138e887ea33SDavid du Colombier void
doindex(Node * n)1139e887ea33SDavid du Colombier doindex(Node *n)
1140e887ea33SDavid du Colombier {
1141e887ea33SDavid du Colombier 	Node nod, nod1;
1142e887ea33SDavid du Colombier 	long v;
1143e887ea33SDavid du Colombier 
1144e887ea33SDavid du Colombier if(debug['Y'])
1145e887ea33SDavid du Colombier prtree(n, "index");
1146e887ea33SDavid du Colombier 
1147e887ea33SDavid du Colombier if(n->left->complex >= FNX)
1148e887ea33SDavid du Colombier print("botch in doindex\n");
1149e887ea33SDavid du Colombier 
1150e887ea33SDavid du Colombier 	regalloc(&nod, &qregnode, Z);
1151e887ea33SDavid du Colombier 	v = constnode.vconst;
1152e887ea33SDavid du Colombier 	cgen(n->right, &nod);
1153e887ea33SDavid du Colombier 	idx.ptr = D_NONE;
1154e887ea33SDavid du Colombier 	if(n->left->op == OCONST)
1155e887ea33SDavid du Colombier 		idx.ptr = D_CONST;
1156e887ea33SDavid du Colombier 	else if(n->left->op == OREGISTER)
1157e887ea33SDavid du Colombier 		idx.ptr = n->left->reg;
1158e887ea33SDavid du Colombier 	else if(n->left->op != OADDR) {
1159e887ea33SDavid du Colombier 		reg[D_BP]++;	// cant be used as a base
1160e887ea33SDavid du Colombier 		regalloc(&nod1, &qregnode, Z);
1161e887ea33SDavid du Colombier 		cgen(n->left, &nod1);
1162e887ea33SDavid du Colombier 		idx.ptr = nod1.reg;
1163e887ea33SDavid du Colombier 		regfree(&nod1);
1164e887ea33SDavid du Colombier 		reg[D_BP]--;
1165e887ea33SDavid du Colombier 	}
1166e887ea33SDavid du Colombier 	idx.reg = nod.reg;
1167e887ea33SDavid du Colombier 	regfree(&nod);
1168e887ea33SDavid du Colombier 	constnode.vconst = v;
1169e887ea33SDavid du Colombier }
1170e887ea33SDavid du Colombier 
1171e887ea33SDavid du Colombier void
gins(int a,Node * f,Node * t)1172e887ea33SDavid du Colombier gins(int a, Node *f, Node *t)
1173e887ea33SDavid du Colombier {
1174e887ea33SDavid du Colombier 
1175e887ea33SDavid du Colombier 	if(f != Z && f->op == OINDEX)
1176e887ea33SDavid du Colombier 		doindex(f);
1177e887ea33SDavid du Colombier 	if(t != Z && t->op == OINDEX)
1178e887ea33SDavid du Colombier 		doindex(t);
1179e887ea33SDavid du Colombier 	nextpc();
1180e887ea33SDavid du Colombier 	p->as = a;
1181e887ea33SDavid du Colombier 	if(f != Z)
1182e887ea33SDavid du Colombier 		naddr(f, &p->from);
1183e887ea33SDavid du Colombier 	if(t != Z)
1184e887ea33SDavid du Colombier 		naddr(t, &p->to);
1185e887ea33SDavid du Colombier 	if(debug['g'])
1186e887ea33SDavid du Colombier 		print("%P\n", p);
1187e887ea33SDavid du Colombier }
1188e887ea33SDavid du Colombier 
1189e887ea33SDavid du Colombier void
gopcode(int o,Type * ty,Node * f,Node * t)1190e887ea33SDavid du Colombier gopcode(int o, Type *ty, Node *f, Node *t)
1191e887ea33SDavid du Colombier {
1192e887ea33SDavid du Colombier 	int a, et;
1193e887ea33SDavid du Colombier 
1194e887ea33SDavid du Colombier 	et = TLONG;
1195e887ea33SDavid du Colombier 	if(ty != T)
1196e887ea33SDavid du Colombier 		et = ty->etype;
1197e887ea33SDavid du Colombier 	if(debug['M']) {
1198e887ea33SDavid du Colombier 		if(f != Z && f->type != T)
1199e887ea33SDavid du Colombier 			print("gop: %O %O[%s],", o, f->op, tnames[et]);
1200e887ea33SDavid du Colombier 		else
1201e887ea33SDavid du Colombier 			print("gop: %O Z,", o);
1202e887ea33SDavid du Colombier 		if(t != Z && t->type != T)
1203e887ea33SDavid du Colombier 			print("%O[%s]\n", t->op, tnames[t->type->etype]);
1204e887ea33SDavid du Colombier 		else
1205e887ea33SDavid du Colombier 			print("Z\n");
1206e887ea33SDavid du Colombier 	}
1207e887ea33SDavid du Colombier 	a = AGOK;
1208e887ea33SDavid du Colombier 	switch(o) {
1209e887ea33SDavid du Colombier 	case OCOM:
1210e887ea33SDavid du Colombier 		a = ANOTL;
1211e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1212e887ea33SDavid du Colombier 			a = ANOTB;
1213e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1214e887ea33SDavid du Colombier 			a = ANOTW;
1215e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1216e887ea33SDavid du Colombier 			a = ANOTQ;
1217e887ea33SDavid du Colombier 		break;
1218e887ea33SDavid du Colombier 
1219e887ea33SDavid du Colombier 	case ONEG:
1220e887ea33SDavid du Colombier 		a = ANEGL;
1221e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1222e887ea33SDavid du Colombier 			a = ANEGB;
1223e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1224e887ea33SDavid du Colombier 			a = ANEGW;
1225e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1226e887ea33SDavid du Colombier 			a = ANEGQ;
1227e887ea33SDavid du Colombier 		break;
1228e887ea33SDavid du Colombier 
1229e887ea33SDavid du Colombier 	case OADDR:
1230e887ea33SDavid du Colombier 		a = ALEAQ;
1231e887ea33SDavid du Colombier 		break;
1232e887ea33SDavid du Colombier 
1233e887ea33SDavid du Colombier 	case OASADD:
1234e887ea33SDavid du Colombier 	case OADD:
1235e887ea33SDavid du Colombier 		a = AADDL;
1236e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1237e887ea33SDavid du Colombier 			a = AADDB;
1238e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1239e887ea33SDavid du Colombier 			a = AADDW;
1240e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1241e887ea33SDavid du Colombier 			a = AADDQ;
1242e887ea33SDavid du Colombier 		if(et == TFLOAT)
1243e887ea33SDavid du Colombier 			a = AADDSS;
1244e887ea33SDavid du Colombier 		if(et == TDOUBLE)
1245e887ea33SDavid du Colombier 			a = AADDSD;
1246e887ea33SDavid du Colombier 		break;
1247e887ea33SDavid du Colombier 
1248e887ea33SDavid du Colombier 	case OASSUB:
1249e887ea33SDavid du Colombier 	case OSUB:
1250e887ea33SDavid du Colombier 		a = ASUBL;
1251e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1252e887ea33SDavid du Colombier 			a = ASUBB;
1253e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1254e887ea33SDavid du Colombier 			a = ASUBW;
1255e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1256e887ea33SDavid du Colombier 			a = ASUBQ;
1257e887ea33SDavid du Colombier 		if(et == TFLOAT)
1258e887ea33SDavid du Colombier 			a = ASUBSS;
1259e887ea33SDavid du Colombier 		if(et == TDOUBLE)
1260e887ea33SDavid du Colombier 			a = ASUBSD;
1261e887ea33SDavid du Colombier 		break;
1262e887ea33SDavid du Colombier 
1263e887ea33SDavid du Colombier 	case OASOR:
1264e887ea33SDavid du Colombier 	case OOR:
1265e887ea33SDavid du Colombier 		a = AORL;
1266e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1267e887ea33SDavid du Colombier 			a = AORB;
1268e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1269e887ea33SDavid du Colombier 			a = AORW;
1270e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1271e887ea33SDavid du Colombier 			a = AORQ;
1272e887ea33SDavid du Colombier 		break;
1273e887ea33SDavid du Colombier 
1274e887ea33SDavid du Colombier 	case OASAND:
1275e887ea33SDavid du Colombier 	case OAND:
1276e887ea33SDavid du Colombier 		a = AANDL;
1277e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1278e887ea33SDavid du Colombier 			a = AANDB;
1279e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1280e887ea33SDavid du Colombier 			a = AANDW;
1281e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1282e887ea33SDavid du Colombier 			a = AANDQ;
1283e887ea33SDavid du Colombier 		break;
1284e887ea33SDavid du Colombier 
1285e887ea33SDavid du Colombier 	case OASXOR:
1286e887ea33SDavid du Colombier 	case OXOR:
1287e887ea33SDavid du Colombier 		a = AXORL;
1288e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1289e887ea33SDavid du Colombier 			a = AXORB;
1290e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1291e887ea33SDavid du Colombier 			a = AXORW;
1292e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1293e887ea33SDavid du Colombier 			a = AXORQ;
1294e887ea33SDavid du Colombier 		break;
1295e887ea33SDavid du Colombier 
1296e887ea33SDavid du Colombier 	case OASLSHR:
1297e887ea33SDavid du Colombier 	case OLSHR:
1298e887ea33SDavid du Colombier 		a = ASHRL;
1299e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1300e887ea33SDavid du Colombier 			a = ASHRB;
1301e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1302e887ea33SDavid du Colombier 			a = ASHRW;
1303e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1304e887ea33SDavid du Colombier 			a = ASHRQ;
1305e887ea33SDavid du Colombier 		break;
1306e887ea33SDavid du Colombier 
1307e887ea33SDavid du Colombier 	case OASASHR:
1308e887ea33SDavid du Colombier 	case OASHR:
1309e887ea33SDavid du Colombier 		a = ASARL;
1310e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1311e887ea33SDavid du Colombier 			a = ASARB;
1312e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1313e887ea33SDavid du Colombier 			a = ASARW;
1314e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1315e887ea33SDavid du Colombier 			a = ASARQ;
1316e887ea33SDavid du Colombier 		break;
1317e887ea33SDavid du Colombier 
1318e887ea33SDavid du Colombier 	case OASASHL:
1319e887ea33SDavid du Colombier 	case OASHL:
1320e887ea33SDavid du Colombier 		a = ASALL;
1321e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1322e887ea33SDavid du Colombier 			a = ASALB;
1323e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1324e887ea33SDavid du Colombier 			a = ASALW;
1325e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1326e887ea33SDavid du Colombier 			a = ASALQ;
1327e887ea33SDavid du Colombier 		break;
1328e887ea33SDavid du Colombier 
1329e887ea33SDavid du Colombier 	case OFUNC:
1330e887ea33SDavid du Colombier 		a = ACALL;
1331e887ea33SDavid du Colombier 		break;
1332e887ea33SDavid du Colombier 
1333e887ea33SDavid du Colombier 	case OASMUL:
1334e887ea33SDavid du Colombier 	case OMUL:
1335e887ea33SDavid du Colombier 		if(f->op == OREGISTER && t != Z && isreg(t, D_AX) && reg[D_DX] == 0)
1336e887ea33SDavid du Colombier 			t = Z;
1337e887ea33SDavid du Colombier 		a = AIMULL;
1338e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1339e887ea33SDavid du Colombier 			a = AIMULQ;
1340e887ea33SDavid du Colombier 		if(et == TFLOAT)
1341e887ea33SDavid du Colombier 			a = AMULSS;
1342e887ea33SDavid du Colombier 		if(et == TDOUBLE)
1343e887ea33SDavid du Colombier 			a = AMULSD;
1344e887ea33SDavid du Colombier 		break;
1345e887ea33SDavid du Colombier 
1346e887ea33SDavid du Colombier 	case OASMOD:
1347e887ea33SDavid du Colombier 	case OMOD:
1348e887ea33SDavid du Colombier 	case OASDIV:
1349e887ea33SDavid du Colombier 	case ODIV:
1350e887ea33SDavid du Colombier 		a = AIDIVL;
1351e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1352e887ea33SDavid du Colombier 			a = AIDIVQ;
1353e887ea33SDavid du Colombier 		if(et == TFLOAT)
1354e887ea33SDavid du Colombier 			a = ADIVSS;
1355e887ea33SDavid du Colombier 		if(et == TDOUBLE)
1356e887ea33SDavid du Colombier 			a = ADIVSD;
1357e887ea33SDavid du Colombier 		break;
1358e887ea33SDavid du Colombier 
1359e887ea33SDavid du Colombier 	case OASLMUL:
1360e887ea33SDavid du Colombier 	case OLMUL:
1361e887ea33SDavid du Colombier 		a = AMULL;
1362e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1363e887ea33SDavid du Colombier 			a = AMULQ;
1364e887ea33SDavid du Colombier 		break;
1365e887ea33SDavid du Colombier 
1366e887ea33SDavid du Colombier 	case OASLMOD:
1367e887ea33SDavid du Colombier 	case OLMOD:
1368e887ea33SDavid du Colombier 	case OASLDIV:
1369e887ea33SDavid du Colombier 	case OLDIV:
1370e887ea33SDavid du Colombier 		a = ADIVL;
1371e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1372e887ea33SDavid du Colombier 			a = ADIVQ;
1373e887ea33SDavid du Colombier 		break;
1374e887ea33SDavid du Colombier 
1375e887ea33SDavid du Colombier 	case OEQ:
1376e887ea33SDavid du Colombier 	case ONE:
1377e887ea33SDavid du Colombier 	case OLT:
1378e887ea33SDavid du Colombier 	case OLE:
1379e887ea33SDavid du Colombier 	case OGE:
1380e887ea33SDavid du Colombier 	case OGT:
1381e887ea33SDavid du Colombier 	case OLO:
1382e887ea33SDavid du Colombier 	case OLS:
1383e887ea33SDavid du Colombier 	case OHS:
1384e887ea33SDavid du Colombier 	case OHI:
1385e887ea33SDavid du Colombier 		a = ACMPL;
1386e887ea33SDavid du Colombier 		if(et == TCHAR || et == TUCHAR)
1387e887ea33SDavid du Colombier 			a = ACMPB;
1388e887ea33SDavid du Colombier 		if(et == TSHORT || et == TUSHORT)
1389e887ea33SDavid du Colombier 			a = ACMPW;
1390e887ea33SDavid du Colombier 		if(et == TVLONG || et == TUVLONG || et == TIND)
1391e887ea33SDavid du Colombier 			a = ACMPQ;
1392e887ea33SDavid du Colombier 		if(et == TFLOAT)
1393e887ea33SDavid du Colombier 			a = AUCOMISS;
1394e887ea33SDavid du Colombier 		if(et == TDOUBLE)
1395e887ea33SDavid du Colombier 			a = AUCOMISD;
1396e887ea33SDavid du Colombier 		gins(a, f, t);
1397e887ea33SDavid du Colombier 		switch(o) {
1398e887ea33SDavid du Colombier 		case OEQ:	a = AJEQ; break;
1399e887ea33SDavid du Colombier 		case ONE:	a = AJNE; break;
1400e887ea33SDavid du Colombier 		case OLT:	a = AJLT; break;
1401e887ea33SDavid du Colombier 		case OLE:	a = AJLE; break;
1402e887ea33SDavid du Colombier 		case OGE:	a = AJGE; break;
1403e887ea33SDavid du Colombier 		case OGT:	a = AJGT; break;
1404e887ea33SDavid du Colombier 		case OLO:	a = AJCS; break;
1405e887ea33SDavid du Colombier 		case OLS:	a = AJLS; break;
1406e887ea33SDavid du Colombier 		case OHS:	a = AJCC; break;
1407e887ea33SDavid du Colombier 		case OHI:	a = AJHI; break;
1408e887ea33SDavid du Colombier 		}
1409e887ea33SDavid du Colombier 		gins(a, Z, Z);
1410e887ea33SDavid du Colombier 		return;
1411e887ea33SDavid du Colombier 	}
1412e887ea33SDavid du Colombier 	if(a == AGOK)
1413e887ea33SDavid du Colombier 		diag(Z, "bad in gopcode %O", o);
1414e887ea33SDavid du Colombier 	gins(a, f, t);
1415e887ea33SDavid du Colombier }
1416e887ea33SDavid du Colombier 
1417e887ea33SDavid du Colombier int
samaddr(Node * f,Node * t)1418e887ea33SDavid du Colombier samaddr(Node *f, Node *t)
1419e887ea33SDavid du Colombier {
1420e887ea33SDavid du Colombier 	return f->op == OREGISTER && t->op == OREGISTER && f->reg == t->reg;
1421e887ea33SDavid du Colombier }
1422e887ea33SDavid du Colombier 
1423e887ea33SDavid du Colombier void
gbranch(int o)1424e887ea33SDavid du Colombier gbranch(int o)
1425e887ea33SDavid du Colombier {
1426e887ea33SDavid du Colombier 	int a;
1427e887ea33SDavid du Colombier 
1428e887ea33SDavid du Colombier 	a = AGOK;
1429e887ea33SDavid du Colombier 	switch(o) {
1430e887ea33SDavid du Colombier 	case ORETURN:
1431e887ea33SDavid du Colombier 		a = ARET;
1432e887ea33SDavid du Colombier 		break;
1433e887ea33SDavid du Colombier 	case OGOTO:
1434e887ea33SDavid du Colombier 		a = AJMP;
1435e887ea33SDavid du Colombier 		break;
1436e887ea33SDavid du Colombier 	}
1437e887ea33SDavid du Colombier 	nextpc();
1438e887ea33SDavid du Colombier 	if(a == AGOK) {
1439e887ea33SDavid du Colombier 		diag(Z, "bad in gbranch %O",  o);
1440e887ea33SDavid du Colombier 		nextpc();
1441e887ea33SDavid du Colombier 	}
1442e887ea33SDavid du Colombier 	p->as = a;
1443e887ea33SDavid du Colombier }
1444e887ea33SDavid du Colombier 
1445e887ea33SDavid du Colombier void
patch(Prog * op,long pc)1446e887ea33SDavid du Colombier patch(Prog *op, long pc)
1447e887ea33SDavid du Colombier {
1448e887ea33SDavid du Colombier 
1449e887ea33SDavid du Colombier 	op->to.offset = pc;
1450e887ea33SDavid du Colombier 	op->to.type = D_BRANCH;
1451e887ea33SDavid du Colombier }
1452e887ea33SDavid du Colombier 
1453e887ea33SDavid du Colombier void
gpseudo(int a,Sym * s,Node * n)1454e887ea33SDavid du Colombier gpseudo(int a, Sym *s, Node *n)
1455e887ea33SDavid du Colombier {
1456e887ea33SDavid du Colombier 
1457e887ea33SDavid du Colombier 	nextpc();
1458e887ea33SDavid du Colombier 	p->as = a;
1459e887ea33SDavid du Colombier 	p->from.type = D_EXTERN;
1460e887ea33SDavid du Colombier 	p->from.sym = s;
1461e887ea33SDavid du Colombier 	p->from.scale = (profileflg ? 0 : NOPROF);
1462e887ea33SDavid du Colombier 	if(s->class == CSTATIC)
1463e887ea33SDavid du Colombier 		p->from.type = D_STATIC;
1464e887ea33SDavid du Colombier 	naddr(n, &p->to);
1465e887ea33SDavid du Colombier 	if(a == ADATA || a == AGLOBL)
1466e887ea33SDavid du Colombier 		pc--;
1467e887ea33SDavid du Colombier }
1468e887ea33SDavid du Colombier 
1469e887ea33SDavid du Colombier int
sconst(Node * n)1470e887ea33SDavid du Colombier sconst(Node *n)
1471e887ea33SDavid du Colombier {
1472e887ea33SDavid du Colombier 	long v;
1473e887ea33SDavid du Colombier 
1474e887ea33SDavid du Colombier 	if(n->op == OCONST && !typefd[n->type->etype]) {
1475e887ea33SDavid du Colombier 		v = n->vconst;
1476e887ea33SDavid du Colombier 		if(v >= -32766L && v < 32766L)
1477e887ea33SDavid du Colombier 			return 1;
1478e887ea33SDavid du Colombier 	}
1479e887ea33SDavid du Colombier 	return 0;
1480e887ea33SDavid du Colombier }
1481e887ea33SDavid du Colombier 
1482e887ea33SDavid du Colombier long
exreg(Type * t)1483e887ea33SDavid du Colombier exreg(Type *t)
1484e887ea33SDavid du Colombier {
1485e887ea33SDavid du Colombier 	long o;
1486e887ea33SDavid du Colombier 
1487e887ea33SDavid du Colombier 	if(typechlpv[t->etype]) {
1488e887ea33SDavid du Colombier 		if(exregoffset <= REGEXT-4)
1489e887ea33SDavid du Colombier 			return 0;
1490e887ea33SDavid du Colombier 		o = exregoffset;
1491e887ea33SDavid du Colombier 		exregoffset--;
1492e887ea33SDavid du Colombier 		return o;
1493e887ea33SDavid du Colombier 	}
1494e887ea33SDavid du Colombier 	return 0;
1495e887ea33SDavid du Colombier }
1496e887ea33SDavid du Colombier 
1497e887ea33SDavid du Colombier schar	ewidth[NTYPE] =
1498e887ea33SDavid du Colombier {
1499e887ea33SDavid du Colombier 	-1,		/*[TXXX]*/
1500e887ea33SDavid du Colombier 	SZ_CHAR,	/*[TCHAR]*/
1501e887ea33SDavid du Colombier 	SZ_CHAR,	/*[TUCHAR]*/
1502e887ea33SDavid du Colombier 	SZ_SHORT,	/*[TSHORT]*/
1503e887ea33SDavid du Colombier 	SZ_SHORT,	/*[TUSHORT]*/
1504e887ea33SDavid du Colombier 	SZ_INT,		/*[TINT]*/
1505e887ea33SDavid du Colombier 	SZ_INT,		/*[TUINT]*/
1506e887ea33SDavid du Colombier 	SZ_LONG,	/*[TLONG]*/
1507e887ea33SDavid du Colombier 	SZ_LONG,	/*[TULONG]*/
1508e887ea33SDavid du Colombier 	SZ_VLONG,	/*[TVLONG]*/
1509e887ea33SDavid du Colombier 	SZ_VLONG,	/*[TUVLONG]*/
1510e887ea33SDavid du Colombier 	SZ_FLOAT,	/*[TFLOAT]*/
1511e887ea33SDavid du Colombier 	SZ_DOUBLE,	/*[TDOUBLE]*/
1512e887ea33SDavid du Colombier 	SZ_IND,		/*[TIND]*/
1513e887ea33SDavid du Colombier 	0,		/*[TFUNC]*/
1514e887ea33SDavid du Colombier 	-1,		/*[TARRAY]*/
1515e887ea33SDavid du Colombier 	0,		/*[TVOID]*/
1516e887ea33SDavid du Colombier 	-1,		/*[TSTRUCT]*/
1517e887ea33SDavid du Colombier 	-1,		/*[TUNION]*/
1518e887ea33SDavid du Colombier 	SZ_INT,		/*[TENUM]*/
1519e887ea33SDavid du Colombier };
1520e887ea33SDavid du Colombier long	ncast[NTYPE] =
1521e887ea33SDavid du Colombier {
1522e887ea33SDavid du Colombier 	0,				/*[TXXX]*/
1523e887ea33SDavid du Colombier 	BCHAR|BUCHAR,			/*[TCHAR]*/
1524e887ea33SDavid du Colombier 	BCHAR|BUCHAR,			/*[TUCHAR]*/
1525e887ea33SDavid du Colombier 	BSHORT|BUSHORT,			/*[TSHORT]*/
1526e887ea33SDavid du Colombier 	BSHORT|BUSHORT,			/*[TUSHORT]*/
1527e887ea33SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/*[TINT]*/
1528e887ea33SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/*[TUINT]*/
1529e887ea33SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/*[TLONG]*/
1530e887ea33SDavid du Colombier 	BINT|BUINT|BLONG|BULONG,	/*[TULONG]*/
1531e887ea33SDavid du Colombier 	BVLONG|BUVLONG|BIND,			/*[TVLONG]*/
1532e887ea33SDavid du Colombier 	BVLONG|BUVLONG|BIND,			/*[TUVLONG]*/
1533e887ea33SDavid du Colombier 	BFLOAT,				/*[TFLOAT]*/
1534e887ea33SDavid du Colombier 	BDOUBLE,			/*[TDOUBLE]*/
1535e887ea33SDavid du Colombier 	BVLONG|BUVLONG|BIND,		/*[TIND]*/
1536e887ea33SDavid du Colombier 	0,				/*[TFUNC]*/
1537e887ea33SDavid du Colombier 	0,				/*[TARRAY]*/
1538e887ea33SDavid du Colombier 	0,				/*[TVOID]*/
1539e887ea33SDavid du Colombier 	BSTRUCT,			/*[TSTRUCT]*/
1540e887ea33SDavid du Colombier 	BUNION,				/*[TUNION]*/
1541e887ea33SDavid du Colombier 	0,				/*[TENUM]*/
1542e887ea33SDavid du Colombier };
1543