changelog shortlog tags branches changeset files revisions annotate raw help

Mercurial > hg > plan9front / sys/src/cmd/cc/com64.c

changeset 6843: 7db92ee68f7e
parent: 8849c1bf3860
author: 23hiro@gmail.com
date: Thu, 25 Oct 2018 08:09:10 +0200
permissions: -rw-r--r--
description: add Centrino Wireless-N 1030 (thanks lksmk from brazil)
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 }