]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/pswt.c
ip/ipconfig: use ewrite() to enable routing command for sendra
[plan9front.git] / sys / src / cmd / cc / pswt.c
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 }