]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/com64.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[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                         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 }