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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
			rt = 0;	/* CMP[FD] */		else if(o1 & (1<<15))			r = 0;	/* monadic */		else if(r == NREG)			r = rt;		o1 |= rf | (r<<16) | (rt<<12);		break;	case 55:	/* floating point fix and float */		o1 = oprrr(p->as, p->scond);		rf = p->from.reg;		rt = p->to.reg;		if(p->to.type == D_NONE){			rt = 0;			diag("to.type==D_NONE (asm/fp)");		}		if(p->from.type == D_REG)			o1 |= (rf<<12) | (rt<<16);		else			o1 |= rf | (rt<<12);		break;	case 56:	/* move to FP[CS]R */		o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);		o1 |= ((p->to.reg+1)<<21) | (p->from.reg << 12);		break;	case 57:	/* move from FP[CS]R */		o1 = ((p->scond & C_SCOND) << 28) | (0xe << 24) | (1<<8) | (1<<4);		o1 |= ((p->from.reg+1)<<21) | (p->to.reg<<12) | (1<<20);		break;	case 58:	/* movbu R,R */		o1 = oprrr(AAND, p->scond);		o1 |= immrot(0xff);		rt = p->to.reg;		r = p->from.reg;		if(p->to.type == D_NONE)			rt = 0;		if(r == NREG)			r = rt;		o1 |= (r<<16) | (rt<<12);		break;	case 59:	/* movw/bu R<<I(R),R -> ldr indexed */		if(p->from.reg == NREG) {			if(p->as != AMOVW)				diag("byte MOV from shifter operand");			goto mov;		}		if(p->from.offset&(1<<4))			diag("bad shift in LDR");		o1 = olrr(p->from.offset, p->from.reg, p->to.reg, p->scond);		if(p->as == AMOVBU)			o1 |= 1<<22;		break;	case 60:	/* movb R(R),R -> ldrsb indexed */		if(p->from.reg == NREG) {			diag("byte MOV from shifter operand");			goto mov;		}		if(p->from.offset&(~0xf))			diag("bad shift in LDRSB");		o1 = olhrr(p->from.offset, p->from.reg, p->to.reg, p->scond);		o1 ^= (1<<5)|(1<<6);		break;	case 61:	/* movw/b/bu R,R<<[IR](R) -> str indexed */		if(p->to.reg == NREG)			diag("MOV to shifter operand");		o1 = osrr(p->from.reg, p->to.offset, p->to.reg, p->scond);		if(p->as == AMOVB || p->as == AMOVBU)			o1 |= 1<<22;		break;	case 62:	/* case R -> movw	R<<2(PC),PC */		o1 = olrr(p->from.reg, REGPC, REGPC, p->scond);		o1 |= 2<<7;		break;	case 63:	/* bcase */		if(p->cond != P) {			o1 = p->cond->pc;			if(dlm)				dynreloc(S, p->pc, 1);		}		break;	/* reloc ops */	case 64:	/* mov/movb/movbu R,addr */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);		break;	case 65:	/* mov/movbu addr,R */	case 66:	/* movh/movhu/movb addr,R */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		o2 = olr(0, REGTMP, p->to.reg, p->scond);		if(p->as == AMOVBU || p->as == AMOVB)			o2 |= 1<<22;		if(o->type == 65)			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 67:	/* movh/movhu R,addr -> sb, sb */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		o2 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);		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 = osr(p->as, p->from.reg, 0, REGTMP, p->scond);		o6 = oprrr(ASRL, p->scond);		o6 |= (24<<7)|(p->from.reg)|(p->from.reg<<12);		o6 |= (1<<6);	/* ROL 8 */		break;	case 68:	/* floating point store -> ADDR */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		o2 = ofsr(p->as, p->from.reg, 0, REGTMP, p->scond, p);		break;	case 69:	/* floating point load <- ADDR */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		o2 = ofsr(p->as, p->to.reg, 0, REGTMP, p->scond, p) | (1<<20);		break;	/* ArmV4 ops: */	case 70:	/* movh/movhu R,O(R) -> strh */		aclass(&p->to);		r = p->to.reg;		if(r == NREG)			r = o->param;		o1 = oshr(p->from.reg, instoffset, r, p->scond);		break;		case 71:	/* movb/movh/movhu O(R),R -> ldrsb/ldrsh/ldrh */		aclass(&p->from);		r = p->from.reg;		if(r == NREG)			r = o->param;		o1 = olhr(instoffset, r, p->to.reg, p->scond);		if(p->as == AMOVB)			o1 ^= (1<<5)|(1<<6);		else if(p->as == AMOVH)			o1 ^= (1<<6);		break;	case 72:	/* movh/movhu R,L(R) -> strh */		o1 = omvl(p, &p->to, REGTMP);		if(!o1)			break;		r = p->to.reg;		if(r == NREG)			r = o->param;		o2 = oshrr(p->from.reg, REGTMP,r, p->scond);		break;		case 73:	/* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */		o1 = omvl(p, &p->from, REGTMP);		if(!o1)			break;		r = p->from.reg;		if(r == NREG)			r = o->param;		o2 = olhrr(REGTMP, r, p->to.reg, p->scond);		if(p->as == AMOVB)			o2 ^= (1<<5)|(1<<6);		else if(p->as == AMOVH)			o2 ^= (1<<6);		break;	}	if(debug['a'] > 1)		Bprint(&bso, "%2d ", o->type);	v = p->pc;	switch(o->size) {	default:		if(debug['a'])			Bprint(&bso, " %.8lux:\t\t%P\n", v, p);		break;	case 4:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);		lputl(o1);		break;	case 8:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);		lputl(o1);		lputl(o2);		break;	case 12:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);		lputl(o1);		lputl(o2);		lputl(o3);		break;	case 16:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",				v, o1, o2, o3, o4, p);		lputl(o1);		lputl(o2);		lputl(o3);		lputl(o4);		break;	case 20:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",				v, o1, o2, o3, o4, o5, p);		lputl(o1);		lputl(o2);		lputl(o3);		lputl(o4);		lputl(o5);		break;	case 24:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",				v, o1, o2, o3, o4, o5, o6, p);		lputl(o1);		lputl(o2);		lputl(o3);		lputl(o4);		lputl(o5);		lputl(o6);		break;	}}longoprrr(int a, int sc){	long o;	o = (sc & C_SCOND) << 28;	if(sc & C_SBIT)		o |= 1 << 20;	if(sc & (C_PBIT|C_WBIT))		diag(".P/.W on dp instruction");	switch(a) {	case AMULU:	case AMUL:	return o | (0x0<<21) | (0x9<<4);	case AMULA:	return o | (0x1<<21) | (0x9<<4);	case AMULLU:	return o | (0x4<<21) | (0x9<<4);	case AMULL:	return o | (0x6<<21) | (0x9<<4);	case AMULALU:	return o | (0x5<<21) | (0x9<<4);	case AMULAL:	return o | (0x7<<21) | (0x9<<4);	case AAND:	return o | (0x0<<21);	case AEOR:	return o | (0x1<<21);	case ASUB:	return o | (0x2<<21);	case ARSB:	return o | (0x3<<21);	case AADD:	return o | (0x4<<21);	case AADC:	return o | (0x5<<21);	case ASBC:	return o | (0x6<<21);	case ARSC:	return o | (0x7<<21);	case ATST:	return o | (0x8<<21) | (1<<20);	case ATEQ:	return o | (0x9<<21) | (1<<20);	case ACMP:	return o | (0xa<<21) | (1<<20);	case ACMN:	return o | (0xb<<21) | (1<<20);	case AORR:	return o | (0xc<<21);	case AMOVW:	return o | (0xd<<21);	case ABIC:	return o | (0xe<<21);	case AMVN:	return o | (0xf<<21);	case ASLL:	return o | (0xd<<21) | (0<<5);	case ASRL:	return o | (0xd<<21) | (1<<5);	case ASRA:	return o | (0xd<<21) | (2<<5);	case ASWI:	return o | (0xf<<24);	case AADDD:	return o | (0xe<<24) | (0x0<<20) | (1<<8) | (1<<7);	case AADDF:	return o | (0xe<<24) | (0x0<<20) | (1<<8);	case AMULD:	return o | (0xe<<24) | (0x1<<20) | (1<<8) | (1<<7);	case AMULF:	return o | (0xe<<24) | (0x1<<20) | (1<<8);	case ASUBD:	return o | (0xe<<24) | (0x2<<20) | (1<<8) | (1<<7);	case ASUBF:	return o | (0xe<<24) | (0x2<<20) | (1<<8);	case ADIVD:	return o | (0xe<<24) | (0x4<<20) | (1<<8) | (1<<7);	case ADIVF:	return o | (0xe<<24) | (0x4<<20) | (1<<8);	case ACMPD:	case ACMPF:	return o | (0xe<<24) | (0x9<<20) | (0xF<<12) | (1<<8) | (1<<4);	/* arguably, ACMPF should expand to RNDF, CMPD */	case AMOVF:	case AMOVDF:	return o | (0xe<<24) | (0x0<<20) | (1<<15) | (1<<8);	case AMOVD:	case AMOVFD:	return o | (0xe<<24) | (0x0<<20) | (1<<15) | (1<<8) | (1<<7);	case AMOVWF:	return o | (0xe<<24) | (0<<20) | (1<<8) | (1<<4);	case AMOVWD:	return o | (0xe<<24) | (0<<20) | (1<<8) | (1<<4) | (1<<7);	case AMOVFW:	return o | (0xe<<24) | (1<<20) | (1<<8) | (1<<4);	case AMOVDW:	return o | (0xe<<24) | (1<<20) | (1<<8) | (1<<4) | (1<<7);	}	diag("bad rrr %d", a);	prasm(curp);	return 0;}longopbra(int a, int sc){	if(sc & (C_SBIT|C_PBIT|C_WBIT))		diag(".S/.P/.W on bra instruction");	sc &= C_SCOND;	if(a == ABL)		return (sc<<28)|(0x5<<25)|(0x1<<24);	if(sc != 0xe)		diag(".COND on bcond instruction");	switch(a) {	case ABEQ:	return (0x0<<28)|(0x5<<25);	case ABNE:	return (0x1<<28)|(0x5<<25);	case ABCS:	return (0x2<<28)|(0x5<<25);	case ABHS:	return (0x2<<28)|(0x5<<25);	case ABCC:	return (0x3<<28)|(0x5<<25);	case ABLO:	return (0x3<<28)|(0x5<<25);	case ABMI:	return (0x4<<28)|(0x5<<25);	case ABPL:	return (0x5<<28)|(0x5<<25);	case ABVS:	return (0x6<<28)|(0x5<<25);	case ABVC:	return (0x7<<28)|(0x5<<25);	case ABHI:	return (0x8<<28)|(0x5<<25);	case ABLS:	return (0x9<<28)|(0x5<<25);	case ABGE:	return (0xa<<28)|(0x5<<25);	case ABLT:	return (0xb<<28)|(0x5<<25);	case ABGT:	return (0xc<<28)|(0x5<<25);	case ABLE:	return (0xd<<28)|(0x5<<25);	case AB:	return (0xe<<28)|(0x5<<25);	}	diag("bad bra %A", a);	prasm(curp);	return 0;}longolr(long v, int b, int r, int sc){	long o;	if(sc & C_SBIT)		diag(".S on LDR/STR instruction");	o = (sc & C_SCOND) << 28;	if(!(sc & C_PBIT))		o |= 1 << 24;	if(!(sc & C_UBIT))		o |= 1 << 23;	if(sc & C_WBIT)		o |= 1 << 21;	o |= (0x1<<26) | (1<<20);	if(v < 0) {		v = -v;		o ^= 1 << 23;	}	if(v >= (1<<12))		diag("literal span too large: %d (R%d)\n%P", v, b, PP);	o |= v;	o |= b << 16;	o |= r << 12;	return o;}longolhr(long v, int b, int r, int sc){	long o;	if(sc & C_SBIT)		diag(".S on LDRH/STRH instruction");	o = (sc & C_SCOND) << 28;	if(!(sc & C_PBIT))		o |= 1 << 24;	if(sc & C_WBIT)		o |= 1 << 21;	o |= (1<<23) | (1<<20)|(0xb<<4);	if(v < 0) {		v = -v;		o ^= 1 << 23;	}	if(v >= (1<<8))		diag("literal span too large: %d (R%d)\n%P", v, b, PP);	o |= (v&0xf)|((v>>4)<<8)|(1<<22);	o |= b << 16;	o |= r << 12;	return o;}longosr(int a, int r, long v, int b, int sc){	long o;	o = olr(v, b, r, sc) ^ (1<<20);	if(a != AMOVW)		o |= 1<<22;	return o;}longoshr(int r, long v, int b, int sc){	long o;	o = olhr(v, b, r, sc) ^ (1<<20);	return o;}	longosrr(int r, int i, int b, int sc){	return olr(i, b, r, sc) ^ ((1<<25) | (1<<20));}longoshrr(int r, int i, int b, int sc){	return olhr(i, b, r, sc) ^ ((1<<22) | (1<<20));}longolrr(int i, int b, int r, int sc){	return olr(i, b, r, sc) ^ (1<<25);}longolhrr(int i, int b, int r, int sc){	return olhr(i, b, r, sc) ^ (1<<22);}longofsr(int a, int r, long v, int b, int sc, Prog *p){	long o;	if(sc & C_SBIT)		diag(".S on FLDR/FSTR instruction");	o = (sc & C_SCOND) << 28;	if(!(sc & C_PBIT))		o |= 1 << 24;	if(sc & C_WBIT)		o |= 1 << 21;	o |= (6<<25) | (1<<24) | (1<<23);	if(v < 0) {		v = -v;		o ^= 1 << 23;	}	if(v & 3)		diag("odd offset for floating point op: %d\n%P", v, p);	else if(v >= (1<<10))		diag("literal span too large: %d\n%P", v, p);	o |= (v>>2) & 0xFF;	o |= b << 16;	o |= r << 12;	o |= 1 << 8;	switch(a) {	default:		diag("bad fst %A", a);	case AMOVD:		o |= 1<<15;	case AMOVF:		break;	}	return o;}longomvl(Prog *p, Adr *a, int dr){		long v, o1;	if(!p->cond) {		aclass(a);		v = immrot(~instoffset);		if(v == 0) {			diag("missing literal");			prasm(p);			return 0;		}		o1 = oprrr(AMVN, p->scond&C_SCOND);		o1 |= v;		o1 |= dr << 12;	} else {		v = p->cond->pc - p->pc - 8;		o1 = olr(v, REGPC, dr, p->scond&C_SCOND);	}	return o1;}static Ieee chipfloats[] = {	{0x00000000, 0x00000000}, /* 0 */	{0x00000000, 0x3ff00000}, /* 1 */	{0x00000000, 0x40000000}, /* 2 */	{0x00000000, 0x40080000}, /* 3 */	{0x00000000, 0x40100000}, /* 4 */	{0x00000000, 0x40140000}, /* 5 */	{0x00000000, 0x3fe00000}, /* .5 */	{0x00000000, 0x40240000}, /* 10 */};intchipfloat(Ieee *e){	Ieee *p;	int n;	for(n = sizeof(chipfloats)/sizeof(chipfloats[0]); --n >= 0;){		p = &chipfloats[n];		if(p->l == e->l && p->h == e->h)			return n;	}	return -1;}

⌨️ 快捷键说明

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