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