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

📄 swt.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "gc.h"intswcmp(const void *a1, const void *a2){	C1 *p1, *p2;	p1 = (C1*)a1;	p2 = (C1*)a2;	if(p1->val < p2->val)		return -1;	return p1->val > p2->val;}voiddoswit(int g, Node *n){	Case *c;	C1 *q, *iq;	long def, nc, i;	def = 0;	nc = 0;	for(c = cases; c->link != C; c = c->link) {		if(c->def) {			if(def)				diag(n, "more than one default in switch");			def = c->label;			continue;		}		nc++;	}	iq = alloc(nc*sizeof(C1));	q = iq;	for(c = cases; c->link != C; c = c->link) {		if(c->def)			continue;		q->label = c->label;		q->val = c->val;		q++;	}	qsort(iq, nc, sizeof(C1), swcmp);	if(def == 0)		def = breakpc;	for(i=0; i<nc-1; i++)		if(iq[i].val == iq[i+1].val)			diag(n, "duplicate cases in switch %ld", iq[i].val);	swit1(iq, nc, def, g, n);}#define	N1	4	/* ncase: always linear */			/* else binary */voidswit1(C1 *q, int nc, long def, int g, Node *n){	C1 *r;	int i;	long v;	Prog *sp1, *sp2;	/* note that g and g+1 are not allocated */	if(nc <= N1)		goto linear;	/*	 * divide and conquer	 */	i = nc / 2;	r = q+i;	v = r->val;	/* compare median */	if(v >= -128 && v < 128) {		gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);		gopcode(OEQ, n->type, g, n, g+1, n);	} else		gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));	gbranch(OLT);	sp1 = p;	gbranch(OGT);	sp2 = p;	gbranch(OGOTO);	patch(p, r->label);	patch(sp1, pc);	swit1(q, i, def, g, n);	patch(sp2, pc);	swit1(r+1, nc-i-1, def, g, n);	return;linear:	for(i=0; i<nc; i++) {		v = q->val;		if(v >= -128 && v < 128) {			gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n);			gopcode(OEQ, n->type, g+1, n, g, n);		} else			gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v));		gbranch(OEQ);		patch(p, q->label);		q++;	}	gbranch(OGOTO);	patch(p, def);}voidcas(void){	Case *c;	c = alloc(sizeof(*c));	c->link = cases;	cases = c;}intbitload(Node *b, int n1, int n2, int n3, Node *nn){	int sh, g, gs;	long v;	Node *l;	Type *t;	/*	 * n1 gets adjusted/masked value	 * n2 gets address of cell	 * n3 gets contents of cell	 */	gs = 0;	t = tfield;	l = b->left;	g = regalloc(t, n3);	if(n2 != D_NONE) {		lcgen(l, n2, Z);		n2 |= I_INDIR;		gmove(t, t, n2, l, g, l);		gmove(t, t, g, l, n1, l);	} else		cgen(l, g, nn);	if(b->type->shift == 0 && typeu[b->type->etype]) {		v = ~0 + (1L << b->type->nbits);		gopcode(OAND, t, D_CONST, nodconst(v), g, l);	} else {		sh = 32 - b->type->shift - b->type->nbits;		if(sh > 0)			if(sh >= 8) {				gs = regalloc(t, D_NONE);				gmove(t, t, D_CONST, nodconst(sh), gs, l);				gopcode(OASHL, t, gs, l, g, l);				if(b->type->shift)					regfree(gs);			} else				gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);		sh += b->type->shift;		if(sh > 0) {			if(sh >= 8) {				if(b->type->shift) {					gs = regalloc(t, D_NONE);					gmove(t, t, D_CONST, nodconst(sh), gs, l);				}				if(typeu[b->type->etype])					gopcode(OLSHR, t, gs, l, g, l);				else					gopcode(OASHR, t, gs, l, g, l);				regfree(gs);			} else {				if(typeu[b->type->etype])					gopcode(OLSHR, t, D_CONST, nodconst(sh), g, l);				else					gopcode(OASHR, t, D_CONST, nodconst(sh), g, l);			}		}	}	return g;}voidbitstore(Node *b, int n1, int n2, int n3, int result, Node *nn){	long v;	Node *l;	Type *t;	int sh, g, gs;	/*	 * n1 has adjusted/masked value	 * n2 has address of cell	 * n3 has contents of cell	 */	t = tfield;	l = b->left;	g = regalloc(t, D_NONE);	v = ~0 + (1L << b->type->nbits);	gopcode(OAND, t, D_CONST, nodconst(v), n1, l);	gmove(t, t, n1, l, g, l);	if(result != D_NONE)		gmove(t, nn->type, n1, l, result, nn);	sh = b->type->shift;	if(sh > 0) {		if(sh >= 8) {			gs = regalloc(t, D_NONE);			gmove(t, t, D_CONST, nodconst(sh), gs, l);			gopcode(OASHL, t, gs, l, g, l);			regfree(gs);		} else			gopcode(OASHL, t, D_CONST, nodconst(sh), g, l);	}	v <<= sh;	gopcode(OAND, t, D_CONST, nodconst(~v), n3, l);	gopcode(OOR, t, n3, l, g, l);	gmove(t, t, g, l, n2|I_INDIR, l);	regfree(g);	regfree(n1);	regfree(n2);	regfree(n3);}longoutstring(char *s, long n){	long r;	r = nstring;	while(n) {		string[mnstring] = *s++;		mnstring++;		nstring++;		if(mnstring >= NSNAME) {			gpseudo(ADATA, symstring, D_SCONST, 0L);			memmove(p->to.sval, string, NSNAME);			p->from.offset = nstring - NSNAME;			p->from.displace = NSNAME;			mnstring = 0;		}		n--;	}	return r;}longoutlstring(ushort *s, long n){	char buf[2];	int c;	long r;	while(nstring & 1)		outstring("", 1);	r = nstring;	while(n > 0) {		c = *s++;		if(align(0, types[TCHAR], Aarg1)) {			buf[0] = c>>8;			buf[1] = c;		} else {			buf[0] = c;			buf[1] = c>>8;		}		outstring(buf, 2);		n -= sizeof(ushort);	}	return r;}intdoinc(Node *n, int f){	Node *l;	int a;loop:	if(n == Z)		return 0;	l = n->left;	switch(n->op) {	case OPOSTINC:	case OPOSTDEC:		if(f & POST) {			a = n->addable;			if(a >= INDEXED) {				if(f & TEST)					return 1;				n->addable = 0;				cgen(n, D_NONE, n);				n->addable = a;			}		}		break;	case OAS:	case OASLMUL:	case OASLDIV:	case OASLMOD:	case OASMUL:	case OASDIV:	case OASMOD:	case OASXOR:	case OASOR:	case OASADD:	case OASSUB:	case OASLSHR:	case OASASHR:	case OASASHL:	case OASAND:	case OPREINC:	case OPREDEC:		if(f & PRE) {			a = n->addable;			if(a >= INDEXED) {				if(f & TEST)					return 1;				n->addable = 0;				doinc(n, PRE);				cgen(n, D_NONE, n);				n->addable = a;				return 0;			}		}		break;	case OFUNC:		if(f & PRE)			break;		return 0;	case ONAME:	case OREGISTER:	case OSTRING:	case OCONST:	case OANDAND:	case OOROR:		return 0;	case OCOND:		return 0;	case OCOMMA:		n = n->right;		if(f & PRE)			n = l;		goto loop;	}	if(l != Z)		if(doinc(l, f))			return 1;	n = n->right;	goto loop;}voidsetsp(void){	nextpc();	p->as = AADJSP;	p->from.type = D_CONST;	p->from.offset = 0;}voidadjsp(long o){	if(o != 0) {		nextpc();		p->as = AADJSP;		p->from.type = D_CONST;		p->from.offset = o;		argoff += o;	}}intsimplv(Node *n){	if(n->addable <= INDEXED)		return 0;	while(n->op == OIND)		n = n->left;	if(n->op == ONAME)		return 1;	return 0;}inteval(Node *n, int g){	if(n->addable >= INDEXED)		return D_TREE;	g = regalloc(n->type, g);	cgen(n, g, n);	return g;}void	outhist(Biobuf*);void	zname(Biobuf*, Sym*, int);void	zaddr(Biobuf*, Adr*, int);void	zwrite(Biobuf*, Prog*, int, int);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, "cant open %s", outfile);		errorexit();	}	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 & D_MASK;			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 & D_MASK;			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)

⌨️ 快捷键说明

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