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

📄 span.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include	"l.h"voidspan(void){	Prog *p;	Sym *setext;	Optab *o;	int m;	long c;	if(debug['v'])		Bprint(&bso, "%5.2f span\n", cputime());	Bflush(&bso);	c = INITTEXT;	for(p = firstp; p != P; p = p->link) {		p->pc = c;		o = oplook(p);		m = o->size;		if(m == 0) {			if(p->as == ATEXT) {				curtext = p;				autosize = p->to.offset + 4;				if(p->from.sym != S)					p->from.sym->value = c;				continue;			}			if(p->as != ANOP)				diag("zero-width instruction\n%P", p);			continue;		}		c += m;	}	c = rnd(c, 8);	setext = lookup("etext", 0);	if(setext != S) {		setext->value = c;		textsize = c - INITTEXT;	}	if(INITRND)		INITDAT = rnd(c, INITRND);	if(debug['v'])		Bprint(&bso, "tsize = %lux\n", textsize);	Bflush(&bso);}		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;	}}longregoff(Adr *a){	instoffset = 0;	aclass(a);	return instoffset;}intaclass(Adr *a){	Sym *s;	int t;	switch(a->type) {	case D_NONE:		return C_NONE;	case D_REG:		return C_REG;	case D_FREG:		return C_FREG;	case D_CREG:		return C_CREG;	case D_PREG:		if(a->reg == D_FSR)			return C_FSR;		if(a->reg == D_FPQ)			return C_FQ;		return C_PREG;	case D_OREG:		switch(a->name) {		case D_EXTERN:		case D_STATIC:			if(a->sym == S)				break;			t = a->sym->type;			if(t == 0 || t == SXREF) {				diag("undefined external: %s in %s",					a->sym->name, TNAME);				a->sym->type = SDATA;			}			instoffset = a->sym->value + a->offset - BIG;			if(instoffset >= -BIG && instoffset < BIG) {				if(instoffset & 7)					return C_OSEXT;				return C_ESEXT;			}			if(instoffset & 7)				return C_OLEXT;			return C_ELEXT;		case D_AUTO:			instoffset = autosize + a->offset;			goto dauto;		case D_PARAM:			instoffset = autosize + a->offset + 4L;		dauto:			if(instoffset >= -BIG && instoffset < BIG) {				if(instoffset & 7)					return C_OSAUTO;				return C_ESAUTO;			}			if(instoffset & 7)				return C_OLAUTO;			return C_ELAUTO;		case D_NONE:			instoffset = a->offset;			if(instoffset == 0)				return C_ZOREG;			if(instoffset >= -BIG && instoffset < BIG)				return C_SOREG;			return C_LOREG;		}		return C_GOK;	case D_ASI:		if(a->name == D_NONE)			return C_ASI;		return C_GOK;	case D_CONST:		switch(a->name) {		case D_NONE:			instoffset = a->offset;		consize:			if(instoffset == 0)				return C_ZCON;			if(instoffset >= -0x1000 && instoffset <= 0xfff)				return C_SCON;			if((instoffset & 0x3ff) == 0)				return C_UCON;			return C_LCON;		case D_EXTERN:		case D_STATIC:			s = a->sym;			if(s == S)				break;			t = s->type;			if(t == 0 || t == SXREF) {				diag("undefined external: %s in %s",					s->name, TNAME);				s->type = SDATA;			}			if(s->type == STEXT || s->type == SLEAF) {				instoffset = s->value + a->offset;				return C_LCON;			}			if(s->type == SCONST) {				instoffset = s->value + a->offset;				goto consize;			}			instoffset = s->value + a->offset - BIG;			if(instoffset >= -BIG && instoffset < BIG && instoffset != 0)				return C_SECON;			instoffset = s->value + a->offset + INITDAT;/* not sure why this barfs */return C_LCON;/*			if(instoffset == 0)				return C_ZCON;			if(instoffset >= -0x1000 && instoffset <= 0xfff)				return C_SCON;			if((instoffset & 0x3ff) == 0)				return C_UCON;			return C_LCON;*/		case D_AUTO:			instoffset = autosize + a->offset;			if(instoffset >= -BIG && instoffset < BIG)				return C_SACON;			return C_LACON;		case D_PARAM:			instoffset = autosize + a->offset + 4L;			if(instoffset >= -BIG && instoffset < BIG)				return C_SACON;			return C_LACON;		}		return C_GOK;	case D_BRANCH:		return C_SBRA;	}	return C_GOK;}Optab*oplook(Prog *p){	int a1, a2, a3, r;	char *c1, *c3;	Optab *o, *e;	a1 = p->optab;	if(a1)		return optab+(a1-1);	a1 = p->from.class;	if(a1 == 0) {		a1 = aclass(&p->from) + 1;		p->from.class = a1;	}	a1--;	a3 = p->to.class;	if(a3 == 0) {		a3 = aclass(&p->to) + 1;		p->to.class = a3;	}	a3--;	a2 = C_NONE;	if(p->reg != NREG)		a2 = C_REG;	r = p->as;	o = oprange[r].start;	if(o == 0)		o = oprange[r].stop; /* just generate an error */	e = oprange[r].stop;	c1 = xcmp[a1];	c3 = xcmp[a3];	for(; o<e; o++)		if(o->a2 == a2)		if(c1[o->a1])		if(c3[o->a3]) {			p->optab = (o-optab)+1;			return o;		}	diag("illegal combination %A %d %d %d",		p->as, a1, a2, a3);	if(1||!debug['a'])		prasm(p);	if(o == 0)		errorexit();	return o;}intcmp(int a, int b){	if(a == b)		return 1;	switch(a) {	case C_LCON:		if(b == C_ZCON || b == C_SCON || b == C_UCON)			return 1;		break;	case C_UCON:		if(b == C_ZCON)			return 1;		break;	case C_SCON:		if(b == C_ZCON)			return 1;		break;	case C_LACON:		if(b == C_SACON)			return 1;		break;	case C_LBRA:		if(b == C_SBRA)			return 1;		break;	case C_ELEXT:		if(b == C_ESEXT)			return 1;		break;	case C_LEXT:		if(b == C_SEXT ||		   b == C_ESEXT || b == C_OSEXT ||		   b == C_ELEXT || b == C_OLEXT)			return 1;		break;	case C_SEXT:		if(b == C_ESEXT || b == C_OSEXT)			return 1;		break;	case C_ELAUTO:		if(b == C_ESAUTO)			return 1;		break;	case C_LAUTO:		if(b == C_SAUTO ||		   b == C_ESAUTO || b == C_OSAUTO ||		   b == C_ELAUTO || b == C_OLAUTO)			return 1;		break;	case C_SAUTO:		if(b == C_ESAUTO || b == C_OSAUTO)			return 1;		break;	case C_REG:		if(b == C_ZCON)			return 1;		break;	case C_LOREG:		if(b == C_ZOREG || b == C_SOREG)			return 1;		break;	case C_SOREG:		if(b == C_ZOREG)			return 1;		break;	case C_ANY:		return 1;	}	return 0;}intocmp(const void *a1, const void *a2){	Optab *p1, *p2;	int n;	p1 = (Optab*)a1;	p2 = (Optab*)a2;	n = p1->as - p2->as;	if(n)		return n;	n = p1->a1 - p2->a1;	if(n)		return n;	n = p1->a2 - p2->a2;	if(n)		return n;	n = p1->a3 - p2->a3;	if(n)		return n;	return 0;}voidbuildop(void){	int i, n, r;	for(i=0; i<C_NCLASS; i++)		for(n=0; n<C_NCLASS; n++)			xcmp[i][n] = cmp(n, i);	for(n=0; optab[n].as != AXXX; n++)		;	qsort(optab, n, sizeof(optab[0]), ocmp);	for(i=0; i<n; i++) {		r = optab[i].as;		oprange[r].start = optab+i;		while(optab[i].as == r)			i++;		oprange[r].stop = optab+i;		i--;				switch(r)		{		default:			diag("unknown op in build: %A", r);			errorexit();		case AADD:			oprange[AADDX] = oprange[r];			oprange[ASUB] = oprange[r];			oprange[ASUBX] = oprange[r];			oprange[AMUL] = oprange[r];			oprange[AXOR] = oprange[r];			oprange[AXNOR] = oprange[r];			oprange[AAND] = oprange[r];			oprange[AANDN] = oprange[r];			oprange[AOR] = oprange[r];			oprange[AORN] = oprange[r];			oprange[ASLL] = oprange[r];			oprange[ASRL] = oprange[r];			oprange[ASRA] = oprange[r];			oprange[AADDCC] = oprange[r];			oprange[AADDXCC] = oprange[r];			oprange[ATADDCC] = oprange[r];			oprange[ATADDCCTV] = oprange[r];			oprange[ASUBCC] = oprange[r];			oprange[ASUBXCC] = oprange[r];			oprange[ATSUBCC] = oprange[r];			oprange[ATSUBCCTV] = oprange[r];			oprange[AXORCC] = oprange[r];			oprange[AXNORCC] = oprange[r];			oprange[AANDCC] = oprange[r];			oprange[AANDNCC] = oprange[r];			oprange[AORCC] = oprange[r];			oprange[AORNCC] = oprange[r];			oprange[AMULSCC] = oprange[r];			oprange[ASAVE] = oprange[r];			oprange[ARESTORE] = oprange[r];			break;		case AMOVB:			oprange[AMOVH] = oprange[r];			oprange[AMOVHU] = oprange[r];			oprange[AMOVBU] = oprange[r];			oprange[ASWAP] = oprange[r];			oprange[ATAS] = oprange[r];			break;		case ABA:			oprange[ABN] = oprange[r];			oprange[AFBA] = oprange[r];			oprange[AFBN] = oprange[r];			break;		case ABE:			oprange[ABCC] = oprange[r];			oprange[ABCS] = oprange[r];			oprange[ABGE] = oprange[r];			oprange[ABGU] = oprange[r];			oprange[ABG] = oprange[r];			oprange[ABLEU] = oprange[r];			oprange[ABLE] = oprange[r];			oprange[ABL] = oprange[r];			oprange[ABNEG] = oprange[r];			oprange[ABNE] = oprange[r];			oprange[ABPOS] = oprange[r];			oprange[ABVC] = oprange[r];			oprange[ABVS] = oprange[r];			oprange[AFBE] = oprange[r];			oprange[AFBG] = oprange[r];			oprange[AFBGE] = oprange[r];			oprange[AFBL] = oprange[r];			oprange[AFBLE] = oprange[r];			oprange[AFBLG] = oprange[r];			oprange[AFBNE] = oprange[r];			oprange[AFBO] = oprange[r];			oprange[AFBU] = oprange[r];			oprange[AFBUE] = oprange[r];			oprange[AFBUG] = oprange[r];			oprange[AFBUGE] = oprange[r];			oprange[AFBUL] = oprange[r];			oprange[AFBULE] = oprange[r];			break;		case ATA:			oprange[ATCC] = oprange[r];			oprange[ATCS] = oprange[r];			oprange[ATE] = oprange[r];			oprange[ATGE] = oprange[r];			oprange[ATGU] = oprange[r];			oprange[ATG] = oprange[r];			oprange[ATLEU] = oprange[r];			oprange[ATLE] = oprange[r];			oprange[ATL] = oprange[r];			oprange[ATNEG] = oprange[r];			oprange[ATNE] = oprange[r];			oprange[ATN] = oprange[r];			oprange[ATPOS] = oprange[r];			oprange[ATVC] = oprange[r];			oprange[ATVS] = oprange[r];			break;		case AFADDD:			oprange[AFADDF] = oprange[r];			oprange[AFADDX] = oprange[r];			oprange[AFDIVD] = oprange[r];			oprange[AFDIVF] = oprange[r];			oprange[AFDIVX] = oprange[r];			oprange[AFMULD] = oprange[r];			oprange[AFMULF] = oprange[r];			oprange[AFMULX] = oprange[r];			oprange[AFSUBD] = oprange[r];			oprange[AFSUBF] = oprange[r];			oprange[AFSUBX] = oprange[r];			break;		case AFCMPD:			oprange[AFCMPF] = oprange[r];			oprange[AFCMPX] = oprange[r];			oprange[AFCMPED] = oprange[r];			oprange[AFCMPEF] = oprange[r];			oprange[AFCMPEX] = oprange[r];			break;		case AFABSF:			oprange[AFMOVDF] = oprange[r];			oprange[AFMOVDW] = oprange[r];			oprange[AFMOVFD] = oprange[r];			oprange[AFMOVFW] = oprange[r];			oprange[AFMOVWD] = oprange[r];			oprange[AFMOVWF] = oprange[r];			oprange[AFNEGF] = oprange[r];			oprange[AFSQRTD] = oprange[r];			oprange[AFSQRTF] = oprange[r];			break;		case AFMOVF:		case AFMOVD:		case AMOVW:		case AMOVD:		case AWORD:		case ARETT:		case AJMPL:		case AJMP:		case ACMP:		case ANOP:		case ATEXT:		case ADIV:		case ADIVL:		case AMOD:		case AMODL:			break;		}	}}

⌨️ 快捷键说明

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