xref: /inferno-os/utils/cc/com64.c (revision e57c7e16a3789cd4de1a3c2560d49b1ee39cd10a)
1 #include "cc.h"
2 
3 /*
4  * this is machine dependent, but it is totally
5  * common on all of the 64-bit symulating machines.
6  */
7 
8 #define	FNX	100	/* botch -- redefinition */
9 
10 Node*	nodaddv;
11 Node*	nodsubv;
12 Node*	nodmulv;
13 Node*	noddivv;
14 Node*	noddivvu;
15 Node*	nodmodv;
16 Node*	nodmodvu;
17 Node*	nodlshv;
18 Node*	nodrshav;
19 Node*	nodrshlv;
20 Node*	nodandv;
21 Node*	nodorv;
22 Node*	nodxorv;
23 Node*	nodnegv;
24 Node*	nodcomv;
25 
26 Node*	nodtestv;
27 Node*	nodeqv;
28 Node*	nodnev;
29 Node*	nodlev;
30 Node*	nodltv;
31 Node*	nodgev;
32 Node*	nodgtv;
33 Node*	nodhiv;
34 Node*	nodhsv;
35 Node*	nodlov;
36 Node*	nodlsv;
37 
38 Node*	nodf2v;
39 Node*	nodd2v;
40 Node*	nodp2v;
41 Node*	nodsi2v;
42 Node*	nodui2v;
43 Node*	nodsl2v;
44 Node*	nodul2v;
45 Node*	nodsh2v;
46 Node*	noduh2v;
47 Node*	nodsc2v;
48 Node*	noduc2v;
49 
50 Node*	nodv2f;
51 Node*	nodv2d;
52 Node*	nodv2ui;
53 Node*	nodv2si;
54 Node*	nodv2ul;
55 Node*	nodv2sl;
56 Node*	nodv2uh;
57 Node*	nodv2sh;
58 Node*	nodv2uc;
59 Node*	nodv2sc;
60 
61 Node*	nodvpp;
62 Node*	nodppv;
63 Node*	nodvmm;
64 Node*	nodmmv;
65 
66 Node*	nodvasop;
67 
68 char	etconv[NTYPE];	/* for _vasop */
69 Init	initetconv[] =
70 {
71 	TCHAR,		1,	0,
72 	TUCHAR,		2,	0,
73 	TSHORT,		3,	0,
74 	TUSHORT,	4,	0,
75 	TLONG,		5,	0,
76 	TULONG,		6,	0,
77 	TVLONG,		7,	0,
78 	TUVLONG,	8,	0,
79 	TINT,		9,	0,
80 	TUINT,		10,	0,
81 	-1,		0,	0,
82 };
83 
84 Node*
85 fvn(char *name, int type)
86 {
87 	Node *n;
88 
89 	n = new(ONAME, Z, Z);
90 	n->sym = slookup(name);
91 	n->sym->sig = SIGINTERN;
92 	if(fntypes[type] == 0)
93 		fntypes[type] = typ(TFUNC, types[type]);
94 	n->type = fntypes[type];
95 	n->etype = type;
96 	n->class = CGLOBL;
97 	n->addable = 10;
98 	n->complex = 0;
99 	return n;
100 }
101 
102 void
103 com64init(void)
104 {
105 	Init *p;
106 
107 	nodaddv = fvn("_addv", TVLONG);
108 	nodsubv = fvn("_subv", TVLONG);
109 	nodmulv = fvn("_mulv", TVLONG);
110 	noddivv = fvn("_divv", TVLONG);
111 	noddivvu = fvn("_divvu", TVLONG);
112 	nodmodv = fvn("_modv", TVLONG);
113 	nodmodvu = fvn("_modvu", TVLONG);
114 	nodlshv = fvn("_lshv", TVLONG);
115 	nodrshav = fvn("_rshav", TVLONG);
116 	nodrshlv = fvn("_rshlv", TVLONG);
117 	nodandv = fvn("_andv", TVLONG);
118 	nodorv = fvn("_orv", TVLONG);
119 	nodxorv = fvn("_xorv", TVLONG);
120 	nodnegv = fvn("_negv", TVLONG);
121 	nodcomv = fvn("_comv", TVLONG);
122 
123 	nodtestv = fvn("_testv", TLONG);
124 	nodeqv = fvn("_eqv", TLONG);
125 	nodnev = fvn("_nev", TLONG);
126 	nodlev = fvn("_lev", TLONG);
127 	nodltv = fvn("_ltv", TLONG);
128 	nodgev = fvn("_gev", TLONG);
129 	nodgtv = fvn("_gtv", TLONG);
130 	nodhiv = fvn("_hiv", TLONG);
131 	nodhsv = fvn("_hsv", TLONG);
132 	nodlov = fvn("_lov", TLONG);
133 	nodlsv = fvn("_lsv", TLONG);
134 
135 	nodf2v = fvn("_f2v", TVLONG);
136 	nodd2v = fvn("_d2v", TVLONG);
137 	nodp2v = fvn("_p2v", TVLONG);
138 	nodsi2v = fvn("_si2v", TVLONG);
139 	nodui2v = fvn("_ui2v", TVLONG);
140 	nodsl2v = fvn("_sl2v", TVLONG);
141 	nodul2v = fvn("_ul2v", TVLONG);
142 	nodsh2v = fvn("_sh2v", TVLONG);
143 	noduh2v = fvn("_uh2v", TVLONG);
144 	nodsc2v = fvn("_sc2v", TVLONG);
145 	noduc2v = fvn("_uc2v", TVLONG);
146 
147 	nodv2f = fvn("_v2f", TFLOAT);
148 	nodv2d = fvn("_v2d", TDOUBLE);
149 	nodv2sl = fvn("_v2sl", TLONG);
150 	nodv2ul = fvn("_v2ul", TULONG);
151 	nodv2si = fvn("_v2si", TINT);
152 	nodv2ui = fvn("_v2ui", TUINT);
153 	nodv2sh = fvn("_v2sh", TSHORT);
154 	nodv2uh = fvn("_v2ul", TUSHORT);
155 	nodv2sc = fvn("_v2sc", TCHAR);
156 	nodv2uc = fvn("_v2uc", TUCHAR);
157 
158 	nodvpp = fvn("_vpp", TVLONG);
159 	nodppv = fvn("_ppv", TVLONG);
160 	nodvmm = fvn("_vmm", TVLONG);
161 	nodmmv = fvn("_mmv", TVLONG);
162 
163 	nodvasop = fvn("_vasop", TVLONG);
164 
165 	for(p = initetconv; p->code >= 0; p++)
166 		etconv[p->code] = p->value;
167 }
168 
169 int
170 com64(Node *n)
171 {
172 	Node *l, *r, *a, *t;
173 	int lv, rv;
174 
175 	if(n->type == 0)
176 		return 0;
177 
178 	l = n->left;
179 	r = n->right;
180 
181 	lv = 0;
182 	if(l && l->type && typev[l->type->etype])
183 		lv = 1;
184 	rv = 0;
185 	if(r && r->type && typev[r->type->etype])
186 		rv = 1;
187 
188 	if(lv) {
189 		switch(n->op) {
190 		case OEQ:
191 			a = nodeqv;
192 			goto setbool;
193 		case ONE:
194 			a = nodnev;
195 			goto setbool;
196 		case OLE:
197 			a = nodlev;
198 			goto setbool;
199 		case OLT:
200 			a = nodltv;
201 			goto setbool;
202 		case OGE:
203 			a = nodgev;
204 			goto setbool;
205 		case OGT:
206 			a = nodgtv;
207 			goto setbool;
208 		case OHI:
209 			a = nodhiv;
210 			goto setbool;
211 		case OHS:
212 			a = nodhsv;
213 			goto setbool;
214 		case OLO:
215 			a = nodlov;
216 			goto setbool;
217 		case OLS:
218 			a = nodlsv;
219 			goto setbool;
220 
221 		case OANDAND:
222 		case OOROR:
223 			if(machcap(n))
224 				return 1;
225 
226 			if(rv) {
227 				r = new(OFUNC, nodtestv, r);
228 				n->right = r;
229 				r->complex = FNX;
230 				r->op = OFUNC;
231 				r->type = types[TLONG];
232 			}
233 
234 		case OCOND:
235 		case ONOT:
236 			if(machcap(n))
237 				return 1;
238 
239 			l = new(OFUNC, nodtestv, l);
240 			n->left = l;
241 			l->complex = FNX;
242 			l->op = OFUNC;
243 			l->type = types[TLONG];
244 			n->complex = FNX;
245 			return 1;
246 		}
247 	}
248 
249 	if(rv) {
250 		if(machcap(n))
251 			return 1;
252 		switch(n->op) {
253 		case OANDAND:
254 		case OOROR:
255 			r = new(OFUNC, nodtestv, r);
256 			n->right = r;
257 			r->complex = FNX;
258 			r->op = OFUNC;
259 			r->type = types[TLONG];
260 			return 1;
261 		case OCOND:
262 			return 1;
263 		}
264 	}
265 
266 	if(typev[n->type->etype]) {
267 		if(machcap(n))
268 			return 1;
269 		switch(n->op) {
270 		default:
271 			diag(n, "unknown vlong %O", n->op);
272 		case OFUNC:
273 			n->complex = FNX;
274 		case ORETURN:
275 		case OAS:
276 		case OIND:
277 			return 1;
278 		case OADD:
279 			a = nodaddv;
280 			goto setbop;
281 		case OSUB:
282 			a = nodsubv;
283 			goto setbop;
284 		case OMUL:
285 		case OLMUL:
286 			a = nodmulv;
287 			goto setbop;
288 		case ODIV:
289 			a = noddivv;
290 			goto setbop;
291 		case OLDIV:
292 			a = noddivvu;
293 			goto setbop;
294 		case OMOD:
295 			a = nodmodv;
296 			goto setbop;
297 		case OLMOD:
298 			a = nodmodvu;
299 			goto setbop;
300 		case OASHL:
301 			a = nodlshv;
302 			goto setbop;
303 		case OASHR:
304 			a = nodrshav;
305 			goto setbop;
306 		case OLSHR:
307 			a = nodrshlv;
308 			goto setbop;
309 		case OAND:
310 			a = nodandv;
311 			goto setbop;
312 		case OOR:
313 			a = nodorv;
314 			goto setbop;
315 		case OXOR:
316 			a = nodxorv;
317 			goto setbop;
318 		case OPOSTINC:
319 			a = nodvpp;
320 			goto setvinc;
321 		case OPOSTDEC:
322 			a = nodvmm;
323 			goto setvinc;
324 		case OPREINC:
325 			a = nodppv;
326 			goto setvinc;
327 		case OPREDEC:
328 			a = nodmmv;
329 			goto setvinc;
330 		case ONEG:
331 			a = nodnegv;
332 			goto setfnx;
333 		case OCOM:
334 			a = nodcomv;
335 			goto setfnx;
336 		case OCAST:
337 			switch(l->type->etype) {
338 			case TCHAR:
339 				a = nodsc2v;
340 				goto setfnxl;
341 			case TUCHAR:
342 				a = noduc2v;
343 				goto setfnxl;
344 			case TSHORT:
345 				a = nodsh2v;
346 				goto setfnxl;
347 			case TUSHORT:
348 				a = noduh2v;
349 				goto setfnxl;
350 			case TINT:
351 				a = nodsi2v;
352 				goto setfnx;
353 			case TUINT:
354 				a = nodui2v;
355 				goto setfnx;
356 			case TLONG:
357 				a = nodsl2v;
358 				goto setfnx;
359 			case TULONG:
360 				a = nodul2v;
361 				goto setfnx;
362 			case TFLOAT:
363 				a = nodf2v;
364 				goto setfnx;
365 			case TDOUBLE:
366 				a = nodd2v;
367 				goto setfnx;
368 			case TIND:
369 				a = nodp2v;
370 				goto setfnx;
371 			}
372 			diag(n, "unknown %T->vlong cast", l->type);
373 			return 1;
374 		case OASADD:
375 			a = nodaddv;
376 			goto setasop;
377 		case OASSUB:
378 			a = nodsubv;
379 			goto setasop;
380 		case OASMUL:
381 		case OASLMUL:
382 			a = nodmulv;
383 			goto setasop;
384 		case OASDIV:
385 			a = noddivv;
386 			goto setasop;
387 		case OASLDIV:
388 			a = noddivvu;
389 			goto setasop;
390 		case OASMOD:
391 			a = nodmodv;
392 			goto setasop;
393 		case OASLMOD:
394 			a = nodmodvu;
395 			goto setasop;
396 		case OASASHL:
397 			a = nodlshv;
398 			goto setasop;
399 		case OASASHR:
400 			a = nodrshav;
401 			goto setasop;
402 		case OASLSHR:
403 			a = nodrshlv;
404 			goto setasop;
405 		case OASAND:
406 			a = nodandv;
407 			goto setasop;
408 		case OASOR:
409 			a = nodorv;
410 			goto setasop;
411 		case OASXOR:
412 			a = nodxorv;
413 			goto setasop;
414 		}
415 	}
416 
417 	if(typefd[n->type->etype] && l && l->op == OFUNC) {
418 		switch(n->op) {
419 		case OASADD:
420 		case OASSUB:
421 		case OASMUL:
422 		case OASLMUL:
423 		case OASDIV:
424 		case OASLDIV:
425 		case OASMOD:
426 		case OASLMOD:
427 		case OASASHL:
428 		case OASASHR:
429 		case OASLSHR:
430 		case OASAND:
431 		case OASOR:
432 		case OASXOR:
433 			if(l->right && typev[l->right->etype]) {
434 				diag(n, "sorry float <asop> vlong not implemented\n");
435 			}
436 		}
437 	}
438 
439 	if(n->op == OCAST) {
440 		if(l->type && typev[l->type->etype]) {
441 			if(machcap(n))
442 				return 1;
443 			switch(n->type->etype) {
444 			case TDOUBLE:
445 				a = nodv2d;
446 				goto setfnx;
447 			case TFLOAT:
448 				a = nodv2f;
449 				goto setfnx;
450 			case TLONG:
451 				a = nodv2sl;
452 				goto setfnx;
453 			case TULONG:
454 				a = nodv2ul;
455 				goto setfnx;
456 			case TINT:
457 				a = nodv2si;
458 				goto setfnx;
459 			case TUINT:
460 				a = nodv2ui;
461 				goto setfnx;
462 			case TSHORT:
463 				a = nodv2sh;
464 				goto setfnx;
465 			case TUSHORT:
466 				a = nodv2uh;
467 				goto setfnx;
468 			case TCHAR:
469 				a = nodv2sc;
470 				goto setfnx;
471 			case TUCHAR:
472 				a = nodv2uc;
473 				goto setfnx;
474 			case TIND:	// small pun here
475 				a = nodv2ul;
476 				goto setfnx;
477 			}
478 			diag(n, "unknown vlong->%T cast", n->type);
479 			return 1;
480 		}
481 	}
482 
483 	return 0;
484 
485 setbop:
486 	n->left = a;
487 	n->right = new(OLIST, l, r);
488 	n->complex = FNX;
489 	n->op = OFUNC;
490 	return 1;
491 
492 setfnxl:
493 	l = new(OCAST, l, 0);
494 	l->type = types[TLONG];
495 	l->complex = l->left->complex;
496 
497 setfnx:
498 	n->left = a;
499 	n->right = l;
500 	n->complex = FNX;
501 	n->op = OFUNC;
502 	return 1;
503 
504 setvinc:
505 	n->left = a;
506 	l = new(OADDR, l, Z);
507 	l->type = typ(TIND, l->left->type);
508 	l->complex = l->left->complex;
509 	n->right = new(OLIST, l, r);
510 	n->complex = FNX;
511 	n->op = OFUNC;
512 	return 1;
513 
514 setbool:
515 	if(machcap(n))
516 		return 1;
517 	n->left = a;
518 	n->right = new(OLIST, l, r);
519 	n->complex = FNX;
520 	n->op = OFUNC;
521 	n->type = types[TLONG];
522 	return 1;
523 
524 setasop:
525 	if(l->op == OFUNC) {
526 		l = l->right;
527 		goto setasop;
528 	}
529 
530 	t = new(OCONST, 0, 0);
531 	t->vconst = etconv[l->type->etype];
532 	t->type = types[TLONG];
533 	t->addable = 20;
534 	r = new(OLIST, t, r);
535 
536 	t = new(OADDR, a, 0);
537 	t->type = typ(TIND, a->type);
538 	r = new(OLIST, t, r);
539 
540 	t = new(OADDR, l, 0);
541 	t->type = typ(TIND, l->type);
542 	t->complex = l->complex;
543 	r = new(OLIST, t, r);
544 
545 	n->left = nodvasop;
546 	n->right = r;
547 	n->complex = FNX;
548 	n->op = OFUNC;
549 
550 	return 1;
551 }
552 
553 void
554 bool64(Node *n)
555 {
556 	Node *n1;
557 
558 	if(machcap(Z))
559 		return;
560 	if(typev[n->type->etype]) {
561 		n1 = new(OXXX, 0, 0);
562 		*n1 = *n;
563 
564 		n->right = n1;
565 		n->left = nodtestv;
566 		n->complex = FNX;
567 		n->addable = 0;
568 		n->op = OFUNC;
569 		n->type = types[TLONG];
570 	}
571 }
572 
573 /*
574  * more machine depend stuff.
575  * this is common for 8,16,32,64 bit machines.
576  * this is common for ieee machines.
577  */
578 double
579 convvtof(vlong v)
580 {
581 	double d;
582 
583 	d = v;		/* BOTCH */
584 	return d;
585 }
586 
587 vlong
588 convftov(double d)
589 {
590 	vlong v;
591 
592 
593 	v = d;		/* BOTCH */
594 	return v;
595 }
596 
597 double
598 convftox(double d, int et)
599 {
600 
601 	if(!typefd[et])
602 		diag(Z, "bad type in castftox %s", tnames[et]);
603 	return d;
604 }
605 
606 vlong
607 convvtox(vlong c, int et)
608 {
609 	int n;
610 
611 	n = 8 * ewidth[et];
612 	c &= MASK(n);
613 	if(!typeu[et])
614 		if(c & SIGN(n))
615 			c |= ~MASK(n);
616 	return c;
617 }
618