xref: /plan9/sys/src/cmd/cc/com64.c (revision 4ac975e2e38b792d24bc60de7fce5e6173f046ea)
1219b2ee8SDavid du Colombier #include "cc.h"
2219b2ee8SDavid du Colombier 
3219b2ee8SDavid du Colombier /*
4219b2ee8SDavid du Colombier  * this is machine depend, 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*
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
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
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;
2617dd7cddfSDavid du Colombier 		}
2627dd7cddfSDavid du Colombier 	}
2637dd7cddfSDavid du Colombier 
2647dd7cddfSDavid du Colombier 	if(typev[n->type->etype]) {
265da51d93aSDavid du Colombier 		if(machcap(n))
266da51d93aSDavid du Colombier 			return 1;
267219b2ee8SDavid du Colombier 		switch(n->op) {
268219b2ee8SDavid du Colombier 		default:
2697dd7cddfSDavid du Colombier 			diag(n, "unknown vlong %O", n->op);
270219b2ee8SDavid du Colombier 		case OFUNC:
271219b2ee8SDavid du Colombier 			n->complex = FNX;
272219b2ee8SDavid du Colombier 		case ORETURN:
273219b2ee8SDavid du Colombier 		case OAS:
274219b2ee8SDavid du Colombier 		case OIND:
275219b2ee8SDavid du Colombier 			return 1;
276219b2ee8SDavid du Colombier 		case OADD:
277219b2ee8SDavid du Colombier 			a = nodaddv;
278219b2ee8SDavid du Colombier 			goto setbop;
279219b2ee8SDavid du Colombier 		case OSUB:
280219b2ee8SDavid du Colombier 			a = nodsubv;
281219b2ee8SDavid du Colombier 			goto setbop;
282219b2ee8SDavid du Colombier 		case OMUL:
283219b2ee8SDavid du Colombier 		case OLMUL:
284219b2ee8SDavid du Colombier 			a = nodmulv;
285219b2ee8SDavid du Colombier 			goto setbop;
286219b2ee8SDavid du Colombier 		case ODIV:
287219b2ee8SDavid du Colombier 			a = noddivv;
288219b2ee8SDavid du Colombier 			goto setbop;
289219b2ee8SDavid du Colombier 		case OLDIV:
290219b2ee8SDavid du Colombier 			a = noddivvu;
291219b2ee8SDavid du Colombier 			goto setbop;
292219b2ee8SDavid du Colombier 		case OMOD:
293219b2ee8SDavid du Colombier 			a = nodmodv;
294219b2ee8SDavid du Colombier 			goto setbop;
295219b2ee8SDavid du Colombier 		case OLMOD:
296219b2ee8SDavid du Colombier 			a = nodmodvu;
297219b2ee8SDavid du Colombier 			goto setbop;
298219b2ee8SDavid du Colombier 		case OASHL:
299219b2ee8SDavid du Colombier 			a = nodlshv;
300219b2ee8SDavid du Colombier 			goto setbop;
301219b2ee8SDavid du Colombier 		case OASHR:
302219b2ee8SDavid du Colombier 			a = nodrshav;
303219b2ee8SDavid du Colombier 			goto setbop;
304219b2ee8SDavid du Colombier 		case OLSHR:
305219b2ee8SDavid du Colombier 			a = nodrshlv;
306219b2ee8SDavid du Colombier 			goto setbop;
307219b2ee8SDavid du Colombier 		case OAND:
308219b2ee8SDavid du Colombier 			a = nodandv;
309219b2ee8SDavid du Colombier 			goto setbop;
310219b2ee8SDavid du Colombier 		case OOR:
311219b2ee8SDavid du Colombier 			a = nodorv;
312219b2ee8SDavid du Colombier 			goto setbop;
313219b2ee8SDavid du Colombier 		case OXOR:
314219b2ee8SDavid du Colombier 			a = nodxorv;
315219b2ee8SDavid du Colombier 			goto setbop;
316219b2ee8SDavid du Colombier 		case OPOSTINC:
317219b2ee8SDavid du Colombier 			a = nodvpp;
318219b2ee8SDavid du Colombier 			goto setvinc;
319219b2ee8SDavid du Colombier 		case OPOSTDEC:
320219b2ee8SDavid du Colombier 			a = nodvmm;
321219b2ee8SDavid du Colombier 			goto setvinc;
322219b2ee8SDavid du Colombier 		case OPREINC:
323219b2ee8SDavid du Colombier 			a = nodppv;
324219b2ee8SDavid du Colombier 			goto setvinc;
325219b2ee8SDavid du Colombier 		case OPREDEC:
326219b2ee8SDavid du Colombier 			a = nodmmv;
327219b2ee8SDavid du Colombier 			goto setvinc;
328219b2ee8SDavid du Colombier 		case ONEG:
329219b2ee8SDavid du Colombier 			a = nodnegv;
330219b2ee8SDavid du Colombier 			goto setfnx;
331219b2ee8SDavid du Colombier 		case OCOM:
332219b2ee8SDavid du Colombier 			a = nodcomv;
333219b2ee8SDavid du Colombier 			goto setfnx;
334219b2ee8SDavid du Colombier 		case OCAST:
335219b2ee8SDavid du Colombier 			switch(l->type->etype) {
336219b2ee8SDavid du Colombier 			case TCHAR:
337219b2ee8SDavid du Colombier 				a = nodsc2v;
338219b2ee8SDavid du Colombier 				goto setfnxl;
339219b2ee8SDavid du Colombier 			case TUCHAR:
340219b2ee8SDavid du Colombier 				a = noduc2v;
341219b2ee8SDavid du Colombier 				goto setfnxl;
342219b2ee8SDavid du Colombier 			case TSHORT:
343219b2ee8SDavid du Colombier 				a = nodsh2v;
344219b2ee8SDavid du Colombier 				goto setfnxl;
345219b2ee8SDavid du Colombier 			case TUSHORT:
346219b2ee8SDavid du Colombier 				a = noduh2v;
347219b2ee8SDavid du Colombier 				goto setfnxl;
3487dd7cddfSDavid du Colombier 			case TINT:
3497dd7cddfSDavid du Colombier 				a = nodsi2v;
3507dd7cddfSDavid du Colombier 				goto setfnx;
3517dd7cddfSDavid du Colombier 			case TUINT:
3527dd7cddfSDavid du Colombier 				a = nodui2v;
3537dd7cddfSDavid du Colombier 				goto setfnx;
354219b2ee8SDavid du Colombier 			case TLONG:
355219b2ee8SDavid du Colombier 				a = nodsl2v;
356219b2ee8SDavid du Colombier 				goto setfnx;
357219b2ee8SDavid du Colombier 			case TULONG:
358219b2ee8SDavid du Colombier 				a = nodul2v;
359219b2ee8SDavid du Colombier 				goto setfnx;
360219b2ee8SDavid du Colombier 			case TFLOAT:
361219b2ee8SDavid du Colombier 				a = nodf2v;
362219b2ee8SDavid du Colombier 				goto setfnx;
363219b2ee8SDavid du Colombier 			case TDOUBLE:
364219b2ee8SDavid du Colombier 				a = nodd2v;
365219b2ee8SDavid du Colombier 				goto setfnx;
3667dd7cddfSDavid du Colombier 			case TIND:
3677dd7cddfSDavid du Colombier 				a = nodp2v;
3687dd7cddfSDavid du Colombier 				goto setfnx;
369219b2ee8SDavid du Colombier 			}
370219b2ee8SDavid du Colombier 			diag(n, "unknown %T->vlong cast", l->type);
371219b2ee8SDavid du Colombier 			return 1;
372219b2ee8SDavid du Colombier 		case OASADD:
373219b2ee8SDavid du Colombier 			a = nodaddv;
374219b2ee8SDavid du Colombier 			goto setasop;
375219b2ee8SDavid du Colombier 		case OASSUB:
376219b2ee8SDavid du Colombier 			a = nodsubv;
377219b2ee8SDavid du Colombier 			goto setasop;
378219b2ee8SDavid du Colombier 		case OASMUL:
379219b2ee8SDavid du Colombier 		case OASLMUL:
380219b2ee8SDavid du Colombier 			a = nodmulv;
381219b2ee8SDavid du Colombier 			goto setasop;
382219b2ee8SDavid du Colombier 		case OASDIV:
383219b2ee8SDavid du Colombier 			a = noddivv;
384219b2ee8SDavid du Colombier 			goto setasop;
385219b2ee8SDavid du Colombier 		case OASLDIV:
386219b2ee8SDavid du Colombier 			a = noddivvu;
387219b2ee8SDavid du Colombier 			goto setasop;
388219b2ee8SDavid du Colombier 		case OASMOD:
389219b2ee8SDavid du Colombier 			a = nodmodv;
390219b2ee8SDavid du Colombier 			goto setasop;
391219b2ee8SDavid du Colombier 		case OASLMOD:
392219b2ee8SDavid du Colombier 			a = nodmodvu;
393219b2ee8SDavid du Colombier 			goto setasop;
394219b2ee8SDavid du Colombier 		case OASASHL:
395219b2ee8SDavid du Colombier 			a = nodlshv;
396219b2ee8SDavid du Colombier 			goto setasop;
397219b2ee8SDavid du Colombier 		case OASASHR:
398219b2ee8SDavid du Colombier 			a = nodrshav;
399219b2ee8SDavid du Colombier 			goto setasop;
400219b2ee8SDavid du Colombier 		case OASLSHR:
401219b2ee8SDavid du Colombier 			a = nodrshlv;
402219b2ee8SDavid du Colombier 			goto setasop;
403219b2ee8SDavid du Colombier 		case OASAND:
404219b2ee8SDavid du Colombier 			a = nodandv;
405219b2ee8SDavid du Colombier 			goto setasop;
406219b2ee8SDavid du Colombier 		case OASOR:
407219b2ee8SDavid du Colombier 			a = nodorv;
408219b2ee8SDavid du Colombier 			goto setasop;
409219b2ee8SDavid du Colombier 		case OASXOR:
410219b2ee8SDavid du Colombier 			a = nodxorv;
411219b2ee8SDavid du Colombier 			goto setasop;
412219b2ee8SDavid du Colombier 		}
413219b2ee8SDavid du Colombier 	}
414219b2ee8SDavid du Colombier 
4157dd7cddfSDavid du Colombier 	if(typefd[n->type->etype] && l && l->op == OFUNC) {
416219b2ee8SDavid du Colombier 		switch(n->op) {
417219b2ee8SDavid du Colombier 		case OASADD:
418219b2ee8SDavid du Colombier 		case OASSUB:
419219b2ee8SDavid du Colombier 		case OASMUL:
420219b2ee8SDavid du Colombier 		case OASLMUL:
421219b2ee8SDavid du Colombier 		case OASDIV:
422219b2ee8SDavid du Colombier 		case OASLDIV:
423219b2ee8SDavid du Colombier 		case OASMOD:
424219b2ee8SDavid du Colombier 		case OASLMOD:
425219b2ee8SDavid du Colombier 		case OASASHL:
426219b2ee8SDavid du Colombier 		case OASASHR:
427219b2ee8SDavid du Colombier 		case OASLSHR:
428219b2ee8SDavid du Colombier 		case OASAND:
429219b2ee8SDavid du Colombier 		case OASOR:
430219b2ee8SDavid du Colombier 		case OASXOR:
431219b2ee8SDavid du Colombier 			if(l->right && typev[l->right->etype]) {
432219b2ee8SDavid du Colombier 				diag(n, "sorry float <asop> vlong not implemented\n");
433219b2ee8SDavid du Colombier 			}
434219b2ee8SDavid du Colombier 		}
435219b2ee8SDavid du Colombier 	}
436219b2ee8SDavid du Colombier 
437219b2ee8SDavid du Colombier 	if(n->op == OCAST) {
438219b2ee8SDavid du Colombier 		if(l->type && typev[l->type->etype]) {
439da51d93aSDavid du Colombier 			if(machcap(n))
440da51d93aSDavid du Colombier 				return 1;
441219b2ee8SDavid du Colombier 			switch(n->type->etype) {
442219b2ee8SDavid du Colombier 			case TDOUBLE:
443219b2ee8SDavid du Colombier 				a = nodv2d;
444219b2ee8SDavid du Colombier 				goto setfnx;
445219b2ee8SDavid du Colombier 			case TFLOAT:
446219b2ee8SDavid du Colombier 				a = nodv2f;
447219b2ee8SDavid du Colombier 				goto setfnx;
448219b2ee8SDavid du Colombier 			case TLONG:
449219b2ee8SDavid du Colombier 				a = nodv2sl;
450219b2ee8SDavid du Colombier 				goto setfnx;
451219b2ee8SDavid du Colombier 			case TULONG:
452219b2ee8SDavid du Colombier 				a = nodv2ul;
453219b2ee8SDavid du Colombier 				goto setfnx;
4547dd7cddfSDavid du Colombier 			case TINT:
4557dd7cddfSDavid du Colombier 				a = nodv2si;
4567dd7cddfSDavid du Colombier 				goto setfnx;
4577dd7cddfSDavid du Colombier 			case TUINT:
4587dd7cddfSDavid du Colombier 				a = nodv2ui;
4597dd7cddfSDavid du Colombier 				goto setfnx;
460219b2ee8SDavid du Colombier 			case TSHORT:
461219b2ee8SDavid du Colombier 				a = nodv2sh;
462219b2ee8SDavid du Colombier 				goto setfnx;
463219b2ee8SDavid du Colombier 			case TUSHORT:
464219b2ee8SDavid du Colombier 				a = nodv2uh;
465219b2ee8SDavid du Colombier 				goto setfnx;
466219b2ee8SDavid du Colombier 			case TCHAR:
467219b2ee8SDavid du Colombier 				a = nodv2sc;
468219b2ee8SDavid du Colombier 				goto setfnx;
469219b2ee8SDavid du Colombier 			case TUCHAR:
470219b2ee8SDavid du Colombier 				a = nodv2uc;
471219b2ee8SDavid du Colombier 				goto setfnx;
4727dd7cddfSDavid du Colombier 			case TIND:	// small pun here
4737dd7cddfSDavid du Colombier 				a = nodv2ul;
4747dd7cddfSDavid du Colombier 				goto setfnx;
475219b2ee8SDavid du Colombier 			}
476219b2ee8SDavid du Colombier 			diag(n, "unknown vlong->%T cast", n->type);
477219b2ee8SDavid du Colombier 			return 1;
478219b2ee8SDavid du Colombier 		}
479219b2ee8SDavid du Colombier 	}
480219b2ee8SDavid du Colombier 
481219b2ee8SDavid du Colombier 	return 0;
482219b2ee8SDavid du Colombier 
483219b2ee8SDavid du Colombier setbop:
484219b2ee8SDavid du Colombier 	n->left = a;
485219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
486219b2ee8SDavid du Colombier 	n->complex = FNX;
487219b2ee8SDavid du Colombier 	n->op = OFUNC;
488219b2ee8SDavid du Colombier 	return 1;
489219b2ee8SDavid du Colombier 
490219b2ee8SDavid du Colombier setfnxl:
491219b2ee8SDavid du Colombier 	l = new(OCAST, l, 0);
492219b2ee8SDavid du Colombier 	l->type = types[TLONG];
493219b2ee8SDavid du Colombier 	l->complex = l->left->complex;
494219b2ee8SDavid du Colombier 
495219b2ee8SDavid du Colombier setfnx:
496219b2ee8SDavid du Colombier 	n->left = a;
497219b2ee8SDavid du Colombier 	n->right = l;
498219b2ee8SDavid du Colombier 	n->complex = FNX;
499219b2ee8SDavid du Colombier 	n->op = OFUNC;
500219b2ee8SDavid du Colombier 	return 1;
501219b2ee8SDavid du Colombier 
502219b2ee8SDavid du Colombier setvinc:
503219b2ee8SDavid du Colombier 	n->left = a;
504219b2ee8SDavid du Colombier 	l = new(OADDR, l, Z);
505219b2ee8SDavid du Colombier 	l->type = typ(TIND, l->left->type);
506219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
507219b2ee8SDavid du Colombier 	n->complex = FNX;
508219b2ee8SDavid du Colombier 	n->op = OFUNC;
509219b2ee8SDavid du Colombier 	return 1;
510219b2ee8SDavid du Colombier 
511219b2ee8SDavid du Colombier setbool:
512da51d93aSDavid du Colombier 	if(machcap(n))
513da51d93aSDavid du Colombier 		return 1;
514219b2ee8SDavid du Colombier 	n->left = a;
515219b2ee8SDavid du Colombier 	n->right = new(OLIST, l, r);
516219b2ee8SDavid du Colombier 	n->complex = FNX;
517219b2ee8SDavid du Colombier 	n->op = OFUNC;
518219b2ee8SDavid du Colombier 	n->type = types[TLONG];
519219b2ee8SDavid du Colombier 	return 1;
520219b2ee8SDavid du Colombier 
521219b2ee8SDavid du Colombier setasop:
522219b2ee8SDavid du Colombier 	if(l->op == OFUNC) {
523219b2ee8SDavid du Colombier 		l = l->right;
524219b2ee8SDavid du Colombier 		goto setasop;
525219b2ee8SDavid du Colombier 	}
526219b2ee8SDavid du Colombier 
527219b2ee8SDavid du Colombier 	t = new(OCONST, 0, 0);
5287dd7cddfSDavid du Colombier 	t->vconst = etconv[l->type->etype];
529219b2ee8SDavid du Colombier 	t->type = types[TLONG];
530219b2ee8SDavid du Colombier 	t->addable = 20;
531219b2ee8SDavid du Colombier 	r = new(OLIST, t, r);
532219b2ee8SDavid du Colombier 
533219b2ee8SDavid du Colombier 	t = new(OADDR, a, 0);
534219b2ee8SDavid du Colombier 	t->type = typ(TIND, a->type);
535219b2ee8SDavid du Colombier 	r = new(OLIST, t, r);
536219b2ee8SDavid du Colombier 
537219b2ee8SDavid du Colombier 	t = new(OADDR, l, 0);
538219b2ee8SDavid du Colombier 	t->type = typ(TIND, l->type);
539219b2ee8SDavid du Colombier 	r = new(OLIST, t, r);
540219b2ee8SDavid du Colombier 
541219b2ee8SDavid du Colombier 	n->left = nodvasop;
542219b2ee8SDavid du Colombier 	n->right = r;
543219b2ee8SDavid du Colombier 	n->complex = FNX;
544219b2ee8SDavid du Colombier 	n->op = OFUNC;
545219b2ee8SDavid du Colombier 
546219b2ee8SDavid du Colombier 	return 1;
547219b2ee8SDavid du Colombier }
548219b2ee8SDavid du Colombier 
549219b2ee8SDavid du Colombier void
550219b2ee8SDavid du Colombier bool64(Node *n)
551219b2ee8SDavid du Colombier {
552219b2ee8SDavid du Colombier 	Node *n1;
553219b2ee8SDavid du Colombier 
554*4ac975e2SDavid du Colombier 	if(machcap(Z))
555*4ac975e2SDavid du Colombier 		return;
556219b2ee8SDavid du Colombier 	if(typev[n->type->etype]) {
557219b2ee8SDavid du Colombier 		n1 = new(OXXX, 0, 0);
558219b2ee8SDavid du Colombier 		*n1 = *n;
559219b2ee8SDavid du Colombier 
560219b2ee8SDavid du Colombier 		n->right = n1;
561219b2ee8SDavid du Colombier 		n->left = nodtestv;
562219b2ee8SDavid du Colombier 		n->complex = FNX;
563219b2ee8SDavid du Colombier 		n->addable = 0;
564219b2ee8SDavid du Colombier 		n->op = OFUNC;
565219b2ee8SDavid du Colombier 		n->type = types[TLONG];
566219b2ee8SDavid du Colombier 	}
567219b2ee8SDavid du Colombier }
568219b2ee8SDavid du Colombier 
569219b2ee8SDavid du Colombier /*
570219b2ee8SDavid du Colombier  * more machine depend stuff.
571219b2ee8SDavid du Colombier  * this is common for 8,16,32,64 bit machines.
572219b2ee8SDavid du Colombier  * this is common for ieee machines.
573219b2ee8SDavid du Colombier  */
574219b2ee8SDavid du Colombier double
575219b2ee8SDavid du Colombier convvtof(vlong v)
576219b2ee8SDavid du Colombier {
577219b2ee8SDavid du Colombier 	double d;
578219b2ee8SDavid du Colombier 
579219b2ee8SDavid du Colombier 	d = v;		/* BOTCH */
580219b2ee8SDavid du Colombier 	return d;
581219b2ee8SDavid du Colombier }
582219b2ee8SDavid du Colombier 
583219b2ee8SDavid du Colombier vlong
584219b2ee8SDavid du Colombier convftov(double d)
585219b2ee8SDavid du Colombier {
586219b2ee8SDavid du Colombier 	vlong v;
587219b2ee8SDavid du Colombier 
588219b2ee8SDavid du Colombier 
589219b2ee8SDavid du Colombier 	v = d;		/* BOTCH */
590219b2ee8SDavid du Colombier 	return v;
591219b2ee8SDavid du Colombier }
592219b2ee8SDavid du Colombier 
593219b2ee8SDavid du Colombier double
5947dd7cddfSDavid du Colombier convftox(double d, int et)
595219b2ee8SDavid du Colombier {
596219b2ee8SDavid du Colombier 
5977dd7cddfSDavid du Colombier 	if(!typefd[et])
5987dd7cddfSDavid du Colombier 		diag(Z, "bad type in castftox %s", tnames[et]);
599219b2ee8SDavid du Colombier 	return d;
600219b2ee8SDavid du Colombier }
601219b2ee8SDavid du Colombier 
602219b2ee8SDavid du Colombier vlong
6037dd7cddfSDavid du Colombier convvtox(vlong c, int et)
604219b2ee8SDavid du Colombier {
6057dd7cddfSDavid du Colombier 	int n;
606219b2ee8SDavid du Colombier 
6077dd7cddfSDavid du Colombier 	n = 8 * ewidth[et];
6087dd7cddfSDavid du Colombier 	c &= MASK(n);
6097dd7cddfSDavid du Colombier 	if(!typeu[et])
6107dd7cddfSDavid du Colombier 		if(c & SIGN(n))
6117dd7cddfSDavid du Colombier 			c |= ~MASK(n);
612219b2ee8SDavid du Colombier 	return c;
613219b2ee8SDavid du Colombier }
614