Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_unix/sys/src/cmd/qc/swt.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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