xref: /inferno-os/utils/cc/pswt.c (revision 2b69dba5038ffd0b59cf30a4c44bce549e5097f8)
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 }
145