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