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