xref: /plan9/sys/src/cmd/cc/com64.c (revision ad6ca847b1a6a504acb0003cd6c5c6d92687369b)
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 
66219b2ee8SDavid du Colombier Node*	nodvasop;
67219b2ee8SDavid du Colombier 
687dd7cddfSDavid du Colombier char	etconv[NTYPE];	/* for _vasop */
697dd7cddfSDavid du Colombier Init	initetconv[] =
707dd7cddfSDavid du Colombier {
717dd7cddfSDavid du Colombier 	TCHAR,		1,	0,
727dd7cddfSDavid du Colombier 	TUCHAR,		2,	0,
737dd7cddfSDavid du Colombier 	TSHORT,		3,	0,
747dd7cddfSDavid du Colombier 	TUSHORT,	4,	0,
757dd7cddfSDavid du Colombier 	TLONG,		5,	0,
767dd7cddfSDavid du Colombier 	TULONG,		6,	0,
777dd7cddfSDavid du Colombier 	TVLONG,		7,	0,
787dd7cddfSDavid du Colombier 	TUVLONG,	8,	0,
797dd7cddfSDavid du Colombier 	TINT,		9,	0,
807dd7cddfSDavid du Colombier 	TUINT,		10,	0,
817dd7cddfSDavid du Colombier 	-1,		0,	0,
827dd7cddfSDavid du Colombier };
837dd7cddfSDavid du Colombier 
84219b2ee8SDavid du Colombier Node*
fvn(char * name,int type)85219b2ee8SDavid du Colombier fvn(char *name, int type)
86219b2ee8SDavid du Colombier {
87219b2ee8SDavid du Colombier 	Node *n;
88219b2ee8SDavid du Colombier 
89219b2ee8SDavid du Colombier 	n = new(ONAME, Z, Z);
90219b2ee8SDavid du Colombier 	n->sym = slookup(name);
91375daca8SDavid du Colombier 	n->sym->sig = SIGINTERN;
92219b2ee8SDavid du Colombier 	if(fntypes[type] == 0)
93219b2ee8SDavid du Colombier 		fntypes[type] = typ(TFUNC, types[type]);
94219b2ee8SDavid du Colombier 	n->type = fntypes[type];
95219b2ee8SDavid du Colombier 	n->etype = type;
96219b2ee8SDavid du Colombier 	n->class = CGLOBL;
97219b2ee8SDavid du Colombier 	n->addable = 10;
98219b2ee8SDavid du Colombier 	n->complex = 0;
99219b2ee8SDavid du Colombier 	return n;
100219b2ee8SDavid du Colombier }
101219b2ee8SDavid du Colombier 
102219b2ee8SDavid du Colombier void
com64init(void)103219b2ee8SDavid du Colombier com64init(void)
104219b2ee8SDavid du Colombier {
1057dd7cddfSDavid du Colombier 	Init *p;
1067dd7cddfSDavid du Colombier 
107219b2ee8SDavid du Colombier 	nodaddv = fvn("_addv", TVLONG);
108219b2ee8SDavid du Colombier 	nodsubv = fvn("_subv", TVLONG);
109219b2ee8SDavid du Colombier 	nodmulv = fvn("_mulv", TVLONG);
110219b2ee8SDavid du Colombier 	noddivv = fvn("_divv", TVLONG);
111219b2ee8SDavid du Colombier 	noddivvu = fvn("_divvu", TVLONG);
112219b2ee8SDavid du Colombier 	nodmodv = fvn("_modv", TVLONG);
113219b2ee8SDavid du Colombier 	nodmodvu = fvn("_modvu", TVLONG);
114219b2ee8SDavid du Colombier 	nodlshv = fvn("_lshv", TVLONG);
115219b2ee8SDavid du Colombier 	nodrshav = fvn("_rshav", TVLONG);
116219b2ee8SDavid du Colombier 	nodrshlv = fvn("_rshlv", TVLONG);
117219b2ee8SDavid du Colombier 	nodandv = fvn("_andv", TVLONG);
118219b2ee8SDavid du Colombier 	nodorv = fvn("_orv", TVLONG);
119219b2ee8SDavid du Colombier 	nodxorv = fvn("_xorv", TVLONG);
120219b2ee8SDavid du Colombier 	nodnegv = fvn("_negv", TVLONG);
121219b2ee8SDavid du Colombier 	nodcomv = fvn("_comv", TVLONG);
122219b2ee8SDavid du Colombier 
123219b2ee8SDavid du Colombier 	nodtestv = fvn("_testv", TLONG);
124219b2ee8SDavid du Colombier 	nodeqv = fvn("_eqv", TLONG);
125219b2ee8SDavid du Colombier 	nodnev = fvn("_nev", TLONG);
126219b2ee8SDavid du Colombier 	nodlev = fvn("_lev", TLONG);
127219b2ee8SDavid du Colombier 	nodltv = fvn("_ltv", TLONG);
128219b2ee8SDavid du Colombier 	nodgev = fvn("_gev", TLONG);
129219b2ee8SDavid du Colombier 	nodgtv = fvn("_gtv", TLONG);
130219b2ee8SDavid du Colombier 	nodhiv = fvn("_hiv", TLONG);
131219b2ee8SDavid du Colombier 	nodhsv = fvn("_hsv", TLONG);
132219b2ee8SDavid du Colombier 	nodlov = fvn("_lov", TLONG);
133219b2ee8SDavid du Colombier 	nodlsv = fvn("_lsv", TLONG);
134219b2ee8SDavid du Colombier 
135219b2ee8SDavid du Colombier 	nodf2v = fvn("_f2v", TVLONG);
136219b2ee8SDavid du Colombier 	nodd2v = fvn("_d2v", TVLONG);
1377dd7cddfSDavid du Colombier 	nodp2v = fvn("_p2v", TVLONG);
1387dd7cddfSDavid du Colombier 	nodsi2v = fvn("_si2v", TVLONG);
1397dd7cddfSDavid du Colombier 	nodui2v = fvn("_ui2v", TVLONG);
140219b2ee8SDavid du Colombier 	nodsl2v = fvn("_sl2v", TVLONG);
141219b2ee8SDavid du Colombier 	nodul2v = fvn("_ul2v", TVLONG);
142219b2ee8SDavid du Colombier 	nodsh2v = fvn("_sh2v", TVLONG);
143219b2ee8SDavid du Colombier 	noduh2v = fvn("_uh2v", TVLONG);
144219b2ee8SDavid du Colombier 	nodsc2v = fvn("_sc2v", TVLONG);
145219b2ee8SDavid du Colombier 	noduc2v = fvn("_uc2v", TVLONG);
146219b2ee8SDavid du Colombier 
147219b2ee8SDavid du Colombier 	nodv2f = fvn("_v2f", TFLOAT);
148219b2ee8SDavid du Colombier 	nodv2d = fvn("_v2d", TDOUBLE);
149219b2ee8SDavid du Colombier 	nodv2sl = fvn("_v2sl", TLONG);
150219b2ee8SDavid du Colombier 	nodv2ul = fvn("_v2ul", TULONG);
1517dd7cddfSDavid du Colombier 	nodv2si = fvn("_v2si", TINT);
1527dd7cddfSDavid du Colombier 	nodv2ui = fvn("_v2ui", TUINT);
153219b2ee8SDavid du Colombier 	nodv2sh = fvn("_v2sh", TSHORT);
154219b2ee8SDavid du Colombier 	nodv2uh = fvn("_v2ul", TUSHORT);
155219b2ee8SDavid du Colombier 	nodv2sc = fvn("_v2sc", TCHAR);
156219b2ee8SDavid du Colombier 	nodv2uc = fvn("_v2uc", TUCHAR);
157219b2ee8SDavid du Colombier 
158219b2ee8SDavid du Colombier 	nodvpp = fvn("_vpp", TVLONG);
159219b2ee8SDavid du Colombier 	nodppv = fvn("_ppv", TVLONG);
160219b2ee8SDavid du Colombier 	nodvmm = fvn("_vmm", TVLONG);
161219b2ee8SDavid du Colombier 	nodmmv = fvn("_mmv", TVLONG);
162219b2ee8SDavid du Colombier 
163219b2ee8SDavid du Colombier 	nodvasop = fvn("_vasop", TVLONG);
1647dd7cddfSDavid du Colombier 
1657dd7cddfSDavid du Colombier 	for(p = initetconv; p->code >= 0; p++)
1667dd7cddfSDavid du Colombier 		etconv[p->code] = p->value;
167219b2ee8SDavid du Colombier }
168219b2ee8SDavid du Colombier 
169219b2ee8SDavid du Colombier int
com64(Node * n)170219b2ee8SDavid du Colombier com64(Node *n)
171219b2ee8SDavid du Colombier {
172219b2ee8SDavid du Colombier 	Node *l, *r, *a, *t;
1737dd7cddfSDavid du Colombier 	int lv, rv;
1747dd7cddfSDavid du Colombier 
1757dd7cddfSDavid du Colombier 	if(n->type == 0)
1767dd7cddfSDavid du Colombier 		return 0;
177219b2ee8SDavid du Colombier 
178219b2ee8SDavid du Colombier 	l = n->left;
179219b2ee8SDavid du Colombier 	r = n->right;
180219b2ee8SDavid du Colombier 
1817dd7cddfSDavid du Colombier 	lv = 0;
1827dd7cddfSDavid du Colombier 	if(l && l->type && typev[l->type->etype])
1837dd7cddfSDavid du Colombier 		lv = 1;
1847dd7cddfSDavid du Colombier 	rv = 0;
1857dd7cddfSDavid du Colombier 	if(r && r->type && typev[r->type->etype])
1867dd7cddfSDavid du Colombier 		rv = 1;
1877dd7cddfSDavid du Colombier 
1887dd7cddfSDavid du Colombier 	if(lv) {
189219b2ee8SDavid du Colombier 		switch(n->op) {
190219b2ee8SDavid du Colombier 		case OEQ:
191219b2ee8SDavid du Colombier 			a = nodeqv;
192219b2ee8SDavid du Colombier 			goto setbool;
193219b2ee8SDavid du Colombier 		case ONE:
194219b2ee8SDavid du Colombier 			a = nodnev;
195219b2ee8SDavid du Colombier 			goto setbool;
196219b2ee8SDavid du Colombier 		case OLE:
197219b2ee8SDavid du Colombier 			a = nodlev;
198219b2ee8SDavid du Colombier 			goto setbool;
199219b2ee8SDavid du Colombier 		case OLT:
200219b2ee8SDavid du Colombier 			a = nodltv;
201219b2ee8SDavid du Colombier 			goto setbool;
202219b2ee8SDavid du Colombier 		case OGE:
203219b2ee8SDavid du Colombier 			a = nodgev;
204219b2ee8SDavid du Colombier 			goto setbool;
205219b2ee8SDavid du Colombier 		case OGT:
206219b2ee8SDavid du Colombier 			a = nodgtv;
207219b2ee8SDavid du Colombier 			goto setbool;
208219b2ee8SDavid du Colombier 		case OHI:
209219b2ee8SDavid du Colombier 			a = nodhiv;
210219b2ee8SDavid du Colombier 			goto setbool;
211219b2ee8SDavid du Colombier 		case OHS:
212219b2ee8SDavid du Colombier 			a = nodhsv;
213219b2ee8SDavid du Colombier 			goto setbool;
214219b2ee8SDavid du Colombier 		case OLO:
215219b2ee8SDavid du Colombier 			a = nodlov;
216219b2ee8SDavid du Colombier 			goto setbool;
217219b2ee8SDavid du Colombier 		case OLS:
218219b2ee8SDavid du Colombier 			a = nodlsv;
219219b2ee8SDavid du Colombier 			goto setbool;
220219b2ee8SDavid du Colombier 
221219b2ee8SDavid du Colombier 		case OANDAND:
222219b2ee8SDavid du Colombier 		case OOROR:
223da51d93aSDavid du Colombier 			if(machcap(n))
224da51d93aSDavid du Colombier 				return 1;
225da51d93aSDavid du Colombier 
2267dd7cddfSDavid du Colombier 			if(rv) {
227219b2ee8SDavid du Colombier 				r = new(OFUNC, nodtestv, r);
228219b2ee8SDavid du Colombier 				n->right = r;
229219b2ee8SDavid du Colombier 				r->complex = FNX;
230219b2ee8SDavid du Colombier 				r->op = OFUNC;
231219b2ee8SDavid du Colombier 				r->type = types[TLONG];
2327dd7cddfSDavid du Colombier 			}
233219b2ee8SDavid du Colombier 
234219b2ee8SDavid du Colombier 		case OCOND:
235219b2ee8SDavid du Colombier 		case ONOT:
236da51d93aSDavid du Colombier 			if(machcap(n))
237da51d93aSDavid du Colombier 				return 1;
238da51d93aSDavid du Colombier 
239219b2ee8SDavid du Colombier 			l = new(OFUNC, nodtestv, l);
240219b2ee8SDavid du Colombier 			n->left = l;
241219b2ee8SDavid du Colombier 			l->complex = FNX;
242219b2ee8SDavid du Colombier 			l->op = OFUNC;
243219b2ee8SDavid du Colombier 			l->type = types[TLONG];
244219b2ee8SDavid du Colombier 			n->complex = FNX;
245219b2ee8SDavid du Colombier 			return 1;
246219b2ee8SDavid du Colombier 		}
247219b2ee8SDavid du Colombier 	}
248219b2ee8SDavid du Colombier 
2497dd7cddfSDavid du Colombier 	if(rv) {
250da51d93aSDavid du Colombier 		if(machcap(n))
251da51d93aSDavid du Colombier 			return 1;
2527dd7cddfSDavid du Colombier 		switch(n->op) {
2537dd7cddfSDavid du Colombier 		case OANDAND:
2547dd7cddfSDavid du Colombier 		case OOROR:
2557dd7cddfSDavid du Colombier 			r = new(OFUNC, nodtestv, r);
2567dd7cddfSDavid du Colombier 			n->right = r;
2577dd7cddfSDavid du Colombier 			r->complex = FNX;
2587dd7cddfSDavid du Colombier 			r->op = OFUNC;
2597dd7cddfSDavid du Colombier 			r->type = types[TLONG];
2607dd7cddfSDavid du Colombier 			return 1;
2616891d857SDavid du Colombier 		case OCOND:
2626891d857SDavid du Colombier 			return 1;
2637dd7cddfSDavid du Colombier 		}
2647dd7cddfSDavid du Colombier 	}
2657dd7cddfSDavid du Colombier 
2667dd7cddfSDavid du Colombier 	if(typev[n->type->etype]) {
267da51d93aSDavid du Colombier 		if(machcap(n))
268da51d93aSDavid du Colombier 			return 1;
269219b2ee8SDavid du Colombier 		switch(n->op) {
270219b2ee8SDavid du Colombier 		default:
2717dd7cddfSDavid du Colombier 			diag(n, "unknown vlong %O", n->op);
272219b2ee8SDavid du Colombier 		case OFUNC:
273219b2ee8SDavid du Colombier 			n->complex = FNX;
274219b2ee8SDavid du Colombier 		case ORETURN:
275219b2ee8SDavid du Colombier 		case OAS:
276219b2ee8SDavid du Colombier 		case OIND:
277*ad6ca847SDavid du Colombier 		case OLIST:
278*ad6ca847SDavid du Colombier 		case OCOMMA:
279219b2ee8SDavid du Colombier 			return 1;
280219b2ee8SDavid du Colombier 		case OADD:
281219b2ee8SDavid du Colombier 			a = nodaddv;
282219b2ee8SDavid du Colombier 			goto setbop;
283219b2ee8SDavid du Colombier 		case OSUB:
284219b2ee8SDavid du Colombier 			a = nodsubv;
285219b2ee8SDavid du Colombier 			goto setbop;
286219b2ee8SDavid du Colombier 		case OMUL:
287219b2ee8SDavid du Colombier 		case OLMUL:
288219b2ee8SDavid du Colombier 			a = nodmulv;
289219b2ee8SDavid du Colombier 			goto setbop;
290219b2ee8SDavid du Colombier 		case ODIV:
291219b2ee8SDavid du Colombier 			a = noddivv;
292219b2ee8SDavid du Colombier 			goto setbop;
293219b2ee8SDavid du Colombier 		case OLDIV:
294219b2ee8SDavid du Colombier 			a = noddivvu;
295219b2ee8SDavid du Colombier 			goto setbop;
296219b2ee8SDavid du Colombier 		case OMOD:
297219b2ee8SDavid du Colombier 			a = nodmodv;
298219b2ee8SDavid du Colombier 			goto setbop;
299219b2ee8SDavid du Colombier 		case OLMOD:
300219b2ee8SDavid du Colombier 			a = nodmodvu;
301219b2ee8SDavid du Colombier 			goto setbop;
302219b2ee8SDavid du Colombier 		case OASHL:
303219b2ee8SDavid du Colombier 			a = nodlshv;
304219b2ee8SDavid du Colombier 			goto setbop;
305219b2ee8SDavid du Colombier 		case OASHR:
306219b2ee8SDavid du Colombier 			a = nodrshav;
307219b2ee8SDavid du Colombier 			goto setbop;
308219b2ee8SDavid du Colombier 		case OLSHR:
309219b2ee8SDavid du Colombier 			a = nodrshlv;
310219b2ee8SDavid du Colombier 			goto setbop;
311219b2ee8SDavid du Colombier 		case OAND:
312219b2ee8SDavid du Colombier 			a = nodandv;
313219b2ee8SDavid du Colombier 			goto setbop;
314219b2ee8SDavid du Colombier 		case OOR:
315219b2ee8SDavid du Colombier 			a = nodorv;
316219b2ee8SDavid du Colombier 			goto setbop;
317219b2ee8SDavid du Colombier 		case OXOR:
318219b2ee8SDavid du Colombier 			a = nodxorv;
319219b2ee8SDavid du Colombier 			goto setbop;
320219b2ee8SDavid du Colombier 		case OPOSTINC:
321219b2ee8SDavid du Colombier 			a = nodvpp;
322219b2ee8SDavid du Colombier 			goto setvinc;
323219b2ee8SDavid du Colombier 		case OPOSTDEC:
324219b2ee8SDavid du Colombier 			a = nodvmm;
325219b2ee8SDavid du Colombier 			goto setvinc;
326219b2ee8SDavid du Colombier 		case OPREINC:
327219b2ee8SDavid du Colombier 			a = nodppv;
328219b2ee8SDavid du Colombier 			goto setvinc;
329219b2ee8SDavid du Colombier 		case OPREDEC:
330219b2ee8SDavid du Colombier 			a = nodmmv;
331219b2ee8SDavid du Colombier 			goto setvinc;
332219b2ee8SDavid du Colombier 		case ONEG:
333219b2ee8SDavid du Colombier 			a = nodnegv;
334219b2ee8SDavid du Colombier 			goto setfnx;
335219b2ee8SDavid du Colombier 		case OCOM:
336219b2ee8SDavid du Colombier 			a = nodcomv;
337219b2ee8SDavid du Colombier 			goto setfnx;
338219b2ee8SDavid du Colombier 		case OCAST:
339219b2ee8SDavid du Colombier 			switch(l->type->etype) {
340219b2ee8SDavid du Colombier 			case TCHAR:
341219b2ee8SDavid du Colombier 				a = nodsc2v;
342219b2ee8SDavid du Colombier 				goto setfnxl;
343219b2ee8SDavid du Colombier 			case TUCHAR:
344219b2ee8SDavid du Colombier 				a = noduc2v;
345219b2ee8SDavid du Colombier 				goto setfnxl;
346219b2ee8SDavid du Colombier 			case TSHORT:
347219b2ee8SDavid du Colombier 				a = nodsh2v;
348219b2ee8SDavid du Colombier 				goto setfnxl;
349219b2ee8SDavid du Colombier 			case TUSHORT:
350219b2ee8SDavid du Colombier 				a = noduh2v;
351219b2ee8SDavid du Colombier 				goto setfnxl;
3527dd7cddfSDavid du Colombier 			case TINT:
3537dd7cddfSDavid du Colombier 				a = nodsi2v;
3547dd7cddfSDavid du Colombier 				goto setfnx;
3557dd7cddfSDavid du Colombier 			case TUINT:
3567dd7cddfSDavid du Colombier 				a = nodui2v;
3577dd7cddfSDavid du Colombier 				goto setfnx;
358219b2ee8SDavid du Colombier 			case TLONG:
359219b2ee8SDavid du Colombier 				a = nodsl2v;
360219b2ee8SDavid du Colombier 				goto setfnx;
361219b2ee8SDavid du Colombier 			case TULONG:
362219b2ee8SDavid du Colombier 				a = nodul2v;
363219b2ee8SDavid du Colombier 				goto setfnx;
364219b2ee8SDavid du Colombier 			case TFLOAT:
365219b2ee8SDavid du Colombier 				a = nodf2v;
366219b2ee8SDavid du Colombier 				goto setfnx;
367219b2ee8SDavid du Colombier 			case TDOUBLE:
368219b2ee8SDavid du Colombier 				a = nodd2v;
369219b2ee8SDavid du Colombier 				goto setfnx;
3707dd7cddfSDavid du Colombier 			case TIND:
3717dd7cddfSDavid du Colombier 				a = nodp2v;
3727dd7cddfSDavid du Colombier 				goto setfnx;
373219b2ee8SDavid du Colombier 			}
374219b2ee8SDavid du Colombier 			diag(n, "unknown %T->vlong cast", l->type);
375219b2ee8SDavid du Colombier 			return 1;
376219b2ee8SDavid du Colombier 		case OASADD:
377219b2ee8SDavid du Colombier 			a = nodaddv;
378219b2ee8SDavid du Colombier 			goto setasop;
379219b2ee8SDavid du Colombier 		case OASSUB:
380219b2ee8SDavid du Colombier 			a = nodsubv;
381219b2ee8SDavid du Colombier 			goto setasop;
382219b2ee8SDavid du Colombier 		case OASMUL:
383219b2ee8SDavid du Colombier 		case OASLMUL:
384219b2ee8SDavid du Colombier 			a = nodmulv;
385219b2ee8SDavid du Colombier 			goto setasop;
386219b2ee8SDavid du Colombier 		case OASDIV:
387219b2ee8SDavid du Colombier 			a = noddivv;
388219b2ee8SDavid du Colombier 			goto setasop;
389219b2ee8SDavid du Colombier 		case OASLDIV:
390219b2ee8SDavid du Colombier 			a = noddivvu;
391219b2ee8SDavid du Colombier 			goto setasop;
392219b2ee8SDavid du Colombier 		case OASMOD:
393219b2ee8SDavid du Colombier 			a = nodmodv;
394219b2ee8SDavid du Colombier 			goto setasop;
395219b2ee8SDavid du Colombier 		case OASLMOD:
396219b2ee8SDavid du Colombier 			a = nodmodvu;
397219b2ee8SDavid du Colombier 			goto setasop;
398219b2ee8SDavid du Colombier 		case OASASHL:
399219b2ee8SDavid du Colombier 			a = nodlshv;
400219b2ee8SDavid du Colombier 			goto setasop;
401219b2ee8SDavid du Colombier 		case OASASHR:
402219b2ee8SDavid du Colombier 			a = nodrshav;
403219b2ee8SDavid du Colombier 			goto setasop;
404219b2ee8SDavid du Colombier 		case OASLSHR:
405219b2ee8SDavid du Colombier 			a = nodrshlv;
406219b2ee8SDavid du Colombier 			goto setasop;
407219b2ee8SDavid du Colombier 		case OASAND:
408219b2ee8SDavid du Colombier 			a = nodandv;
409219b2ee8SDavid du Colombier 			goto setasop;
410219b2ee8SDavid du Colombier 		case OASOR:
411219b2ee8SDavid du Colombier 			a = nodorv;
412219b2ee8SDavid du Colombier 			goto setasop;
413219b2ee8SDavid du Colombier 		case OASXOR:
414219b2ee8SDavid du Colombier 			a = nodxorv;
415219b2ee8SDavid du Colombier 			goto setasop;
416219b2ee8SDavid du Colombier 		}
417219b2ee8SDavid du Colombier 	}
418219b2ee8SDavid du Colombier 
4197dd7cddfSDavid du Colombier 	if(typefd[n->type->etype] && l && l->op == OFUNC) {
420219b2ee8SDavid du Colombier 		switch(n->op) {
421219b2ee8SDavid du Colombier 		case OASADD:
422219b2ee8SDavid du Colombier 		case OASSUB:
423219b2ee8SDavid du Colombier 		case OASMUL:
424219b2ee8SDavid du Colombier 		case OASLMUL:
425219b2ee8SDavid du Colombier 		case OASDIV:
426219b2ee8SDavid du Colombier 		case OASLDIV:
427219b2ee8SDavid du Colombier 		case OASMOD:
428219b2ee8SDavid du Colombier 		case OASLMOD:
429219b2ee8SDavid du Colombier 		case OASASHL:
430219b2ee8SDavid du Colombier 		case OASASHR:
431219b2ee8SDavid du Colombier 		case OASLSHR:
432219b2ee8SDavid du Colombier 		case OASAND:
433219b2ee8SDavid du Colombier 		case OASOR:
434219b2ee8SDavid du Colombier 		case OASXOR:
435219b2ee8SDavid du Colombier 			if(l->right && typev[l->right->etype]) {
436219b2ee8SDavid du Colombier 				diag(n, "sorry float <asop> vlong not implemented\n");
437219b2ee8SDavid du Colombier 			}
438219b2ee8SDavid du Colombier 		}
439219b2ee8SDavid du Colombier 	}
440219b2ee8SDavid du Colombier 
441219b2ee8SDavid du Colombier 	if(n->op == OCAST) {
442219b2ee8SDavid du Colombier 		if(l->type && typev[l->type->etype]) {
443da51d93aSDavid du Colombier 			if(machcap(n))
444da51d93aSDavid du Colombier 				return 1;
445219b2ee8SDavid du Colombier 			switch(n->type->etype) {
446219b2ee8SDavid du Colombier 			case TDOUBLE:
447219b2ee8SDavid du Colombier 				a = nodv2d;
448219b2ee8SDavid du Colombier 				goto setfnx;
449219b2ee8SDavid du Colombier 			case TFLOAT:
450219b2ee8SDavid du Colombier 				a = nodv2f;
451219b2ee8SDavid du Colombier 				goto setfnx;
452219b2ee8SDavid du Colombier 			case TLONG:
453219b2ee8SDavid du Colombier 				a = nodv2sl;
454219b2ee8SDavid du Colombier 				goto setfnx;
455219b2ee8SDavid du Colombier 			case TULONG:
456219b2ee8SDavid du Colombier 				a = nodv2ul;
457219b2ee8SDavid du Colombier 				goto setfnx;
4587dd7cddfSDavid du Colombier 			case TINT:
4597dd7cddfSDavid du Colombier 				a = nodv2si;
4607dd7cddfSDavid du Colombier 				goto setfnx;
4617dd7cddfSDavid du Colombier 			case TUINT:
4627dd7cddfSDavid du Colombier 				a = nodv2ui;
4637dd7cddfSDavid du Colombier 				goto setfnx;
464219b2ee8SDavid du Colombier 			case TSHORT:
465219b2ee8SDavid du Colombier 				a = nodv2sh;
466219b2ee8SDavid du Colombier 				goto setfnx;
467219b2ee8SDavid du Colombier 			case TUSHORT:
468219b2ee8SDavid du Colombier 				a = nodv2uh;
469219b2ee8SDavid du Colombier 				goto setfnx;
470219b2ee8SDavid du Colombier 			case TCHAR:
471219b2ee8SDavid du Colombier 				a = nodv2sc;
472219b2ee8SDavid du Colombier 				goto setfnx;
473219b2ee8SDavid du Colombier 			case TUCHAR:
474219b2ee8SDavid du Colombier 				a = nodv2uc;
475219b2ee8SDavid du Colombier 				goto setfnx;
4767dd7cddfSDavid du Colombier 			case TIND:	// small pun here
4777dd7cddfSDavid du Colombier 				a = nodv2ul;
4787dd7cddfSDavid du Colombier 				goto setfnx;
479219b2ee8SDavid du Colombier 			}
480219b2ee8SDavid du Colombier 			diag(n, "unknown vlong->%T cast", n->type);
481219b2ee8SDavid du Colombier 			return 1;
482219b2ee8SDavid du Colombier 		}
483219b2ee8SDavid du Colombier 	}
484219b2ee8SDavid du Colombier 
485219b2ee8SDavid du Colombier 	return 0;
486219b2ee8SDavid du Colombier 
487219b2ee8SDavid du Colombier setbop:
488219b2ee8SDavid du Colombier 	n->left = a;
489219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
490219b2ee8SDavid du Colombier 	n->complex = FNX;
491219b2ee8SDavid du Colombier 	n->op = OFUNC;
492219b2ee8SDavid du Colombier 	return 1;
493219b2ee8SDavid du Colombier 
494219b2ee8SDavid du Colombier setfnxl:
495219b2ee8SDavid du Colombier 	l = new(OCAST, l, 0);
496219b2ee8SDavid du Colombier 	l->type = types[TLONG];
497219b2ee8SDavid du Colombier 	l->complex = l->left->complex;
498219b2ee8SDavid du Colombier 
499219b2ee8SDavid du Colombier setfnx:
500219b2ee8SDavid du Colombier 	n->left = a;
501219b2ee8SDavid du Colombier 	n->right = l;
502219b2ee8SDavid du Colombier 	n->complex = FNX;
503219b2ee8SDavid du Colombier 	n->op = OFUNC;
504219b2ee8SDavid du Colombier 	return 1;
505219b2ee8SDavid du Colombier 
506219b2ee8SDavid du Colombier setvinc:
507219b2ee8SDavid du Colombier 	n->left = a;
508219b2ee8SDavid du Colombier 	l = new(OADDR, l, Z);
509219b2ee8SDavid du Colombier 	l->type = typ(TIND, l->left->type);
5106891d857SDavid du Colombier 	l->complex = l->left->complex;
511219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
512219b2ee8SDavid du Colombier 	n->complex = FNX;
513219b2ee8SDavid du Colombier 	n->op = OFUNC;
514219b2ee8SDavid du Colombier 	return 1;
515219b2ee8SDavid du Colombier 
516219b2ee8SDavid du Colombier setbool:
517da51d93aSDavid du Colombier 	if(machcap(n))
518da51d93aSDavid du Colombier 		return 1;
519219b2ee8SDavid du Colombier 	n->left = a;
520219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
521219b2ee8SDavid du Colombier 	n->complex = FNX;
522219b2ee8SDavid du Colombier 	n->op = OFUNC;
523219b2ee8SDavid du Colombier 	n->type = types[TLONG];
524219b2ee8SDavid du Colombier 	return 1;
525219b2ee8SDavid du Colombier 
526219b2ee8SDavid du Colombier setasop:
527219b2ee8SDavid du Colombier 	if(l->op == OFUNC) {
528219b2ee8SDavid du Colombier 		l = l->right;
529219b2ee8SDavid du Colombier 		goto setasop;
530219b2ee8SDavid du Colombier 	}
531219b2ee8SDavid du Colombier 
532219b2ee8SDavid du Colombier 	t = new(OCONST, 0, 0);
5337dd7cddfSDavid du Colombier 	t->vconst = etconv[l->type->etype];
534219b2ee8SDavid du Colombier 	t->type = types[TLONG];
535219b2ee8SDavid du Colombier 	t->addable = 20;
536219b2ee8SDavid du Colombier 	r = new(OLIST, t, r);
537219b2ee8SDavid du Colombier 
538219b2ee8SDavid du Colombier 	t = new(OADDR, a, 0);
539219b2ee8SDavid du Colombier 	t->type = typ(TIND, a->type);
540219b2ee8SDavid du Colombier 	r = new(OLIST, t, r);
541219b2ee8SDavid du Colombier 
542219b2ee8SDavid du Colombier 	t = new(OADDR, l, 0);
543219b2ee8SDavid du Colombier 	t->type = typ(TIND, l->type);
5446891d857SDavid du Colombier 	t->complex = l->complex;
545219b2ee8SDavid du Colombier 	r = new(OLIST, t, r);
546219b2ee8SDavid du Colombier 
547219b2ee8SDavid du Colombier 	n->left = nodvasop;
548219b2ee8SDavid du Colombier 	n->right = r;
549219b2ee8SDavid du Colombier 	n->complex = FNX;
550219b2ee8SDavid du Colombier 	n->op = OFUNC;
551219b2ee8SDavid du Colombier 
552219b2ee8SDavid du Colombier 	return 1;
553219b2ee8SDavid du Colombier }
554219b2ee8SDavid du Colombier 
555219b2ee8SDavid du Colombier void
bool64(Node * n)556219b2ee8SDavid du Colombier bool64(Node *n)
557219b2ee8SDavid du Colombier {
558219b2ee8SDavid du Colombier 	Node *n1;
559219b2ee8SDavid du Colombier 
5604ac975e2SDavid du Colombier 	if(machcap(Z))
5614ac975e2SDavid du Colombier 		return;
562219b2ee8SDavid du Colombier 	if(typev[n->type->etype]) {
563219b2ee8SDavid du Colombier 		n1 = new(OXXX, 0, 0);
564219b2ee8SDavid du Colombier 		*n1 = *n;
565219b2ee8SDavid du Colombier 
566219b2ee8SDavid du Colombier 		n->right = n1;
567219b2ee8SDavid du Colombier 		n->left = nodtestv;
568219b2ee8SDavid du Colombier 		n->complex = FNX;
569219b2ee8SDavid du Colombier 		n->addable = 0;
570219b2ee8SDavid du Colombier 		n->op = OFUNC;
571219b2ee8SDavid du Colombier 		n->type = types[TLONG];
572219b2ee8SDavid du Colombier 	}
573219b2ee8SDavid du Colombier }
574219b2ee8SDavid du Colombier 
575219b2ee8SDavid du Colombier /*
576219b2ee8SDavid du Colombier  * more machine depend stuff.
577219b2ee8SDavid du Colombier  * this is common for 8,16,32,64 bit machines.
578219b2ee8SDavid du Colombier  * this is common for ieee machines.
579219b2ee8SDavid du Colombier  */
580219b2ee8SDavid du Colombier double
convvtof(vlong v)581219b2ee8SDavid du Colombier convvtof(vlong v)
582219b2ee8SDavid du Colombier {
583219b2ee8SDavid du Colombier 	double d;
584219b2ee8SDavid du Colombier 
585219b2ee8SDavid du Colombier 	d = v;		/* BOTCH */
586219b2ee8SDavid du Colombier 	return d;
587219b2ee8SDavid du Colombier }
588219b2ee8SDavid du Colombier 
589219b2ee8SDavid du Colombier vlong
convftov(double d)590219b2ee8SDavid du Colombier convftov(double d)
591219b2ee8SDavid du Colombier {
592219b2ee8SDavid du Colombier 	vlong v;
593219b2ee8SDavid du Colombier 
594219b2ee8SDavid du Colombier 
595219b2ee8SDavid du Colombier 	v = d;		/* BOTCH */
596219b2ee8SDavid du Colombier 	return v;
597219b2ee8SDavid du Colombier }
598219b2ee8SDavid du Colombier 
599219b2ee8SDavid du Colombier double
convftox(double d,int et)6007dd7cddfSDavid du Colombier convftox(double d, int et)
601219b2ee8SDavid du Colombier {
602219b2ee8SDavid du Colombier 
6037dd7cddfSDavid du Colombier 	if(!typefd[et])
6047dd7cddfSDavid du Colombier 		diag(Z, "bad type in castftox %s", tnames[et]);
605219b2ee8SDavid du Colombier 	return d;
606219b2ee8SDavid du Colombier }
607219b2ee8SDavid du Colombier 
608219b2ee8SDavid du Colombier vlong
convvtox(vlong c,int et)6097dd7cddfSDavid du Colombier convvtox(vlong c, int et)
610219b2ee8SDavid du Colombier {
6117dd7cddfSDavid du Colombier 	int n;
612219b2ee8SDavid du Colombier 
6137dd7cddfSDavid du Colombier 	n = 8 * ewidth[et];
6147dd7cddfSDavid du Colombier 	c &= MASK(n);
6157dd7cddfSDavid du Colombier 	if(!typeu[et])
6167dd7cddfSDavid du Colombier 		if(c & SIGN(n))
6177dd7cddfSDavid du Colombier 			c |= ~MASK(n);
618219b2ee8SDavid du Colombier 	return c;
619219b2ee8SDavid du Colombier }
620