]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/pswt.c
fixed issue #47
[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;
20         long def, nc, i, isv;
21         int dup;
22
23         def = 0;
24         nc = 0;
25         isv = 0;
26         for(c = cases; c->link != C; c = c->link) {
27                 if(c->def) {
28                         if(def)
29                                 diag(n, "more than one default in switch");
30                         def = c->label;
31                         continue;
32                 }
33                 isv |= c->isv;
34                 nc++;
35         }
36         if(isv && !typev[n->type->etype])
37                 warn(n, "32-bit switch expression with 64-bit case constant");
38
39         iq = alloc(nc*sizeof(C1));
40         q = iq;
41         for(c = cases; c->link != C; c = c->link) {
42                 if(c->def)
43                         continue;
44                 q->label = c->label;
45                 if(isv)
46                         q->val = c->val;
47                 else
48                         q->val = (long)c->val;  /* cast ensures correct value for 32-bit switch on 64-bit architecture */
49                 q++;
50         }
51         qsort(iq, nc, sizeof(C1), swcmp);
52         if(debug['W'])
53         for(i=0; i<nc; i++)
54                 print("case %2ld: = %.8llux\n", i, (vlong)iq[i].val);
55         dup = 0;
56         for(i=0; i<nc-1; i++)
57                 if(iq[i].val == iq[i+1].val) {
58                         diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val);
59                         dup = 1;
60                 }
61         if(dup)
62                 return;
63         if(def == 0) {
64                 def = breakpc;
65                 nbreak++;
66         }
67         swit1(iq, nc, def, n);
68 }
69
70 void
71 casf(void)
72 {
73         Case *c;
74
75         c = alloc(sizeof(*c));
76         c->link = cases;
77         cases = c;
78 }
79
80 long
81 outlstring(ushort *s, long n)
82 {
83         char buf[2];
84         int c;
85         long r;
86
87         if(suppress)
88                 return nstring;
89         while(nstring & 1)
90                 outstring("", 1);
91         r = nstring;
92         while(n > 0) {
93                 c = *s++;
94                 if(align(0, types[TCHAR], Aarg1)) {
95                         buf[0] = c>>8;
96                         buf[1] = c;
97                 } else {
98                         buf[0] = c;
99                         buf[1] = c>>8;
100                 }
101                 outstring(buf, 2);
102                 n -= sizeof(ushort);
103         }
104         return r;
105 }
106
107 void
108 nullwarn(Node *l, Node *r)
109 {
110         warn(Z, "result of operation not used");
111         if(l != Z)
112                 cgen(l, Z);
113         if(r != Z)
114                 cgen(r, Z);
115 }
116
117 void
118 ieeedtod(Ieee *ieee, double native)
119 {
120         double fr, ho, f;
121         int exp;
122
123         if(native < 0) {
124                 ieeedtod(ieee, -native);
125                 ieee->h |= 0x80000000L;
126                 return;
127         }
128         if(native == 0) {
129                 ieee->l = 0;
130                 ieee->h = 0;
131                 return;
132         }
133         fr = frexp(native, &exp);
134         f = 2097152L;           /* shouldnt use fp constants here */
135         fr = modf(fr*f, &ho);
136         ieee->h = ho;
137         ieee->h &= 0xfffffL;
138         ieee->h |= (exp+1022L) << 20;
139         f = 65536L;
140         fr = modf(fr*f, &ho);
141         ieee->l = ho;
142         ieee->l <<= 16;
143         ieee->l |= (long)(fr*f);
144 }