xref: /plan9-contrib/sys/src/cmd/cc/com64.c (revision 14ea38b6f8adaf7a49ae969a6611c1375d5f4c57)
1219b2ee8SDavid du Colombier #include "cc.h"
2219b2ee8SDavid du Colombier 
3219b2ee8SDavid du Colombier /*
46891d857SDavid du Colombier  * this is machine dependent, but it is totally
5219b2ee8SDavid du Colombier  * common on all of the 64-bit symulating machines.
6219b2ee8SDavid du Colombier  */
7219b2ee8SDavid du Colombier 
8219b2ee8SDavid du Colombier #define	FNX	100	/* botch -- redefinition */
9219b2ee8SDavid du Colombier 
10219b2ee8SDavid du Colombier Node*	nodaddv;
11219b2ee8SDavid du Colombier Node*	nodsubv;
12219b2ee8SDavid du Colombier Node*	nodmulv;
13219b2ee8SDavid du Colombier Node*	noddivv;
14219b2ee8SDavid du Colombier Node*	noddivvu;
15219b2ee8SDavid du Colombier Node*	nodmodv;
16219b2ee8SDavid du Colombier Node*	nodmodvu;
17219b2ee8SDavid du Colombier Node*	nodlshv;
18219b2ee8SDavid du Colombier Node*	nodrshav;
19219b2ee8SDavid du Colombier Node*	nodrshlv;
20219b2ee8SDavid du Colombier Node*	nodandv;
21219b2ee8SDavid du Colombier Node*	nodorv;
22219b2ee8SDavid du Colombier Node*	nodxorv;
23219b2ee8SDavid du Colombier Node*	nodnegv;
24219b2ee8SDavid du Colombier Node*	nodcomv;
25219b2ee8SDavid du Colombier 
26219b2ee8SDavid du Colombier Node*	nodtestv;
27219b2ee8SDavid du Colombier Node*	nodeqv;
28219b2ee8SDavid du Colombier Node*	nodnev;
29219b2ee8SDavid du Colombier Node*	nodlev;
30219b2ee8SDavid du Colombier Node*	nodltv;
31219b2ee8SDavid du Colombier Node*	nodgev;
32219b2ee8SDavid du Colombier Node*	nodgtv;
33219b2ee8SDavid du Colombier Node*	nodhiv;
34219b2ee8SDavid du Colombier Node*	nodhsv;
35219b2ee8SDavid du Colombier Node*	nodlov;
36219b2ee8SDavid du Colombier Node*	nodlsv;
37219b2ee8SDavid du Colombier 
38219b2ee8SDavid du Colombier Node*	nodf2v;
39219b2ee8SDavid du Colombier Node*	nodd2v;
407dd7cddfSDavid du Colombier Node*	nodp2v;
417dd7cddfSDavid du Colombier Node*	nodsi2v;
427dd7cddfSDavid du Colombier Node*	nodui2v;
43219b2ee8SDavid du Colombier Node*	nodsl2v;
44219b2ee8SDavid du Colombier Node*	nodul2v;
45219b2ee8SDavid du Colombier Node*	nodsh2v;
46219b2ee8SDavid du Colombier Node*	noduh2v;
47219b2ee8SDavid du Colombier Node*	nodsc2v;
48219b2ee8SDavid du Colombier Node*	noduc2v;
49219b2ee8SDavid du Colombier 
50219b2ee8SDavid du Colombier Node*	nodv2f;
51219b2ee8SDavid du Colombier Node*	nodv2d;
527dd7cddfSDavid du Colombier Node*	nodv2ui;
537dd7cddfSDavid du Colombier Node*	nodv2si;
54219b2ee8SDavid du Colombier Node*	nodv2ul;
55219b2ee8SDavid du Colombier Node*	nodv2sl;
56219b2ee8SDavid du Colombier Node*	nodv2uh;
57219b2ee8SDavid du Colombier Node*	nodv2sh;
58219b2ee8SDavid du Colombier Node*	nodv2uc;
59219b2ee8SDavid du Colombier Node*	nodv2sc;
60219b2ee8SDavid du Colombier 
61219b2ee8SDavid du Colombier Node*	nodvpp;
62219b2ee8SDavid du Colombier Node*	nodppv;
63219b2ee8SDavid du Colombier Node*	nodvmm;
64219b2ee8SDavid du Colombier Node*	nodmmv;
65219b2ee8SDavid du Colombier 
66*14ea38b6SDavid du Colombier Node*	nodaddd;
67*14ea38b6SDavid du Colombier Node*	nodsubd;
68*14ea38b6SDavid du Colombier Node*	nodmuld;
69*14ea38b6SDavid du Colombier Node*	noddivd;
70*14ea38b6SDavid du Colombier 
71219b2ee8SDavid du Colombier Node*	nodvasop;
72219b2ee8SDavid du Colombier 
737dd7cddfSDavid du Colombier char	etconv[NTYPE];	/* for _vasop */
747dd7cddfSDavid du Colombier Init	initetconv[] =
757dd7cddfSDavid du Colombier {
767dd7cddfSDavid du Colombier 	TCHAR,		1,	0,
777dd7cddfSDavid du Colombier 	TUCHAR,		2,	0,
787dd7cddfSDavid du Colombier 	TSHORT,		3,	0,
797dd7cddfSDavid du Colombier 	TUSHORT,	4,	0,
807dd7cddfSDavid du Colombier 	TLONG,		5,	0,
817dd7cddfSDavid du Colombier 	TULONG,		6,	0,
827dd7cddfSDavid du Colombier 	TVLONG,		7,	0,
837dd7cddfSDavid du Colombier 	TUVLONG,	8,	0,
847dd7cddfSDavid du Colombier 	TINT,		9,	0,
857dd7cddfSDavid du Colombier 	TUINT,		10,	0,
867dd7cddfSDavid du Colombier 	-1,		0,	0,
877dd7cddfSDavid du Colombier };
887dd7cddfSDavid du Colombier 
89219b2ee8SDavid du Colombier Node*
fvn(char * name,int type)90219b2ee8SDavid du Colombier fvn(char *name, int type)
91219b2ee8SDavid du Colombier {
92219b2ee8SDavid du Colombier 	Node *n;
93219b2ee8SDavid du Colombier 
94219b2ee8SDavid du Colombier 	n = new(ONAME, Z, Z);
95219b2ee8SDavid du Colombier 	n->sym = slookup(name);
96375daca8SDavid du Colombier 	n->sym->sig = SIGINTERN;
97219b2ee8SDavid du Colombier 	if(fntypes[type] == 0)
98219b2ee8SDavid du Colombier 		fntypes[type] = typ(TFUNC, types[type]);
99219b2ee8SDavid du Colombier 	n->type = fntypes[type];
100219b2ee8SDavid du Colombier 	n->etype = type;
101219b2ee8SDavid du Colombier 	n->class = CGLOBL;
102219b2ee8SDavid du Colombier 	n->addable = 10;
103219b2ee8SDavid du Colombier 	n->complex = 0;
104219b2ee8SDavid du Colombier 	return n;
105219b2ee8SDavid du Colombier }
106219b2ee8SDavid du Colombier 
107219b2ee8SDavid du Colombier void
com64init(void)108219b2ee8SDavid du Colombier com64init(void)
109219b2ee8SDavid du Colombier {
1107dd7cddfSDavid du Colombier 	Init *p;
1117dd7cddfSDavid du Colombier 
112219b2ee8SDavid du Colombier 	nodaddv = fvn("_addv", TVLONG);
113219b2ee8SDavid du Colombier 	nodsubv = fvn("_subv", TVLONG);
114219b2ee8SDavid du Colombier 	nodmulv = fvn("_mulv", TVLONG);
115219b2ee8SDavid du Colombier 	noddivv = fvn("_divv", TVLONG);
116219b2ee8SDavid du Colombier 	noddivvu = fvn("_divvu", TVLONG);
117219b2ee8SDavid du Colombier 	nodmodv = fvn("_modv", TVLONG);
118219b2ee8SDavid du Colombier 	nodmodvu = fvn("_modvu", TVLONG);
119219b2ee8SDavid du Colombier 	nodlshv = fvn("_lshv", TVLONG);
120219b2ee8SDavid du Colombier 	nodrshav = fvn("_rshav", TVLONG);
121219b2ee8SDavid du Colombier 	nodrshlv = fvn("_rshlv", TVLONG);
122219b2ee8SDavid du Colombier 	nodandv = fvn("_andv", TVLONG);
123219b2ee8SDavid du Colombier 	nodorv = fvn("_orv", TVLONG);
124219b2ee8SDavid du Colombier 	nodxorv = fvn("_xorv", TVLONG);
125219b2ee8SDavid du Colombier 	nodnegv = fvn("_negv", TVLONG);
126219b2ee8SDavid du Colombier 	nodcomv = fvn("_comv", TVLONG);
127219b2ee8SDavid du Colombier 
128219b2ee8SDavid du Colombier 	nodtestv = fvn("_testv", TLONG);
129219b2ee8SDavid du Colombier 	nodeqv = fvn("_eqv", TLONG);
130219b2ee8SDavid du Colombier 	nodnev = fvn("_nev", TLONG);
131219b2ee8SDavid du Colombier 	nodlev = fvn("_lev", TLONG);
132219b2ee8SDavid du Colombier 	nodltv = fvn("_ltv", TLONG);
133219b2ee8SDavid du Colombier 	nodgev = fvn("_gev", TLONG);
134219b2ee8SDavid du Colombier 	nodgtv = fvn("_gtv", TLONG);
135219b2ee8SDavid du Colombier 	nodhiv = fvn("_hiv", TLONG);
136219b2ee8SDavid du Colombier 	nodhsv = fvn("_hsv", TLONG);
137219b2ee8SDavid du Colombier 	nodlov = fvn("_lov", TLONG);
138219b2ee8SDavid du Colombier 	nodlsv = fvn("_lsv", TLONG);
139219b2ee8SDavid du Colombier 
140219b2ee8SDavid du Colombier 	nodf2v = fvn("_f2v", TVLONG);
141219b2ee8SDavid du Colombier 	nodd2v = fvn("_d2v", TVLONG);
1427dd7cddfSDavid du Colombier 	nodp2v = fvn("_p2v", TVLONG);
1437dd7cddfSDavid du Colombier 	nodsi2v = fvn("_si2v", TVLONG);
1447dd7cddfSDavid du Colombier 	nodui2v = fvn("_ui2v", TVLONG);
145219b2ee8SDavid du Colombier 	nodsl2v = fvn("_sl2v", TVLONG);
146219b2ee8SDavid du Colombier 	nodul2v = fvn("_ul2v", TVLONG);
147219b2ee8SDavid du Colombier 	nodsh2v = fvn("_sh2v", TVLONG);
148219b2ee8SDavid du Colombier 	noduh2v = fvn("_uh2v", TVLONG);
149219b2ee8SDavid du Colombier 	nodsc2v = fvn("_sc2v", TVLONG);
150219b2ee8SDavid du Colombier 	noduc2v = fvn("_uc2v", TVLONG);
151219b2ee8SDavid du Colombier 
152219b2ee8SDavid du Colombier 	nodv2f = fvn("_v2f", TFLOAT);
153219b2ee8SDavid du Colombier 	nodv2d = fvn("_v2d", TDOUBLE);
154219b2ee8SDavid du Colombier 	nodv2sl = fvn("_v2sl", TLONG);
155219b2ee8SDavid du Colombier 	nodv2ul = fvn("_v2ul", TULONG);
1567dd7cddfSDavid du Colombier 	nodv2si = fvn("_v2si", TINT);
1577dd7cddfSDavid du Colombier 	nodv2ui = fvn("_v2ui", TUINT);
158219b2ee8SDavid du Colombier 	nodv2sh = fvn("_v2sh", TSHORT);
159219b2ee8SDavid du Colombier 	nodv2uh = fvn("_v2ul", TUSHORT);
160219b2ee8SDavid du Colombier 	nodv2sc = fvn("_v2sc", TCHAR);
161219b2ee8SDavid du Colombier 	nodv2uc = fvn("_v2uc", TUCHAR);
162219b2ee8SDavid du Colombier 
163219b2ee8SDavid du Colombier 	nodvpp = fvn("_vpp", TVLONG);
164219b2ee8SDavid du Colombier 	nodppv = fvn("_ppv", TVLONG);
165219b2ee8SDavid du Colombier 	nodvmm = fvn("_vmm", TVLONG);
166219b2ee8SDavid du Colombier 	nodmmv = fvn("_mmv", TVLONG);
167219b2ee8SDavid du Colombier 
168*14ea38b6SDavid du Colombier 	nodaddd = fvn("_vasaddd", TVLONG);
169*14ea38b6SDavid du Colombier 	nodsubd = fvn("_vassubd", TVLONG);
170*14ea38b6SDavid du Colombier 	nodmuld = fvn("_vasmuld", TVLONG);
171*14ea38b6SDavid du Colombier 	noddivd = fvn("_vasdivd", TVLONG);
172*14ea38b6SDavid du Colombier 
173219b2ee8SDavid du Colombier 	nodvasop = fvn("_vasop", TVLONG);
1747dd7cddfSDavid du Colombier 
1757dd7cddfSDavid du Colombier 	for(p = initetconv; p->code >= 0; p++)
1767dd7cddfSDavid du Colombier 		etconv[p->code] = p->value;
177219b2ee8SDavid du Colombier }
178219b2ee8SDavid du Colombier 
179219b2ee8SDavid du Colombier int
com64(Node * n)180219b2ee8SDavid du Colombier com64(Node *n)
181219b2ee8SDavid du Colombier {
182219b2ee8SDavid du Colombier 	Node *l, *r, *a, *t;
1837dd7cddfSDavid du Colombier 	int lv, rv;
1847dd7cddfSDavid du Colombier 
1857dd7cddfSDavid du Colombier 	if(n->type == 0)
1867dd7cddfSDavid du Colombier 		return 0;
187219b2ee8SDavid du Colombier 
188219b2ee8SDavid du Colombier 	l = n->left;
189219b2ee8SDavid du Colombier 	r = n->right;
190219b2ee8SDavid du Colombier 
1917dd7cddfSDavid du Colombier 	lv = 0;
1927dd7cddfSDavid du Colombier 	if(l && l->type && typev[l->type->etype])
1937dd7cddfSDavid du Colombier 		lv = 1;
1947dd7cddfSDavid du Colombier 	rv = 0;
1957dd7cddfSDavid du Colombier 	if(r && r->type && typev[r->type->etype])
1967dd7cddfSDavid du Colombier 		rv = 1;
1977dd7cddfSDavid du Colombier 
1987dd7cddfSDavid du Colombier 	if(lv) {
199219b2ee8SDavid du Colombier 		switch(n->op) {
200219b2ee8SDavid du Colombier 		case OEQ:
201219b2ee8SDavid du Colombier 			a = nodeqv;
202219b2ee8SDavid du Colombier 			goto setbool;
203219b2ee8SDavid du Colombier 		case ONE:
204219b2ee8SDavid du Colombier 			a = nodnev;
205219b2ee8SDavid du Colombier 			goto setbool;
206219b2ee8SDavid du Colombier 		case OLE:
207219b2ee8SDavid du Colombier 			a = nodlev;
208219b2ee8SDavid du Colombier 			goto setbool;
209219b2ee8SDavid du Colombier 		case OLT:
210219b2ee8SDavid du Colombier 			a = nodltv;
211219b2ee8SDavid du Colombier 			goto setbool;
212219b2ee8SDavid du Colombier 		case OGE:
213219b2ee8SDavid du Colombier 			a = nodgev;
214219b2ee8SDavid du Colombier 			goto setbool;
215219b2ee8SDavid du Colombier 		case OGT:
216219b2ee8SDavid du Colombier 			a = nodgtv;
217219b2ee8SDavid du Colombier 			goto setbool;
218219b2ee8SDavid du Colombier 		case OHI:
219219b2ee8SDavid du Colombier 			a = nodhiv;
220219b2ee8SDavid du Colombier 			goto setbool;
221219b2ee8SDavid du Colombier 		case OHS:
222219b2ee8SDavid du Colombier 			a = nodhsv;
223219b2ee8SDavid du Colombier 			goto setbool;
224219b2ee8SDavid du Colombier 		case OLO:
225219b2ee8SDavid du Colombier 			a = nodlov;
226219b2ee8SDavid du Colombier 			goto setbool;
227219b2ee8SDavid du Colombier 		case OLS:
228219b2ee8SDavid du Colombier 			a = nodlsv;
229219b2ee8SDavid du Colombier 			goto setbool;
230219b2ee8SDavid du Colombier 
231219b2ee8SDavid du Colombier 		case OANDAND:
232219b2ee8SDavid du Colombier 		case OOROR:
233da51d93aSDavid du Colombier 			if(machcap(n))
234da51d93aSDavid du Colombier 				return 1;
235da51d93aSDavid du Colombier 
2367dd7cddfSDavid du Colombier 			if(rv) {
237219b2ee8SDavid du Colombier 				r = new(OFUNC, nodtestv, r);
238219b2ee8SDavid du Colombier 				n->right = r;
239219b2ee8SDavid du Colombier 				r->complex = FNX;
240219b2ee8SDavid du Colombier 				r->op = OFUNC;
241219b2ee8SDavid du Colombier 				r->type = types[TLONG];
2427dd7cddfSDavid du Colombier 			}
243219b2ee8SDavid du Colombier 
244219b2ee8SDavid du Colombier 		case OCOND:
245219b2ee8SDavid du Colombier 		case ONOT:
246da51d93aSDavid du Colombier 			if(machcap(n))
247da51d93aSDavid du Colombier 				return 1;
248da51d93aSDavid du Colombier 
249219b2ee8SDavid du Colombier 			l = new(OFUNC, nodtestv, l);
250219b2ee8SDavid du Colombier 			n->left = l;
251219b2ee8SDavid du Colombier 			l->complex = FNX;
252219b2ee8SDavid du Colombier 			l->op = OFUNC;
253219b2ee8SDavid du Colombier 			l->type = types[TLONG];
254219b2ee8SDavid du Colombier 			n->complex = FNX;
255219b2ee8SDavid du Colombier 			return 1;
256219b2ee8SDavid du Colombier 		}
257219b2ee8SDavid du Colombier 	}
258219b2ee8SDavid du Colombier 
2597dd7cddfSDavid du Colombier 	if(rv) {
260da51d93aSDavid du Colombier 		if(machcap(n))
261da51d93aSDavid du Colombier 			return 1;
2627dd7cddfSDavid du Colombier 		switch(n->op) {
2637dd7cddfSDavid du Colombier 		case OANDAND:
2647dd7cddfSDavid du Colombier 		case OOROR:
2657dd7cddfSDavid du Colombier 			r = new(OFUNC, nodtestv, r);
2667dd7cddfSDavid du Colombier 			n->right = r;
2677dd7cddfSDavid du Colombier 			r->complex = FNX;
2687dd7cddfSDavid du Colombier 			r->op = OFUNC;
2697dd7cddfSDavid du Colombier 			r->type = types[TLONG];
2707dd7cddfSDavid du Colombier 			return 1;
2716891d857SDavid du Colombier 		case OCOND:
2726891d857SDavid du Colombier 			return 1;
2737dd7cddfSDavid du Colombier 		}
2747dd7cddfSDavid du Colombier 	}
2757dd7cddfSDavid du Colombier 
2767dd7cddfSDavid du Colombier 	if(typev[n->type->etype]) {
277da51d93aSDavid du Colombier 		if(machcap(n))
278da51d93aSDavid du Colombier 			return 1;
279219b2ee8SDavid du Colombier 		switch(n->op) {
280219b2ee8SDavid du Colombier 		default:
2817dd7cddfSDavid du Colombier 			diag(n, "unknown vlong %O", n->op);
282219b2ee8SDavid du Colombier 		case OFUNC:
283219b2ee8SDavid du Colombier 			n->complex = FNX;
284219b2ee8SDavid du Colombier 		case ORETURN:
285219b2ee8SDavid du Colombier 		case OAS:
286219b2ee8SDavid du Colombier 		case OIND:
287ad6ca847SDavid du Colombier 		case OLIST:
288ad6ca847SDavid du Colombier 		case OCOMMA:
289219b2ee8SDavid du Colombier 			return 1;
290219b2ee8SDavid du Colombier 		case OADD:
291219b2ee8SDavid du Colombier 			a = nodaddv;
292219b2ee8SDavid du Colombier 			goto setbop;
293219b2ee8SDavid du Colombier 		case OSUB:
294219b2ee8SDavid du Colombier 			a = nodsubv;
295219b2ee8SDavid du Colombier 			goto setbop;
296219b2ee8SDavid du Colombier 		case OMUL:
297219b2ee8SDavid du Colombier 		case OLMUL:
298219b2ee8SDavid du Colombier 			a = nodmulv;
299219b2ee8SDavid du Colombier 			goto setbop;
300219b2ee8SDavid du Colombier 		case ODIV:
301219b2ee8SDavid du Colombier 			a = noddivv;
302219b2ee8SDavid du Colombier 			goto setbop;
303219b2ee8SDavid du Colombier 		case OLDIV:
304219b2ee8SDavid du Colombier 			a = noddivvu;
305219b2ee8SDavid du Colombier 			goto setbop;
306219b2ee8SDavid du Colombier 		case OMOD:
307219b2ee8SDavid du Colombier 			a = nodmodv;
308219b2ee8SDavid du Colombier 			goto setbop;
309219b2ee8SDavid du Colombier 		case OLMOD:
310219b2ee8SDavid du Colombier 			a = nodmodvu;
311219b2ee8SDavid du Colombier 			goto setbop;
312219b2ee8SDavid du Colombier 		case OASHL:
313219b2ee8SDavid du Colombier 			a = nodlshv;
314219b2ee8SDavid du Colombier 			goto setbop;
315219b2ee8SDavid du Colombier 		case OASHR:
316219b2ee8SDavid du Colombier 			a = nodrshav;
317219b2ee8SDavid du Colombier 			goto setbop;
318219b2ee8SDavid du Colombier 		case OLSHR:
319219b2ee8SDavid du Colombier 			a = nodrshlv;
320219b2ee8SDavid du Colombier 			goto setbop;
321219b2ee8SDavid du Colombier 		case OAND:
322219b2ee8SDavid du Colombier 			a = nodandv;
323219b2ee8SDavid du Colombier 			goto setbop;
324219b2ee8SDavid du Colombier 		case OOR:
325219b2ee8SDavid du Colombier 			a = nodorv;
326219b2ee8SDavid du Colombier 			goto setbop;
327219b2ee8SDavid du Colombier 		case OXOR:
328219b2ee8SDavid du Colombier 			a = nodxorv;
329219b2ee8SDavid du Colombier 			goto setbop;
330219b2ee8SDavid du Colombier 		case OPOSTINC:
331219b2ee8SDavid du Colombier 			a = nodvpp;
332219b2ee8SDavid du Colombier 			goto setvinc;
333219b2ee8SDavid du Colombier 		case OPOSTDEC:
334219b2ee8SDavid du Colombier 			a = nodvmm;
335219b2ee8SDavid du Colombier 			goto setvinc;
336219b2ee8SDavid du Colombier 		case OPREINC:
337219b2ee8SDavid du Colombier 			a = nodppv;
338219b2ee8SDavid du Colombier 			goto setvinc;
339219b2ee8SDavid du Colombier 		case OPREDEC:
340219b2ee8SDavid du Colombier 			a = nodmmv;
341219b2ee8SDavid du Colombier 			goto setvinc;
342219b2ee8SDavid du Colombier 		case ONEG:
343219b2ee8SDavid du Colombier 			a = nodnegv;
344219b2ee8SDavid du Colombier 			goto setfnx;
345219b2ee8SDavid du Colombier 		case OCOM:
346219b2ee8SDavid du Colombier 			a = nodcomv;
347219b2ee8SDavid du Colombier 			goto setfnx;
348219b2ee8SDavid du Colombier 		case OCAST:
349219b2ee8SDavid du Colombier 			switch(l->type->etype) {
350219b2ee8SDavid du Colombier 			case TCHAR:
351219b2ee8SDavid du Colombier 				a = nodsc2v;
352219b2ee8SDavid du Colombier 				goto setfnxl;
353219b2ee8SDavid du Colombier 			case TUCHAR:
354219b2ee8SDavid du Colombier 				a = noduc2v;
355219b2ee8SDavid du Colombier 				goto setfnxl;
356219b2ee8SDavid du Colombier 			case TSHORT:
357219b2ee8SDavid du Colombier 				a = nodsh2v;
358219b2ee8SDavid du Colombier 				goto setfnxl;
359219b2ee8SDavid du Colombier 			case TUSHORT:
360219b2ee8SDavid du Colombier 				a = noduh2v;
361219b2ee8SDavid du Colombier 				goto setfnxl;
3627dd7cddfSDavid du Colombier 			case TINT:
3637dd7cddfSDavid du Colombier 				a = nodsi2v;
3647dd7cddfSDavid du Colombier 				goto setfnx;
3657dd7cddfSDavid du Colombier 			case TUINT:
3667dd7cddfSDavid du Colombier 				a = nodui2v;
3677dd7cddfSDavid du Colombier 				goto setfnx;
368219b2ee8SDavid du Colombier 			case TLONG:
369219b2ee8SDavid du Colombier 				a = nodsl2v;
370219b2ee8SDavid du Colombier 				goto setfnx;
371219b2ee8SDavid du Colombier 			case TULONG:
372219b2ee8SDavid du Colombier 				a = nodul2v;
373219b2ee8SDavid du Colombier 				goto setfnx;
374219b2ee8SDavid du Colombier 			case TFLOAT:
375219b2ee8SDavid du Colombier 				a = nodf2v;
376219b2ee8SDavid du Colombier 				goto setfnx;
377219b2ee8SDavid du Colombier 			case TDOUBLE:
378219b2ee8SDavid du Colombier 				a = nodd2v;
379219b2ee8SDavid du Colombier 				goto setfnx;
3807dd7cddfSDavid du Colombier 			case TIND:
3817dd7cddfSDavid du Colombier 				a = nodp2v;
3827dd7cddfSDavid du Colombier 				goto setfnx;
383219b2ee8SDavid du Colombier 			}
384219b2ee8SDavid du Colombier 			diag(n, "unknown %T->vlong cast", l->type);
385219b2ee8SDavid du Colombier 			return 1;
386219b2ee8SDavid du Colombier 		case OASADD:
387219b2ee8SDavid du Colombier 			a = nodaddv;
388219b2ee8SDavid du Colombier 			goto setasop;
389219b2ee8SDavid du Colombier 		case OASSUB:
390219b2ee8SDavid du Colombier 			a = nodsubv;
391219b2ee8SDavid du Colombier 			goto setasop;
392219b2ee8SDavid du Colombier 		case OASMUL:
393219b2ee8SDavid du Colombier 		case OASLMUL:
394219b2ee8SDavid du Colombier 			a = nodmulv;
395219b2ee8SDavid du Colombier 			goto setasop;
396219b2ee8SDavid du Colombier 		case OASDIV:
397219b2ee8SDavid du Colombier 			a = noddivv;
398219b2ee8SDavid du Colombier 			goto setasop;
399219b2ee8SDavid du Colombier 		case OASLDIV:
400219b2ee8SDavid du Colombier 			a = noddivvu;
401219b2ee8SDavid du Colombier 			goto setasop;
402219b2ee8SDavid du Colombier 		case OASMOD:
403219b2ee8SDavid du Colombier 			a = nodmodv;
404219b2ee8SDavid du Colombier 			goto setasop;
405219b2ee8SDavid du Colombier 		case OASLMOD:
406219b2ee8SDavid du Colombier 			a = nodmodvu;
407219b2ee8SDavid du Colombier 			goto setasop;
408219b2ee8SDavid du Colombier 		case OASASHL:
409219b2ee8SDavid du Colombier 			a = nodlshv;
410219b2ee8SDavid du Colombier 			goto setasop;
411219b2ee8SDavid du Colombier 		case OASASHR:
412219b2ee8SDavid du Colombier 			a = nodrshav;
413219b2ee8SDavid du Colombier 			goto setasop;
414219b2ee8SDavid du Colombier 		case OASLSHR:
415219b2ee8SDavid du Colombier 			a = nodrshlv;
416219b2ee8SDavid du Colombier 			goto setasop;
417219b2ee8SDavid du Colombier 		case OASAND:
418219b2ee8SDavid du Colombier 			a = nodandv;
419219b2ee8SDavid du Colombier 			goto setasop;
420219b2ee8SDavid du Colombier 		case OASOR:
421219b2ee8SDavid du Colombier 			a = nodorv;
422219b2ee8SDavid du Colombier 			goto setasop;
423219b2ee8SDavid du Colombier 		case OASXOR:
424219b2ee8SDavid du Colombier 			a = nodxorv;
425219b2ee8SDavid du Colombier 			goto setasop;
426219b2ee8SDavid du Colombier 		}
427219b2ee8SDavid du Colombier 	}
428219b2ee8SDavid du Colombier 
4297dd7cddfSDavid du Colombier 	if(typefd[n->type->etype] && l && l->op == OFUNC) {
430219b2ee8SDavid du Colombier 		switch(n->op) {
431219b2ee8SDavid du Colombier 		case OASADD:
432219b2ee8SDavid du Colombier 		case OASSUB:
433219b2ee8SDavid du Colombier 		case OASMUL:
434219b2ee8SDavid du Colombier 		case OASLMUL:
435219b2ee8SDavid du Colombier 		case OASDIV:
436219b2ee8SDavid du Colombier 		case OASLDIV:
437219b2ee8SDavid du Colombier 		case OASMOD:
438219b2ee8SDavid du Colombier 		case OASLMOD:
439219b2ee8SDavid du Colombier 		case OASASHL:
440219b2ee8SDavid du Colombier 		case OASASHR:
441219b2ee8SDavid du Colombier 		case OASLSHR:
442219b2ee8SDavid du Colombier 		case OASAND:
443219b2ee8SDavid du Colombier 		case OASOR:
444219b2ee8SDavid du Colombier 		case OASXOR:
445219b2ee8SDavid du Colombier 			if(l->right && typev[l->right->etype]) {
446219b2ee8SDavid du Colombier 				diag(n, "sorry float <asop> vlong not implemented\n");
447219b2ee8SDavid du Colombier 			}
448219b2ee8SDavid du Colombier 		}
449219b2ee8SDavid du Colombier 	}
450219b2ee8SDavid du Colombier 
451219b2ee8SDavid du Colombier 	if(n->op == OCAST) {
452219b2ee8SDavid du Colombier 		if(l->type && typev[l->type->etype]) {
453da51d93aSDavid du Colombier 			if(machcap(n))
454da51d93aSDavid du Colombier 				return 1;
455219b2ee8SDavid du Colombier 			switch(n->type->etype) {
456219b2ee8SDavid du Colombier 			case TDOUBLE:
457219b2ee8SDavid du Colombier 				a = nodv2d;
458219b2ee8SDavid du Colombier 				goto setfnx;
459219b2ee8SDavid du Colombier 			case TFLOAT:
460219b2ee8SDavid du Colombier 				a = nodv2f;
461219b2ee8SDavid du Colombier 				goto setfnx;
462219b2ee8SDavid du Colombier 			case TLONG:
463219b2ee8SDavid du Colombier 				a = nodv2sl;
464219b2ee8SDavid du Colombier 				goto setfnx;
465219b2ee8SDavid du Colombier 			case TULONG:
466219b2ee8SDavid du Colombier 				a = nodv2ul;
467219b2ee8SDavid du Colombier 				goto setfnx;
4687dd7cddfSDavid du Colombier 			case TINT:
4697dd7cddfSDavid du Colombier 				a = nodv2si;
4707dd7cddfSDavid du Colombier 				goto setfnx;
4717dd7cddfSDavid du Colombier 			case TUINT:
4727dd7cddfSDavid du Colombier 				a = nodv2ui;
4737dd7cddfSDavid du Colombier 				goto setfnx;
474219b2ee8SDavid du Colombier 			case TSHORT:
475219b2ee8SDavid du Colombier 				a = nodv2sh;
476219b2ee8SDavid du Colombier 				goto setfnx;
477219b2ee8SDavid du Colombier 			case TUSHORT:
478219b2ee8SDavid du Colombier 				a = nodv2uh;
479219b2ee8SDavid du Colombier 				goto setfnx;
480219b2ee8SDavid du Colombier 			case TCHAR:
481219b2ee8SDavid du Colombier 				a = nodv2sc;
482219b2ee8SDavid du Colombier 				goto setfnx;
483219b2ee8SDavid du Colombier 			case TUCHAR:
484219b2ee8SDavid du Colombier 				a = nodv2uc;
485219b2ee8SDavid du Colombier 				goto setfnx;
4867dd7cddfSDavid du Colombier 			case TIND:	// small pun here
4877dd7cddfSDavid du Colombier 				a = nodv2ul;
4887dd7cddfSDavid du Colombier 				goto setfnx;
489219b2ee8SDavid du Colombier 			}
490219b2ee8SDavid du Colombier 			diag(n, "unknown vlong->%T cast", n->type);
491219b2ee8SDavid du Colombier 			return 1;
492219b2ee8SDavid du Colombier 		}
493219b2ee8SDavid du Colombier 	}
494219b2ee8SDavid du Colombier 
495219b2ee8SDavid du Colombier 	return 0;
496219b2ee8SDavid du Colombier 
497219b2ee8SDavid du Colombier setbop:
498219b2ee8SDavid du Colombier 	n->left = a;
499219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
500219b2ee8SDavid du Colombier 	n->complex = FNX;
501219b2ee8SDavid du Colombier 	n->op = OFUNC;
502219b2ee8SDavid du Colombier 	return 1;
503219b2ee8SDavid du Colombier 
504219b2ee8SDavid du Colombier setfnxl:
505219b2ee8SDavid du Colombier 	l = new(OCAST, l, 0);
506219b2ee8SDavid du Colombier 	l->type = types[TLONG];
507219b2ee8SDavid du Colombier 	l->complex = l->left->complex;
508219b2ee8SDavid du Colombier 
509219b2ee8SDavid du Colombier setfnx:
510219b2ee8SDavid du Colombier 	n->left = a;
511219b2ee8SDavid du Colombier 	n->right = l;
512219b2ee8SDavid du Colombier 	n->complex = FNX;
513219b2ee8SDavid du Colombier 	n->op = OFUNC;
514219b2ee8SDavid du Colombier 	return 1;
515219b2ee8SDavid du Colombier 
516219b2ee8SDavid du Colombier setvinc:
517219b2ee8SDavid du Colombier 	n->left = a;
518219b2ee8SDavid du Colombier 	l = new(OADDR, l, Z);
519219b2ee8SDavid du Colombier 	l->type = typ(TIND, l->left->type);
5206891d857SDavid du Colombier 	l->complex = l->left->complex;
521219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
522219b2ee8SDavid du Colombier 	n->complex = FNX;
523219b2ee8SDavid du Colombier 	n->op = OFUNC;
524219b2ee8SDavid du Colombier 	return 1;
525219b2ee8SDavid du Colombier 
526219b2ee8SDavid du Colombier setbool:
527da51d93aSDavid du Colombier 	if(machcap(n))
528da51d93aSDavid du Colombier 		return 1;
529219b2ee8SDavid du Colombier 	n->left = a;
530219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
531219b2ee8SDavid du Colombier 	n->complex = FNX;
532219b2ee8SDavid du Colombier 	n->op = OFUNC;
533219b2ee8SDavid du Colombier 	n->type = types[TLONG];
534219b2ee8SDavid du Colombier 	return 1;
535219b2ee8SDavid du Colombier 
536219b2ee8SDavid du Colombier setasop:
537*14ea38b6SDavid du Colombier 	while(l->op == OFUNC)
538219b2ee8SDavid du Colombier 		l = l->right;
539*14ea38b6SDavid du Colombier 
540*14ea38b6SDavid du Colombier 	if(mixedasop(n->left->type, n->right->type)) {
541*14ea38b6SDavid du Colombier 		if(n->right->type->etype != TDOUBLE) {
542*14ea38b6SDavid du Colombier 			r = new(OCAST, r, 0);
543*14ea38b6SDavid du Colombier 			r->type = types[TDOUBLE];
544219b2ee8SDavid du Colombier 		}
545219b2ee8SDavid du Colombier 
546*14ea38b6SDavid du Colombier 		t = new(OADDR, l, 0);
547*14ea38b6SDavid du Colombier 		t->type = typ(TIND, l->type);
548*14ea38b6SDavid du Colombier 		t->complex = l->complex;
549*14ea38b6SDavid du Colombier 		r = new(OLIST, t, r);
550*14ea38b6SDavid du Colombier 
551*14ea38b6SDavid du Colombier 		switch(n->op) {
552*14ea38b6SDavid du Colombier 		case OASADD:	a = nodaddd; break;
553*14ea38b6SDavid du Colombier 		case OASSUB:	a = nodsubd; break;
554*14ea38b6SDavid du Colombier 		case OASMUL:	a = nodmuld; break;
555*14ea38b6SDavid du Colombier 		case OASDIV:	a = noddivd; break;
556*14ea38b6SDavid du Colombier 		default:	diag(n, "bad vasop %O", n->op); a = nodaddd; break;
557*14ea38b6SDavid du Colombier 		}
558*14ea38b6SDavid du Colombier 
559*14ea38b6SDavid du Colombier 		n->left = a;
560*14ea38b6SDavid du Colombier 		n->right = r;
561*14ea38b6SDavid du Colombier 		n->complex = FNX;
562*14ea38b6SDavid du Colombier 		n->op = OFUNC;
563*14ea38b6SDavid du Colombier 
564*14ea38b6SDavid du Colombier 	} else {
565219b2ee8SDavid du Colombier 		t = new(OCONST, 0, 0);
5667dd7cddfSDavid du Colombier 		t->vconst = etconv[l->type->etype];
567219b2ee8SDavid du Colombier 		t->type = types[TLONG];
568219b2ee8SDavid du Colombier 		t->addable = 20;
569219b2ee8SDavid du Colombier 		r = new(OLIST, t, r);
570219b2ee8SDavid du Colombier 
571219b2ee8SDavid du Colombier 		t = new(OADDR, a, 0);
572219b2ee8SDavid du Colombier 		t->type = typ(TIND, a->type);
573219b2ee8SDavid du Colombier 		r = new(OLIST, t, r);
574219b2ee8SDavid du Colombier 
575219b2ee8SDavid du Colombier 		t = new(OADDR, l, 0);
576219b2ee8SDavid du Colombier 		t->type = typ(TIND, l->type);
5776891d857SDavid du Colombier 		t->complex = l->complex;
578219b2ee8SDavid du Colombier 		r = new(OLIST, t, r);
579219b2ee8SDavid du Colombier 
580219b2ee8SDavid du Colombier 		n->left = nodvasop;
581219b2ee8SDavid du Colombier 		n->right = r;
582219b2ee8SDavid du Colombier 		n->complex = FNX;
583219b2ee8SDavid du Colombier 		n->op = OFUNC;
584*14ea38b6SDavid du Colombier 	}
585219b2ee8SDavid du Colombier 
586219b2ee8SDavid du Colombier 	return 1;
587219b2ee8SDavid du Colombier }
588219b2ee8SDavid du Colombier 
589219b2ee8SDavid du Colombier void
bool64(Node * n)590219b2ee8SDavid du Colombier bool64(Node *n)
591219b2ee8SDavid du Colombier {
592219b2ee8SDavid du Colombier 	Node *n1;
593219b2ee8SDavid du Colombier 
5944ac975e2SDavid du Colombier 	if(machcap(Z))
5954ac975e2SDavid du Colombier 		return;
596219b2ee8SDavid du Colombier 	if(typev[n->type->etype]) {
597219b2ee8SDavid du Colombier 		n1 = new(OXXX, 0, 0);
598219b2ee8SDavid du Colombier 		*n1 = *n;
599219b2ee8SDavid du Colombier 
600219b2ee8SDavid du Colombier 		n->right = n1;
601219b2ee8SDavid du Colombier 		n->left = nodtestv;
602219b2ee8SDavid du Colombier 		n->complex = FNX;
603219b2ee8SDavid du Colombier 		n->addable = 0;
604219b2ee8SDavid du Colombier 		n->op = OFUNC;
605219b2ee8SDavid du Colombier 		n->type = types[TLONG];
606219b2ee8SDavid du Colombier 	}
607219b2ee8SDavid du Colombier }
608219b2ee8SDavid du Colombier 
609219b2ee8SDavid du Colombier /*
610219b2ee8SDavid du Colombier  * more machine depend stuff.
611219b2ee8SDavid du Colombier  * this is common for 8,16,32,64 bit machines.
612219b2ee8SDavid du Colombier  * this is common for ieee machines.
613219b2ee8SDavid du Colombier  */
614219b2ee8SDavid du Colombier double
convvtof(vlong v)615219b2ee8SDavid du Colombier convvtof(vlong v)
616219b2ee8SDavid du Colombier {
617219b2ee8SDavid du Colombier 	double d;
618219b2ee8SDavid du Colombier 
619219b2ee8SDavid du Colombier 	d = v;		/* BOTCH */
620219b2ee8SDavid du Colombier 	return d;
621219b2ee8SDavid du Colombier }
622219b2ee8SDavid du Colombier 
623219b2ee8SDavid du Colombier vlong
convftov(double d)624219b2ee8SDavid du Colombier convftov(double d)
625219b2ee8SDavid du Colombier {
626219b2ee8SDavid du Colombier 	vlong v;
627219b2ee8SDavid du Colombier 
628219b2ee8SDavid du Colombier 
629219b2ee8SDavid du Colombier 	v = d;		/* BOTCH */
630219b2ee8SDavid du Colombier 	return v;
631219b2ee8SDavid du Colombier }
632219b2ee8SDavid du Colombier 
633219b2ee8SDavid du Colombier double
convftox(double d,int et)6347dd7cddfSDavid du Colombier convftox(double d, int et)
635219b2ee8SDavid du Colombier {
636219b2ee8SDavid du Colombier 
6377dd7cddfSDavid du Colombier 	if(!typefd[et])
6387dd7cddfSDavid du Colombier 		diag(Z, "bad type in castftox %s", tnames[et]);
639219b2ee8SDavid du Colombier 	return d;
640219b2ee8SDavid du Colombier }
641219b2ee8SDavid du Colombier 
642219b2ee8SDavid du Colombier vlong
convvtox(vlong c,int et)6437dd7cddfSDavid du Colombier convvtox(vlong c, int et)
644219b2ee8SDavid du Colombier {
6457dd7cddfSDavid du Colombier 	int n;
646219b2ee8SDavid du Colombier 
6477dd7cddfSDavid du Colombier 	n = 8 * ewidth[et];
6487dd7cddfSDavid du Colombier 	c &= MASK(n);
6497dd7cddfSDavid du Colombier 	if(!typeu[et])
6507dd7cddfSDavid du Colombier 		if(c & SIGN(n))
6517dd7cddfSDavid du Colombier 			c |= ~MASK(n);
652219b2ee8SDavid du Colombier 	return c;
653219b2ee8SDavid du Colombier }
654