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*
fvn(char * name,int type)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
com64init(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
com64(Node * n)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
bool64(Node * n)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
convvtof(vlong v)581 convvtof(vlong v)
582 {
583 double d;
584
585 d = v; /* BOTCH */
586 return d;
587 }
588
589 vlong
convftov(double d)590 convftov(double d)
591 {
592 vlong v;
593
594
595 v = d; /* BOTCH */
596 return v;
597 }
598
599 double
convftox(double d,int et)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
convvtox(vlong c,int et)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