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