From 2c8c4f51a571c0faad4e0b28e0d9d002c8aff32b Mon Sep 17 00:00:00 2001 From: Hykilpikonna Date: Sat, 12 Nov 2022 17:06:02 -0500 Subject: [PATCH] [O] Optimize a lot of things --- src/main/java/mars/MIPSprogram.java | 4 +- src/main/java/mars/MarsLaunch.kt | 2 +- src/main/java/mars/ProcessingException.java | 2 +- src/main/java/mars/Settings.java | 3 +- src/main/java/mars/mips/hardware/Memory.java | 91 +--- .../java/mars/mips/hardware/Register.java | 30 +- .../java/mars/mips/hardware/RegisterFile.java | 395 ------------------ .../java/mars/mips/hardware/RegisterFile.kt | 310 ++++++++++++++ .../mips/instructions/InstructionSet.java | 10 +- src/main/java/mars/simulator/BackStepper.java | 4 +- src/main/java/mars/simulator/Exceptions.java | 2 +- src/main/java/mars/simulator/Simulator.java | 16 +- src/main/java/mars/tools/BHTSimulator.java | 2 +- src/main/java/mars/tools/BitmapDisplay.kt | 78 ++-- .../mars/tools/InstructionStatistics.java | 2 +- src/main/java/mars/tools/MipsXray.java | 6 - src/main/java/mars/venus/RegistersWindow.java | 5 +- .../java/mars/venus/RunBackstepAction.java | 4 +- src/main/java/mars/venus/RunGoAction.java | 2 +- src/main/java/mars/venus/RunStepAction.java | 2 +- .../java/mars/venus/TextSegmentWindow.java | 4 +- src/test/java/SpeedTest.kt | 14 + 22 files changed, 400 insertions(+), 588 deletions(-) delete mode 100644 src/main/java/mars/mips/hardware/RegisterFile.java create mode 100644 src/main/java/mars/mips/hardware/RegisterFile.kt create mode 100644 src/test/java/SpeedTest.kt diff --git a/src/main/java/mars/MIPSprogram.java b/src/main/java/mars/MIPSprogram.java index 4d9e7ef..ec935e5 100644 --- a/src/main/java/mars/MIPSprogram.java +++ b/src/main/java/mars/MIPSprogram.java @@ -410,7 +410,7 @@ public class MIPSprogram { steppedExecution = false; Simulator sim = Simulator.getInstance(); - return sim.simulate(this, RegisterFile.getProgramCounter(), maxSteps, breakPoints, a); + return sim.simulate(this, RegisterFile.getPc(), maxSteps, breakPoints, a); } @@ -426,7 +426,7 @@ public class MIPSprogram { steppedExecution = true; Simulator sim = Simulator.getInstance(); - boolean done = sim.simulate(this, RegisterFile.getProgramCounter(), 1, null, a); + boolean done = sim.simulate(this, RegisterFile.getPc(), 1, null, a); return done; } diff --git a/src/main/java/mars/MarsLaunch.kt b/src/main/java/mars/MarsLaunch.kt index 976d411..82124cd 100644 --- a/src/main/java/mars/MarsLaunch.kt +++ b/src/main/java/mars/MarsLaunch.kt @@ -669,7 +669,7 @@ class MarsLaunch(var args: Array) { out.print(reg + "\t") } - value = RegisterFile.getUserRegister(reg).value + value = RegisterFile.getUserRegister(reg)!!.value out.println(formatIntForDisplay(value)) } else { diff --git a/src/main/java/mars/ProcessingException.java b/src/main/java/mars/ProcessingException.java index 2ad8628..7956e8a 100644 --- a/src/main/java/mars/ProcessingException.java +++ b/src/main/java/mars/ProcessingException.java @@ -79,7 +79,7 @@ public class ProcessingException extends Exception { errs = new ErrorList(); errs.add(new ErrorMessage(ps, "Runtime exception at " + - Binary.intToHexString(RegisterFile.getProgramCounter() - Instruction.INSTRUCTION_LENGTH) + + Binary.intToHexString(RegisterFile.getPc() - Instruction.INSTRUCTION_LENGTH) + ": " + m)); // Stopped using ps.getAddress() because of pseudo-instructions. All instructions in // the macro expansion point to the same ProgramStatement, and thus all will return the diff --git a/src/main/java/mars/Settings.java b/src/main/java/mars/Settings.java index 0b72fdb..3f48205 100644 --- a/src/main/java/mars/Settings.java +++ b/src/main/java/mars/Settings.java @@ -2,6 +2,7 @@ package mars; import mars.util.Binary; import mars.util.EditorFont; +import mars.venus.RunSpeedPanel; import mars.venus.editors.jeditsyntax.SyntaxStyle; import mars.venus.editors.jeditsyntax.SyntaxUtilities; @@ -448,7 +449,7 @@ public class Settings extends Observable */ public boolean getBackSteppingEnabled() { - return (Globals.program != null && Globals.program.getBackStepper() != null && Globals.program.getBackStepper().enabled()); + return RunSpeedPanel.getInstance().getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED; } /** diff --git a/src/main/java/mars/mips/hardware/Memory.java b/src/main/java/mars/mips/hardware/Memory.java index c56a095..31ae738 100644 --- a/src/main/java/mars/mips/hardware/Memory.java +++ b/src/main/java/mars/mips/hardware/Memory.java @@ -3,7 +3,6 @@ package mars.mips.hardware; import mars.Globals; import mars.ProgramStatement; import mars.Settings; -import mars.mips.instructions.Instruction; import mars.simulator.Exceptions; import mars.util.Binary; @@ -571,7 +570,7 @@ public class Memory extends Observable if (Globals.getSettings().getBooleanSetting(Settings.SELF_MODIFYING_CODE_ENABLED)) { - ProgramStatement oldStatement = getStatementNoNotify(address); + ProgramStatement oldStatement = getStatement(address); if (oldStatement != null) { oldValue = oldStatement.getBinaryStatement(); @@ -650,7 +649,7 @@ public class Memory extends Observable // DPS adaptation 5-Jul-2013: either throw or call, depending on setting if (Globals.getSettings().getBooleanSetting(Settings.SELF_MODIFYING_CODE_ENABLED)) { - ProgramStatement oldStatement = getStatementNoNotify(address); + ProgramStatement oldStatement = getStatement(address); if (oldStatement != null) { oldValue = oldStatement.getBinaryStatement(); @@ -861,11 +860,11 @@ public class Memory extends Observable } else if (inTextSegment(address)) { - // Burch Mod (Jan 2013): replace throw with calls to getStatementNoNotify & getBinaryStatement + // Burch Mod (Jan 2013): replace throw with calls to getStatement & getBinaryStatement // DPS adaptation 5-Jul-2013: either throw or call, depending on setting if (Globals.getSettings().getBooleanSetting(Settings.SELF_MODIFYING_CODE_ENABLED)) { - ProgramStatement stmt = getStatementNoNotify(address); + ProgramStatement stmt = getStatement(address); value = stmt == null ? 0 : stmt.getBinaryStatement(); } else @@ -947,11 +946,11 @@ public class Memory extends Observable } else if (inTextSegment(address)) { - // Burch Mod (Jan 2013): replace throw with calls to getStatementNoNotify & getBinaryStatement + // Burch Mod (Jan 2013): replace throw with calls to getStatement & getBinaryStatement // DPS adaptation 5-Jul-2013: either throw or call, depending on setting if (Globals.getSettings().getBooleanSetting(Settings.SELF_MODIFYING_CODE_ENABLED)) { - ProgramStatement stmt = getStatementNoNotify(address); + ProgramStatement stmt = getStatement(address); value = stmt == null ? 0 : stmt.getBinaryStatement(); } else @@ -1028,7 +1027,7 @@ public class Memory extends Observable { try { - value = (getStatementNoNotify(address) == null) ? null : getStatementNoNotify(address).getBinaryStatement(); + value = (getStatement(address) == null) ? null : getStatement(address).getBinaryStatement(); } catch (AddressErrorException aee) { @@ -1139,68 +1138,12 @@ public class Memory extends Observable return get(address, 1); } - /** - * Gets ProgramStatement from Text Segment. - * - * @param address Starting address of Memory address to be read. Must be word boundary. - * @return reference to ProgramStatement object associated with that address, or null if none. - * @throws AddressErrorException If address is not on word boundary or is outside Text Segment. - * @see ProgramStatement - **/ - - public ProgramStatement getStatement(int address) throws AddressErrorException - { - return getStatement(address, true); - /* - if (address % 4 != 0 || !(inTextSegment(address) || inKernelTextSegment(address))) { - throw new AddressErrorException( - "fetch address for text segment out of range or not aligned to word boundary ", - Exceptions.ADDRESS_EXCEPTION_LOAD, address); - } - if (inTextSegment(address)) { - return readProgramStatement(address, textBaseAddress, textBlockTable, true); - } - else { - return readProgramStatement(address, kernelTextBaseAddress, kernelTextBlockTable,true); - } - */ - } - - /////////////////////////////////////////////////////////////////////////// // ALL THE OBSERVABLE STUFF GOES HERE. FOR COMPATIBILITY, Memory IS STILL // EXTENDING OBSERVABLE, BUT WILL NOT USE INHERITED METHODS. WILL INSTEAD // USE A COLLECTION OF MemoryObserver OBJECTS, EACH OF WHICH IS COMBINATION // OF AN OBSERVER WITH AN ADDRESS RANGE. - - /** - * Gets ProgramStatement from Text Segment without notifying observers. - * - * @param address Starting address of Memory address to be read. Must be word boundary. - * @return reference to ProgramStatement object associated with that address, or null if none. - * @throws AddressErrorException If address is not on word boundary or is outside Text Segment. - * @see ProgramStatement - **/ - - public ProgramStatement getStatementNoNotify(int address) throws AddressErrorException - { - return getStatement(address, false); - /* - if (address % 4 != 0 || !(inTextSegment(address) || inKernelTextSegment(address))) { - throw new AddressErrorException( - "fetch address for text segment out of range or not aligned to word boundary ", - Exceptions.ADDRESS_EXCEPTION_LOAD, address); - } - if (inTextSegment(address)) { - return readProgramStatement(address, textBaseAddress, textBlockTable, false); - } - else { - return readProgramStatement(address, kernelTextBaseAddress, kernelTextBlockTable, false); - } - */ - } - - private ProgramStatement getStatement(int address, boolean notify) throws AddressErrorException + public ProgramStatement getStatement(int address) throws AddressErrorException { if (!wordAligned(address)) { @@ -1217,11 +1160,11 @@ public class Memory extends Observable } if (inTextSegment(address)) { - return readProgramStatement(address, textBaseAddress, textBlockTable, notify); + return readProgramStatement(address, textBaseAddress, textBlockTable); } else if (inKernelTextSegment(address)) { - return readProgramStatement(address, kernelTextBaseAddress, kernelTextBlockTable, notify); + return readProgramStatement(address, kernelTextBaseAddress, kernelTextBlockTable); } else { @@ -1601,7 +1544,7 @@ public class Memory extends Observable // as valid. It may be either in user or kernel text segment, as specified by arguments. // Returns associated ProgramStatement or null if none. // Last parameter controls whether or not observers will be notified. - private ProgramStatement readProgramStatement(int address, int baseAddress, ProgramStatement[][] blockTable, boolean notify) + private ProgramStatement readProgramStatement(int address, int baseAddress, ProgramStatement[][] blockTable) { int relative = (address - baseAddress) >> 2; // convert byte address to words int block = relative / TEXT_BLOCK_LENGTH_WORDS; @@ -1611,25 +1554,13 @@ public class Memory extends Observable if (blockTable[block] == null || blockTable[block][offset] == null) { // No instructions are stored in this block or offset. - if (notify) - { - notifyAnyObservers(AccessNotice.READ, address, Instruction.INSTRUCTION_LENGTH, 0); - } return null; } else { - if (notify) - { - notifyAnyObservers(AccessNotice.READ, address, Instruction.INSTRUCTION_LENGTH, blockTable[block][offset].getBinaryStatement()); - } return blockTable[block][offset]; } } - if (notify) - { - notifyAnyObservers(AccessNotice.READ, address, Instruction.INSTRUCTION_LENGTH, 0); - } return null; } diff --git a/src/main/java/mars/mips/hardware/Register.java b/src/main/java/mars/mips/hardware/Register.java index 80588ba..f10aa7c 100644 --- a/src/main/java/mars/mips/hardware/Register.java +++ b/src/main/java/mars/mips/hardware/Register.java @@ -45,7 +45,7 @@ public class Register extends Observable private int resetValue; - // volatile should be enough to allow safe multi-threaded access + // volatile should be enough to allow safe multithreaded access // w/o the use of synchronized methods. getValue and setValue // are the only methods here used by the register collection // (RegisterFile, Coprocessor0, Coprocessor1) methods. @@ -85,19 +85,6 @@ public class Register extends Observable */ public synchronized int getValue() - { - notifyAnyObservers(AccessNotice.READ); - return value; - } - - - /** - * Returns the value of the Register. Observers are not notified. Added for release 3.8. - * - * @return value The value of the Register. - */ - - public synchronized int getValueNoNotify() { return value; } @@ -136,7 +123,6 @@ public class Register extends Observable { int old = value; value = val; - notifyAnyObservers(AccessNotice.WRITE); return old; } @@ -157,18 +143,4 @@ public class Register extends Observable { resetValue = reset; } - - // - // Method to notify any observers of register operation that has just occurred. - // - private void notifyAnyObservers(int type) - { - if (this.countObservers() > 0) - {// && Globals.program != null) && Globals.program.inSteppedExecution()) { - this.setChanged(); - this.notifyObservers(new RegisterAccessNotice(type, this.name)); - } - } - - } diff --git a/src/main/java/mars/mips/hardware/RegisterFile.java b/src/main/java/mars/mips/hardware/RegisterFile.java deleted file mode 100644 index 54bf135..0000000 --- a/src/main/java/mars/mips/hardware/RegisterFile.java +++ /dev/null @@ -1,395 +0,0 @@ -package mars.mips.hardware; - -import mars.Globals; -import mars.assembler.SymbolTable; -import mars.mips.instructions.Instruction; -import mars.util.Binary; - -import java.util.Observer; - -/* -Copyright (c) 2003-2008, Pete Sanderson and Kenneth Vollmar - -Developed by Pete Sanderson (psanderson@otterbein.edu) -and Kenneth Vollmar (kenvollmar@missouristate.edu) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject -to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -(MIT license, http://www.opensource.org/licenses/mit-license.html) - */ - -/** - * Represents the collection of MIPS registers. - * - * @author Jason Bumgarner, Jason Shrewsbury - * @version June 2003 - **/ - -public class RegisterFile -{ - - public static final int GLOBAL_POINTER_REGISTER = 28; - - public static final int STACK_POINTER_REGISTER = 29; - - private static final Register[] regFile = - {new Register("$zero", 0, 0), new Register("$at", 1, 0), - new Register("$v0", 2, 0), new Register("$v1", 3, 0), - new Register("$a0", 4, 0), new Register("$a1", 5, 0), - new Register("$a2", 6, 0), new Register("$a3", 7, 0), - new Register("$t0", 8, 0), new Register("$t1", 9, 0), - new Register("$t2", 10, 0), new Register("$t3", 11, 0), - new Register("$t4", 12, 0), new Register("$t5", 13, 0), - new Register("$t6", 14, 0), new Register("$t7", 15, 0), - new Register("$s0", 16, 0), new Register("$s1", 17, 0), - new Register("$s2", 18, 0), new Register("$s3", 19, 0), - new Register("$s4", 20, 0), new Register("$s5", 21, 0), - new Register("$s6", 22, 0), new Register("$s7", 23, 0), - new Register("$t8", 24, 0), new Register("$t9", 25, 0), - new Register("$k0", 26, 0), new Register("$k1", 27, 0), - new Register("$gp", GLOBAL_POINTER_REGISTER, Memory.globalPointer), - new Register("$sp", STACK_POINTER_REGISTER, Memory.stackPointer), - new Register("$fp", 30, 0), new Register("$ra", 31, 0) - }; - - private static final Register programCounter = new Register("pc", 32, Memory.textBaseAddress); - - private static final Register hi = new Register("hi", 33, 0);//this is an internal register with arbitrary number - - private static final Register lo = new Register("lo", 34, 0);// this is an internal register with arbitrary number - - - /** - * Method for displaying the register values for debugging. - **/ - - public static void showRegisters() - { - for (int i = 0; i < regFile.length; i++) - { - System.out.println("Name: " + regFile[i].getName()); - System.out.println("Number: " + regFile[i].getNumber()); - System.out.println("Value: " + regFile[i].getValue()); - System.out.println(); - } - } - - - /** - * This method updates the register value who's number is num. Also handles the lo and hi registers - * - * @param num Register to set the value of. - * @param val The desired value for the register. - **/ - - public static int updateRegister(int num, int val) - { - int old = 0; - if (num == 0) - { - //System.out.println("You can not change the value of the zero register."); - } - else - { - for (int i = 0; i < regFile.length; i++) - { - if (regFile[i].getNumber() == num) - { - old = (Globals.getSettings().getBackSteppingEnabled()) - ? Globals.program.getBackStepper().addRegisterFileRestore(num, regFile[i].setValue(val)) - : regFile[i].setValue(val); - break; - } - } - } - if (num == 33) - {//updates the hi register - old = (Globals.getSettings().getBackSteppingEnabled()) - ? Globals.program.getBackStepper().addRegisterFileRestore(num, hi.setValue(val)) - : hi.setValue(val); - } - else if (num == 34) - {// updates the low register - old = (Globals.getSettings().getBackSteppingEnabled()) - ? Globals.program.getBackStepper().addRegisterFileRestore(num, lo.setValue(val)) - : lo.setValue(val); - } - return old; - } - - /** - * Sets the value of the register given to the value given. - * - * @param reg Name of register to set the value of. - * @param val The desired value for the register. - **/ - - public static void updateRegister(String reg, int val) - { - if (reg.equals("zero")) - { - //System.out.println("You can not change the value of the zero register."); - } - else - { - for (int i = 0; i < regFile.length; i++) - { - if (regFile[i].getName().equals(reg)) - { - updateRegister(i, val); - break; - } - } - } - } - - /** - * Returns the value of the register who's number is num. - * - * @param num The register number. - * @return The value of the given register. - **/ - - public static int getValue(int num) - { - if (num == 33) - { - return hi.getValue(); - } - else if (num == 34) - { - return lo.getValue(); - } - else - { - return regFile[num].getValue(); - } - - } - - /** - * For getting the number representation of the register. - * - * @param n The string formatted register name to look for. - * @return The number of the register represented by the string or -1 if no match. - **/ - - public static int getNumber(String n) - { - int j = -1; - for (int i = 0; i < regFile.length; i++) - { - if (regFile[i].getName().equals(n)) - { - j = regFile[i].getNumber(); - break; - } - } - return j; - } - - /** - * For returning the set of registers. - * - * @return The set of registers. - **/ - - public static Register[] getRegisters() - { - return regFile; - } - - /** - * Get register object corresponding to given name. If no match, return null. - * - * @param Rname The register name, either in $0 or $zero format. - * @return The register object,or null if not found. - **/ - - public static Register getUserRegister(String Rname) - { - Register reg = null; - if (Rname.charAt(0) == '$') - { - try - { - // check for register number 0-31. - reg = regFile[Binary.stringToInt(Rname.substring(1))]; // KENV 1/6/05 - } - catch (Exception e) - { - // handles both NumberFormat and ArrayIndexOutOfBounds - // check for register mnemonic $zero thru $ra - reg = null; // just to be sure - // just do linear search; there aren't that many registers - for (int i = 0; i < regFile.length; i++) - { - if (Rname.equals(regFile[i].getName())) - { - reg = regFile[i]; - break; - } - } - } - } - return reg; - } - - /** - * For initializing the Program Counter. Do not use this to implement jumps and branches, as it will NOT record a - * backstep entry with the restore value. If you need backstepping capability, use setProgramCounter instead. - * - * @param value The value to set the Program Counter to. - **/ - - public static void initializeProgramCounter(int value) - { - programCounter.setValue(value); - } - - /** - * Will initialize the Program Counter to either the default reset value, or the address associated with source - * program global label "main", if it exists as a text segment label and the global setting is set. - * - * @param startAtMain If true, will set program counter to address of statement labeled 'main' (or other defined - * start label) if defined. If not defined, or if parameter false, will set program counter to default reset - * value. - **/ - - public static void initializeProgramCounter(boolean startAtMain) - { - int mainAddr = Globals.symbolTable.getAddress(SymbolTable.getStartLabel()); - if (startAtMain && mainAddr != SymbolTable.NOT_FOUND && (Memory.inTextSegment(mainAddr) || Memory.inKernelTextSegment(mainAddr))) - { - initializeProgramCounter(mainAddr); - } - else - { - initializeProgramCounter(programCounter.getResetValue()); - } - } - - /** - * For setting the Program Counter. Note that ordinary PC update should be done using incrementPC() method. Use - * this only when processing jumps and branches. - * - * @param value The value to set the Program Counter to. - * @return previous PC value - **/ - - public static int setProgramCounter(int value) - { - int old = programCounter.getValue(); - programCounter.setValue(value); - if (Globals.getSettings().getBackSteppingEnabled()) - { - Globals.program.getBackStepper().addPCRestore(old); - } - return old; - } - - /** - * For returning the program counters value. - * - * @return The program counters value as an int. - **/ - - public static int getProgramCounter() - { - return programCounter.getValue(); - } - - /** - * Returns Register object for program counter. Use with caution. - * - * @return program counter's Register object. - */ - public static Register getProgramCounterRegister() - { - return programCounter; - } - - /** - * For returning the program counter's initial (reset) value. - * - * @return The program counter's initial value - **/ - - public static int getInitialProgramCounter() - { - return programCounter.getResetValue(); - } - - /** - * Method to reinitialize the values of the registers. - * NOTE: Should not be called from command-mode MARS because this - * this method uses global settings from the registry. Command-mode must operate using only the command switches, - * not registry settings. It can be called from tools running stand-alone, and this is done in - * AbstractMarsToolAndApplication. - **/ - - public static void resetRegisters() - { - for (int i = 0; i < regFile.length; i++) - { - regFile[i].resetValue(); - } - initializeProgramCounter(Globals.getSettings().getStartAtMain());// replaces "programCounter.resetValue()", DPS 3/3/09 - hi.resetValue(); - lo.resetValue(); - } - - /** - * Method to increment the Program counter in the general case (not a jump or branch). - **/ - - public static void incrementPC() - { - programCounter.setValue(programCounter.getValue() + Instruction.INSTRUCTION_LENGTH); - } - - /** - * Each individual register is a separate object and Observable. This handy method will add the given Observer to - * each one. Currently does not apply to Program Counter. - */ - public static void addRegistersObserver(Observer observer) - { - for (int i = 0; i < regFile.length; i++) - { - regFile[i].addObserver(observer); - } - hi.addObserver(observer); - lo.addObserver(observer); - } - - /** - * Each individual register is a separate object and Observable. This handy method will delete the given Observer - * from each one. Currently does not apply to Program Counter. - */ - public static void deleteRegistersObserver(Observer observer) - { - for (int i = 0; i < regFile.length; i++) - { - regFile[i].deleteObserver(observer); - } - hi.deleteObserver(observer); - lo.deleteObserver(observer); - } -} diff --git a/src/main/java/mars/mips/hardware/RegisterFile.kt b/src/main/java/mars/mips/hardware/RegisterFile.kt new file mode 100644 index 0000000..a2c75c7 --- /dev/null +++ b/src/main/java/mars/mips/hardware/RegisterFile.kt @@ -0,0 +1,310 @@ +package mars.mips.hardware + +import mars.Globals +import mars.assembler.SymbolTable +import mars.mips.instructions.Instruction +import mars.util.Binary +import java.util.* + +/* +Copyright (c) 2003-2008, Pete Sanderson and Kenneth Vollmar + +Developed by Pete Sanderson (psanderson@otterbein.edu) +and Kenneth Vollmar (kenvollmar@missouristate.edu) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject +to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +(MIT license, http://www.opensource.org/licenses/mit-license.html) + */ +/** + * Represents the collection of MIPS registers. + * + * @author Jason Bumgarner, Jason Shrewsbury + * @version June 2003 + */ +object RegisterFile +{ + const val GLOBAL_POINTER_REGISTER = 28 + const val STACK_POINTER_REGISTER = 29 + + /** + * For returning the set of registers. + * + * @return The set of registers. + */ + @JvmStatic + val registers = arrayOf( + Register("\$zero", 0, 0), Register("\$at", 1, 0), + Register("\$v0", 2, 0), Register("\$v1", 3, 0), + Register("\$a0", 4, 0), Register("\$a1", 5, 0), + Register("\$a2", 6, 0), Register("\$a3", 7, 0), + Register("\$t0", 8, 0), Register("\$t1", 9, 0), + Register("\$t2", 10, 0), Register("\$t3", 11, 0), + Register("\$t4", 12, 0), Register("\$t5", 13, 0), + Register("\$t6", 14, 0), Register("\$t7", 15, 0), + Register("\$s0", 16, 0), Register("\$s1", 17, 0), + Register("\$s2", 18, 0), Register("\$s3", 19, 0), + Register("\$s4", 20, 0), Register("\$s5", 21, 0), + Register("\$s6", 22, 0), Register("\$s7", 23, 0), + Register("\$t8", 24, 0), Register("\$t9", 25, 0), + Register("\$k0", 26, 0), Register("\$k1", 27, 0), + Register("\$gp", GLOBAL_POINTER_REGISTER, Memory.globalPointer), + Register("\$sp", STACK_POINTER_REGISTER, Memory.stackPointer), + Register("\$fp", 30, 0), Register("\$ra", 31, 0), // Internal registers + Register("pc", 32, Memory.textBaseAddress), + Register("hi", 33, 0), + Register("lo", 34, 0) + ) + + val registerNameIndex = registers.associateBy { it.name } + + @JvmStatic + val programCounterRegister = registers[32] + @JvmStatic + private val HI = registers[33] + @JvmStatic + private val LO = registers[34] + + val backstep by lazy { Globals.getSettings().backSteppingEnabled } + + /** + * Method for displaying the register values for debugging. + */ + @JvmStatic + fun showRegisters() + { + for (register in registers) + { + println("Name: " + register.name) + println("Number: " + register.number) + println("Value: " + register.value) + println() + } + } + + /** + * This method updates the register value who's number is num. Also handles the lo and hi registers + * + * @param num Register to set the value of. + * @param value The desired value for the register. + */ + @JvmStatic + fun updateRegister(num: Int, value: Int): Int + { + val old = 0 + if (num == 0) + { + println("You can not change the value of the zero register.") + } + else + { + registers[num].value = value + } + return old + } + + /** + * Sets the value of the register given to the value given. + * + * @param reg Name of register to set the value of. + * @param value The desired value for the register. + */ + @JvmStatic + fun updateRegister(reg: String, value: Int) + { + registerNameIndex[reg]?.let { + updateRegister(it.number, value) + } + } + + /** + * Returns the value of the register who's number is num. + * + * @param num The register number. + * @return The value of the given register. + */ + @JvmStatic + fun getValue(num: Int) = registers[num].value + + /** + * For getting the number representation of the register. + * + * @param n The string formatted register name to look for. + * @return The number of the register represented by the string or -1 if no match. + */ + @JvmStatic + fun getNumber(n: String) = registerNameIndex[n]?.number ?: -1 + + /** + * Get register object corresponding to given name. If no match, return null. + * + * @param Rname The register name, either in $0 or $zero format. + * @return The register object,or null if not found. + */ + @JvmStatic + fun getUserRegister(Rname: String): Register? + { + var reg: Register? = null + if (Rname[0] == '$') + { + try + { + // check for register number 0-31. + reg = registers[Binary.stringToInt(Rname.substring(1))] // KENV 1/6/05 + } catch (e: Exception) + { + // handles both NumberFormat and ArrayIndexOutOfBounds + // check for register mnemonic $zero thru $ra + reg = null // just to be sure + // just do linear search; there aren't that many registers + var i = 0 + while (i < registers.size) + { + if (Rname == registers[i].name) + { + reg = registers[i] + break + } + i++ + } + } + } + return reg + } + + /** + * For initializing the Program Counter. Do not use this to implement jumps and branches, as it will NOT record a + * backstep entry with the restore value. If you need backstepping capability, use setProgramCounter instead. + * + * @param value The value to set the Program Counter to. + */ + @JvmStatic + fun initializeProgramCounter(value: Int) + { + programCounterRegister.value = value + } + + /** + * Will initialize the Program Counter to either the default reset value, or the address associated with source + * program global label "main", if it exists as a text segment label and the global setting is set. + * + * @param startAtMain If true, will set program counter to address of statement labeled 'main' (or other defined + * start label) if defined. If not defined, or if parameter false, will set program counter to default reset + * value. + */ + fun initializeProgramCounter(startAtMain: Boolean) + { + val mainAddr = Globals.symbolTable.getAddress(SymbolTable.getStartLabel()) + if (startAtMain && mainAddr != SymbolTable.NOT_FOUND && (Memory.inTextSegment(mainAddr) || Memory.inKernelTextSegment( + mainAddr + )) + ) + { + initializeProgramCounter(mainAddr) + } else + { + initializeProgramCounter(programCounterRegister.resetValue) + } + } + + /** + * For setting the Program Counter. Note that ordinary PC update should be done using incrementPC() method. Use + * this only when processing jumps and branches. + * + * @param value The value to set the Program Counter to. + * @return previous PC value + */ + @JvmStatic + fun setProgramCounter(value: Int): Int + { + val old = programCounterRegister.value + programCounterRegister.value = value + if (Globals.getSettings().backSteppingEnabled) + { + Globals.program.backStepper.addPCRestore(old) + } + return old + } + + /** + * For returning the program counters value. + * + * @return The program counters value as an int. + */ + @JvmStatic + val pc: Int + get() = programCounterRegister.value + + /** + * For returning the program counter's initial (reset) value. + * + * @return The program counter's initial value + */ + val initialProgramCounter: Int + get() = programCounterRegister.resetValue + + /** + * Method to reinitialize the values of the registers. + * **NOTE:** Should *not* be called from command-mode MARS because this + * this method uses global settings from the registry. Command-mode must operate using only the command switches, + * not registry settings. It can be called from tools running stand-alone, and this is done in + * `AbstractMarsToolAndApplication`. + */ + @JvmStatic + fun resetRegisters() + { + for (i in registers.indices) + { + registers[i].resetValue() + } + initializeProgramCounter(Globals.getSettings().startAtMain) // replaces "programCounter.resetValue()", DPS 3/3/09 + HI.resetValue() + LO.resetValue() + } + + /** + * Method to increment the Program counter in the general case (not a jump or branch). + */ + @JvmStatic + fun incrementPC() + { + programCounterRegister.value += Instruction.INSTRUCTION_LENGTH + } + + /** + * Each individual register is a separate object and Observable. This handy method will add the given Observer to + * each one. Currently does not apply to Program Counter. + */ + @JvmStatic + fun addRegistersObserver(observer: Observer?) + { + registers.filter { it.number != 32 }.forEach { it.addObserver(observer) } + } + + /** + * Each individual register is a separate object and Observable. This handy method will delete the given Observer + * from each one. Currently does not apply to Program Counter. + */ + @JvmStatic + fun deleteRegistersObserver(observer: Observer?) + { + registers.filter { it.number != 32 }.forEach { it.deleteObserver(observer) } + } +} diff --git a/src/main/java/mars/mips/instructions/InstructionSet.java b/src/main/java/mars/mips/instructions/InstructionSet.java index 341658b..797e15b 100644 --- a/src/main/java/mars/mips/instructions/InstructionSet.java +++ b/src/main/java/mars/mips/instructions/InstructionSet.java @@ -1239,7 +1239,7 @@ public class InstructionSet { int[] operands = statement.getOperands(); processJump( - ((RegisterFile.getProgramCounter() & 0xF0000000) + ((RegisterFile.getPc() & 0xF0000000) | (operands[0] << 2))); } })); @@ -1268,7 +1268,7 @@ public class InstructionSet int[] operands = statement.getOperands(); processReturnAddress(31);// RegisterFile.updateRegister(31, RegisterFile.getProgramCounter()); processJump( - (RegisterFile.getProgramCounter() & 0xF0000000) + (RegisterFile.getPc() & 0xF0000000) | (operands[0] << 2)); } })); @@ -3442,13 +3442,13 @@ public class InstructionSet if (Globals.getSettings().getDelayedBranchingEnabled()) { // Register the branch target address (absolute byte address). - DelayedBranch.register(RegisterFile.getProgramCounter() + (displacement << 2)); + DelayedBranch.register(RegisterFile.getPc() + (displacement << 2)); } else { // Decrement needed because PC has already been incremented RegisterFile.setProgramCounter( - RegisterFile.getProgramCounter() + RegisterFile.getPc() + (displacement << 2)); // - Instruction.INSTRUCTION_LENGTH); } } @@ -3489,7 +3489,7 @@ public class InstructionSet private void processReturnAddress(int register) { - RegisterFile.updateRegister(register, RegisterFile.getProgramCounter() + + RegisterFile.updateRegister(register, RegisterFile.getPc() + ((Globals.getSettings().getDelayedBranchingEnabled()) ? Instruction.INSTRUCTION_LENGTH : 0)); } diff --git a/src/main/java/mars/simulator/BackStepper.java b/src/main/java/mars/simulator/BackStepper.java index 3b34adb..48dbd37 100644 --- a/src/main/java/mars/simulator/BackStepper.java +++ b/src/main/java/mars/simulator/BackStepper.java @@ -222,7 +222,7 @@ public class BackStepper private int pc() { // PC incremented prior to instruction simulation, so need to adjust for that. - return RegisterFile.getProgramCounter() - Instruction.INSTRUCTION_LENGTH; + return RegisterFile.getPc() - Instruction.INSTRUCTION_LENGTH; } /** @@ -406,7 +406,7 @@ public class BackStepper // Client does not have direct access to program statement, and rather than making all // of them go through the methods below to obtain it, we will do it here. // Want the program statement but do not want observers notified. - ps = Globals.memory.getStatementNoNotify(programCounter); + ps = Globals.memory.getStatement(programCounter); } catch (Exception e) { diff --git a/src/main/java/mars/simulator/Exceptions.java b/src/main/java/mars/simulator/Exceptions.java index 4676508..82854be 100644 --- a/src/main/java/mars/simulator/Exceptions.java +++ b/src/main/java/mars/simulator/Exceptions.java @@ -88,7 +88,7 @@ public class Exceptions // identify devices for External Interrupt (8=keyboard,9=display). Coprocessor0.updateRegister(Coprocessor0.CAUSE, (Coprocessor0.getValue(Coprocessor0.CAUSE) & 0xFFFFFC83 | (cause << 2))); // When exception occurred, PC had already been incremented so need to subtract 4 here. - Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getProgramCounter() - Instruction.INSTRUCTION_LENGTH); + Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getPc() - Instruction.INSTRUCTION_LENGTH); // Set EXL (Exception Level) bit, bit position 1, in STATUS register to 1. Coprocessor0.updateRegister(Coprocessor0.STATUS, Binary.setBit(Coprocessor0.getValue(Coprocessor0.STATUS), Coprocessor0.EXCEPTION_LEVEL)); } diff --git a/src/main/java/mars/simulator/Simulator.java b/src/main/java/mars/simulator/Simulator.java index e790912..51ade15 100644 --- a/src/main/java/mars/simulator/Simulator.java +++ b/src/main/java/mars/simulator/Simulator.java @@ -319,18 +319,18 @@ public class Simulator extends Observable ProgramStatement statement = null; try { - statement = Globals.memory.getStatement(RegisterFile.getProgramCounter()); + statement = Globals.memory.getStatement(RegisterFile.getPc()); } catch (AddressErrorException e) { ErrorList el = new ErrorList(); - el.add(new ErrorMessage((MIPSprogram) null, 0, 0, "invalid program counter value: " + Binary.intToHexString(RegisterFile.getProgramCounter()))); + el.add(new ErrorMessage((MIPSprogram) null, 0, 0, "invalid program counter value: " + Binary.intToHexString(RegisterFile.getPc()))); this.pe = new ProcessingException(el, e); // Next statement is a hack. Previous statement sets EPC register to ProgramCounter-4 // because it assumes the bad address comes from an operand so the ProgramCounter has already been // incremented. In this case, bad address is the instruction fetch itself so Program Counter has // not yet been incremented. We'll set the EPC directly here. DPS 8-July-2013 - Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getProgramCounter()); + Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getPc()); this.constructReturnReason = EXCEPTION; this.done = true; SystemIO.resetFiles(); // close any files opened in MIPS program @@ -373,7 +373,7 @@ public class Simulator extends Observable while (statement != null) { - pc = RegisterFile.getProgramCounter(); // added: 7/26/06 (explanation above) + pc = RegisterFile.getPc(); // added: 7/26/06 (explanation above) RegisterFile.incrementPC(); // Perform the MIPS instruction in synchronized block. If external threads agree // to access MIPS memory and registers only through synchronized blocks on same @@ -469,7 +469,7 @@ public class Simulator extends Observable } // Return if we've reached a breakpoint. if ((breakPoints != null) && - (Arrays.binarySearch(breakPoints, RegisterFile.getProgramCounter()) >= 0)) + (Arrays.binarySearch(breakPoints, RegisterFile.getPc()) >= 0)) { this.constructReturnReason = BREAKPOINT; this.done = false; @@ -518,18 +518,18 @@ public class Simulator extends Observable try { - statement = Globals.memory.getStatement(RegisterFile.getProgramCounter()); + statement = Globals.memory.getStatement(RegisterFile.getPc()); } catch (AddressErrorException e) { ErrorList el = new ErrorList(); - el.add(new ErrorMessage((MIPSprogram) null, 0, 0, "invalid program counter value: " + Binary.intToHexString(RegisterFile.getProgramCounter()))); + el.add(new ErrorMessage((MIPSprogram) null, 0, 0, "invalid program counter value: " + Binary.intToHexString(RegisterFile.getPc()))); this.pe = new ProcessingException(el, e); // Next statement is a hack. Previous statement sets EPC register to ProgramCounter-4 // because it assumes the bad address comes from an operand so the ProgramCounter has already been // incremented. In this case, bad address is the instruction fetch itself so Program Counter has // not yet been incremented. We'll set the EPC directly here. DPS 8-July-2013 - Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getProgramCounter()); + Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getPc()); this.constructReturnReason = EXCEPTION; this.done = true; SystemIO.resetFiles(); // close any files opened in MIPS program diff --git a/src/main/java/mars/tools/BHTSimulator.java b/src/main/java/mars/tools/BHTSimulator.java index f702b7a..482b493 100644 --- a/src/main/java/mars/tools/BHTSimulator.java +++ b/src/main/java/mars/tools/BHTSimulator.java @@ -365,7 +365,7 @@ public class BHTSimulator extends AbstractMarsToolAndApplication implements Acti try { // access the statement in the text segment without notifying other tools etc. - ProgramStatement stmt = Memory.getInstance().getStatementNoNotify(memAccNotice.getAddress()); + ProgramStatement stmt = Memory.getInstance().getStatement(memAccNotice.getAddress()); // necessary to handle possible null pointers at the end of the program // (e.g., if the simulator tries to execute the next instruction after the last instruction in the text segment) diff --git a/src/main/java/mars/tools/BitmapDisplay.kt b/src/main/java/mars/tools/BitmapDisplay.kt index 7a22e10..a7b0a45 100644 --- a/src/main/java/mars/tools/BitmapDisplay.kt +++ b/src/main/java/mars/tools/BitmapDisplay.kt @@ -13,7 +13,6 @@ import java.util.* import javax.swing.* import javax.swing.border.EmptyBorder import kotlin.collections.ArrayList -import kotlin.collections.HashMap import kotlin.collections.HashSet /* @@ -51,10 +50,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class BitmapDisplay : AbstractMarsToolAndApplication { // Major GUI components - private lateinit var uiUnitWidthSelector: JComboBox - private lateinit var uiUnitHeightSelector: JComboBox - private lateinit var uiWidthSelector: JComboBox - private lateinit var uiHeightSelector: JComboBox private lateinit var uiBaseAddressSelector: JComboBox private lateinit var uiKeyboardCheckbox: JCheckBox private lateinit var canvas: JPanel @@ -65,10 +60,10 @@ class BitmapDisplay : AbstractMarsToolAndApplication private val backgroundColor = Color.WHITE // Values for display canvas. Note their initialization uses the identifiers just above. - private val unitWidth get() = uiUnitWidthSelector.getInt() - private val unitHeight get() = uiUnitHeightSelector.getInt() - private val displayWidth get() = uiWidthSelector.getInt() - private val displayHeight get() = uiHeightSelector.getInt() + private var unitWidth: Int = 2 + private var unitHeight: Int = 2 + private var displayWidth: Int = 512 + private var displayHeight: Int = 256 private val displayDimension get() = Dimension(displayWidth, displayHeight) private val baseAddresses = intArrayOf(Memory.dataSegmentBaseAddress, Memory.globalPointer, Memory.dataBaseAddress, @@ -78,6 +73,7 @@ class BitmapDisplay : AbstractMarsToolAndApplication // Keyboard++ private var keyboardAddr: UInt = 0xFFFF0010u + private var displayUpdateAddr: UInt = 0xFFFF0008u private var keyboardAttached = false private lateinit var uiKeyboard: JTextField @@ -180,7 +176,17 @@ class BitmapDisplay : AbstractMarsToolAndApplication } // For the display - updateColorForAddress(ac) + val value = ac.value + val offset = ((addr - baseAddress.toUInt()) / 4u).toInt() + try + { + grid.setElement(offset / grid.cols, offset % grid.cols, value) + } + catch (e: IndexOutOfBoundsException) + { + // If address is out of range for display, do nothing. + } + if (offset == 0) canvas.repaint() } /** @@ -239,17 +245,10 @@ class BitmapDisplay : AbstractMarsToolAndApplication */ override fun reset() { - resetCounts() - updateDisplay() + grid.reset() + canvas.repaint() } - /** - * Updates display immediately after each update (AccessNotice) is processed, after display configuration changes as - * needed, and after each execution step when Mars is running in timed mode. Overrides inherited method that does - * nothing. - */ - override fun updateDisplay() = canvas.repaint() - /** * Overrides default method, to provide a Help button for this tool/app. */ @@ -291,51 +290,55 @@ class BitmapDisplay : AbstractMarsToolAndApplication // UI components and layout for left half of GUI, where settings are specified. private fun buildOrganizationArea(): JComponent { - uiUnitWidthSelector = JComboBox(arrayOf(1, 2, 4, 8, 16, 32)).apply { + val uiUnitWidthSelector = JComboBox(arrayOf(1, 2, 4, 8, 16, 32)).apply { isEditable = false background = backgroundColor selectedIndex = 1 toolTipText = "Width in pixels of rectangle representing memory word" addActionListener { + unitWidth = getInt() grid = createNewGrid() - updateDisplay() + reset() } } - uiUnitHeightSelector = JComboBox(arrayOf(1, 2, 4, 8, 16, 32)).apply { + val uiUnitHeightSelector = JComboBox(arrayOf(1, 2, 4, 8, 16, 32)).apply { isEditable = false background = backgroundColor selectedIndex = 1 toolTipText = "Height in pixels of rectangle representing memory word" addActionListener { + unitHeight = getInt() grid = createNewGrid() - updateDisplay() + reset() } } - uiWidthSelector = JComboBox(arrayOf(64, 128, 256, 512, 1024)).apply { + val uiWidthSelector = JComboBox(arrayOf(64, 128, 256, 512, 1024)).apply { isEditable = false background = backgroundColor selectedIndex = 3 toolTipText = "Total width in pixels of display area" addActionListener { + displayWidth = getInt() canvas.preferredSize = displayDimension canvas.size = displayDimension grid = createNewGrid() - updateDisplay() + reset() } } - uiHeightSelector = JComboBox(arrayOf(64, 128, 256, 512, 1024)).apply { + val uiHeightSelector = JComboBox(arrayOf(64, 128, 256, 512, 1024)).apply { isEditable = false background = backgroundColor selectedIndex = 2 toolTipText = "Total height in pixels of display area" addActionListener { + displayHeight = getInt() canvas.preferredSize = displayDimension canvas.size = displayDimension grid = createNewGrid() - updateDisplay() + reset() } } @@ -358,7 +361,7 @@ class BitmapDisplay : AbstractMarsToolAndApplication addAsObserver() } grid = createNewGrid() - updateDisplay() + reset() } } @@ -467,9 +470,6 @@ class BitmapDisplay : AbstractMarsToolAndApplication return canvas } - // reset all counters in the Grid. - private fun resetCounts() = grid.reset() - private fun JComboBox.getInt() = selectedItem!!.toString().toInt() // Use this for consistent results. @@ -484,22 +484,6 @@ class BitmapDisplay : AbstractMarsToolAndApplication return Grid(rows, columns) } - // Given memory address, update color for the corresponding grid element. - private fun updateColorForAddress(notice: MemoryAccessNotice) - { - val address = notice.address - val value = notice.value - val offset = (address - baseAddress) / Memory.WORD_LENGTH_BYTES - try - { - grid.setElement(offset / grid.cols, offset % grid.cols, value) - } - catch (e: IndexOutOfBoundsException) - { - // If address is out of range for display, do nothing. - } - } - ////////////////////////////////////////////////////////////////////////////////////// // Specialized inner classes for modeling and animation. ////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/mars/tools/InstructionStatistics.java b/src/main/java/mars/tools/InstructionStatistics.java index cff3073..429a45f 100644 --- a/src/main/java/mars/tools/InstructionStatistics.java +++ b/src/main/java/mars/tools/InstructionStatistics.java @@ -318,7 +318,7 @@ public class InstructionStatistics extends AbstractMarsToolAndApplication { // access the statement in the text segment without notifying other tools etc. - ProgramStatement stmt = Memory.getInstance().getStatementNoNotify(memAccNotice.getAddress()); + ProgramStatement stmt = Memory.getInstance().getStatement(memAccNotice.getAddress()); // necessary to handle possible null pointers at the end of the program // (e.g., if the simulator tries to execute the next instruction after the last instruction in the text segment) diff --git a/src/main/java/mars/tools/MipsXray.java b/src/main/java/mars/tools/MipsXray.java index a78f4d3..8eb4921 100644 --- a/src/main/java/mars/tools/MipsXray.java +++ b/src/main/java/mars/tools/MipsXray.java @@ -9,7 +9,6 @@ import mars.mips.hardware.MemoryAccessNotice; import mars.mips.instructions.BasicInstruction; import mars.mips.instructions.BasicInstructionFormat; import mars.venus.RunAssembleAction; -import mars.venus.RunBackstepAction; import mars.venus.RunStepAction; import mars.venus.VenusUI; import org.w3c.dom.Document; @@ -313,11 +312,6 @@ public class MipsXray extends AbstractMarsToolAndApplication "Run one step at a time", Integer.valueOf(KeyEvent.VK_T), KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0), mainUI); - runBackstepAction = new RunBackstepAction("Backstep", - new ImageIcon(tk.getImage(cs.getResource(Globals.imagesPath + "StepBack22.png"))), - "Undo the last step", Integer.valueOf(KeyEvent.VK_B), - KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0), - mainUI); } catch (Exception e) { diff --git a/src/main/java/mars/venus/RegistersWindow.java b/src/main/java/mars/venus/RegistersWindow.java index ec9c1b9..103f71a 100644 --- a/src/main/java/mars/venus/RegistersWindow.java +++ b/src/main/java/mars/venus/RegistersWindow.java @@ -117,7 +117,7 @@ public class RegistersWindow extends JPanel implements Observer } tableData[32][0] = "pc"; tableData[32][1] = "";//new Integer(32); - tableData[32][2] = NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getProgramCounter(), valueBase); + tableData[32][2] = NumberDisplayBaseChooser.formatUnsignedInteger(RegisterFile.getPc(), valueBase); tableData[33][0] = "hi"; tableData[33][1] = "";//new Integer(33); @@ -184,7 +184,7 @@ public class RegistersWindow extends JPanel implements Observer { updateRegisterValue(registers[i].getNumber(), registers[i].getValue(), base); } - updateRegisterUnsignedValue(32, RegisterFile.getProgramCounter(), base); + updateRegisterUnsignedValue(32, RegisterFile.getPc(), base); updateRegisterValue(33, RegisterFile.getValue(33), base); updateRegisterValue(34, RegisterFile.getValue(34), base); } @@ -227,6 +227,7 @@ public class RegistersWindow extends JPanel implements Observer // or stepped mode. if (notice.getRunSpeed() != RunSpeedPanel.UNLIMITED_SPEED || notice.getMaxSteps() == 1) { + System.out.println("Running in timed mode"); RegisterFile.addRegistersObserver(this); this.highlighting = true; } diff --git a/src/main/java/mars/venus/RunBackstepAction.java b/src/main/java/mars/venus/RunBackstepAction.java index 02635fc..3b4b798 100644 --- a/src/main/java/mars/venus/RunBackstepAction.java +++ b/src/main/java/mars/venus/RunBackstepAction.java @@ -75,12 +75,12 @@ public class RunBackstepAction extends GuiAction { boolean inDelaySlot = Globals.program.getBackStepper().inDelaySlot(); // Added 25 June 2007 Memory.getInstance().addObserver(executePane.getDataSegmentWindow()); - RegisterFile.addRegistersObserver(executePane.getRegistersWindow()); + //RegisterFile.addRegistersObserver(executePane.getRegistersWindow()); Coprocessor0.addRegistersObserver(executePane.getCoprocessor0Window()); Coprocessor1.addRegistersObserver(executePane.getCoprocessor1Window()); Globals.program.getBackStepper().backStep(); Memory.getInstance().deleteObserver(executePane.getDataSegmentWindow()); - RegisterFile.deleteRegistersObserver(executePane.getRegistersWindow()); + //RegisterFile.deleteRegistersObserver(executePane.getRegistersWindow()); executePane.getRegistersWindow().updateRegisters(); executePane.getCoprocessor1Window().updateRegisters(); executePane.getCoprocessor0Window().updateRegisters(); diff --git a/src/main/java/mars/venus/RunGoAction.java b/src/main/java/mars/venus/RunGoAction.java index 7c88135..968f32c 100644 --- a/src/main/java/mars/venus/RunGoAction.java +++ b/src/main/java/mars/venus/RunGoAction.java @@ -170,7 +170,7 @@ public class RunGoAction extends GuiAction mainUI.getRegistersPane().setSelectedComponent(executePane.getCoprocessor0Window()); executePane.getTextSegmentWindow().setCodeHighlighting(true); executePane.getTextSegmentWindow().unhighlightAllSteps(); - executePane.getTextSegmentWindow().highlightStepAtAddress(RegisterFile.getProgramCounter() - 4); + executePane.getTextSegmentWindow().highlightStepAtAddress(RegisterFile.getPc() - 4); } switch (reason) { diff --git a/src/main/java/mars/venus/RunStepAction.java b/src/main/java/mars/venus/RunStepAction.java index 136f336..0e2bc77 100644 --- a/src/main/java/mars/venus/RunStepAction.java +++ b/src/main/java/mars/venus/RunStepAction.java @@ -126,7 +126,7 @@ public class RunStepAction extends GuiAction FileStatus.set(FileStatus.TERMINATED); // should be redundant. executePane.getTextSegmentWindow().setCodeHighlighting(true); executePane.getTextSegmentWindow().unhighlightAllSteps(); - executePane.getTextSegmentWindow().highlightStepAtAddress(RegisterFile.getProgramCounter() - 4); + executePane.getTextSegmentWindow().highlightStepAtAddress(RegisterFile.getPc() - 4); } VenusUI.setReset(false); } diff --git a/src/main/java/mars/venus/TextSegmentWindow.java b/src/main/java/mars/venus/TextSegmentWindow.java index b05faf3..4139b4d 100644 --- a/src/main/java/mars/venus/TextSegmentWindow.java +++ b/src/main/java/mars/venus/TextSegmentWindow.java @@ -577,7 +577,7 @@ public class TextSegmentWindow extends JInternalFrame implements Observer */ public void highlightStepAtPC() { - highlightStepAtAddress(RegisterFile.getProgramCounter(), false); + highlightStepAtAddress(RegisterFile.getPc(), false); } /** @@ -589,7 +589,7 @@ public class TextSegmentWindow extends JInternalFrame implements Observer */ public void highlightStepAtPC(boolean inDelaySlot) { - highlightStepAtAddress(RegisterFile.getProgramCounter(), inDelaySlot); + highlightStepAtAddress(RegisterFile.getPc(), inDelaySlot); } /** diff --git a/src/test/java/SpeedTest.kt b/src/test/java/SpeedTest.kt new file mode 100644 index 0000000..2a8783b --- /dev/null +++ b/src/test/java/SpeedTest.kt @@ -0,0 +1,14 @@ +import mars.Globals +import mars.mips.hardware.MemoryConfigurations +import kotlin.system.measureTimeMillis + +fun main(args: Array) +{ + Globals.initialize(true) + MemoryConfigurations.setCurrentConfiguration(MemoryConfigurations.getDefaultConfiguration()) + println(measureTimeMillis { + for (n in 0..100) + for (i in 0..128*256) + Globals.memory.getWord(0x10008000 + i * 4) + }) +}