Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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['K'])
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(TRune *s, long n)
136
{
137
	char buf[sizeof(TRune)];
138
	uint c;
139
	int i;
140
	long r;
141
 
142
	if(suppress)
143
		return nstring;
144
	while(nstring & (sizeof(TRune)-1))
145
		outstring("", 1);
146
	r = nstring;
147
	while(n > 0) {
148
		c = *s++;
149
		if(align(0, types[TCHAR], Aarg1)) {
150
			for(i = 0; i < sizeof(TRune); i++)
151
				buf[i] = c>>(8*(sizeof(TRune) - i - 1));
152
		} else {
153
			for(i = 0; i < sizeof(TRune); i++)
154
				buf[i] = c>>(8*i);
155
		}
156
		outstring(buf, sizeof(TRune));
157
		n -= sizeof(TRune);
158
	}
159
	return r;
160
}
161
 
162
void
163
nullwarn(Node *l, Node *r)
164
{
165
	warn(Z, "result of operation not used");
166
	if(l != Z)
167
		cgen(l, Z);
168
	if(r != Z)
169
		cgen(r, Z);
170
}
171
 
172
void
173
ieeedtod(Ieee *ieee, double native)
174
{
175
	double fr, ho, f;
176
	int exp;
177
 
178
	if(native < 0) {
179
		ieeedtod(ieee, -native);
180
		ieee->h |= 0x80000000L;
181
		return;
182
	}
183
	if(native == 0) {
184
		ieee->l = 0;
185
		ieee->h = 0;
186
		return;
187
	}
188
	fr = frexp(native, &exp);
189
	f = 2097152L;		/* shouldnt use fp constants here */
190
	fr = modf(fr*f, &ho);
191
	ieee->h = ho;
192
	ieee->h &= 0xfffffL;
193
	ieee->h |= (exp+1022L) << 20;
194
	f = 65536L;
195
	fr = modf(fr*f, &ho);
196
	ieee->l = ho;
197
	ieee->l <<= 16;
198
	ieee->l |= (long)(fr*f);
199
}