⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swt.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include "gc.h"voidswit1(C1 *q, int nc, long def, Node *n){	C1 *r;	int i;	Prog *sp;	if(nc < 5) {		for(i=0; i<nc; i++) {			if(debug['W'])				print("case = %.8lux\n", q->val);			gopcode(OEQ, n->type, n, nodconst(q->val));			patch(p, q->label);			q++;		}		gbranch(OGOTO);		patch(p, def);		return;	}	i = nc / 2;	r = q+i;	if(debug['W'])		print("case > %.8lux\n", r->val);	gopcode(OGT, n->type, n, nodconst(r->val));	sp = p;	gbranch(OGOTO);	p->as = AJEQ;	patch(p, r->label);	swit1(q, i, def, n);	if(debug['W'])		print("case < %.8lux\n", r->val);	patch(sp, pc);	swit1(r+1, nc-i-1, def, n);}voidbitload(Node *b, Node *n1, Node *n2, Node *n3, Node *nn){	int sh;	long v;	Node *l;	/*	 * n1 gets adjusted/masked value	 * n2 gets address of cell	 * n3 gets contents of cell	 */	l = b->left;	if(n2 != Z) {		regalloc(n1, l, nn);		reglcgen(n2, l, Z);		regalloc(n3, l, Z);		gmove(n2, n3);		gmove(n3, n1);	} else {		regalloc(n1, l, nn);		cgen(l, n1);	}	if(b->type->shift == 0 && typeu[b->type->etype]) {		v = ~0 + (1L << b->type->nbits);		gopcode(OAND, types[TLONG], nodconst(v), n1);	} else {		sh = 32 - b->type->shift - b->type->nbits;		if(sh > 0)			gopcode(OASHL, types[TLONG], nodconst(sh), n1);		sh += b->type->shift;		if(sh > 0)			if(typeu[b->type->etype])				gopcode(OLSHR, types[TLONG], nodconst(sh), n1);			else				gopcode(OASHR, types[TLONG], nodconst(sh), n1);	}}voidbitstore(Node *b, Node *n1, Node *n2, Node *n3, Node *nn){	long v;	Node nod;	int sh;	regalloc(&nod, b->left, Z);	v = ~0 + (1L << b->type->nbits);	gopcode(OAND, types[TLONG], nodconst(v), n1);	gmove(n1, &nod);	if(nn != Z)		gmove(n1, nn);	sh = b->type->shift;	if(sh > 0)		gopcode(OASHL, types[TLONG], nodconst(sh), &nod);	v <<= sh;	gopcode(OAND, types[TLONG], nodconst(~v), n3);	gopcode(OOR, types[TLONG], n3, &nod);	gmove(&nod, n2);	regfree(&nod);	regfree(n1);	regfree(n2);	regfree(n3);}longoutstring(char *s, long n){	long r;	if(suppress)		return nstring;	r = nstring;	while(n) {		string[mnstring] = *s++;		mnstring++;		nstring++;		if(mnstring >= NSNAME) {			gpseudo(ADATA, symstring, nodconst(0L));			p->from.offset += nstring - NSNAME;			p->from.scale = NSNAME;			p->to.type = D_SCONST;			memmove(p->to.sval, string, NSNAME);			mnstring = 0;		}		n--;	}	return r;}voidsextern(Sym *s, Node *a, long o, long w){	long e, lw;	for(e=0; e<w; e+=NSNAME) {		lw = NSNAME;		if(w-e < lw)			lw = w-e;		gpseudo(ADATA, s, nodconst(0L));		p->from.offset += o+e;		p->from.scale = lw;		p->to.type = D_SCONST;		memmove(p->to.sval, a->cstring+e, lw);	}}voidgextern(Sym *s, Node *a, long o, long w){	if(a->op == OCONST && typev[a->type->etype]) {		gpseudo(ADATA, s, lo64(a));		p->from.offset += o;		p->from.scale = 4;		gpseudo(ADATA, s, hi64(a));		p->from.offset += o + 4;		p->from.scale = 4;		return;	}	gpseudo(ADATA, s, a);	p->from.offset += o;	p->from.scale = w;	switch(p->to.type) {	default:		p->to.index = p->to.type;		p->to.type = D_ADDR;	case D_CONST:	case D_FCONST:	case D_ADDR:		break;	}}void	zname(Biobuf*, Sym*, int);void	zaddr(Biobuf*, Adr*, int);void	outhist(Biobuf*);voidoutcode(void){	struct { Sym *sym; short type; } h[NSYM];	Prog *p;	Sym *s;	int f, sf, st, t, sym;	Biobuf b;	if(debug['S']) {		for(p = firstp; p != P; p = p->link)			if(p->as != ADATA && p->as != AGLOBL)				pc--;		for(p = firstp; p != P; p = p->link) {			print("%P\n", p);			if(p->as != ADATA && p->as != AGLOBL)				pc++;		}	}	f = open(outfile, OWRITE);	if(f < 0) {		diag(Z, "cannot open %s", outfile);		return;	}	Binit(&b, f, OWRITE);	Bseek(&b, 0L, 2);	outhist(&b);	for(sym=0; sym<NSYM; sym++) {		h[sym].sym = S;		h[sym].type = 0;	}	sym = 1;	for(p = firstp; p != P; p = p->link) {	jackpot:		sf = 0;		s = p->from.sym;		while(s != S) {			sf = s->sym;			if(sf < 0 || sf >= NSYM)				sf = 0;			t = p->from.type;			if(t == D_ADDR)				t = p->from.index;			if(h[sf].type == t)			if(h[sf].sym == s)				break;			s->sym = sym;			zname(&b, s, t);			h[sym].sym = s;			h[sym].type = t;			sf = sym;			sym++;			if(sym >= NSYM)				sym = 1;			break;		}		st = 0;		s = p->to.sym;		while(s != S) {			st = s->sym;			if(st < 0 || st >= NSYM)				st = 0;			t = p->to.type;			if(t == D_ADDR)				t = p->to.index;			if(h[st].type == t)			if(h[st].sym == s)				break;			s->sym = sym;			zname(&b, s, t);			h[sym].sym = s;			h[sym].type = t;			st = sym;			sym++;			if(sym >= NSYM)				sym = 1;			if(st == sf)				goto jackpot;			break;		}		Bputc(&b, p->as);		Bputc(&b, p->as>>8);		Bputc(&b, p->lineno);		Bputc(&b, p->lineno>>8);		Bputc(&b, p->lineno>>16);		Bputc(&b, p->lineno>>24);		zaddr(&b, &p->from, sf);		zaddr(&b, &p->to, st);	}	Bflush(&b);	close(f);	firstp = P;	lastp = P;}voidouthist(Biobuf *b){	Hist *h;	char *p, *q, *op, c;	Prog pg;	int n;	pg = zprog;	pg.as = AHISTORY;	c = pathchar();	for(h = hist; h != H; h = h->link) {		p = h->name;		op = 0;		/* on windows skip drive specifier in pathname */		if(systemtype(Windows) && p && p[1] == ':'){			p += 2;			c = *p;		}		if(p && p[0] != c && h->offset == 0 && pathname){			/* on windows skip drive specifier in pathname */			if(systemtype(Windows) && pathname[1] == ':') {				op = p;				p = pathname+2;				c = *p;			} else if(pathname[0] == c){				op = p;				p = pathname;			}		}		while(p) {			q = utfrune(p, c);			if(q) {				n = q-p;				if(n == 0){					n = 1;	/* leading "/" */					*p = '/';	/* don't emit "\" on windows */				}				q++;			} else {				n = strlen(p);				q = 0;			}			if(n) {				Bputc(b, ANAME);				Bputc(b, ANAME>>8);				Bputc(b, D_FILE);				Bputc(b, 1);				Bputc(b, '<');				Bwrite(b, p, n);				Bputc(b, 0);			}			p = q;			if(p == 0 && op) {				p = op;				op = 0;			}		}		pg.lineno = h->line;		pg.to.type = zprog.to.type;		pg.to.offset = h->offset;		if(h->offset)			pg.to.type = D_CONST;		Bputc(b, pg.as);		Bputc(b, pg.as>>8);		Bputc(b, pg.lineno);		Bputc(b, pg.lineno>>8);		Bputc(b, pg.lineno>>16);		Bputc(b, pg.lineno>>24);		zaddr(b, &pg.from, 0);		zaddr(b, &pg.to, 0);	}}voidzname(Biobuf *b, Sym *s, int t){	char *n;	ulong sig;	if(debug['T'] && t == D_EXTERN && s->sig != SIGDONE && s->type != types[TENUM] && s != symrathole){		sig = sign(s);		Bputc(b, ASIGNAME);		Bputc(b, ASIGNAME>>8);		Bputc(b, sig);		Bputc(b, sig>>8);		Bputc(b, sig>>16);		Bputc(b, sig>>24);		s->sig = SIGDONE;	}	else{		Bputc(b, ANAME);	/* as */		Bputc(b, ANAME>>8);	/* as */	}	Bputc(b, t);			/* type */	Bputc(b, s->sym);		/* sym */	n = s->name;	while(*n) {		Bputc(b, *n);		n++;	}	Bputc(b, 0);}voidzaddr(Biobuf *b, Adr *a, int s){	long l;	int i, t;	char *n;	Ieee e;	t = 0;	if(a->index != D_NONE || a->scale != 0)		t |= T_INDEX;	if(s != 0)		t |= T_SYM;	switch(a->type) {	default:		t |= T_TYPE;	case D_NONE:		if(a->offset != 0)			t |= T_OFFSET;		break;	case D_FCONST:		t |= T_FCONST;		break;	case D_SCONST:		t |= T_SCONST;		break;	}	Bputc(b, t);	if(t & T_INDEX) {	/* implies index, scale */		Bputc(b, a->index);		Bputc(b, a->scale);	}	if(t & T_OFFSET) {	/* implies offset */		l = a->offset;		Bputc(b, l);		Bputc(b, l>>8);		Bputc(b, l>>16);		Bputc(b, l>>24);	}	if(t & T_SYM)		/* implies sym */		Bputc(b, s);	if(t & T_FCONST) {		ieeedtod(&e, a->dval);		l = e.l;		Bputc(b, l);		Bputc(b, l>>8);		Bputc(b, l>>16);		Bputc(b, l>>24);		l = e.h;		Bputc(b, l);		Bputc(b, l>>8);		Bputc(b, l>>16);		Bputc(b, l>>24);		return;	}	if(t & T_SCONST) {		n = a->sval;		for(i=0; i<NSNAME; i++) {			Bputc(b, *n);			n++;		}		return;	}	if(t & T_TYPE)		Bputc(b, a->type);}longalign(long i, Type *t, int op){	long o;	Type *v;	int w;	o = i;	w = 1;	switch(op) {	default:		diag(Z, "unknown align opcode %d", op);		break;	case Asu2:	/* padding at end of a struct */		w = SZ_LONG;		if(packflg)			w = packflg;		break;	case Ael1:	/* initial allign of struct element */		for(v=t; v->etype==TARRAY; v=v->link)			;		w = ewidth[v->etype];		if(w <= 0 || w >= SZ_LONG)			w = SZ_LONG;		if(packflg)			w = packflg;		break;	case Ael2:	/* width of a struct element */		o += t->width;		break;	case Aarg0:	/* initial passbyptr argument in arg list */		if(typesuv[t->etype]) {			o = align(o, types[TIND], Aarg1);			o = align(o, types[TIND], Aarg2);		}		break;	case Aarg1:	/* initial allign of parameter */		w = ewidth[t->etype];		if(w <= 0 || w >= SZ_LONG) {			w = SZ_LONG;			break;		}		w = 1;		/* little endian no adjustment */		break;	case Aarg2:	/* width of a parameter */		o += t->width;		w = SZ_LONG;		break;	case Aaut3:	/* total allign of automatic */		o = align(o, t, Ael1);		o = align(o, t, Ael2);		break;	}	o = round(o, w);	if(debug['A'])		print("align %s %ld %T = %ld\n", bnames[op], i, t, o);	return o;}longmaxround(long max, long v){	v += SZ_LONG-1;	if(v > max)		max = round(v, SZ_LONG);	return max;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -