Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "gc.h"
2
 
3
void
4
swit1(C1 *q, int nc, long def, Node *n)
5
{
6
	C1 *r;
7
	int i;
8
	Prog *sp;
9
 
10
	if(nc < 5) {
11
		for(i=0; i<nc; i++) {
12
			if(debug['K'])
13
				print("case = %.8llux\n", q->val);
14
			gcmp(OEQ, n, q->val);
15
			patch(p, q->label);
16
			q++;
17
		}
18
		gbranch(OGOTO);
19
		patch(p, def);
20
		return;
21
	}
22
	i = nc / 2;
23
	r = q+i;
24
	if(debug['K'])
25
		print("case > %.8llux\n", r->val);
26
	gcmp(OGT, n, r->val);
27
	sp = p;
28
	gbranch(OGOTO);
29
	p->as = AJEQ;
30
	patch(p, r->label);
31
	swit1(q, i, def, n);
32
 
33
	if(debug['K'])
34
		print("case < %.8llux\n", r->val);
35
	patch(sp, pc);
36
	swit1(r+1, nc-i-1, def, n);
37
}
38
 
39
void
40
bitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
41
{
42
	int sh;
43
	long v;
44
	Node *l;
45
 
46
	/*
47
	 * n1 gets adjusted/masked value
48
	 * n2 gets address of cell
49
	 * n3 gets contents of cell
50
	 */
51
	l = b->left;
52
	if(n2 != Z) {
53
		regalloc(n1, l, nn);
54
		reglcgen(n2, l, Z);
55
		regalloc(n3, l, Z);
56
		gmove(n2, n3);
57
		gmove(n3, n1);
58
	} else {
59
		regalloc(n1, l, nn);
60
		cgen(l, n1);
61
	}
62
	if(b->type->shift == 0 && typeu[b->type->etype]) {
63
		v = ~0 + (1L << b->type->nbits);
64
		gopcode(OAND, tfield, nodconst(v), n1);
65
	} else {
66
		sh = 32 - b->type->shift - b->type->nbits;
67
		if(sh > 0)
68
			gopcode(OASHL, tfield, nodconst(sh), n1);
69
		sh += b->type->shift;
70
		if(sh > 0)
71
			if(typeu[b->type->etype])
72
				gopcode(OLSHR, tfield, nodconst(sh), n1);
73
			else
74
				gopcode(OASHR, tfield, nodconst(sh), n1);
75
	}
76
}
77
 
78
void
79
bitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn)
80
{
81
	long v;
82
	Node nod;
83
	int sh;
84
 
85
	regalloc(&nod, b->left, Z);
86
	v = ~0 + (1L << b->type->nbits);
87
	gopcode(OAND, types[TLONG], nodconst(v), n1);
88
	gmove(n1, &nod);
89
	if(nn != Z)
90
		gmove(n1, nn);
91
	sh = b->type->shift;
92
	if(sh > 0)
93
		gopcode(OASHL, types[TLONG], nodconst(sh), &nod);
94
	v <<= sh;
95
	gopcode(OAND, types[TLONG], nodconst(~v), n3);
96
	gopcode(OOR, types[TLONG], n3, &nod);
97
	gmove(&nod, n2);
98
 
99
	regfree(&nod);
100
	regfree(n1);
101
	regfree(n2);
102
	regfree(n3);
103
}
104
 
105
long
106
outstring(char *s, long n)
107
{
108
	long r;
109
 
110
	if(suppress)
111
		return nstring;
112
	r = nstring;
113
	while(n) {
114
		string[mnstring] = *s++;
115
		mnstring++;
116
		nstring++;
117
		if(mnstring >= NSNAME) {
118
			gpseudo(ADATA, symstring, nodconst(0L));
119
			p->from.offset += nstring - NSNAME;
120
			p->from.scale = NSNAME;
121
			p->to.type = D_SCONST;
122
			memmove(p->to.sval, string, NSNAME);
123
			mnstring = 0;
124
		}
125
		n--;
126
	}
127
	return r;
128
}
129
 
130
void
131
gextern(Sym *s, Node *a, long o, long w)
132
{
133
	if(0 && a->op == OCONST && typev[a->type->etype]) {
134
		gpseudo(ADATA, s, lo64(a));
135
		p->from.offset += o;
136
		p->from.scale = 4;
137
		gpseudo(ADATA, s, hi64(a));
138
		p->from.offset += o + 4;
139
		p->from.scale = 4;
140
		return;
141
	}
142
	gpseudo(ADATA, s, a);
143
	p->from.offset += o;
144
	p->from.scale = w;
145
	switch(p->to.type) {
146
	default:
147
		p->to.index = p->to.type;
148
		p->to.type = D_ADDR;
149
	case D_CONST:
150
	case D_FCONST:
151
	case D_ADDR:
152
		break;
153
	}
154
}
155
 
156
void	zname(Biobuf*, Sym*, int);
157
void	zaddr(Biobuf*, Adr*, int);
158
void	outhist(Biobuf*);
159
 
160
void
161
outcode(void)
162
{
163
	struct { Sym *sym; short type; } h[NSYM];
164
	Prog *p;
165
	Sym *s;
166
	int f, sf, st, t, sym;
167
	Biobuf b;
168
 
169
	if(debug['S']) {
170
		for(p = firstp; p != P; p = p->link)
171
			if(p->as != ADATA && p->as != AGLOBL)
172
				pc--;
173
		for(p = firstp; p != P; p = p->link) {
174
			print("%P\n", p);
175
			if(p->as != ADATA && p->as != AGLOBL)
176
				pc++;
177
		}
178
	}
179
	f = open(outfile, OWRITE);
180
	if(f < 0) {
181
		diag(Z, "cannot open %s", outfile);
182
		return;
183
	}
184
	Binit(&b, f, OWRITE);
185
	Bseek(&b, 0L, 2);
186
	outhist(&b);
187
	for(sym=0; sym<NSYM; sym++) {
188
		h[sym].sym = S;
189
		h[sym].type = 0;
190
	}
191
	sym = 1;
192
	for(p = firstp; p != P; p = p->link) {
193
	jackpot:
194
		sf = 0;
195
		s = p->from.sym;
196
		while(s != S) {
197
			sf = s->sym;
198
			if(sf < 0 || sf >= NSYM)
199
				sf = 0;
200
			t = p->from.type;
201
			if(t == D_ADDR)
202
				t = p->from.index;
203
			if(h[sf].type == t)
204
			if(h[sf].sym == s)
205
				break;
206
			s->sym = sym;
207
			zname(&b, s, t);
208
			h[sym].sym = s;
209
			h[sym].type = t;
210
			sf = sym;
211
			sym++;
212
			if(sym >= NSYM)
213
				sym = 1;
214
			break;
215
		}
216
		st = 0;
217
		s = p->to.sym;
218
		while(s != S) {
219
			st = s->sym;
220
			if(st < 0 || st >= NSYM)
221
				st = 0;
222
			t = p->to.type;
223
			if(t == D_ADDR)
224
				t = p->to.index;
225
			if(h[st].type == t)
226
			if(h[st].sym == s)
227
				break;
228
			s->sym = sym;
229
			zname(&b, s, t);
230
			h[sym].sym = s;
231
			h[sym].type = t;
232
			st = sym;
233
			sym++;
234
			if(sym >= NSYM)
235
				sym = 1;
236
			if(st == sf)
237
				goto jackpot;
238
			break;
239
		}
240
		Bputc(&b, p->as);
241
		Bputc(&b, p->as>>8);
242
		Bputc(&b, p->lineno);
243
		Bputc(&b, p->lineno>>8);
244
		Bputc(&b, p->lineno>>16);
245
		Bputc(&b, p->lineno>>24);
246
		zaddr(&b, &p->from, sf);
247
		zaddr(&b, &p->to, st);
248
	}
249
	Bflush(&b);
250
	close(f);
251
	firstp = P;
252
	lastp = P;
253
}
254
 
255
void
256
outhist(Biobuf *b)
257
{
258
	Hist *h;
259
	char *p, *q, *op, c;
260
	Prog pg;
261
	int n;
262
 
263
	pg = zprog;
264
	pg.as = AHISTORY;
265
	c = pathchar();
266
	for(h = hist; h != H; h = h->link) {
267
		p = h->name;
268
		op = 0;
269
		/* on windows skip drive specifier in pathname */
270
		if(systemtype(Windows) && p && p[1] == ':'){
271
			p += 2;
272
			c = *p;
273
		}
274
		if(p && p[0] != c && h->offset == 0 && pathname){
275
			/* on windows skip drive specifier in pathname */
276
			if(systemtype(Windows) && pathname[1] == ':') {
277
				op = p;
278
				p = pathname+2;
279
				c = *p;
280
			} else if(pathname[0] == c){
281
				op = p;
282
				p = pathname;
283
			}
284
		}
285
		while(p) {
286
			q = utfrune(p, c);
287
			if(q) {
288
				n = q-p;
289
				if(n == 0){
290
					n = 1;	/* leading "/" */
291
					*p = '/';	/* don't emit "\" on windows */
292
				}
293
				q++;
294
			} else {
295
				n = strlen(p);
296
				q = 0;
297
			}
298
			if(n) {
299
				Bputc(b, ANAME);
300
				Bputc(b, ANAME>>8);
301
				Bputc(b, D_FILE);
302
				Bputc(b, 1);
303
				Bputc(b, '<');
304
				Bwrite(b, p, n);
305
				Bputc(b, 0);
306
			}
307
			p = q;
308
			if(p == 0 && op) {
309
				p = op;
310
				op = 0;
311
			}
312
		}
313
		pg.lineno = h->line;
314
		pg.to.type = zprog.to.type;
315
		pg.to.offset = h->offset;
316
		if(h->offset)
317
			pg.to.type = D_CONST;
318
 
319
		Bputc(b, pg.as);
320
		Bputc(b, pg.as>>8);
321
		Bputc(b, pg.lineno);
322
		Bputc(b, pg.lineno>>8);
323
		Bputc(b, pg.lineno>>16);
324
		Bputc(b, pg.lineno>>24);
325
		zaddr(b, &pg.from, 0);
326
		zaddr(b, &pg.to, 0);
327
	}
328
}
329
 
330
void
331
zname(Biobuf *b, Sym *s, int t)
332
{
333
	char *n;
334
	ulong sig;
335
 
336
	if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){
337
		sig = sign(s);
338
		Bputc(b, ASIGNAME);
339
		Bputc(b, ASIGNAME>>8);
340
		Bputc(b, sig);
341
		Bputc(b, sig>>8);
342
		Bputc(b, sig>>16);
343
		Bputc(b, sig>>24);
344
		s->sig = SIGDONE;
345
	}
346
	else{
347
		Bputc(b, ANAME);	/* as */
348
		Bputc(b, ANAME>>8);	/* as */
349
	}
350
	Bputc(b, t);			/* type */
351
	Bputc(b, s->sym);		/* sym */
352
	n = s->name;
353
	while(*n) {
354
		Bputc(b, *n);
355
		n++;
356
	}
357
	Bputc(b, 0);
358
}
359
 
360
void
361
zaddr(Biobuf *b, Adr *a, int s)
362
{
363
	long l;
364
	int i, t;
365
	char *n;
366
	Ieee e;
367
 
368
	t = 0;
369
	if(a->index != D_NONE || a->scale != 0)
370
		t |= T_INDEX;
371
	if(s != 0)
372
		t |= T_SYM;
373
 
374
	switch(a->type) {
375
	default:
376
		t |= T_TYPE;
377
	case D_NONE:
378
		if(a->offset != 0) {
379
			t |= T_OFFSET;
380
			l = a->offset;
381
			if((vlong)l != a->offset)
382
				t |= T_64;
383
		}
384
		break;
385
	case D_FCONST:
386
		t |= T_FCONST;
387
		break;
388
	case D_SCONST:
389
		t |= T_SCONST;
390
		break;
391
	}
392
	Bputc(b, t);
393
 
394
	if(t & T_INDEX) {	/* implies index, scale */
395
		Bputc(b, a->index);
396
		Bputc(b, a->scale);
397
	}
398
	if(t & T_OFFSET) {	/* implies offset */
399
		l = a->offset;
400
		Bputc(b, l);
401
		Bputc(b, l>>8);
402
		Bputc(b, l>>16);
403
		Bputc(b, l>>24);
404
		if(t & T_64) {
405
			l = a->offset>>32;
406
			Bputc(b, l);
407
			Bputc(b, l>>8);
408
			Bputc(b, l>>16);
409
			Bputc(b, l>>24);
410
		}
411
	}
412
	if(t & T_SYM)		/* implies sym */
413
		Bputc(b, s);
414
	if(t & T_FCONST) {
415
		ieeedtod(&e, a->dval);
416
		l = e.l;
417
		Bputc(b, l);
418
		Bputc(b, l>>8);
419
		Bputc(b, l>>16);
420
		Bputc(b, l>>24);
421
		l = e.h;
422
		Bputc(b, l);
423
		Bputc(b, l>>8);
424
		Bputc(b, l>>16);
425
		Bputc(b, l>>24);
426
		return;
427
	}
428
	if(t & T_SCONST) {
429
		n = a->sval;
430
		for(i=0; i<NSNAME; i++) {
431
			Bputc(b, *n);
432
			n++;
433
		}
434
		return;
435
	}
436
	if(t & T_TYPE)
437
		Bputc(b, a->type);
438
}
439
 
440
long
441
align(long i, Type *t, int op)
442
{
443
	long o;
444
	Type *v;
445
	int w;
446
 
447
	o = i;
448
	w = 1;
449
	switch(op) {
450
	default:
451
		diag(Z, "unknown align opcode %d", op);
452
		break;
453
 
454
	case Asu2:	/* padding at end of a struct */
455
		w = SZ_VLONG;
456
		if(packflg)
457
			w = packflg;
458
		break;
459
 
460
	case Ael1:	/* initial align of struct element */
461
		for(v=t; v->etype==TARRAY; v=v->link)
462
			;
463
		w = ewidth[v->etype];
464
		if(w <= 0 || w >= SZ_VLONG)
465
			w = SZ_VLONG;
466
		if(packflg)
467
			w = packflg;
468
		break;
469
 
470
	case Ael2:	/* width of a struct element */
471
		o += t->width;
472
		break;
473
 
474
	case Aarg0:	/* initial passbyptr argument in arg list */
475
		if(typesu[t->etype]) {
476
			o = align(o, types[TIND], Aarg1);
477
			o = align(o, types[TIND], Aarg2);
478
		}
479
		break;
480
 
481
	case Aarg1:	/* initial align of parameter */
482
		w = ewidth[t->etype];
483
		if(w <= 0 || w >= SZ_VLONG) {
484
			w = SZ_VLONG;
485
			break;
486
		}
487
		w = 1;		/* little endian no adjustment */
488
		break;
489
 
490
	case Aarg2:	/* width of a parameter */
491
		o += t->width;
492
		w = SZ_VLONG;
493
		break;
494
 
495
	case Aaut3:	/* total allign of automatic */
496
		o = align(o, t, Ael1);
497
		o = align(o, t, Ael2);
498
		break;
499
	}
500
	o = round(o, w);
501
	if(debug['A'])
502
		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);
503
	return o;
504
}
505
 
506
long
507
maxround(long max, long v)
508
{
509
	v = round(v, SZ_VLONG);
510
	if(v > max)
511
		return v;
512
	return max;
513
}