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

📄 run.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>#include "arm.h"static	int	dummy;static	char*	shtype[4] ={	"<<",	">>",	"->",	"@>",};static	char*	cond[16] ={	".EQ",	".NE",	".HS",	".LO",	".MI",	".PL",	".VS",	".VC",	".HI",	".LS",	".GE",	".LT",	".GT",	".LE",	"",	".NO",};void	Idp0(ulong);void	Idp1(ulong);void	Idp2(ulong);void	Idp3(ulong);void	Imul(ulong);void	Imula(ulong);void	Imull(ulong);void	Iswap(ulong);void	Imem1(ulong);void	Imem2(ulong);void	Ilsm(ulong inst);void	Ib(ulong);void	Ibl(ulong);void	Ssyscall(ulong);Inst itab[] ={	{ Idp0,		"AND",	Iarith },	/* 00 - r,r,r */	{ Idp0,		"EOR",	Iarith },	/* 01 */	{ Idp0,		"SUB",	Iarith },	/* 02 */	{ Idp0,		"RSB",	Iarith },	/* 03 */	{ Idp0,		"ADD",	Iarith },	/* 04 */	{ Idp0,		"ADC",	Iarith },	/* 05 */	{ Idp0,		"SBC",	Iarith },	/* 06 */	{ Idp0,		"RSC",	Iarith },	/* 07 */	{ Idp0,		"TST",	Iarith },	/* 08 */	{ Idp0,		"TEQ",	Iarith },	/* 09 */	{ Idp0,		"CMP",	Iarith },	/* 10 */	{ Idp0,		"CMN",	Iarith },	/* 11 */	{ Idp0,		"ORR",	Iarith },	/* 12 */	{ Idp0,		"MOV",	Iarith },	/* 13 */	{ Idp0,		"BIC",	Iarith },	/* 14 */	{ Idp0,		"MVN",	Iarith },	/* 15 */	{ Idp1,		"AND",	Iarith },	/* 16 */	{ Idp1,		"EOR",	Iarith },	/* 17 */	{ Idp1,		"SUB",	Iarith },	/* 18 */	{ Idp1,		"RSB",	Iarith },	/* 19 */	{ Idp1,		"ADD",	Iarith },	/* 20 */	{ Idp1,		"ADC",	Iarith },	/* 21 */	{ Idp1,		"SBC",	Iarith },	/* 22 */	{ Idp1,		"RSC",	Iarith },	/* 23 */	{ Idp1,		"TST",	Iarith },	/* 24 */	{ Idp1,		"TEQ",	Iarith },	/* 25 */	{ Idp1,		"CMP",	Iarith },	/* 26 */	{ Idp1,		"CMN",	Iarith },	/* 27 */	{ Idp1,		"ORR",	Iarith },	/* 28 */	{ Idp1,		"MOV",	Iarith },	/* 29 */	{ Idp1,		"BIC",	Iarith },	/* 30 */	{ Idp1,		"MVN",	Iarith },	/* 31 */	{ Idp2,		"AND",	Iarith },	/* 32 */	{ Idp2,		"EOR",	Iarith },	/* 33 */	{ Idp2,		"SUB",	Iarith },	/* 34 */	{ Idp2,		"RSB",	Iarith },	/* 35 */	{ Idp2,		"ADD",	Iarith },	/* 36 */	{ Idp2,		"ADC",	Iarith },	/* 37 */	{ Idp2,		"SBC",	Iarith },	/* 38 */	{ Idp2,		"RSC",	Iarith },	/* 39 */	{ Idp2,		"TST",	Iarith },	/* 40 */	{ Idp2,		"TEQ",	Iarith },	/* 41 */	{ Idp2,		"CMP",	Iarith },	/* 42 */	{ Idp2,		"CMN",	Iarith },	/* 43 */	{ Idp2,		"ORR",	Iarith },	/* 44 */	{ Idp2,		"MOV",	Iarith },	/* 45 */	{ Idp2,		"BIC",	Iarith },	/* 46 */	{ Idp2,		"MVN",	Iarith },	/* 47 */	{ Idp3,		"AND",	Iarith },	/* 48 - i,r,r */	{ Idp3,		"EOR",	Iarith },	/* 49 */	{ Idp3,		"SUB",	Iarith },	/* 50 */	{ Idp3,		"RSB",	Iarith },	/* 51 */	{ Idp3,		"ADD",	Iarith },	/* 52 */	{ Idp3,		"ADC",	Iarith },	/* 53 */	{ Idp3,		"SBC",	Iarith },	/* 54 */	{ Idp3,		"RSC",	Iarith },	/* 55 */	{ Idp3,		"TST",	Iarith },	/* 56 */	{ Idp3,		"TEQ",	Iarith },	/* 57 */	{ Idp3,		"CMP",	Iarith },	/* 58 */	{ Idp3,		"CMN",	Iarith },	/* 59 */	{ Idp3,		"ORR",	Iarith },	/* 60 */	{ Idp3,		"MOV",	Iarith },	/* 61 */	{ Idp3,		"BIC",	Iarith },	/* 62 */	{ Idp3,		"MVN",	Iarith },	/* 63 */	{ Imul,		"MUL",	Iarith },	/* 64 */	{ Imula,	"MULA",	Iarith },	/* 65 */	{ Iswap,	"SWPW",	Imem },	/* 66 */	{ Iswap,	"SWPBU",	Imem },	/* 67 */	{ Imem2,	"MOV",	Imem },	/* 68 load/store h/sb */	{ Imem2,	"MOV",	Imem },	/* 69 */	{ Imem2,	"MOV",	Imem },	/* 70 */	{ Imem2,	"MOV",	Imem },	/* 71 */	{ Imem1,	"MOVW",	Imem },	/* 72 load/store w/ub i,r */	{ Imem1,	"MOVB",	Imem },	/* 73 */	{ Imem1,	"MOVW",	Imem },	/* 74 */	{ Imem1,	"MOVB",	Imem },	/* 75 */	{ Imem1,	"MOVW",	Imem },	/* 76 load/store r,r */	{ Imem1,	"MOVB",	Imem },	/* 77 */	{ Imem1,	"MOVW",	Imem },	/* 78 */	{ Imem1,	"MOVB",	Imem },	/* 79 */	{ Ilsm,		"LDM",	Imem },	/* 80 block move r,r */	{ Ilsm,		"STM",	Imem },	/* 81 */	{ Ib,		"B",	Ibranch },		/* 82 branch */	{ Ibl,		"BL",	Ibranch },		/* 83 */	{ Ssyscall,	"SWI",	Isyscall },	/* 84 co processor */	{ undef,	"undef" },	/* 85 */	{ undef,	"undef" },	/* 86 */	{ undef,	"undef"  },	/* 87 */	{ Imull,	"MULLU",	Iarith },	/* 88 */	{ Imull,	"MULALU",	Iarith },	/* 89 */	{ Imull,	"MULL",	Iarith  },	/* 90 */	{ Imull,	"MULAL",	Iarith  },	/* 91 */	{ undef,	"undef"  },	/* 92 */	{ 0 }};intruncmp(void){	switch(reg.cond) {	case 0x0:	/* eq */	return (reg.cc1 == reg.cc2);	case 0x1:	/* ne */	return (reg.cc1 != reg.cc2);	case 0x2:	/* hs */	return ((ulong)reg.cc1 >= (ulong)reg.cc2);	case 0x3:	/* lo */	return ((ulong)reg.cc1 < (ulong)reg.cc2);	case 0x4:	/* mi */	return (reg.cc1 - reg.cc2 < 0);	case 0x5:	/* pl */	return (reg.cc1 - reg.cc2 >= 0);	case 0x8:	/* hi */	return ((ulong)reg.cc1 > (ulong)reg.cc2);	case 0x9:	/* ls */	return ((ulong)reg.cc1 <= (ulong)reg.cc2);	case 0xa:	/* ge */	return (reg.cc1 >= reg.cc2);	case 0xb:	/* lt */	return (reg.cc1 < reg.cc2);	case 0xc:	/* gt */	return (reg.cc1 > reg.cc2);	case 0xd:	/* le */	return (reg.cc1 <= reg.cc2);	case 0xe:	/* al */	return 1;	case 0xf:	/* nv */	return 0;	default:		Bprint(bioout, "unimplemented condition prefix %x (%ld %ld)\n",			reg.cond, reg.cc1, reg.cc2);		undef(reg.ir);		return 0;	}}intrunteq(void){	long res = reg.cc1 ^ reg.cc2;	switch(reg.cond) {	case 0x0:	/* eq */	return res == 0;	case 0x1:	/* ne */	return res != 0;	case 0x4:	/* mi */	return (res & SIGNBIT) != 0;	case 0x5:	/* pl */	return (res & SIGNBIT) == 0;	case 0xe:	/* al */	return 1;	case 0xf:	/* nv */	return 0;	default:		Bprint(bioout, "unimplemented condition prefix %x (%ld %ld)\n",			reg.cond, reg.cc1, reg.cc2);		undef(reg.ir);		return 0;	}}intruntst(void){	long res = reg.cc1 & reg.cc2;	switch(reg.cond) {	case 0x0:	/* eq */	return res == 0;	case 0x1:	/* ne */	return res != 0;	case 0x4:	/* mi */	return (res & SIGNBIT) != 0;	case 0x5:	/* pl */	return (res & SIGNBIT) == 0;	case 0xe:	/* al */	return 1;	case 0xf:	/* nv */	return 0;	default:		Bprint(bioout, "unimplemented condition prefix %x (%ld %ld)\n",			reg.cond, reg.cc1, reg.cc2);		undef(reg.ir);		return 0;	}}voidrun(void){	int execute;	do {		if(trace)			Bflush(bioout);		reg.ar = reg.r[REGPC];		reg.ir = ifetch(reg.ar);		reg.class = armclass(reg.ir);		reg.ip = &itab[reg.class];		reg.cond = (reg.ir>>28) & 0xf;		switch(reg.compare_op) {		case CCcmp:			execute = runcmp();			break;		case CCteq:			execute = runteq();			break;		case CCtst:			execute = runtst();			break;		default:			Bprint(bioout, "unimplemented compare operation %x\n",				reg.compare_op);			return;		}		if(execute) {			reg.ip->count++;			(*reg.ip->func)(reg.ir);		} else {			if(trace)				itrace("%s%s	IGNORED",					reg.ip->name, cond[reg.cond]);		}		reg.r[REGPC] += 4;		if(bplist)			brkchk(reg.r[REGPC], Instruction);	} while(--count);}voidundef(ulong inst){	Bprint(bioout, "undefined instruction trap pc #%lux inst %.8lux class %d\n",		reg.r[REGPC], inst, reg.class);	longjmp(errjmp, 0);}longshift(long v, int st, int sc, int isreg){	if(sc == 0) {		switch(st) {		case 0:	/* logical left */			reg.cout = reg.cbit;			break;		case 1:	/* logical right */			reg.cout = (v >> 31) & 1;			break;		case 2:	/* arith right */			reg.cout = reg.cbit;			break;		case 3:	/* rotate right */			if(isreg) {				reg.cout = reg.cbit;			}			else {				reg.cout = v & 1;				v = ((ulong)v >> 1) | (reg.cbit << 31);			}		}	}	else {		switch(st) {		case 0:	/* logical left */			reg.cout = (v >> (32 - sc)) & 1;			v = v << sc;			break;		case 1:	/* logical right */			reg.cout = (v >> (sc - 1)) & 1;			v = (ulong)v >> sc;			break;		case 2:	/* arith right */			if(sc >= 32) {				reg.cout = (v >> 31) & 1;				if(reg.cout)					v = 0xFFFFFFFF;				else					v = 0;			}			else {				reg.cout = (v >> (sc - 1)) & 1;				v = (long)v >> sc;			}			break;		case 3:	/* rotate right */			reg.cout = (v >> (sc - 1)) & 1;			v = (v << (32-sc)) | ((ulong)v >> sc);			break;		}	}	return v;}voiddpex(long inst, long o1, long o2, int rd){	int cbit;	cbit = 0;	switch((inst>>21) & 0xf) {	case  0:	/* and */		reg.r[rd] = o1 & o2;		cbit = 1;		break;	case  1:	/* eor */		reg.r[rd] = o1 ^ o2;		cbit = 1;		break;	case  2:	/* sub */		reg.r[rd] = o1 - o2;	case 10:	/* cmp */		if(inst & Sbit) {			reg.cc1 = o1;			reg.cc2 = o2;			reg.compare_op = CCcmp;		}		return;	case  3:	/* rsb */		reg.r[rd] = o2 - o1;		if(inst & Sbit) {			reg.cc1 = o2;			reg.cc2 = o1;			reg.compare_op = CCcmp;		}		return;	case  4:	/* add */		if(calltree && rd == REGPC && o2 == 0) {			Symbol s;			findsym(o1 + o2, CTEXT, &s);			Bprint(bioout, "%8lux return to %lux %s r0=%lux\n",						reg.r[REGPC], o1 + o2, s.name, reg.r[REGRET]);		}		reg.r[rd] = o1 + o2;		if(inst & Sbit) {			if(((uvlong)(ulong)o1 + (uvlong)(ulong)o2) & (1LL << 32))				reg.cbit = 1;			else				reg.cbit = 0;			reg.cc1 = o2;			reg.cc2 = -o1;			reg.compare_op = CCcmp;		}		return;	case  5:	/* adc */	case  6:	/* sbc */	case  7:	/* rsc */		undef(inst);	case  8:	/* tst */		if(inst & Sbit) {			reg.cc1 = o1;			reg.cc2 = o2;			reg.compare_op = CCtst;		}		return;	case  9:	/* teq */		if(inst & Sbit) {			reg.cc1 = o1;			reg.cc2 = o2;			reg.compare_op = CCteq;		}		return;	case 11:	/* cmn */		if(inst & Sbit) {			reg.cc1 = o1;			reg.cc2 = -o2;			reg.compare_op = CCcmp;		}		return;	case 12:	/* orr */		reg.r[rd] = o1 | o2;		cbit = 1;		break;	case 13:	/* mov */		reg.r[rd] = o2;		cbit = 1;		break;	case 14:	/* bic */		reg.r[rd] = o1 & ~o2;		cbit = 1;		break;	case 15:	/* mvn */		reg.r[rd] = ~o2;		cbit = 1;		break;	}	if(inst & Sbit) {		if(cbit)			reg.cbit = reg.cout;		reg.cc1 = reg.r[rd];		reg.cc2 = 0;		reg.compare_op = CCcmp;	}}/* * data processing instruction R,R,R */voidIdp0(ulong inst){	int rn, rd, rm;	long o1, o2;	rn = (inst>>16) & 0xf;	rd = (inst>>12) & 0xf;	rm = inst & 0xf;	o1 = reg.r[rn];	if(rn == REGPC)		o1 += 8;	o2 = reg.r[rm];	if(rm == REGPC)		o2 += 8;	dpex(inst, o1, o2, rd);	if(trace)		itrace("%s%s\tR%d,R%d,R%d =#%x",			reg.ip->name, cond[reg.cond],			rm, rn, rd,			reg.r[rd]);	if(rd == REGPC)		reg.r[rd] -= 4;}/* * data processing instruction (R<>#),R,R */voidIdp1(ulong inst){	int rn, rd, rm, st, sc;	long o1, o2;	rn = (inst>>16) & 0xf;	rd = (inst>>12) & 0xf;	rm = inst & 0xf;	st = (inst>>5) & 0x3;	sc = (inst>>7) & 0x1f;	o1 = reg.r[rn];	if(rn == REGPC)		o1 += 8;	o2 = reg.r[rm];	if(rm == REGPC)		o2 += 8;	o2 = shift(o2, st, sc, 0);	dpex(inst, o1, o2, rd);	if(trace)

⌨️ 快捷键说明

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