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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
					l++;				}				break;			}			break;		case D_SCONST:			for(; i<c; i++) {				buf.dbuf[l] = p->to.sval[i];				l++;			}			break;		case D_CONST:			d = p->to.offset;			v = p->to.sym;			if(v) {				switch(v->type) {				case SUNDEF:					ckoff(v, d);				case STEXT:				case SLEAF:				case SSTRING:					d += p->to.sym->value;					break;				case SDATA:				case SBSS:					d += p->to.sym->value + INITDAT;				}				if(dlm)					dynreloc(v, a+INITDAT, 1);			}			cast = (char*)&d;			switch(c) {			default:				diag("bad nuxi %d %d%P", c, i, curp);				break;			case 1:				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi1[i]];					l++;				}				break;			case 2:				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi2[i]];					l++;				}				break;			case 4:				for(; i<c; i++) {					buf.dbuf[l] = cast[inuxi4[i]];					l++;				}				break;			}			break;		}	}	write(cout, buf.dbuf, n);}voidasmout(Prog *p, Optab *o){	long o1, o2, o3, o4, o5, o6, v;	int r, rf, rt, rt2;	Sym *s;PP = p;	o1 = 0;	o2 = 0;	o3 = 0;	o4 = 0;	o5 = 0;	o6 = 0;	switch(o->type) {	default:		diag("unknown asm %d", o->type);		prasm(p);		break;	case 0:		/* pseudo ops */		break;	case 1:		/* op R,[R],R */		o1 = oprrr(p->as, p->scond);		rf = p->from.reg;		rt = p->to.reg;		r = p->reg;		if(p->to.type == D_NONE)			rt = 0;		if(r == NREG)			r = rt;		o1 |= rf | (r<<16) | (rt<<12);		break;	case 2:		/* movbu $I,[R],R */		aclass(&p->from);		o1 = oprrr(p->as, p->scond);		o1 |= immrot(instoffset);		rt = p->to.reg;		r = p->reg;		if(p->to.type == D_NONE)			rt = 0;		if(r == NREG)			r = rt;		o1 |= (r<<16) | (rt<<12);		break;	case 3:		/* add R<<[IR],[R],R */	mov:		aclass(&p->from);		o1 = oprrr(p->as, p->scond);		o1 |= p->from.offset;		rt = p->to.reg;		r = p->reg;		if(p->to.type == D_NONE)			rt = 0;		if(r == NREG)			r = rt;		o1 |= (r<<16) | (rt<<12);		break;	case 4:		/* add $I,[R],R */		aclass(&p->from);		o1 = oprrr(AADD, p->scond);		o1 |= immrot(instoffset);		r = p->from.reg;		if(r == NREG)			r = o->param;		o1 |= r << 16;		o1 |= p->to.reg << 12;		break;	case 5:		/* bra s */		v = -8;		if(p->cond == UP) {			s = p->to.sym;			if(s->type != SUNDEF)				diag("bad branch sym type");			v = (ulong)s->value >> (Roffset-2);			dynreloc(s, p->pc, 0);		}		else if(p->cond != P)			v = (p->cond->pc - pc) - 8;		o1 = opbra(p->as, p->scond);		o1 |= (v >> 2) & 0xffffff;		break;	case 6:		/* b ,O(R) -> add $O,R,PC */		aclass(&p->to);		o1 = oprrr(AADD, p->scond);		o1 |= immrot(instoffset);		o1 |= p->to.reg << 16;		o1 |= REGPC << 12;		break;	case 7:		/* bl ,O(R) -> mov PC,link; add $O,R,PC */		aclass(&p->to);		o1 = oprrr(AADD, p->scond);		o1 |= immrot(0);		o1 |= REGPC << 16;		o1 |= REGLINK << 12;		o2 = oprrr(AADD, p->scond);		o2 |= immrot(instoffset);		o2 |= p->to.reg << 16;		o2 |= REGPC << 12;		break;	case 8:		/* sll $c,[R],R -> mov (R<<$c),R */		aclass(&p->from);		o1 = oprrr(p->as, p->scond);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 |= r;		o1 |= (instoffset&31) << 7;		o1 |= p->to.reg << 12;		break;	case 9:		/* sll R,[R],R -> mov (R<<R),R */		o1 = oprrr(p->as, p->scond);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 |= r;		o1 |= (p->from.reg << 8) | (1<<4);		o1 |= p->to.reg << 12;		break;	case 10:	/* swi [$con] */		o1 = oprrr(p->as, p->scond);		if(p->to.type != D_NONE) {			aclass(&p->to);			o1 |= instoffset & 0xffffff;		}		break;	case 11:	/* word */		switch(aclass(&p->to)) {		case C_LCON:			if(!dlm)				break;			if(p->to.name != D_EXTERN && p->to.name != D_STATIC)				break;		case C_ADDR:			if(p->to.sym->type == SUNDEF)				ckoff(p->to.sym, p->to.offset);			dynreloc(p->to.sym, p->pc, 1);		}		o1 = instoffset;		break;	case 12:	/* movw $lcon, reg */		o1 = omvl(p, &p->from, p->to.reg);		break;	case 13:	/* op $lcon, [R], R */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		o2 = oprrr(p->as, p->scond);		o2 |= REGTMP;		r = p->reg;		if(r == NREG)			r = p->to.reg;		o2 |= r << 16;		if(p->to.type != D_NONE)			o2 |= p->to.reg << 12;		break;	case 14:	/* movb/movbu/movh/movhu R,R */		o1 = oprrr(ASLL, p->scond);		if(p->as == AMOVBU || p->as == AMOVHU)			o2 = oprrr(ASRL, p->scond);		else			o2 = oprrr(ASRA, p->scond);		r = p->to.reg;		o1 |= (p->from.reg)|(r<<12);		o2 |= (r)|(r<<12);		if(p->as == AMOVB || p->as == AMOVBU) {			o1 |= (24<<7);			o2 |= (24<<7);		} else {			o1 |= (16<<7);			o2 |= (16<<7);		}		break;	case 15:	/* mul r,[r,]r */		o1 = oprrr(p->as, p->scond);		rf = p->from.reg;		rt = p->to.reg;		r = p->reg;		if(r == NREG)			r = rt;		if(rt == r) {			r = rf;			rf = rt;		}		if(0)		if(rt == r || rf == REGPC || r == REGPC || rt == REGPC) {			diag("bad registers in MUL");			prasm(p);		}		o1 |= (rf<<8) | r | (rt<<16);		break;	case 16:	/* div r,[r,]r */		o1 = 0xf << 28;		o2 = 0;		break;	case 17:		o1 = oprrr(p->as, p->scond);		rf = p->from.reg;		rt = p->to.reg;		rt2 = p->to.offset;		r = p->reg;		o1 |= (rf<<8) | r | (rt<<16) | (rt2<<12);		break;	case 20:	/* mov/movb/movbu R,O(R) */		aclass(&p->to);		r = p->to.reg;		if(r == NREG)			r = o->param;		o1 = osr(p->as, p->from.reg, instoffset, r, p->scond);		break;	case 21:	/* mov/movbu O(R),R -> lr */		aclass(&p->from);		r = p->from.reg;		if(r == NREG)			r = o->param;		o1 = olr(instoffset, r, p->to.reg, p->scond);		if(p->as != AMOVW)			o1 |= 1<<22;		break;	case 22:	/* movb/movh/movhu O(R),R -> lr,shl,shr */		aclass(&p->from);		r = p->from.reg;		if(r == NREG)			r = o->param;		o1 = olr(instoffset, r, p->to.reg, p->scond);		o2 = oprrr(ASLL, p->scond);		o3 = oprrr(ASRA, p->scond);		r = p->to.reg;		if(p->as == AMOVB) {			o2 |= (24<<7)|(r)|(r<<12);			o3 |= (24<<7)|(r)|(r<<12);		} else {			o2 |= (16<<7)|(r)|(r<<12);			if(p->as == AMOVHU)				o3 = oprrr(ASRL, p->scond);			o3 |= (16<<7)|(r)|(r<<12);		}		break;	case 23:	/* movh/movhu R,O(R) -> sb,sb */		aclass(&p->to);		r = p->to.reg;		if(r == NREG)			r = o->param;		o1 = osr(AMOVH, p->from.reg, instoffset, r, p->scond);		o2 = oprrr(ASRL, p->scond);		o2 |= (8<<7)|(p->from.reg)|(REGTMP<<12);		o3 = osr(AMOVH, REGTMP, instoffset+1, r, p->scond);		break;	case 30:	/* mov/movb/movbu R,L(R) */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		r = p->to.reg;		if(r == NREG)			r = o->param;		o2 = osrr(p->from.reg, REGTMP,r, p->scond);		if(p->as != AMOVW)			o2 |= 1<<22;		break;	case 31:	/* mov/movbu L(R),R -> lr[b] */	case 32:	/* movh/movb L(R),R -> lr[b] */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		r = p->from.reg;		if(r == NREG)			r = o->param;		o2 = olrr(REGTMP,r, p->to.reg, p->scond);		if(p->as == AMOVBU || p->as == AMOVB)			o2 |= 1<<22;		if(o->type == 31)			break;		o3 = oprrr(ASLL, p->scond);		if(p->as == AMOVBU || p->as == AMOVHU)			o4 = oprrr(ASRL, p->scond);		else			o4 = oprrr(ASRA, p->scond);		r = p->to.reg;		o3 |= (r)|(r<<12);		o4 |= (r)|(r<<12);		if(p->as == AMOVB || p->as == AMOVBU) {			o3 |= (24<<7);			o4 |= (24<<7);		} else {			o3 |= (16<<7);			o4 |= (16<<7);		}		break;	case 33:	/* movh/movhu R,L(R) -> sb, sb */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		r = p->to.reg;		if(r == NREG)			r = o->param;		o2 = osrr(p->from.reg, REGTMP, r, p->scond);		o2 |= (1<<22) ;		o3 = oprrr(ASRL, p->scond);		o3 |= (8<<7)|(p->from.reg)|(p->from.reg<<12);		o3 |= (1<<6);	/* ROR 8 */		o4 = oprrr(AADD, p->scond);		o4 |= (REGTMP << 12) | (REGTMP << 16);		o4 |= immrot(1);		o5 = osrr(p->from.reg, REGTMP,r,p->scond);		o5 |= (1<<22);		o6 = oprrr(ASRL, p->scond);		o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12);		o6 |= (1<<6);	/* ROL 8 */		break;			case 34:	/* mov $lacon,R */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		o2 = oprrr(AADD, p->scond);		o2 |= REGTMP;		r = p->from.reg;		if(r == NREG)			r = o->param;		o2 |= r << 16;		if(p->to.type != D_NONE)			o2 |= p->to.reg << 12;		break;	case 35:	/* mov PSR,R */		o1 = (2<<23) | (0xf<<16) | (0<<0);		o1 |= (p->scond & C_SCOND) << 28;		o1 |= (p->from.reg & 1) << 22;		o1 |= p->to.reg << 12;		break;	case 36:	/* mov R,PSR */		o1 = (2<<23) | (0x29f<<12) | (0<<4);		if(p->scond & C_FBIT)			o1 ^= 0x010 << 12;		o1 |= (p->scond & C_SCOND) << 28;		o1 |= (p->to.reg & 1) << 22;		o1 |= p->from.reg << 0;		break;	case 37:	/* mov $con,PSR */		aclass(&p->from);		o1 = (2<<23) | (0x29f<<12) | (0<<4);		if(p->scond & C_FBIT)			o1 ^= 0x010 << 12;		o1 |= (p->scond & C_SCOND) << 28;		o1 |= immrot(instoffset);		o1 |= (p->to.reg & 1) << 22;		o1 |= p->from.reg << 0;		break;	case 38:	/* movm $con,oreg -> stm */		o1 = (0x4 << 25);		o1 |= p->from.offset & 0xffff;		o1 |= p->to.reg << 16;		aclass(&p->to);		goto movm;	case 39:	/* movm oreg,$con -> ldm */		o1 = (0x4 << 25) | (1 << 20);		o1 |= p->to.offset & 0xffff;		o1 |= p->from.reg << 16;		aclass(&p->from);	movm:		if(instoffset != 0)			diag("offset must be zero in MOVM");		o1 |= (p->scond & C_SCOND) << 28;		if(p->scond & C_PBIT)			o1 |= 1 << 24;		if(p->scond & C_UBIT)			o1 |= 1 << 23;		if(p->scond & C_SBIT)			o1 |= 1 << 22;		if(p->scond & C_WBIT)			o1 |= 1 << 21;		break;	case 40:	/* swp oreg,reg,reg */		aclass(&p->from);		if(instoffset != 0)			diag("offset must be zero in SWP");		o1 = (0x2<<23) | (0x9<<4);		if(p->as != ASWPW)			o1 |= 1 << 22;		o1 |= p->from.reg << 16;		o1 |= p->reg << 0;		o1 |= p->to.reg << 12;		o1 |= (p->scond & C_SCOND) << 28;		break;	case 41:	/* rfe -> movm.s.w.u 0(r13),[r15] */		o1 = 0xe8fd8000;		break;	case 50:	/* floating point store */		v = regoff(&p->to);		r = p->to.reg;		if(r == NREG)			r = o->param;		o1 = ofsr(p->as, p->from.reg, v, r, p->scond, p);		break;	case 51:	/* floating point load */		v = regoff(&p->from);		r = p->from.reg;		if(r == NREG)			r = o->param;		o1 = ofsr(p->as, p->to.reg, v, r, p->scond, p) | (1<<20);		break;	case 52:	/* floating point store, long offset UGLY */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		r = p->to.reg;		if(r == NREG)			r = o->param;		o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;		o3 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);		break;	case 53:	/* floating point load, long offset UGLY */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		r = p->from.reg;		if(r == NREG)			r = o->param;		o2 = oprrr(AADD, p->scond) | (REGTMP << 12) | (REGTMP << 16) | r;		o3 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);		break;	case 54:	/* floating point arith */		o1 = oprrr(p->as, p->scond);		if(p->from.type == D_FCONST) {			rf = chipfloat(p->from.ieee);			if(rf < 0){				diag("invalid floating-point immediate\n%P", p);				rf = 0;			}			rf |= (1<<3);		} else			rf = p->from.reg;		rt = p->to.reg;		r = p->reg;		if(p->to.type == D_NONE)

⌨️ 快捷键说明

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