]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/com64.c
fixed issue #47
[plan9front.git] / sys / src / cmd / cc / com64.c
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 OCOMMA:
278                 case OLIST:
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 }