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

📄 processor.java

📁 nachos操作系统框架
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * <p>     * Transfer the contents of the nextPC register into the PC register, and     * then add 4 to the value in the nextPC register. Same as     * <tt>advancePC(readRegister(regNextPC)+4)</tt>.     *     * <p>     * Use after handling a syscall exception so that the processor will move     * on to the next instruction.     */    public void advancePC() {	advancePC(registers[regNextPC]+4);    }    /**     * Transfer the contents of the nextPC register into the PC register, and     * then write the nextPC register.     *     * @param	nextPC	the new value of the nextPC register.     */    private void advancePC(int nextPC) {	registers[regPC] = registers[regNextPC];	registers[regNextPC] = nextPC;    }    /** Caused by a syscall instruction. */    public static final int exceptionSyscall = 0;    /** Caused by an access to an invalid virtual page. */    public static final int exceptionPageFault = 1;    /** Caused by an access to a virtual page not mapped by any TLB entry. */    public static final int exceptionTLBMiss = 2;    /** Caused by a write access to a read-only virtual page. */    public static final int exceptionReadOnly = 3;    /** Caused by an access to an invalid physical page. */    public static final int exceptionBusError = 4;    /** Caused by an access to a misaligned virtual address. */    public static final int exceptionAddressError = 5;    /** Caused by an overflow by a signed operation. */    public static final int exceptionOverflow = 6;    /** Caused by an attempt to execute an illegal instruction. */    public static final int exceptionIllegalInstruction = 7;    /** The names of the CPU exceptions. */    public static final String exceptionNames[] = {	"syscall      ",	"page fault   ",	"TLB miss     ",	"read-only    ",	"bus error    ",	"address error",	"overflow     ",	"illegal inst "    };        /** Index of return value register 0. */    public static final int regV0 = 2;    /** Index of return value register 1. */    public static final int regV1 = 3;    /** Index of argument register 0. */    public static final int regA0 = 4;    /** Index of argument register 1. */    public static final int regA1 = 5;    /** Index of argument register 2. */    public static final int regA2 = 6;    /** Index of argument register 3. */    public static final int regA3 = 7;    /** Index of the stack pointer register. */    public static final int regSP = 29;    /** Index of the return address register. */    public static final int regRA = 31;    /** Index of the low register, used for multiplication and division. */    public static final int regLo = 32;    /** Index of the high register, used for multiplication and division. */    public static final int regHi = 33;    /** Index of the program counter register. */    public static final int regPC = 34;    /** Index of the next program counter register. */    public static final int regNextPC = 35;    /** Index of the exception cause register. */    public static final int regCause = 36;    /** Index of the exception bad virtual address register. */    public static final int regBadVAddr = 37;    /** The total number of software-accessible CPU registers. */    public static final int numUserRegisters = 38;    /** Provides privilege to this processor. */    private Privilege privilege;        /** MIPS registers accessible to the kernel. */    private int registers[] = new int[numUserRegisters];    /** The registered target of the delayed load currently in progress. */    private int loadTarget = 0;    /** The bits to be modified by the delayed load currently in progress. */    private int loadMask;    /** The value to be loaded by the delayed load currently in progress. */    private int loadValue;    /** <tt>true</tt> if using a software-managed TLB. */    private boolean usingTLB;    /** Number of TLB entries. */    private int tlbSize = 4;    /**     * Either an associative or direct-mapped set of translation entries,     * depending on whether there is a TLB.     */    private TranslationEntry[] translations;    /** Size of a page, in bytes. */    public static final int pageSize = 0x400;    /** Number of pages in a 32-bit address space. */    public static final int maxPages = (int) (0x100000000L / pageSize);    /** Number of physical pages in memory. */    private int numPhysPages;    /** Main memory for user programs. */    private byte[] mainMemory;    /** The kernel exception handler, called on every user exception. */    private Runnable exceptionHandler = null;    private static final char dbgProcessor = 'p';    private static final char dbgDisassemble = 'm';    private static final char dbgFullDisassemble = 'M';    private class ProcessorPrivilege implements Privilege.ProcessorPrivilege {	public void flushPipe() {	    finishLoad();	}    }    private class MipsException extends Exception {	public MipsException(int cause) {	    Lib.assert(cause >= 0 && cause < exceptionNames.length);	    this.cause = cause;	}	public MipsException(int cause, int badVAddr) {	    this(cause);	    hasBadVAddr = true;	    this.badVAddr = badVAddr;	}	public void handle() {	    writeRegister(regCause, cause);	    if (hasBadVAddr)		writeRegister(regBadVAddr, badVAddr);	    if (Lib.test(dbgDisassemble) || Lib.test(dbgFullDisassemble))		System.out.println("exception: " + exceptionNames[cause]);	    finishLoad();	    Lib.assert(exceptionHandler != null);	    // autograder might not want kernel to know about this exception	    if (!Machine.autoGrader().exceptionHandler(privilege))		return;	    	    exceptionHandler.run();	}	private boolean hasBadVAddr = false;	private int cause, badVAddr;    }	    private class Instruction {	public void run() throws MipsException {	    // hopefully this looks familiar to 152 students?	    fetch();	    decode();	    execute();	    writeBack();	}		private boolean test(int flag) {	    return Lib.test(flag, flags);	}	private void fetch() throws MipsException {	    if ((Lib.test(dbgDisassemble) && !Lib.test(dbgProcessor)) ||		Lib.test(dbgFullDisassemble))		System.out.print("PC=0x" + Lib.toHexString(registers[regPC])				 + "\t");	    value = readMem(registers[regPC], 4);	}		private void decode() {	    op = Lib.extract(value, 26, 6);	    rs = Lib.extract(value, 21, 5);	    rt = Lib.extract(value, 16, 5);	    rd = Lib.extract(value, 11, 5);	    sh = Lib.extract(value, 6, 5);	    func = Lib.extract(value, 0, 6);	    target = Lib.extract(value, 0, 26);	    imm = Lib.extend(value, 0, 16);	    Mips info;	    switch (op) {	    case 0:		info = Mips.specialtable[func];		break;	    case 1:		info = Mips.regimmtable[rt];		break;	    default:		info = Mips.optable[op];		break;	    }	    operation = info.operation;	    name = info.name;	    format = info.format;	    flags = info.flags;	    mask = 0xFFFFFFFF;		    branch = true;		    // get memory access size	    if (test(Mips.SIZEB))		size = 1;	    else if (test(Mips.SIZEH))		size = 2;	    else if (test(Mips.SIZEW))		size = 4;	    else		size = 0;	    // get nextPC	    nextPC = registers[regNextPC]+4;	    // get dstReg	    if (test(Mips.DSTRA))		dstReg = regRA;	    else if (format == Mips.IFMT)		dstReg = rt;	    else if (format == Mips.RFMT)		dstReg = rd;	    else		dstReg = -1;	    // get jtarget	    if (format == Mips.RFMT)		jtarget = registers[rs];	    else if (format == Mips.IFMT)		jtarget = registers[regNextPC] + (imm<<2);	    else if (format == Mips.JFMT)		jtarget = (registers[regNextPC]&0xF0000000) | (target<<2);	    else		jtarget = -1;	    // get imm	    if (test(Mips.UNSIGNED)) {		imm &= 0xFFFF;	    }	    // get addr	    addr = registers[rs] + imm;	    // get src1	    if (test(Mips.SRC1SH))		src1 = sh;	    else		src1 = registers[rs];	    // get src2	    if (test(Mips.SRC2IMM))		src2 = imm;	    else		src2 = registers[rt];	    if (test(Mips.UNSIGNED)) {		src1 &= 0xFFFFFFFFL;		src2 &= 0xFFFFFFFFL;	    }	    	    if (Lib.test(dbgDisassemble) || Lib.test(dbgFullDisassemble))		print();	    	}	private void print() {	    if (Lib.test(dbgDisassemble) && Lib.test(dbgProcessor) &&		!Lib.test(dbgFullDisassemble))		System.out.print("PC=0x" + Lib.toHexString(registers[regPC])				 + "\t");	    	    if (operation == Mips.INVALID) {		System.out.print("invalid: op=" + Lib.toHexString(op, 2) +				 " rs=" + Lib.toHexString(rs, 2) +				 " rt=" + Lib.toHexString(rt, 2) +				 " rd=" + Lib.toHexString(rd, 2) +				 " sh=" + Lib.toHexString(sh, 2) +				 " func=" + Lib.toHexString(func, 2) +				 "\n");		return;	    }	    int spaceIndex = name.indexOf(' ');	    Lib.assert(spaceIndex!=-1 && spaceIndex==name.lastIndexOf(' '));	    String instname = name.substring(0, spaceIndex);	    char[] args = name.substring(spaceIndex+1).toCharArray();	    System.out.print(instname + "\t");	    int minCharsPrinted = 0, maxCharsPrinted = 0;	    for (int i=0; i<args.length; i++) {		switch (args[i]) {		case Mips.RS:		    System.out.print("$" + rs);		    minCharsPrinted += 2;		    maxCharsPrinted += 3;		    		    if (Lib.test(dbgFullDisassemble)) {			System.out.print("#0x" +					 Lib.toHexString(registers[rs]));			minCharsPrinted += 11;			maxCharsPrinted += 11;		    }		    break;		case Mips.RT:		    System.out.print("$" + rt);		    minCharsPrinted += 2;		    maxCharsPrinted += 3;		    if (Lib.test(dbgFullDisassemble) &&			(i!=0 || !test(Mips.DST)) &&			!test(Mips.DELAYEDLOAD)) {			System.out.print("#0x" +					 Lib.toHexString(registers[rt]));			minCharsPrinted += 11;			maxCharsPrinted += 11;		    }		    break;		case Mips.RETURNADDRESS:		    if (rd == 31)			continue;		case Mips.RD:		    System.out.print("$" + rd);		    minCharsPrinted += 2;		    maxCharsPrinted += 3;		    break;		case Mips.IMM:		    System.out.print(imm);		    minCharsPrinted += 1;		    maxCharsPrinted += 6;		    break;		case Mips.SHIFTAMOUNT:		    System.out.print(sh);		    minCharsPrinted += 1;		    maxCharsPrinted += 2;		    break;		case Mips.ADDR:		    System.out.print(imm + "($" + rs);		    minCharsPrinted += 4;		    maxCharsPrinted += 5;		    if (Lib.test(dbgFullDisassemble)) {			System.out.print("#0x" +					 Lib.toHexString(registers[rs]));			minCharsPrinted += 11;			maxCharsPrinted += 11;		    }		    		    System.out.print(")");		    break;		case Mips.TARGET:		    System.out.print("0x" + Lib.toHexString(jtarget));		    minCharsPrinted += 10;		    maxCharsPrinted += 10;		    break;		default:		    Lib.assert(false);    		}		if (i+1 < args.length) {		    System.out.print(", ");		    minCharsPrinted += 2;		    maxCharsPrinted += 2;		}		else {		    // most separation possible is tsi, 5+1+1=7,		    // thankfully less than 8 (makes this possible)		    Lib.assert(maxCharsPrinted-minCharsPrinted < 8);		    // longest string is stj, which is 40-42 chars w/ -d M;		    // go for 48		    while ((minCharsPrinted%8) != 0) {			System.out.print(" ");			minCharsPrinted++;			maxCharsPrinted++;		    }		    while (minCharsPrinted < 48) {			System.out.print("\t");			minCharsPrinted += 8;		    }		}	    }	    if (Lib.test(dbgDisassemble) && Lib.test(dbgProcessor) &&		!Lib.test(dbgFullDisassemble))		System.out.print("\n");	}	private void execute() throws MipsException {	    int value;	    int preserved;	    	    switch (operation) {	    case Mips.ADD:		dst = src1 + src2;		break;	    case Mips.SUB:		dst = src1 - src2;		break;	    case Mips.MULT:		dst = src1 * src2;		registers[regLo] = (int) Lib.extract(dst, 0, 32);		registers[regHi] = (int) Lib.extract(dst, 32, 32);		break;	    case Mips.DIV:		try {		    registers[regLo] = (int) (src1 / src2);		    registers[regHi] = (int) (src1 % src2);		    if (registers[regLo]*src2 + registers[regHi] != src1)			throw new ArithmeticException();		}		catch (ArithmeticException e) {		    throw new MipsException(exceptionOverflow);		}		break;	    case Mips.SLL:		dst = src2 << (src1&0x1F);		break;	    case Mips.SRA:		dst = src2 >> (src1&0x1F);		break;	    case Mips.SRL:

⌨️ 快捷键说明

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