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

📄 machine.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
    int argtype, amode, argno, argval;    String r;    Boolean indexf;    enum { KNOWN, SEQUENTIAL, BRANCH } addrstatus;    argval = 0;    indexf = false;    addr = startaddr;	found_a_vec_inst = false;    iread(&ins, addr, sizeof(ins));    switch (ins) {	/*	 * It used to be that unconditional jumps and branches were handled	 * by taking their destination address as the next address.  While	 * saving the cost of starting up the process, this approach	 * doesn't work when jumping indirect (since the value in the	 * register might not yet have been set).	 *	 * So unconditional jumps and branches are now handled the same way	 * as conditional jumps and branches.	 *	case O_BRB:	case O_BRW:	    addrstatus = BRANCH;	    break;	 *	 */	    	case O_BSBB:	case O_BSBW:	case O_JSB:	case O_CALLG:	case O_CALLS:	    addrstatus = KNOWN;	    stepto(addr);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    setcurfunc(whatblock(pc));	    if (not isbperr()) {		printstatus();		/* NOTREACHED */	    }	    bpact();	    if (isnext or skipfunc(ins, curfunc)) {		addrstatus = KNOWN;		addr = return_addr();		stepto(addr);		bpact();	    } else {		callnews(/* iscall = */ true);	    }	    break;	case O_RSB:	case O_RET:	    addrstatus = KNOWN;	    stepto(addr);	    callnews(/* iscall = */ false);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    if (not isbperr()) {		printstatus();	    }	    bpact();	    break;	case O_BRB: case O_BRW:	case O_JMP: /* because it may be jmp (r1) */	case O_BNEQ: case O_BEQL: case O_BGTR:	case O_BLEQ: case O_BGEQ: case O_BLSS:	case O_BGTRU: case O_BLEQU: case O_BVC:	case O_BVS: case O_BCC: case O_BCS:	case O_CASEB: case O_CASEW: case O_CASEL:	case O_BBS: case O_BBC: case O_BBSS: case O_BBCS:	case O_BBSC: case O_BBCC: case O_BBSSI:	case O_BBCCI: case O_BLBS: case O_BLBC:	case O_ACBL: case O_AOBLSS: case O_AOBLEQ:	case O_SOBGEQ: case O_SOBGTR:	    addrstatus = KNOWN;	    stepto(addr);	    pstep(process, DEFSIG);	    addr = reg(PROGCTR);	    pc = addr;	    if (not isbperr()) {		printstatus();	    }	    bpact();	    break;	default:	    addrstatus = SEQUENTIAL;	    break;    }    if (addrstatus != KNOWN) {	addr += 1;	op = optab[ins];	argno= 0;	if (ins == O_ESCD) {      	iread(&ins2, addr, sizeof(ins));      	addr += 1;      	op = eoptab[ins2-FIRST_EOP];      	if ((ins2 == O_MTVP) || (ins2 == O_MFVP) || (ins2 == O_VSYNC)) {			argno = 1;			addr += 1;			found_a_vec_inst = true;      	}      	if (op.fmt != 0) {			argno = 1;			addr += 3;			found_a_vec_inst = true;      	}	}	for (argno; argno < op.numargs; argno++) {	    if (indexf == true) {		indexf = false;	    }	    argtype = op.argtype[argno];	    if (is_branch_disp(argtype)) {		mode = 0xAF + (typelen(argtype) << 5);	    } else {		iread(&mode, addr, sizeof(mode));		addr += 1;	    }	    r = regname[regnm(mode)];	    amode = addrmode(mode);	    switch (amode) {		case LITSHORT:		case LITUPTO31:		case LITUPTO47:		case LITUPTO63:		    argval = mode;		    break;		case INDEX:		    indexf = true;		    --argno;		    break;		case REG:		case REGDEF:		case AUTODEC:		    break;		case AUTOINC:		    if (r == regname[PROGCTR]) {			switch (typelen(argtype)) {			    case TYPB:				argval = getdisp(addr, 1, r, amode);				addr += 1;				break;			    case TYPW:				argval = getdisp(addr, 2, r, amode);				addr += 2;				break;			    case TYPL:				argval = getdisp(addr, 4, r, amode);				addr += 4;				break;			    case TYPF:				iread(&argval, addr, sizeof(argval));				addr += 4;				break;			    case TYPQ:			    case TYPD:			    case TYPG:				iread(&argval, addr+4, sizeof(argval));				addr += 8;				break;			}		    }		    break;		case AUTOINCDEF:		    if (r == regname[PROGCTR]) {			argval = getdisp(addr, 4, r, amode);			addr += 4;		    }		    break;		case BYTEDISP:		case BYTEDISPDEF:		    argval = getdisp(addr, 1, r, amode);		    addr += 1;		    break;		case WORDDISP:		case WORDDISPDEF:		    argval = getdisp(addr, 2, r, amode);		    addr += 2;		    break;		case LONGDISP:		case LONGDISPDEF:		    argval = getdisp(addr, 4, r, amode);		    addr += 4;		    break;	    }	}	if (ins == O_CALLS or ins == O_CALLG) {	    argval += 2;	}	if (addrstatus == BRANCH) {	    addr = argval;	}    }    return addr;}/* * Get the displacement of an instruction that uses displacement addressing. */private int getdisp(addr, nbytes, reg, mode)Address addr;int nbytes;String reg;int mode;{    char byte;    short hword;    int argval;    switch (nbytes) {	case 1:	    iread(&byte, addr, sizeof(byte));	    argval = byte;	    break;	case 2:	    iread(&hword, addr, sizeof(hword));	    argval = hword;	    break;	case 4:	    iread(&argval, addr, sizeof(argval));	    break;    }    if (reg == regname[PROGCTR] && mode >= BYTEDISP) {	argval += addr + nbytes;    }    return argval;}#define BP_OP       O_BPT       /* breakpoint trap */#define BP_ERRNO    SIGTRAP     /* signal received at a breakpoint *//* * Setting a breakpoint at a location consists of saving * the word at the location and poking a BP_OP there. * * We save the locations and words on a list for use in unsetting. */typedef struct Savelist *Savelist;struct Savelist {    Address location;    Byte save;    Byte refcount;    Savelist link;};private Savelist savelist;/* * Set a breakpoint at the given address.  Only save the word there * if it's not already a breakpoint. */public setbp(addr)Address addr;{    Byte w;    Byte save;    register Savelist newsave, s;    for (s = savelist; s != nil; s = s->link) {	if (s->location == addr) {	    s->refcount++;	    return;	}    }    iread(&save, addr, sizeof(save));    newsave = new(Savelist);    newsave->location = addr;    newsave->save = save;    newsave->refcount = 1;    newsave->link = savelist;    savelist = newsave;    w = BP_OP;    iwrite(&w, addr, sizeof(w));}/* * Unset a breakpoint; unfortunately we have to search the SAVELIST * to find the saved value.  The assumption is that the SAVELIST will * usually be quite small. */public unsetbp(addr)Address addr;{    register Savelist s, prev;    prev = nil;    for (s = savelist; s != nil; s = s->link) {	if (s->location == addr) {	    iwrite(&s->save, addr, sizeof(s->save));	    s->refcount--;	    if (s->refcount == 0) {		if (prev == nil) {		    savelist = s->link;		} else {		    prev->link = s->link;		}		dispose(s);	    }	    return;	}	prev = s;    }    panic("unsetbp: couldn't find address %d", addr);}/* * Enter a procedure by creating and executing a call instruction. */#define CALLSIZE 7	/* size of call instruction */public beginproc(p, argc)Symbol p;Integer argc;{    char save[CALLSIZE];    struct {	VaxOpcode op;	unsigned char numargs;	unsigned char mode;	char addr[sizeof(long)];	/* unaligned long */    } call;    long dest;    pc = 2;    iread(save, pc, sizeof(save));    call.op = O_CALLS;    call.numargs = argc;    call.mode = 0xef;    dest = codeloc(p) - 2 - (pc + 7);    mov(&dest, call.addr, sizeof(call.addr));    iwrite(&call, pc, sizeof(call));    setreg(PROGCTR, pc);    pstep(process, DEFSIG);    iwrite(save, pc, sizeof(save));    pc = reg(PROGCTR);    if (not isbperr()) {	printstatus();    }}/* * Create and execute sync instruction. */#define SYNCSIZE 4/* size of sync instruction */public execsync(sync_type)int sync_type;{    char save[SYNCSIZE];    struct {	VaxOpcode op1;	VaxOpcode op2;	unsigned char sync_type;	unsigned char mode;    } sync_inst;	Address saved_pc = pc;	Word saved_r0 = reg(0);    iread(save, pc, sizeof(save));    sync_inst.op1 = O_ESCD;             /* set sync instr two */    sync_inst.op2 = O_MFVP;             /* byte opcode */    sync_inst.sync_type = sync_type;    /* 1st operand - literal 4 or 5 */    sync_inst.mode = 0x50;              /* 2nd operand = r0 as operand */    iwrite(&sync_inst, pc, sizeof(sync_inst));    setreg(PROGCTR, pc);                /* reset program counter */    pstep(process, DEFSIG);             /* execute sync instruction */    pc = saved_pc;                    /* restore saved program counter */    iwrite(save, pc, sizeof(save));     /* restore saved code */    setreg(PROGCTR, pc);                /* reset program counter */    setreg(0, saved_r0);                /* reset register zero */	printstatus();}/*  * Display vector instruction modifiers */private printmod (op, modifiers)VaxOpcode op;unsigned modifiers;{  	int cnt = 0;    	if (modifiers != 0) {		printf("/");		cnt++;    	if (modifiers & mi) {      		if ((op == O_VLDL) || (op == O_VLDQ) ||	  				(op == O_VGATHL) || (op == O_VGATHQ)) {				printf("m");				cnt++;      		} else {				printf("u(v)");				cnt += 4;      		}    	}    	if (modifiers & moe) {      		if (modifiers & mtf) {				printf("1");				cnt++;      		} else {				printf("0");				cnt++;    		}    	} else {      		if ((op == O_VVMERGE) || (op == O_VSMERGE) || (op == O_IOTA)) {				if (modifiers & mtf) {	  				printf("1");					cnt++;				} else {	  				printf("0");					cnt++;    			}    		}  		}	}	return(cnt);}typedef int INTFUNC();#define ERR_IGNORE ((INTFUNC *) 0)#define ERR_CATCH  ((INTFUNC *) 1)/* * test if the machine is vector capable and set the global * vectorcapable, return vectorcapable. */public  boolean is_vector_capable(){	long vptotal = 0;	#ifndef NOVECTORS	onsyserr(EINVAL, ERR_IGNORE);	if(getsysinfo(GSI_VPTOTAL, (char *)&vptotal, sizeof(long), 0, NULL ) <= 0)	{#endif /* NOVECTORS */		vectorcapable = false;#ifndef NOVECTORS	} else {		if(vptotal > 0) {			if(!vectorcapable) {				fprintf(stderr, "machine is now vector capable\n");				vectorcapable = true;			}		} else {			if(vectorcapable) {				fprintf(stderr, "machine is now NOT vector capable\n");				vectorcapable = false;			}		}	}	onsyserr(EINVAL, ERR_CATCH);#endif /* NOVECTORS */	return(vectorcapable);}

⌨️ 快捷键说明

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