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

📄 span.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"l.h"voidspan(void){	Prog *p, *q;	long v, c, idat;	int m, n, again;	xdefine("etext", STEXT, 0L);	idat = INITDAT;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT)			curtext = p;		n = 0;		if(p->to.type == D_BRANCH)			if(p->pcond == P)				p->pcond = p;		if((q = p->pcond) != P)			if(q->back != 2)				n = 1;		p->back = n;		if(p->as == AADJSP) {			p->to.type = D_SP;			v = -p->from.offset;			p->from.offset = v;			p->as = AADDL;			if(v < 0) {				p->as = ASUBL;				v = -v;				p->from.offset = v;			}			if(v == 0)				p->as = ANOP;		}	}	n = 0;start:	if(debug['v'])		Bprint(&bso, "%5.2f span\n", cputime());	Bflush(&bso);	c = INITTEXT;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT)			curtext = p;		if(p->to.type == D_BRANCH)			if(p->back)				p->pc = c;		asmins(p);		p->pc = c;		m = andptr-and;		p->mark = m;		c += m;	}loop:	n++;	if(debug['v'])		Bprint(&bso, "%5.2f span %d\n", cputime(), n);	Bflush(&bso);	if(n > 50) {		print("span must be looping\n");		errorexit();	}	again = 0;	c = INITTEXT;	for(p = firstp; p != P; p = p->link) {		if(p->as == ATEXT)			curtext = p;		if(p->to.type == D_BRANCH) {			if(p->back)				p->pc = c;			asmins(p);			m = andptr-and;			if(m != p->mark) {				p->mark = m;				again++;			}		}		p->pc = c;		c += p->mark;	}	if(again) {		textsize = c;		goto loop;	}	if(INITRND) {		INITDAT = rnd(c, INITRND);		if(INITDAT != idat) {			idat = INITDAT;			goto start;		}	}	xdefine("etext", STEXT, c);	if(debug['v'])		Bprint(&bso, "etext = %lux\n", c);	Bflush(&bso);	for(p = textp; p != P; p = p->pcond)		p->from.sym->value = p->pc;	textsize = c - INITTEXT;}voidxdefine(char *p, int t, long v){	Sym *s;	s = lookup(p, 0);	if(s->type == 0 || s->type == SXREF) {		s->type = t;		s->value = v;	}	if(s->type == STEXT && s->value == 0)		s->value = v;}voidputsymb(char *s, int t, long v, int ver){	int i, f;	if(t == 'f')		s++;	lput(v);	if(ver)		t += 'a' - 'A';	cput(t+0x80);			/* 0x80 is variable length */	if(t == 'Z' || t == 'z') {		cput(s[0]);		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {			cput(s[i]);			cput(s[i+1]);		}		cput(0);		cput(0);		i++;	}	else {		for(i=0; s[i]; i++)			cput(s[i]);		cput(0);	}	symsize += 4 + 1 + i + 1;	if(debug['n']) {		if(t == 'z' || t == 'Z') {			Bprint(&bso, "%c %.8lux ", t, v);			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);				Bprint(&bso, "/%x", f);			}			Bprint(&bso, "\n");			return;		}		if(ver)			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);		else			Bprint(&bso, "%c %.8lux %s\n", t, v, s);	}}voidasmsym(void){	Prog *p;	Auto *a;	Sym *s;	int h;	s = lookup("etext", 0);	if(s->type == STEXT)		putsymb(s->name, 'T', s->value, s->version);	for(h=0; h<NHASH; h++)		for(s=hash[h]; s!=S; s=s->link)			switch(s->type) {			case SCONST:				putsymb(s->name, 'D', s->value, s->version);				continue;			case SDATA:				putsymb(s->name, 'D', s->value+INITDAT, s->version);				continue;			case SBSS:				putsymb(s->name, 'B', s->value+INITDAT, s->version);				continue;			case SFILE:				putsymb(s->name, 'f', s->value, s->version);				continue;			}	for(p=textp; p!=P; p=p->pcond) {		s = p->from.sym;		if(s->type != STEXT)			continue;		/* filenames first */		for(a=p->to.autom; a; a=a->link)			if(a->type == D_FILE)				putsymb(a->asym->name, 'z', a->aoffset, 0);			else			if(a->type == D_FILE1)				putsymb(a->asym->name, 'Z', a->aoffset, 0);		putsymb(s->name, 'T', s->value, s->version);		/* frame, auto and param after */		putsymb(".frame", 'm', p->to.offset+4, 0);		for(a=p->to.autom; a; a=a->link)			if(a->type == D_AUTO)				putsymb(a->asym->name, 'a', -a->aoffset, 0);			else			if(a->type == D_PARAM)				putsymb(a->asym->name, 'p', a->aoffset, 0);	}	if(debug['v'] || debug['n'])		Bprint(&bso, "symsize = %lud\n", symsize);	Bflush(&bso);}voidasmlc(void){	long oldpc, oldlc;	Prog *p;	long v, s;	oldpc = INITTEXT;	oldlc = 0;	for(p = firstp; p != P; p = p->link) {		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {			if(p->as == ATEXT)				curtext = p;			if(debug['L'])				Bprint(&bso, "%6lux %P\n",					p->pc, p);			continue;		}		if(debug['L'])			Bprint(&bso, "\t\t%6ld", lcsize);		v = (p->pc - oldpc) / MINLC;		while(v) {			s = 127;			if(v < 127)				s = v;			cput(s+128);	/* 129-255 +pc */			if(debug['L'])				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);			v -= s;			lcsize++;		}		s = p->line - oldlc;		oldlc = p->line;		oldpc = p->pc + MINLC;		if(s > 64 || s < -64) {			cput(0);	/* 0 vv +lc */			cput(s>>24);			cput(s>>16);			cput(s>>8);			cput(s);			if(debug['L']) {				if(s > 0)					Bprint(&bso, " lc+%ld(%d,%ld)\n",						s, 0, s);				else					Bprint(&bso, " lc%ld(%d,%ld)\n",						s, 0, s);				Bprint(&bso, "%6lux %P\n",					p->pc, p);			}			lcsize += 5;			continue;		}		if(s > 0) {			cput(0+s);	/* 1-64 +lc */			if(debug['L']) {				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);				Bprint(&bso, "%6lux %P\n",					p->pc, p);			}		} else {			cput(64-s);	/* 65-128 -lc */			if(debug['L']) {				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);				Bprint(&bso, "%6lux %P\n",					p->pc, p);			}		}		lcsize++;	}	while(lcsize & 1) {		s = 129;		cput(s);		lcsize++;	}	if(debug['v'] || debug['L'])		Bprint(&bso, "lcsize = %ld\n", lcsize);	Bflush(&bso);}intoclass(Adr *a){	long v;	if(a->type >= D_INDIR || a->index != D_NONE) {		if(a->index != D_NONE && a->scale == 0) {			if(a->type == D_ADDR) {				switch(a->index) {				case D_EXTERN:				case D_STATIC:					return Yi32;				case D_AUTO:				case D_PARAM:					return Yiauto;				}				return Yxxx;			}			return Ycol;		}		return Ym;	}	switch(a->type)	{	case D_AL:		return Yal;	case D_AX:		return Yax;	case D_CL:	case D_DL:	case D_BL:	case D_AH:	case D_CH:	case D_DH:	case D_BH:		return Yrb;	case D_CX:		return Ycx;	case D_DX:	case D_BX:		return Yrx;	case D_SP:	case D_BP:	case D_SI:	case D_DI:		return Yrl;	case D_F0+0:		return	Yf0;	case D_F0+1:	case D_F0+2:	case D_F0+3:	case D_F0+4:	case D_F0+5:	case D_F0+6:	case D_F0+7:		return	Yrf;	case D_NONE:		return Ynone;	case D_CS:	return	Ycs;	case D_SS:	return	Yss;	case D_DS:	return	Yds;	case D_ES:	return	Yes;	case D_FS:	return	Yfs;	case D_GS:	return	Ygs;	case D_GDTR:	return	Ygdtr;	case D_IDTR:	return	Yidtr;	case D_LDTR:	return	Yldtr;	case D_MSW:	return	Ymsw;	case D_TASK:	return	Ytask;	case D_CR+0:	return	Ycr0;	case D_CR+1:	return	Ycr1;	case D_CR+2:	return	Ycr2;	case D_CR+3:	return	Ycr3;	case D_CR+4:	return	Ycr4;	case D_CR+5:	return	Ycr5;	case D_CR+6:	return	Ycr6;	case D_CR+7:	return	Ycr7;	case D_DR+0:	return	Ydr0;	case D_DR+1:	return	Ydr1;	case D_DR+2:	return	Ydr2;	case D_DR+3:	return	Ydr3;	case D_DR+4:	return	Ydr4;	case D_DR+5:	return	Ydr5;	case D_DR+6:	return	Ydr6;	case D_DR+7:	return	Ydr7;	case D_TR+0:	return	Ytr0;	case D_TR+1:	return	Ytr1;	case D_TR+2:	return	Ytr2;	case D_TR+3:	return	Ytr3;	case D_TR+4:	return	Ytr4;	case D_TR+5:	return	Ytr5;	case D_TR+6:	return	Ytr6;	case D_TR+7:	return	Ytr7;	case D_EXTERN:	case D_STATIC:	case D_AUTO:	case D_PARAM:		return Ym;	case D_CONST:	case D_ADDR:		if(a->sym == S) {			v = a->offset;			if(v == 0)				return Yi0;			if(v == 1)				return Yi1;			if(v >= -128 && v <= 127)				return Yi8;		}		return Yi32;	case D_BRANCH:		return Ybr;	}	return Yxxx;}voidasmidx(Adr *a, int base){	int i;	switch(a->index) {	default:		goto bad;	case D_NONE:		i = 4 << 3;		goto bas;	case D_AX:	case D_CX:	case D_DX:	case D_BX:	case D_BP:	case D_SI:	case D_DI:		i = reg[a->index] << 3;		break;	}	switch(a->scale) {	default:		goto bad;	case 1:		break;	case 2:		i |= (1<<6);		break;	case 4:		i |= (2<<6);		break;	case 8:		i |= (3<<6);		break;	}bas:	switch(base) {	default:		goto bad;	case D_NONE:	/* must be mod=00 */		i |= 5;		break;	case D_AX:	case D_CX:	case D_DX:	case D_BX:	case D_SP:	case D_BP:	case D_SI:	case D_DI:		i |= reg[base];		break;	}	*andptr++ = i;	return;bad:	diag("asmidx: bad address %D", a);	*andptr++ = 0;	return;}static voidput4(long v){	if(dlm && curp != P && reloca != nil){		dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1);		reloca = nil;	}	andptr[0] = v;	andptr[1] = v>>8;	andptr[2] = v>>16;	andptr[3] = v>>24;	andptr += 4;}longvaddr(Adr *a){	int t;	long v;	Sym *s;	t = a->type;	v = a->offset;	if(t == D_ADDR)		t = a->index;	switch(t) {	case D_STATIC:	case D_EXTERN:		s = a->sym;		if(s != nil) {			if(dlm && curp != P)				reloca = a;			switch(s->type) {			case SUNDEF:				ckoff(s, v);			case STEXT:			case SCONST:				v += s->value;				break;			default:				v += INITDAT + s->value;			}		}	}	return v;}voidasmand(Adr *a, int r){	long v;	int t;	Adr aa;	v = a->offset;	t = a->type;	if(a->index != D_NONE) {		if(t >= D_INDIR) {			t -= D_INDIR;			if(t == D_NONE) {				*andptr++ = (0 << 6) | (4 << 0) | (r << 3);				asmidx(a, t);				put4(v);				return;			}			if(v == 0 && t != D_BP) {				*andptr++ = (0 << 6) | (4 << 0) | (r << 3);				asmidx(a, t);				return;			}			if(v >= -128 && v < 128) {				*andptr++ = (1 << 6) | (4 << 0) | (r << 3);				asmidx(a, t);				*andptr++ = v;				return;			}			*andptr++ = (2 << 6) | (4 << 0) | (r << 3);			asmidx(a, t);			put4(v);			return;		}		switch(t) {		default:			goto bad;		case D_STATIC:		case D_EXTERN:			aa.type = D_NONE+D_INDIR;			break;		case D_AUTO:		case D_PARAM:			aa.type = D_SP+D_INDIR;			break;		}		aa.offset = vaddr(a);		aa.index = a->index;		aa.scale = a->scale;		asmand(&aa, r);		return;	}	if(t >= D_AL && t <= D_F0+7) {		if(v)			goto bad;		*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);		return;	}	if(t >= D_INDIR) {		t -= D_INDIR;		if(t == D_NONE) {			*andptr++ = (0 << 6) | (5 << 0) | (r << 3);			put4(v);			return;		}		if(t == D_SP) {			if(v == 0) {				*andptr++ = (0 << 6) | (4 << 0) | (r << 3);				asmidx(a, D_SP);				return;			}			if(v >= -128 && v < 128) {				*andptr++ = (1 << 6) | (4 << 0) | (r << 3);				asmidx(a, D_SP);				*andptr++ = v;				return;			}			*andptr++ = (2 << 6) | (4 << 0) | (r << 3);			asmidx(a, D_SP);			put4(v);			return;		}		if(t >= D_AX && t <= D_DI) {			if(v == 0 && t != D_BP) {				*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);				return;			}			if(v >= -128 && v < 128) {				andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);				andptr[1] = v;				andptr += 2;				return;			}			*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);			put4(v);			return;		}		goto bad;	}	switch(a->type) {	default:		goto bad;	case D_STATIC:	case D_EXTERN:		aa.type = D_NONE+D_INDIR;		break;	case D_AUTO:	case D_PARAM:		aa.type = D_SP+D_INDIR;		break;	}	aa.index = D_NONE;	aa.scale = 1;	aa.offset = vaddr(a);	asmand(&aa, r);	return;bad:	diag("asmand: bad address %D", a);	return;}#define	E	0xffuchar	ymovtab[] ={/* push */	APUSHL,	Ycs,	Ynone,	0,	0x0e,E,0,0,	APUSHL,	Yss,	Ynone,	0,	0x16,E,0,0,	APUSHL,	Yds,	Ynone,	0,	0x1e,E,0,0,	APUSHL,	Yes,	Ynone,	0,	0x06,E,0,0,	APUSHL,	Yfs,	Ynone,	0,	0x0f,0xa0,E,0,	APUSHL,	Ygs,	Ynone,	0,	0x0f,0xa8,E,0,	APUSHW,	Ycs,	Ynone,	0,	Pe,0x0e,E,0,	APUSHW,	Yss,	Ynone,	0,	Pe,0x16,E,0,	APUSHW,	Yds,	Ynone,	0,	Pe,0x1e,E,0,	APUSHW,	Yes,	Ynone,	0,	Pe,0x06,E,0,	APUSHW,	Yfs,	Ynone,	0,	Pe,0x0f,0xa0,E,	APUSHW,	Ygs,	Ynone,	0,	Pe,0x0f,0xa8,E,/* pop */	APOPL,	Ynone,	Yds,	0,	0x1f,E,0,0,	APOPL,	Ynone,	Yes,	0,	0x07,E,0,0,	APOPL,	Ynone,	Yss,	0,	0x17,E,0,0,	APOPL,	Ynone,	Yfs,	0,	0x0f,0xa1,E,0,	APOPL,	Ynone,	Ygs,	0,	0x0f,0xa9,E,0,

⌨️ 快捷键说明

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