xref: /inferno-os/utils/cc/com64.c (revision 50b0dbb170df61467e42c7ea4deb0b5692d15f4c)
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 		case OLIST:
278 		case OCOMMA:
279 			return 1;
280 		case OADD:
281 			a = nodaddv;
282 			goto setbop;
283 		case OSUB:
284 			a = nodsubv;
285 			goto setbop;
286 		case OMUL:
287 		case OLMUL:
288 			a = nodmulv;
289 			goto setbop;
290 		case ODIV:
291 			a = noddivv;
292 			goto setbop;
293 		case OLDIV:
294 			a = noddivvu;
295 			goto setbop;
296 		case OMOD:
297 			a = nodmodv;
298 			goto setbop;
299 		case OLMOD:
300 			a = nodmodvu;
301 			goto setbop;
302 		case OASHL:
303 			a = nodlshv;
304 			goto setbop;
305 		case OASHR:
306 			a = nodrshav;
307 			goto setbop;
308 		case OLSHR:
309 			a = nodrshlv;
310 			goto setbop;
311 		case OAND:
312 			a = nodandv;
313 			goto setbop;
314 		case OOR:
315 			a = nodorv;
316 			goto setbop;
317 		case OXOR:
318 			a = nodxorv;
319 			goto setbop;
320 		case OPOSTINC:
321 			a = nodvpp;
322 			goto setvinc;
323 		case OPOSTDEC:
324 			a = nodvmm;
325 			goto setvinc;
326 		case OPREINC:
327 			a = nodppv;
328 			goto setvinc;
329 		case OPREDEC:
330 			a = nodmmv;
331 			goto setvinc;
332 		case ONEG:
333 			a = nodnegv;
334 			goto setfnx;
335 		case OCOM:
336 			a = nodcomv;
337 			goto setfnx;
338 		case OCAST:
339 			switch(l->type->etype) {
340 			case TCHAR:
341 				a = nodsc2v;
342 				goto setfnxl;
343 			case TUCHAR:
344 				a = noduc2v;
345 				goto setfnxl;
346 			case TSHORT:
347 				a = nodsh2v;
348 				goto setfnxl;
349 			case TUSHORT:
350 				a = noduh2v;
351 				goto setfnxl;
352 			case TINT:
353 				a = nodsi2v;
354 				goto setfnx;
355 			case TUINT:
356 				a = nodui2v;
357 				goto setfnx;
358 			case TLONG:
359 				a = nodsl2v;
360 				goto setfnx;
361 			case TULONG:
362 				a = nodul2v;
363 				goto setfnx;
364 			case TFLOAT:
365 				a = nodf2v;
366 				goto setfnx;
367 			case TDOUBLE:
368 				a = nodd2v;
369 				goto setfnx;
370 			case TIND:
371 				a = nodp2v;
372 				goto setfnx;
373 			}
374 			diag(n, "unknown %T->vlong cast", l->type);
375 			return 1;
376 		case OASADD:
377 			a = nodaddv;
378 			goto setasop;
379 		case OASSUB:
380 			a = nodsubv;
381 			goto setasop;
382 		case OASMUL:
383 		case OASLMUL:
384 			a = nodmulv;
385 			goto setasop;
386 		case OASDIV:
387 			a = noddivv;
388 			goto setasop;
389 		case OASLDIV:
390 			a = noddivvu;
391 			goto setasop;
392 		case OASMOD:
393 			a = nodmodv;
394 			goto setasop;
395 		case OASLMOD:
396 			a = nodmodvu;
397 			goto setasop;
398 		case OASASHL:
399 			a = nodlshv;
400 			goto setasop;
401 		case OASASHR:
402 			a = nodrshav;
403 			goto setasop;
404 		case OASLSHR:
405 			a = nodrshlv;
406 			goto setasop;
407 		case OASAND:
408 			a = nodandv;
409 			goto setasop;
410 		case OASOR:
411 			a = nodorv;
412 			goto setasop;
413 		case OASXOR:
414 			a = nodxorv;
415 			goto setasop;
416 		}
417 	}
418 
419 	if(typefd[n->type->etype] && l && l->op == OFUNC) {
420 		switch(n->op) {
421 		case OASADD:
422 		case OASSUB:
423 		case OASMUL:
424 		case OASLMUL:
425 		case OASDIV:
426 		case OASLDIV:
427 		case OASMOD:
428 		case OASLMOD:
429 		case OASASHL:
430 		case OASASHR:
431 		case OASLSHR:
432 		case OASAND:
433 		case OASOR:
434 		case OASXOR:
435 			if(l->right && typev[l->right->etype]) {
436 				diag(n, "sorry float <asop> vlong not implemented\n");
437 			}
438 		}
439 	}
440 
441 	if(n->op == OCAST) {
442 		if(l->type && typev[l->type->etype]) {
443 			if(machcap(n))
444 				return 1;
445 			switch(n->type->etype) {
446 			case TDOUBLE:
447 				a = nodv2d;
448 				goto setfnx;
449 			case TFLOAT:
450 				a = nodv2f;
451 				goto setfnx;
452 			case TLONG:
453 				a = nodv2sl;
454 				goto setfnx;
455 			case TULONG:
456 				a = nodv2ul;
457 				goto setfnx;
458 			case TINT:
459 				a = nodv2si;
460 				goto setfnx;
461 			case TUINT:
462 				a = nodv2ui;
463 				goto setfnx;
464 			case TSHORT:
465 				a = nodv2sh;
466 				goto setfnx;
467 			case TUSHORT:
468 				a = nodv2uh;
469 				goto setfnx;
470 			case TCHAR:
471 				a = nodv2sc;
472 				goto setfnx;
473 			case TUCHAR:
474 				a = nodv2uc;
475 				goto setfnx;
476 			case TIND:	// small pun here
477 				a = nodv2ul;
478 				goto setfnx;
479 			}
480 			diag(n, "unknown vlong->%T cast", n->type);
481 			return 1;
482 		}
483 	}
484 
485 	return 0;
486 
487 setbop:
488 	n->left = a;
489 	n->right = new(OLIST, l, r);
490 	n->complex = FNX;
491 	n->op = OFUNC;
492 	return 1;
493 
494 setfnxl:
495 	l = new(OCAST, l, 0);
496 	l->type = types[TLONG];
497 	l->complex = l->left->complex;
498 
499 setfnx:
500 	n->left = a;
501 	n->right = l;
502 	n->complex = FNX;
503 	n->op = OFUNC;
504 	return 1;
505 
506 setvinc:
507 	n->left = a;
508 	l = new(OADDR, l, Z);
509 	l->type = typ(TIND, l->left->type);
510 	l->complex = l->left->complex;
511 	n->right = new(OLIST, l, r);
512 	n->complex = FNX;
513 	n->op = OFUNC;
514 	return 1;
515 
516 setbool:
517 	if(machcap(n))
518 		return 1;
519 	n->left = a;
520 	n->right = new(OLIST, l, r);
521 	n->complex = FNX;
522 	n->op = OFUNC;
523 	n->type = types[TLONG];
524 	return 1;
525 
526 setasop:
527 	if(l->op == OFUNC) {
528 		l = l->right;
529 		goto setasop;
530 	}
531 
532 	t = new(OCONST, 0, 0);
533 	t->vconst = etconv[l->type->etype];
534 	t->type = types[TLONG];
535 	t->addable = 20;
536 	r = new(OLIST, t, r);
537 
538 	t = new(OADDR, a, 0);
539 	t->type = typ(TIND, a->type);
540 	r = new(OLIST, t, r);
541 
542 	t = new(OADDR, l, 0);
543 	t->type = typ(TIND, l->type);
544 	t->complex = l->complex;
545 	r = new(OLIST, t, r);
546 
547 	n->left = nodvasop;
548 	n->right = r;
549 	n->complex = FNX;
550 	n->op = OFUNC;
551 
552 	return 1;
553 }
554 
555 void
556 bool64(Node *n)
557 {
558 	Node *n1;
559 
560 	if(machcap(Z))
561 		return;
562 	if(typev[n->type->etype]) {
563 		n1 = new(OXXX, 0, 0);
564 		*n1 = *n;
565 
566 		n->right = n1;
567 		n->left = nodtestv;
568 		n->complex = FNX;
569 		n->addable = 0;
570 		n->op = OFUNC;
571 		n->type = types[TLONG];
572 	}
573 }
574 
575 /*
576  * more machine depend stuff.
577  * this is common for 8,16,32,64 bit machines.
578  * this is common for ieee machines.
579  */
580 double
581 convvtof(vlong v)
582 {
583 	double d;
584 
585 	d = v;		/* BOTCH */
586 	return d;
587 }
588 
589 vlong
590 convftov(double d)
591 {
592 	vlong v;
593 
594 
595 	v = d;		/* BOTCH */
596 	return v;
597 }
598 
599 double
600 convftox(double d, int et)
601 {
602 
603 	if(!typefd[et])
604 		diag(Z, "bad type in castftox %s", tnames[et]);
605 	return d;
606 }
607 
608 vlong
609 convvtox(vlong c, int et)
610 {
611 	int n;
612 
613 	n = 8 * ewidth[et];
614 	c &= MASK(n);
615 	if(!typeu[et])
616 		if(c & SIGN(n))
617 			c |= ~MASK(n);
618 	return c;
619 }
620