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

📄 asm.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
				o1 = OP2(40);	/* rdy */				break;			case D_PSR:				o1 = OP2(41);	/* rdpsr */				break;			case D_WIM:				o1 = OP2(42);	/* rdwim */				break;			case D_TBR:				o1 = OP2(43);	/* rdtbr */				break;			}			o1 = OP_RRR(o1, 0, 0, r);			break;		}		break;	case 9:		/* movb r,r */		v = 24;		if(p->as == AMOVH || p->as == AMOVHU)			v = 16;		r = ASRA;		if(p->as == AMOVBU || p->as == AMOVHU)			r = ASRL;		o1 = OP_IRR(opcode(ASLL), v, p->from.reg, p->to.reg);		o2 = OP_IRR(opcode(r), v, p->to.reg, p->to.reg);		break;	case 10:	/* mov $loreg, reg */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, p->to.reg);		break;	case 11:	/* mov loreg, r */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(opcode(p->as), (v&0x3ff), REGTMP, p->to.reg);		break;	case 12:	/* mov r, loreg */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(opcode(p->as+AEND), (v&0x3ff), REGTMP, p->from.reg);		break;	case 13:	/* mov $ucon, r */		v = regoff(&p->from);		o1 = 0x1000000 | (p->to.reg<<25) | ((v>>10) & 0x3fffff);	/* sethi */		break;	case 20:	/* op $scon,r */		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 21:	/* op r1,r2 */		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 22:	/* op $lcon,r */		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_IRR(opcode(AADD), (v&0x3ff), REGTMP, REGTMP);		o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);		break;	case 23:	/* cmp r,r */		o1 = OP_RRR(opcode(ASUBCC), p->to.reg, p->from.reg, REGZERO);		break;	case 24:	/* cmp r,$c */		v = regoff(&p->to);		o1 = OP_IRR(opcode(ASUBCC), v, p->from.reg, REGZERO);		break;	case 25:	/* cmp $c,r BOTCH, fix compiler */		v = regoff(&p->from);		o1 = OP_IRR(opcode(AADD), v, NREG, REGTMP);		o2 = OP_RRR(opcode(ASUBCC), p->to.reg, REGTMP, REGZERO);		break;	case 26:	/* op $ucon,r */		v = regoff(&p->from);		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);		break;	case 30:	/* jmp/jmpl soreg */		if(aflag)			return 0;		v = regoff(&p->to);		r = p->reg;		if(r == NREG && p->as == AJMPL)			r = 15;		o1 = OP_IRR(opcode(AJMPL), v, p->to.reg, r);		break;	case 31:	/* ba jmp */		if(aflag)			return 0;		r = p->as;		if(r == AJMP)			r = ABA;		v = 0;		if(p->cond)			v = p->cond->pc - p->pc;		o1 = OP_BRA(opcode(r), v/4);		if(r == ABA && p->link && p->cond && isnop(p->link)) {			o2 = asmout(p->cond, oplook(p->cond), 1);			if(o2) {				o1 += 1;				if(debug['a'])					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);				LPUT(o1);				LPUT(o2);				return 1;			}			/* cant set annul here because pc has already been counted */		}		break;	case 32:	/* jmpl lbra */		if(aflag)			return 0;		v = 0;		if(p->cond)			v = p->cond->pc - p->pc;		r = p->reg;		if(r != NREG && r != 15)			diag("cant jmpl other than R15");		o1 = 0x40000000 | ((v/4) & 0x3fffffffL);	/* call */		if(p->link && p->cond && isnop(p->link)) {			o2 = asmout(p->cond, oplook(p->cond), 1);			if(o2) {				o1 += 1;				if(debug['a'])					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);				LPUT(o1);				LPUT(o2);				return 1;			}		}		break;	case 33:	/* trap r */		if(aflag)			return 0;		o1 = opcode(p->as) | (p->from.reg<<14);		break;	case 34:	/* rett r1,r2 -> jmpl (r1); rett (r2) */		if(aflag)			return 0;		o1 = OP_IRR(opcode(AJMPL), 0, p->from.reg, REGZERO);		o2 = OP_IRR(opcode(ARETT), 0, p->to.reg, REGZERO);		break;	case 40:	/* ldfsr, stfsr, stdq */		if(p->to.type == D_PREG) {			r = p->from.reg;			if(r == NREG)				r = o->param;			v = regoff(&p->from);			if(p->to.reg == D_FSR) {				o1 = OP_IRR(OP3(33), v, r, 0);				break;			}			diag("unknown reg load %d", p->to.reg);		} else {			r = p->to.reg;			if(r == NREG)				r = o->param;			v = regoff(&p->to);			if(p->from.reg == D_FSR) {				o1 = OP_IRR(OP3(37), v, r, 0);				break;			}			if(p->as == AMOVD && p->from.reg == D_FPQ) {				o1 = OP_IRR(OP3(38), v, r, 0);				break;			}			diag("unknown reg store %d", p->from.reg);		}		break;	case 41:	/* ldf,ldd */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		if(p->as == AFMOVF || p->as == AMOVW) {			o1 = OP_IRR(OP3(32), v, r, p->to.reg);			break;		}		if(p->as == AMOVD || p->as == AFMOVD) {			o1 = OP_IRR(OP3(35), v, r, p->to.reg);			break;		}		diag("only MOVD and MOVW to FREG");		break;	case 42:	/* ldd -> ldf,ldf */		/* note should be ldd with proper allignment */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = OP_IRR(OP3(32), v, r, p->to.reg);		o2 = OP_IRR(OP3(32), v+4, r, p->to.reg+1);		break;	case 43:	/* stf */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		if(p->as == AFMOVF || p->as == AMOVW) {			o1 = OP_IRR(OP3(36), v, r, p->from.reg);			break;		}		if(p->as == AMOVD || p->as == AFMOVD) {			o1 = OP_IRR(OP3(39), v, r, p->from.reg);			break;		}		diag("only MOVD and MOVW from FREG");		break;	case 44:	/* std -> stf,stf */		/* note should be std with proper allignment */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		o1 = OP_IRR(OP3(36), v, r, p->from.reg);		o2 = OP_IRR(OP3(36), v+4, r, p->from.reg+1);		break;	case 45:	/* ldf lorg */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(OP3(32), v&0x3ff, REGTMP, p->to.reg);		break;	case 46:	/* ldd lorg -> ldf,ldf */		/* note should be ldd with proper allignment */		r = p->from.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->from);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(OP3(32), (v&0x3ff), REGTMP, p->to.reg);		o4 = OP_IRR(OP3(32), (v&0x3ff)+4, REGTMP, p->to.reg+1);		break;	case 47:	/* stf lorg */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(OP3(36), v&0x3ff, REGTMP, p->from.reg);		break;	case 48:	/* std lorg -> stf,stf */		/* note should be std with proper allignment */		r = p->to.reg;		if(r == NREG)			r = o->param;		v = regoff(&p->to);		o1 = 0x1000000 | (REGTMP<<25) | ((v>>10) & 0x3fffff);	/* sethi */		o2 = OP_RRR(opcode(AADD), r, REGTMP, REGTMP);		o3 = OP_IRR(OP3(36), (v&0x3ff), REGTMP, p->from.reg);		o4 = OP_IRR(OP3(36), (v&0x3ff)+4, REGTMP, p->from.reg+1);		break;	case 49:	/* fmovd -> fmovf,fmovf */		o1 = OP_RRR(opcode(AFMOVF), p->from.reg, 0, p->to.reg);		o2 = OP_RRR(opcode(AFMOVF), p->from.reg+1, 0, p->to.reg+1);		break;	case 50:	/* fcmp */		o1 = OP_RRR(opcode(p->as), p->to.reg, p->from.reg, 0);		break;	case 51:	/* word */		if(aflag)			return 0;		o1 = regoff(&p->from);		break;	case 52:	/* div */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP);		o2 = OP_IRR(OP2(48), 0, REGTMP, 0);		o3 = OP_RRR(opcode(ADIV), p->from.reg, r, p->to.reg);		break;	case 53:	/* divl */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_IRR(OP2(48), 0, REGZERO, 0);		o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, p->to.reg);		break;	case 54:	/* mod */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_IRR(opcode(ASRA), 31, r, REGTMP);		o2 = OP_IRR(OP2(48), 0, REGTMP, 0);		o3 = OP_RRR(opcode(ADIV), p->from.reg, r, REGTMP);		o4 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP);		o5 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg);		break;	case 55:	/* modl */		r = p->reg;		if(r == NREG)			r = p->to.reg;		o1 = OP_IRR(OP2(48), 0, REGZERO, 0);		o2 = OP_RRR(opcode(ADIVL), p->from.reg, r, REGTMP);		o3 = OP_RRR(opcode(AMUL), p->from.reg, REGTMP, REGTMP);		o4 = OP_RRR(opcode(ASUB), REGTMP, r, p->to.reg);		break;	case 56:	/* b(cc) -- annullable */		if(aflag)			return 0;		r = p->as;		v = 0;		if(p->cond)			v = p->cond->pc - p->pc;		o1 = OP_BRA(opcode(r), v/4);		if(p->link && p->cond && isnop(p->link))		if(!debug['A']) {			o2 = asmout(p->cond, oplook(p->cond), 2);			if(o2) {				o1 |= 1<<29;	/* annul */				o1 += 1;				if(debug['a'])					Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", p->pc, o1, o2, p);				LPUT(o1);				LPUT(o2);				return 1;			}		}		break;	case 57:	/* op r1,r2 with reserved rs1 */		r = 0;		o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);		break;	}	if(aflag)		return o1;	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);		LPUT(o1);		break;	case 8:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);		LPUT(o1);		LPUT(o2);		break;	case 12:		if(debug['a'])			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, 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",				v, 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",				v, o1, o2, o3, o4, o5, p);		LPUT(o1);		LPUT(o2);		LPUT(o3);		LPUT(o4);		LPUT(o5);		break;	}	return 0;}intisnop(Prog *p){	if(p->as != AORN)		return 0;	if(p->reg != REGZERO && p->reg != NREG)		return 0;	if(p->from.type != D_REG || p->from.reg != REGZERO)		return 0;	if(p->to.type != D_REG || p->to.reg != REGZERO)		return 0;	return 1;}longopcode(int a){	switch(a) {	case AADD:	return OP2(0);	case AADDCC:	return OP2(16);	case AADDX:	return OP2(8);	case AADDXCC:	return OP2(24);	case AMUL:	return OP2(10);	case ADIV:	return OP2(15);	case ADIVL:	return OP2(14);	case ATADDCC:	return OP2(32);	case ATADDCCTV:	return OP2(34);	case ASUB:	return OP2(4);	case ASUBCC:	return OP2(20);	case ASUBX:	return OP2(12);	case ASUBXCC:	return OP2(28);	case ATSUBCC:	return OP2(33);	case ATSUBCCTV:	return OP2(35);	case AMULSCC:	return OP2(36);	case ASAVE:	return OP2(60);	case ARESTORE:	return OP2(61);	case AAND:	return OP2(1);	case AANDCC:	return OP2(17);	case AANDN:	return OP2(5);	case AANDNCC:	return OP2(21);	case AOR:	return OP2(2);	case AORCC:	return OP2(18);	case AORN:	return OP2(6);	case AORNCC:	return OP2(22);	case AXOR:	return OP2(3);	case AXORCC:	return OP2(19);	case AXNOR:	return OP2(7);	case AXNORCC:	return OP2(23);	case ASLL:	return OP2(37);	case ASRL:	return OP2(38);	case ASRA:	return OP2(39);	case AJMPL:	case AJMP:	return OP2(56);	case ARETT:	return OP2(57);	case AMOVBU:	return OP3(1);	/* ldub */	case AMOVB:	return OP3(9);	/* ldsb */	case AMOVHU:	return OP3(2);	/* lduh */	case AMOVH:	return OP3(10);	/* ldsh */	case AMOVW:	return OP3(0);	/* ld */	case AMOVD:	return OP3(3);	/* ldd */	case AMOVBU+AEND:	case AMOVB+AEND:return OP3(5);	/* stb */	case AMOVHU+AEND:	case AMOVH+AEND:return OP3(6);	/* sth */	case AMOVW+AEND:return OP3(4);	/* st */	case AMOVD+AEND:return OP3(7);	/* std */	case ASWAP:			/* swap is symmetric */	case ASWAP+AEND:return OP3(15);	case ATAS:	return OP3(13);	/* tas is really ldstub */	case ABN:	return OPB(0);	case ABE:	return OPB(1);	case ABLE:	return OPB(2);	case ABL:	return OPB(3);	case ABLEU:	return OPB(4);	case ABCS:	return OPB(5);	case ABNEG:	return OPB(6);	case ABVS:	return OPB(7);	case ABA:	return OPB(8);	case ABNE:	return OPB(9);	case ABG:	return OPB(10);	case ABGE:	return OPB(11);	case ABGU:	return OPB(12);	case ABCC:	return OPB(13);	case ABPOS:	return OPB(14);	case ABVC:	return OPB(15);	case AFBA:	return OPFB(8);	case AFBE:	return OPFB(9);	case AFBG:	return OPFB(6);	case AFBGE:	return OPFB(11);	case AFBL:	return OPFB(4);	case AFBLE:	return OPFB(13);	case AFBLG:	return OPFB(2);	case AFBN:	return OPFB(0);	case AFBNE:	return OPFB(1);	case AFBO:	return OPFB(15);	case AFBU:	return OPFB(7);	case AFBUE:	return OPFB(10);	case AFBUG:	return OPFB(5);	case AFBUGE:	return OPFB(12);	case AFBUL:	return OPFB(3);	case AFBULE:	return OPFB(14);	case ATN:	return OPT(0);	case ATE:	return OPT(1);	case ATLE:	return OPT(2);	case ATL:	return OPT(3);	case ATLEU:	return OPT(4);	case ATCS:	return OPT(5);	case ATNEG:	return OPT(6);	case ATVS:	return OPT(7);	case ATA:	return OPT(8);	case ATNE:	return OPT(9);	case ATG:	return OPT(10);	case ATGE:	return OPT(11);	case ATGU:	return OPT(12);	case ATCC:	return OPT(13);	case ATPOS:	return OPT(14);	case ATVC:	return OPT(15);	case AFADDF:	return OPF1(65);	case AFADDD:	return OPF1(66);	case AFADDX:	return OPF1(67);	case AFSUBF:	return OPF1(69);	case AFSUBD:	return OPF1(70);	case AFSUBX:	return OPF1(71);	case AFMULF:	return OPF1(73);	case AFMULD:	return OPF1(74);	case AFMULX:	return OPF1(75);	case AFDIVF:	return OPF1(77);	case AFDIVD:	return OPF1(78);	case AFDIVX:	return OPF1(79);	case AFMOVF:	return OPF1(1);	case AFNEGF:	return OPF1(5);	case AFABSF:	return OPF1(9);	case AFSQRTF:	return OPF1(41);	case AFSQRTD:	return OPF1(42);	case AFSQRTX:	return OPF1(43);	case AFMOVWF:	return OPF1(196);	case AFMOVWD:	return OPF1(200);	case AFMOVWX:	return OPF1(204);	case AFMOVFW:	return OPF1(209);	case AFMOVDW:	return OPF1(210);	case AFMOVXW:	return OPF1(211);	case AFMOVFD:	return OPF1(201);	case AFMOVFX:	return OPF1(205);	case AFMOVDF:	return OPF1(198);	case AFMOVDX:	return OPF1(206);	case AFMOVXF:	return OPF1(199);	case AFMOVXD:	return OPF1(203);	case AFCMPF:	return OPF2(81);	case AFCMPD:	return OPF2(82);	case AFCMPX:	return OPF2(83);	case AFCMPEF:	return OPF2(85);	case AFCMPED:	return OPF2(86);	case AFCMPEX:	return OPF2(87);	case AUNIMP:	return 0;	}	diag("bad opcode %A", a);	return 0;}

⌨️ 快捷键说明

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