changelog shortlog tags branches changeset files revisions annotate raw help

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

changeset 6843: 7db92ee68f7e
parent: 80d018033b9d
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 "gc.h"
2 
3 int
4 swcmp(const void *a1, const void *a2)
5 {
6  C1 *p1, *p2;
7 
8  p1 = (C1*)a1;
9  p2 = (C1*)a2;
10  if(p1->val < p2->val)
11  return -1;
12  return p1->val > p2->val;
13 }
14 
15 void
16 doswit(Node *n)
17 {
18  Case *c;
19  C1 *q, *iq, *iqh, *iql;
20  long def, nc, i, j, isv, nh;
21  Prog *hsb;
22  Node *vr[2];
23  int dup;
24 
25  def = 0;
26  nc = 0;
27  isv = 0;
28  for(c = cases; c->link != C; c = c->link) {
29  if(c->def) {
30  if(def)
31  diag(n, "more than one default in switch");
32  def = c->label;
33  continue;
34  }
35  isv |= c->isv;
36  nc++;
37  }
38  if(typev[n->type->etype])
39  isv = 1;
40  else if(isv){
41  warn(n, "32-bit switch expression with 64-bit case constant");
42  isv = 0;
43  }
44 
45  iq = alloc(nc*sizeof(C1));
46  q = iq;
47  for(c = cases; c->link != C; c = c->link) {
48  if(c->def)
49  continue;
50  if(c->isv && !isv)
51  continue; /* can never match */
52  q->label = c->label;
53  if(isv)
54  q->val = c->val;
55  else
56  q->val = (long)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */
57  q++;
58  }
59  qsort(iq, nc, sizeof(C1), swcmp);
60  if(debug['W'])
61  for(i=0; i<nc; i++)
62  print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val);
63  dup = 0;
64  for(i=0; i<nc-1; i++)
65  if(iq[i].val == iq[i+1].val) {
66  diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val);
67  dup = 1;
68  }
69  if(dup)
70  return;
71  if(def == 0) {
72  def = breakpc;
73  nbreak++;
74  }
75  if(!isv || ewidth[TIND] > ewidth[TLONG] || n->op == OREGISTER) {
76  swit1(iq, nc, def, n);
77  return;
78  }
79 
80  /*
81  * 64-bit case on 32-bit machine:
82  * switch on high-order words, and
83  * in each of those, switch on low-order words
84  */
85  if(n->op != OREGPAIR)
86  fatal(n, "internal: expected register pair");
87  if(thechar == '8'){ /* TO DO: need an enquiry function */
88  vr[0] = n->left; /* low */
89  vr[1] = n->right; /* high */
90  }else{
91  vr[0] = n->right;
92  vr[1] = n->left;
93  }
94  vr[0]->type = types[TLONG];
95  vr[1]->type = types[TLONG];
96  gbranch(OGOTO);
97  hsb = p;
98  iqh = alloc(nc*sizeof(C1));
99  iql = alloc(nc*sizeof(C1));
100  nh = 0;
101  for(i=0; i<nc;){
102  iqh[nh].val = iq[i].val >> 32;
103  q = iql;
104  /* iq is sorted, so equal top halves are adjacent */
105  for(j = i; j < nc; j++){
106  if((iq[j].val>>32) != iqh[nh].val)
107  break;
108  q->val = (long)iq[j].val;
109  q->label = iq[j].label;
110  q++;
111  }
112  qsort(iql, q-iql, sizeof(C1), swcmp);
113 if(0){for(int k=0; k<(q-iql); k++)print("nh=%ld k=%d h=%#llux l=%#llux lab=%ld\n", nh, k, (vlong)iqh[nh].val, (vlong)iql[k].val, iql[k].label);}
114  iqh[nh].label = pc;
115  nh++;
116  swit1(iql, q-iql, def, vr[0]);
117  i = j;
118  }
119  patch(hsb, pc);
120 if(0){for(int k=0; k<nh; k++)print("k*=%d h=%#llux lab=%ld\n", k, (vlong)iqh[k].val, iqh[k].label);}
121  swit1(iqh, nh, def, vr[1]);
122 }
123 
124 void
125 casf(void)
126 {
127  Case *c;
128 
129  c = alloc(sizeof(*c));
130  c->link = cases;
131  cases = c;
132 }
133 
134 long
135 outlstring(Rune *s, long n)
136 {
137  char buf[sizeof(Rune)];
138  int c, i;
139  long r;
140 
141  if(suppress)
142  return nstring;
143  while(nstring % sizeof buf)
144  outstring("", 1);
145  r = nstring;
146  while(n > 0) {
147  c = *s++;
148  if(align(0, types[TCHAR], Aarg1)) {
149  for(i = sizeof buf; i > 0; c >>= 8)
150  buf[--i] = c;
151  } else {
152  for(i = 0; i < sizeof buf; c >>= 8)
153  buf[i++] = c;
154  }
155  outstring(buf, sizeof buf);
156  n -= sizeof buf;
157  }
158  return r;
159 }
160 
161 void
162 nullwarn(Node *l, Node *r)
163 {
164  warn(Z, "result of operation not used");
165  if(l != Z)
166  cgen(l, Z);
167  if(r != Z)
168  cgen(r, Z);
169 }
170 
171 void
172 ieeedtod(Ieee *ieee, double native)
173 {
174  double fr, ho, f;
175  int exp;
176 
177  if(native < 0) {
178  ieeedtod(ieee, -native);
179  ieee->h |= 0x80000000L;
180  return;
181  }
182  if(native == 0) {
183  ieee->l = 0;
184  ieee->h = 0;
185  return;
186  }
187  fr = frexp(native, &exp);
188  f = 2097152L; /* shouldnt use fp constants here */
189  fr = modf(fr*f, &ho);
190  ieee->h = ho;
191  ieee->h &= 0xfffffL;
192  ieee->h |= (exp+1022L) << 20;
193  f = 65536L;
194  fr = modf(fr*f, &ho);
195  ieee->l = ho;
196  ieee->l <<= 16;
197  ieee->l |= (long)(fr*f);
198 }