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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
				v = 3;			o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg);		}		else {			a = AOR;			if(p->as == AMOVL)				a = AADDL;			if(p->as == AMOVLU)				a = AEXTLL;			o1 = OP_RRR(opcode(a), REGZERO, p->from.reg, p->to.reg);		}		break;	case 2:		/* <operate> r1,[r2],r3 */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);		break;	case 3:		/* <operate> $n,[r2],r3 */		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);		break;	case 4:		/* beq r1,sbra */		if(p->cond == P)			v = -4 >> 2;		else			v = (p->cond->pc - pc-4) >> 2;		o1 = OP_BR(opcode(p->as), v, p->from.reg);		break;	case 5:		/* jmp [r1],0(r2) */		r = p->reg;		a = p->as;		if(r == NREG) {			r = o->param;/*			if(a == AJMP && p->to.reg == REGLINK)				a = ARET; /* this breaks the kernel -- maybe we need to clear prediction stack on each context switch... */		}		o1 = OP_MEM(opcode(a), 0, p->to.reg, r);		break;	case 6:		/* movq $n,r1 and movq $soreg,r1 */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg);		break;	case 7:		/* movbu r1, r2 */		v = 1;		if (p->as == AMOVWU)			v = 3;		o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg);		break;	case 8:		/* mov r, soreg ==> stq o(r) */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		if (p->as == AMOVQ || p->as == AMOVT)			if ((r == REGSP || r == REGSB) && (v&7) != 0)				diag("bad alignment: %P", p);		o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg);		break;	case 9:		/* mov soreg, r ==> ldq o(r) */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		if (p->as == AMOVQ || p->as == AMOVT)			if ((r == REGSP || r == REGSB) && (v&7) != 0)				diag("bad alignment: %P", p);		o1 = OP_MEM(opcode(p->as), v, r, p->to.reg);		break;	case 10:	/* movb r1,r2 */		v = 64 - 8;		if (p->as == AMOVW)			v = 64 - 16;		o1 = OP_IRR(opcode(ASLLQ), v, p->from.reg, p->to.reg);		o2 = OP_IRR(opcode(ASRAQ), v, p->to.reg, p->to.reg);		break;	case 11:	/* jmp lbra */		if(p->cond == P)			v = -4 >> 2;		else			v = (p->cond->pc - pc-4) >> 2;		a = ABR;		r = REGZERO;		if (p->as == AJSR) {			a = ABSR;			r = REGLINK;		}		o1 = OP_BR(opcode(a), v, r);		break;	case 12:	/* addq $n,[r2],r3 ==> lda */		v = regoff(&p->from);		if (p->as == ASUBQ)			v = -v;		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg);		break;	case 13:	/* <op> $scon,[r2],r3 */		v = regoff(&p->from);		if(p->to.reg == REGTMP || p->reg == REGTMP)			diag("cant synthesize large constant\n%P", p);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP);		o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);		break;	case 14:	/* <op> $lcon,[r2],r3 */		v = regoff(&p->from);		if(v & 0x8000)			v += 0x10000;		if(p->to.reg == REGTMP || p->reg == REGTMP)			diag("cant synthesize large constant\n%P", p);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP);		o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);		o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);		break;	case 15:	/* mov $lcon,r1 */		v = regoff(&p->from);		if(v & 0x8000)			v += 0x10000;		o1 = OP_MEM(opcode(AMOVA), v, o->param, REGTMP);		o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg);		break;	case 16:	/* mov $qcon,r1 */		v = regoff(&p->from);		if(v & 0x8000)			v += 0x10000;		if((v>>31)&1)			v += (1LL<<32);		if((v>>47)&1)			v += (1LL<<48);		o1 = OP_MEM(opcode(AMOVA), v>>32, o->param, REGTMP);		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);		o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP);		o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg);		break;	case 17:	/* mov f1,f2 ==> fcpys f1,f1,f2 */		o1 = OP_RRR(opcode(ACPYS), p->from.reg, p->from.reg, p->to.reg);		break;	case 18:	/* call_pal imm */		v = regoff(&p->from);		o1 = OP_MEM(opcode(ACALL_PAL), v, 0, 0);		break;	case 19:	/* mov r, loreg ==> ldah,stq */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		if (p->as == AMOVQ || p->as == AMOVT)			if ((r == REGSP || r == REGSB) && (v&7) != 0)				diag("bad alignment: %P", p);		if(v & 0x8000)			v += 0x10000;		o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP);		o2 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg);		break;	case 20:	/* mov loreg, r ==> ldah,ldq */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		if (p->as == AMOVQ || p->as == AMOVT)			if ((r == REGSP || r == REGSB) && (v&7) != 0)				diag("bad alignment: %P", p);		if(v & 0x8000)			v += 0x10000;		o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP);		o2 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg);		break;#ifdef	NEVER	case 21:	/* mov r1,$qoreg */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		if(v & 0x8000)			v += 0x10000;		if((v>>31)&1)			v += (1LL<<32);		if((v>>47)&1)			v += (1LL<<48);		o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP);		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);		o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);		o5 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg);		break;	case 22:	/* mov $qoreg,r1 */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		if(v & 0x8000)			v += 0x10000;		if((v>>31)&1)			v += (1LL<<32);		if((v>>47)&1)			v += (1LL<<48);		o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP);		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);		o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);		o5 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg);		break;#endif	case 23:	/* <op> $qcon,r1 */		if(p->to.reg == REGTMP || p->reg == REGTMP)			diag("cant synthesize large constant\n%P", p);		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		if(v & 0x8000)			v += 0x10000;		if((v>>31)&1)			v += (1LL<<32);		if((v>>47)&1)			v += (1LL<<48);		o1 = OP_MEM(opcode(AMOVA), v>>32, REGZERO, REGTMP);		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);		o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP);		o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);		o6 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);		break;	case 24:	/* movq Fn, FPCR */		r = p->from.reg;		o1 = OP_RRR(opcode(AADDT+AEND), r, r, r);		break;	case 25:	/* movq FPCR, Fn */		r = p->to.reg;		o1 = OP_RRR(opcode(AADDS+AEND), r, r, r);		break;	case 26:	/* movq Rn, C_PREG */		r = p->from.reg;		o1 = OP_RRR(opcode(ASUBQ+AEND), r, r, 0) | p->to.reg & 255;		break;	case 27:	/* movq C_PREG, Rn */		r = p->to.reg;		o1 = OP_RRR(opcode(AADDQ+AEND), r, r, 0) | p->from.reg & 255;		break;	case 28:	/* cvttq r1,r3 */		r = p->from.reg;		o1 = OP_RRR(opcode(p->as), r, REGZERO, p->to.reg);		break;	case 29:	/* movq pcc, rpcc -> Rn */		o1 = OP_MEM(opcode(ARPCC), 0, REGZERO, p->to.reg);		break;	case 30:	/* rei/mb/trapb */		o1 = OP_MEM(opcode(p->as), 0, REGZERO, REGZERO);		break;	case 31:	/* fetch (Rn) */		o1 = OP_MEM(opcode(p->as), 0, REGZERO, p->from.reg);		break;	case 32:	/* movqp r, soreg ==> stqp o(r) */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		if (v < -0x800 || v >= 0x800)			diag("physical store out of range\n%P", p);		v &= 0xfff;		o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg);		break;	case 33:	/* movqp soreg, r ==> ldqp o(r) */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		if (v < -0x800 || v >= 0x800)			diag("physical load out of range\n%P", p);		v &= 0xfff;		o1 = OP_MEM(opcode(p->as), v, r, p->to.reg);		break;	case 34:	/* <operate> $-n,[r2],r3 */		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		switch (a = p->as) {		case AAND:			a = AANDNOT;			break;		case AANDNOT:			a = AAND;			break;		case AOR:			a = AORNOT;			break;		case AORNOT:			a = AOR;			break;		case AXOR:			a = AXORNOT;			break;		case AXORNOT:			a = AXOR;			break;		default:			diag("bad in NCON case: %P", p);		}		v = ~v;		o1 = OP_IRR(opcode(a), v, r, p->to.reg);		break;	case 40:	/* word */		o1 = regoff(&p->to);		break;	}	switch(o->size) {	default:		if(debug['a'])			Bprint(&bso, " %.8lux:\t\t%P\n", p->pc, p);		break;	case 4:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux\t%P\n", p->pc, o1, p);		LPUT(o1);		break;	case 8:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %P\n", p->pc, o1, o2, p);		LPUT(o1);		LPUT(o2);		break;	case 12:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %P\n", p->pc, o1, o2, o3, p);		LPUT(o1);		LPUT(o2);		LPUT(o3);		break;	case 16:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %P\n",				p->pc, o1, o2, o3, o4, p);		LPUT(o1);		LPUT(o2);		LPUT(o3);		LPUT(o4);		break;	case 20:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %P\n",				p->pc, o1, o2, o3, o4, o5, p);		LPUT(o1);		LPUT(o2);		LPUT(o3);		LPUT(o4);		LPUT(o5);		break;	case 24:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %P\n",				p->pc, o1, o2, o3, o4, o5, o6, p);		LPUT(o1);		LPUT(o2);		LPUT(o3);		LPUT(o4);		LPUT(o5);		LPUT(o6);		break;	}	return 0;}#define	OP(x,y)	(((x)<<26)|((y)<<5))#define	FP(x)	OP(22, (x)|0xc0)	/* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */#define	FP2(x)	OP(22, (x) /*|0x080*/)	/* note: this sets round/trap modes (chopped, software?). used for cvtxx? */#define	FP3(x)	OP(22, (x)|0x080)	/* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */longopcode(int a){	switch (a) {	/* loads */	case AMOVB:		/* misnomer; pretend it's ok for now */diag("opcode(AMOVB)");	case AMOVBU:		return OP(10, 0);	/* v 3 */	case AMOVW:		/* misnomer; pretend it's ok for now */diag("opcode(AMOVW)");	case AMOVWU:		return OP(12, 0);	/* v 3 */	case AMOVL:		return OP(40, 0);	case AMOVQ:		return OP(41, 0);	case AMOVQU:		return OP(11, 0);	case AMOVS:		return OP(34, 0);	case AMOVT:		return OP(35, 0);	/* stores */	case AMOVB+AEND:		/* misnomer; pretend it's ok for now */	case AMOVBU+AEND:	return OP(14, 0);	/* v 3 */	case AMOVW+AEND:	/* misnomer; pretend it's ok for now */	case AMOVWU+AEND:	return OP(13, 0);	/* v 3 */	case AMOVL+AEND:	return OP(44, 0);	case AMOVQ+AEND:	return OP(45, 0);	case AMOVQU+AEND:	return OP(15, 0);	case AMOVS+AEND:	return OP(38, 0);	case AMOVT+AEND:	return OP(39, 0);	/* physical */	case AMOVLP+AEND:	return OP(31, 0)|0x8000;	case AMOVQP+AEND:	return OP(31, 0)|0x9000;	case AMOVLP:		return OP(27, 0)|0x8000;	case AMOVQP:		return OP(27, 0)|0x9000;	/* load address */	case AMOVA:		return OP(8, 0);	case AMOVAH:		return OP(9, 0);	/* locking */	case AMOVLL:		return OP(42, 0);	/* load locked */	case AMOVQL:		return OP(43, 0);	/* load locked */	case AMOVLC+AEND:	return OP(46, 0);	/* store cond */	case AMOVQC+AEND:	return OP(47, 0);	/* store cond */	case AADDL:		return OP(16, 0);	case AADDLV:		return OP(16, 64);	case AADDQ:		return OP(16, 32);	case AADDQV:		return OP(16, 96);	case AS4ADDL:		return OP(16, 2);	case AS4ADDQ:		return OP(16, 34);	case AS8ADDL:		return OP(16, 18);	case AS8ADDQ:		return OP(16, 50);	case AS4SUBL:		return OP(16, 11);	case AS4SUBQ:		return OP(16, 43);	case AS8SUBL:		return OP(16, 27);	case AS8SUBQ:		return OP(16, 59);	case ASUBL:		return OP(16, 9);	case ASUBLV:		return OP(16, 73);	case ASUBQ:		return OP(16, 41);	case ASUBQV:		return OP(16, 105);	case ACMPEQ:		return OP(16, 45);	case ACMPGT:		return OP(16, 77);	case ACMPGE:		return OP(16, 109);	case ACMPUGT:		return OP(16, 29);	case ACMPUGE:		return OP(16, 61);	case ACMPBLE:		return OP(16, 15);	case AAND:		return OP(17, 0);	case AANDNOT:		return OP(17, 8);	case AOR:		return OP(17, 32);	case AORNOT:		return OP(17, 40);	case AXOR:		return OP(17, 64);	case AXORNOT:		return OP(17, 72);	case ACMOVEQ:		return OP(17, 36);	case ACMOVNE:		return OP(17, 38);	case ACMOVLT:		return OP(17, 68);	case ACMOVGE:		return OP(17, 70);	case ACMOVLE:		return OP(17, 100);	case ACMOVGT:		return OP(17, 102);	case ACMOVLBS:		return OP(17, 20);	case ACMOVLBC:		return OP(17, 22);	case AMULL:		return OP(19, 0);	case AMULQ:		return OP(19, 32);	case AMULLV:		return OP(19, 64);	case AMULQV:		return OP(19, 96);	case AUMULH:		return OP(19, 48);	case ASLLQ:		return OP(18, 57);	case ASRLQ:		return OP(18, 52);	case ASRAQ:		return OP(18, 60);	case AEXTBL:		return OP(18, 6);	case AEXTWL:		return OP(18, 22);	case AEXTLL:		return OP(18, 38);	case AEXTQL:		return OP(18, 54);	case AEXTWH:		return OP(18, 90);	case AEXTLH:		return OP(18, 106);	case AEXTQH:		return OP(18, 122);	case AINSBL:		return OP(18, 11);	case AINSWL:		return OP(18, 27);	case AINSLL:		return OP(18, 43);	case AINSQL:		return OP(18, 59);	case AINSWH:		return OP(18, 87);	case AINSLH:		return OP(18, 103);	case AINSQH:		return OP(18, 119);	case AMSKBL:		return OP(18, 2);	case AMSKWL:		return OP(18, 18);	case AMSKLL:		return OP(18, 34);	case AMSKQL:		return OP(18, 50);	case AMSKWH:		return OP(18, 82);	case AMSKLH:		return OP(18, 98);	case AMSKQH:		return OP(18, 114);	case AZAP:		return OP(18, 48);	case AZAPNOT:		return OP(18, 49);	case AJMP:		return OP(26, 0);	case AJSR:		return OP(26, 512);	case ARET:		return OP(26, 1024);	case ABR:		return OP(48, 0);	case ABSR:		return OP(52, 0);	case ABEQ:		return OP(57, 0);	case ABNE:		return OP(61, 0);	case ABLT:		return OP(58, 0);	case ABGE:		return OP(62, 0);	case ABLE:		return OP(59, 0);	case ABGT:		return OP(63, 0);	case ABLBC:		return OP(56, 0);	case ABLBS:		return OP(60, 0);	case AFBEQ:		return OP(49, 0);	case AFBNE:		return OP(53, 0);	case AFBLT:		return OP(50, 0);	case AFBGE:		return OP(54, 0);	case AFBLE:		return OP(51, 0);	case AFBGT:		return OP(55, 0);	case ATRAPB:		return OP(24, 0);	case AMB:		return OP(24, 0x200);	case AFETCH:		return OP(24, 0x400);	case AFETCHM:		return OP(24, 0x500);	case ARPCC:		return OP(24, 0x600);	case ACPYS:		return OP(23, 32);	case ACPYSN:		return OP(23, 33);	case ACPYSE:		return OP(23, 34);	case AADDS+AEND:	return OP(23, 37);	/* MF_FPCR */	case AADDT+AEND:	return OP(23, 36);	/* MT_FPCR */	case ACVTLQ:		return OP(23, 16);	case ACVTQL:		return OP(23, 48);	/* XXX trap mode */	case AFCMOVEQ:		return OP(23, 42);	case AFCMOVNE:		return OP(23, 43);	case AFCMOVLT:		return OP(23, 44);	case AFCMOVGE:		return OP(23, 45);	case AFCMOVLE:		return OP(23, 46);	case AFCMOVGT:		return OP(23, 47);	case AADDS:		return FP(0);	case AADDT:		return FP(32);	case ACMPTEQ:		return FP3(37);	case ACMPTGT:		return FP3(38);	case ACMPTGE:		return FP3(39);	case ACMPTUN:		return FP3(36);	case ACVTQS:		return FP2(60);	case ACVTQT:		return FP2(62);	case ACVTTS:		return FP2(44);	case ACVTTQ:		return FP2(47);	case ADIVS:		return FP(3);	case ADIVT:		return FP(35);	case AMULS:		return FP(2);	case AMULT:		return FP(34);	case ASUBS:		return FP(1);	case ASUBT:		return FP(33);	case ACALL_PAL:		return 0;	case AREI:		return OP(30, 0x400);	/* HW_REI */	case AADDQ+AEND:	return OP(25,0);	/* HW_MFPR */	case ASUBQ+AEND:	return OP(29,0);	/* HW_MTPR */	}	diag("bad op %A(%d)", a, a);	return 0;}

⌨️ 快捷键说明

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