Source code of MARS Assembler
First commit of the 4.5 version (latest version available)
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,118 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class for memory dump file formats. Provides constructors and
|
||||
* defaults for everything except the dumpMemoryRange method itself.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version December 2007
|
||||
*/
|
||||
|
||||
|
||||
public abstract class AbstractDumpFormat implements DumpFormat {
|
||||
|
||||
private String name, commandDescriptor, description, extension;
|
||||
|
||||
/**
|
||||
* Typical constructor. Note you cannot creates objects from this
|
||||
* class but subclass constructor can call this one.
|
||||
* @param name Brief descriptive name to be displayed in selection list.
|
||||
* @param commandDescriptor One-word descriptive name to be used by MARS command mode parser and user.
|
||||
* Any spaces in this string will be removed.
|
||||
* @param description Description to go with standard file extension for
|
||||
* display in file save dialog or to be used as tool tip.
|
||||
* @param extension Standard file extension for this format. Null if none.
|
||||
*/
|
||||
public AbstractDumpFormat(String name, String commandDescriptor,
|
||||
String description, String extension) {
|
||||
this.name = name;
|
||||
this.commandDescriptor = (commandDescriptor==null) ? null : commandDescriptor.replaceAll(" ","");
|
||||
this.description = description;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the file extension associated with this format.
|
||||
* @return String containing file extension -- without the leading "." -- or
|
||||
* null if there is no standard extension.
|
||||
*/
|
||||
public String getFileExtension() {
|
||||
return extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description of the format, suitable for displaying along with
|
||||
* the extension, in the file save dialog, or as a tool tip.
|
||||
* @return String containing short description to go with the extension
|
||||
* or for use as tool tip. Possibly null.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* String representing this object.
|
||||
* @return Name given for this object.
|
||||
*
|
||||
*/
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* One-word description of format to be used by MARS command mode parser
|
||||
* and user in conjunction with the "dump" option.
|
||||
* @return One-word String describing the format.
|
||||
*
|
||||
*/
|
||||
public String getCommandDescriptor() {
|
||||
return commandDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents according to the
|
||||
* specification for this format.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public abstract void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException;
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.util.Binary;
|
||||
import mars.Globals;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
Copyright (c) 2003-2011, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represents the "ASCII text" memory dump format. Memory contents
|
||||
* are interpreted as ASCII codes. The output
|
||||
* is a text file with one word of MIPS memory per line. The word is formatted
|
||||
* to leave three spaces for each character. Non-printing characters
|
||||
* rendered as period (.) as placeholder. Common escaped characters
|
||||
* rendered using backslash and single-character descriptor, e.g. \t for tab.
|
||||
* @author Pete Sanderson
|
||||
* @version December 2010
|
||||
*/
|
||||
|
||||
|
||||
public class AsciiTextDumpFormat extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. There is no standard file extension for this format.
|
||||
*/
|
||||
public AsciiTextDumpFormat() {
|
||||
super("ASCII Text", "AsciiText", "Memory contents interpreted as ASCII characters", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interpret MIPS memory contents as ASCII characters. Each line of
|
||||
* text contains one memory word written in ASCII characters. Those
|
||||
* corresponding to tab, newline, null, etc are rendered as backslash
|
||||
* followed by single-character code, e.g. \t for tab, \0 for null.
|
||||
* Non-printing character (control code,
|
||||
* values above 127) is rendered as a period (.). Written
|
||||
* using PrintStream's println() method.
|
||||
* Adapted by Pete Sanderson from code written by Greg Gibeling.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
String string = null;
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
out.println(Binary.intToAscii(temp.intValue()));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,84 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represents the "binary" memory dump format. The output
|
||||
* is a binary file containing the memory words as a byte stream. Output
|
||||
* is produced using PrintStream's write() method.
|
||||
* @author Pete Sanderson
|
||||
* @version December 2007
|
||||
*/
|
||||
|
||||
|
||||
public class BinaryDumpFormat extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. There is no standard file extension for this format.
|
||||
*/
|
||||
public BinaryDumpFormat() {
|
||||
super("Binary", "Binary", "Written as byte stream to binary file", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents in pure binary format. One byte at a time
|
||||
* using PrintStream's write() method. Adapted by Pete Sanderson from
|
||||
* code written by Greg Gibeling.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
int word = temp.intValue();
|
||||
for (int i = 0; i < 4; i++)
|
||||
out.write((word >>> (i << 3)) & 0xFF);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,88 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represents the "binary text" memory dump format. The output
|
||||
* is a text file with one word of MIPS memory per line. The word is formatted
|
||||
* using '0' and '1' characters, e.g. 01110101110000011111110101010011.
|
||||
* @author Pete Sanderson
|
||||
* @version December 2007
|
||||
*/
|
||||
|
||||
|
||||
public class BinaryTextDumpFormat extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. There is no standard file extension for this format.
|
||||
*/
|
||||
public BinaryTextDumpFormat() {
|
||||
super("Binary Text", "BinaryText", "Written as '0' and '1' characters to text file", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents in binary text format. Each line of
|
||||
* text contains one memory word written as 32 '0' and '1' characters. Written
|
||||
* using PrintStream's println() method.
|
||||
* Adapted by Pete Sanderson from code written by Greg Gibeling.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
String string = null;
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
string = Integer.toBinaryString(temp.intValue());
|
||||
while (string.length() < 32) {
|
||||
string = '0' + string;
|
||||
}
|
||||
out.println(string);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface for memory dump file formats. All MARS needs to be able
|
||||
* to do is save an assembled program or data in the specified manner for
|
||||
* a given format. Formats are specified through classes
|
||||
* that implement this interface.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version December 2007
|
||||
*/
|
||||
|
||||
|
||||
public interface DumpFormat {
|
||||
|
||||
/**
|
||||
* Get the file extension associated with this format.
|
||||
* @return String containing file extension -- without the leading "." -- or
|
||||
* null if there is no standard extension.
|
||||
*/
|
||||
public String getFileExtension();
|
||||
|
||||
/**
|
||||
* Get a short description of the format, suitable
|
||||
* for displaying along with the extension, if any, in the file
|
||||
* save dialog and also for displaying as a tool tip.
|
||||
* @return String containing short description to go with the extension
|
||||
* or as tool tip when mouse hovers over GUI component representing
|
||||
* this format.
|
||||
*/
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* A short one-word descriptor that will be used by the MARS
|
||||
* command line parser (and the MARS command line user) to specify
|
||||
* that this format is to be used.
|
||||
*/
|
||||
public String getCommandDescriptor();
|
||||
|
||||
/**
|
||||
* Descriptive name for the format.
|
||||
* @return Format name.
|
||||
*
|
||||
*/
|
||||
public String toString();
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents according to the
|
||||
* specification for this format.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException;
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,97 @@
|
||||
package mars.mips.dump;
|
||||
import mars.*;
|
||||
import mars.util.*;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* This class provides functionality to bring external memory dump format definitions
|
||||
* into MARS. This is adapted from the ToolLoader class, which is in turn adapted
|
||||
* from Bret Barker's GameServer class from the book "Developing Games In Java".
|
||||
*/
|
||||
|
||||
public class DumpFormatLoader {
|
||||
|
||||
private static final String CLASS_PREFIX = "mars.mips.dump.";
|
||||
private static final String DUMP_DIRECTORY_PATH = "mars/mips/dump";
|
||||
private static final String SYSCALL_INTERFACE = "DumpFormat.class";
|
||||
private static final String CLASS_EXTENSION = "class";
|
||||
|
||||
private static ArrayList formatList = null;
|
||||
|
||||
/**
|
||||
* Dynamically loads dump formats into an ArrayList. This method is adapted from
|
||||
* the loadGameControllers() method in Bret Barker's GameServer class.
|
||||
* Barker (bret@hypefiend.com) is co-author of the book "Developing Games
|
||||
* in Java". Also see the ToolLoader and SyscallLoader classes elsewhere in MARS.
|
||||
*/
|
||||
|
||||
public ArrayList loadDumpFormats() {
|
||||
// The list will be populated only the first time this method is called.
|
||||
if (formatList == null) {
|
||||
formatList = new ArrayList();
|
||||
// grab all class files in the dump directory
|
||||
ArrayList candidates = FilenameFinder.getFilenameList(this.getClass( ).getClassLoader(),
|
||||
DUMP_DIRECTORY_PATH, CLASS_EXTENSION);
|
||||
for( int i = 0; i < candidates.size(); i++) {
|
||||
String file = (String) candidates.get(i);
|
||||
try {
|
||||
// grab the class, make sure it implements DumpFormat, instantiate, add to list
|
||||
String formatClassName = CLASS_PREFIX+file.substring(0, file.indexOf(CLASS_EXTENSION)-1);
|
||||
Class clas = Class.forName(formatClassName);
|
||||
if (DumpFormat.class.isAssignableFrom(clas) &&
|
||||
!Modifier.isAbstract(clas.getModifiers()) &&
|
||||
!Modifier.isInterface(clas.getModifiers()) ) {
|
||||
formatList.add(clas.newInstance());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Error instantiating DumpFormat from file " + file + ": "+e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return formatList;
|
||||
}
|
||||
|
||||
public static DumpFormat findDumpFormatGivenCommandDescriptor(ArrayList formatList, String formatCommandDescriptor) {
|
||||
DumpFormat match = null;
|
||||
for (int i=0; i<formatList.size(); i++) {
|
||||
if (((DumpFormat)formatList.get(i)).getCommandDescriptor().equals(formatCommandDescriptor)) {
|
||||
match = (DumpFormat) formatList.get(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return match;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,88 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class that represents the "hexadecimal text" memory dump format. The output
|
||||
* is a text file with one word of MIPS memory per line. The word is formatted
|
||||
* using hexadecimal characters, e.g. 3F205A39.
|
||||
* @author Pete Sanderson
|
||||
* @version December 2007
|
||||
*/
|
||||
|
||||
|
||||
public class HexTextDumpFormat extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. There is no standard file extension for this format.
|
||||
*/
|
||||
public HexTextDumpFormat() {
|
||||
super("Hexadecimal Text", "HexText", "Written as hex characters to text file", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents in hexadecimal text format. Each line of
|
||||
* text contains one memory word written in hexadecimal characters. Written
|
||||
* using PrintStream's println() method.
|
||||
* Adapted by Pete Sanderson from code written by Greg Gibeling.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
String string = null;
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
string = Integer.toHexString(temp.intValue());
|
||||
while (string.length() < 8) {
|
||||
string = '0' + string;
|
||||
}
|
||||
out.println(string);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,74 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Intel's Hex memory initialization format
|
||||
* @author Leo Alterman
|
||||
* @version July 2011
|
||||
*/
|
||||
|
||||
public class IntelHexDumpFormat extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. File extention is "hex".
|
||||
*/
|
||||
public IntelHexDumpFormat() {
|
||||
super("Intel hex format", "HEX", "Written as Intel Hex Memory File", "hex");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents according to the Memory Initialization File
|
||||
* (MIF) specification.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
String string = null;
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
string = Integer.toHexString(temp.intValue());
|
||||
while (string.length() < 8) {
|
||||
string = '0' + string;
|
||||
}
|
||||
String addr = Integer.toHexString(address-firstAddress);
|
||||
while (addr.length() < 4) {
|
||||
addr = '0' + addr;
|
||||
}
|
||||
String chksum;
|
||||
int tmp_chksum = 0;
|
||||
tmp_chksum += 4;
|
||||
tmp_chksum += 0xFF & (address-firstAddress);
|
||||
tmp_chksum += 0xFF & ((address-firstAddress)>>8);
|
||||
tmp_chksum += 0xFF & temp.intValue();
|
||||
tmp_chksum += 0xFF & (temp.intValue()>>8);
|
||||
tmp_chksum += 0xFF & (temp.intValue()>>16);
|
||||
tmp_chksum += 0xFF & (temp.intValue()>>24);
|
||||
tmp_chksum = tmp_chksum % 256;
|
||||
tmp_chksum = ~tmp_chksum + 1;
|
||||
chksum = Integer.toHexString(0xFF & tmp_chksum);
|
||||
if(chksum.length()==1) chksum = '0' + chksum;
|
||||
String finalstr = ":04"+addr+"00"+string+chksum;
|
||||
out.println(finalstr.toUpperCase());
|
||||
}
|
||||
out.println(":00000001FF");
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,71 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* The Memory Initialization File (.mif) VHDL-supported file format
|
||||
* This is documented for the Altera platform at
|
||||
* www.altera.com/support/software/nativelink/quartus2/glossary/def_mif.html.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version December 2007
|
||||
*/
|
||||
|
||||
// NOT READY FOR PRIME TIME. WHEN IT IS, UNCOMMENT THE "extends" CLAUSE
|
||||
// AND THE SUPERCLASS CONSTRUCTOR CALL SO THE FORMAT LOADER WILL ACCEPT IT
|
||||
// AND IT WILL BE ADDED TO THE LIST.
|
||||
public class MIFDumpFormat { //extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. File extention is "mif".
|
||||
*/
|
||||
public MIFDumpFormat() {
|
||||
// super("MIF", "MIF", "Written as Memory Initialization File (Altera)", "mif");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents according to the Memory Initialization File
|
||||
* (MIF) specification.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,150 @@
|
||||
package mars.mips.dump;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.ProgramStatement;
|
||||
import mars.util.Binary;
|
||||
import mars.mips.hardware.*;
|
||||
import java.io.*;
|
||||
/*
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Dump MIPS memory contents in Segment Window format. Each line of
|
||||
* text output resembles the Text Segment Window or Data Segment Window
|
||||
* depending on which segment is selected for the dump. Written
|
||||
* using PrintStream's println() method. Each line of Text Segment
|
||||
* Window represents one word of text segment memory. The line
|
||||
* includes (1) address, (2) machine code in hex, (3) basic instruction,
|
||||
* (4) source line. Each line of Data Segment Window represents 8
|
||||
* words of data segment memory. The line includes address of first
|
||||
* word for that line followed by 8 32-bit values.
|
||||
*
|
||||
* In either case, addresses and values are displayed in decimal or
|
||||
* hexadecimal representation according to the corresponding settings.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version January 2008
|
||||
*/
|
||||
|
||||
|
||||
public class SegmentWindowDumpFormat extends AbstractDumpFormat {
|
||||
|
||||
/**
|
||||
* Constructor. There is no standard file extension for this format.
|
||||
*/
|
||||
public SegmentWindowDumpFormat() {
|
||||
super("Text/Data Segment Window", "SegmentWindow", " Text Segment Window or Data Segment Window format to text file", null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write MIPS memory contents in Segment Window format. Each line of
|
||||
* text output resembles the Text Segment Window or Data Segment Window
|
||||
* depending on which segment is selected for the dump. Written
|
||||
* using PrintStream's println() method.
|
||||
*
|
||||
* @param file File in which to store MIPS memory contents.
|
||||
* @param firstAddress first (lowest) memory address to dump. In bytes but
|
||||
* must be on word boundary.
|
||||
* @param lastAddress last (highest) memory address to dump. In bytes but
|
||||
* must be on word boundary. Will dump the word that starts at this address.
|
||||
* @throws AddressErrorException if firstAddress is invalid or not on a word boundary.
|
||||
* @throws IOException if error occurs during file output.
|
||||
*/
|
||||
public void dumpMemoryRange(File file, int firstAddress, int lastAddress)
|
||||
throws AddressErrorException, IOException {
|
||||
|
||||
PrintStream out = new PrintStream(new FileOutputStream(file));
|
||||
|
||||
boolean hexAddresses = Globals.getSettings().getDisplayAddressesInHex();
|
||||
|
||||
// If address in data segment, print in same format as Data Segment Window
|
||||
if (Memory.inDataSegment(firstAddress)) {
|
||||
boolean hexValues = Globals.getSettings().getDisplayValuesInHex();
|
||||
int offset = 0;
|
||||
String string="";
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
if (offset % 8 == 0) {
|
||||
string = ((hexAddresses) ? Binary.intToHexString(address) : Binary.unsignedIntToIntString(address)) + " ";
|
||||
}
|
||||
offset++;
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
string += ((hexValues)
|
||||
? Binary.intToHexString(temp.intValue())
|
||||
: (" "+temp).substring(temp.toString().length())
|
||||
) + " ";
|
||||
if (offset % 8 == 0) {
|
||||
out.println(string);
|
||||
string = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Memory.inTextSegment(firstAddress)) {
|
||||
return;
|
||||
}
|
||||
// If address in text segment, print in same format as Text Segment Window
|
||||
out.println(" Address Code Basic Source");
|
||||
// 12345678901234567890123456789012345678901234567890
|
||||
// 1 2 3 4 5
|
||||
out.println();
|
||||
String string = null;
|
||||
try {
|
||||
for (int address = firstAddress; address <= lastAddress; address += Memory.WORD_LENGTH_BYTES) {
|
||||
string = ((hexAddresses) ? Binary.intToHexString(address) : Binary.unsignedIntToIntString(address)) + " ";
|
||||
Integer temp = Globals.memory.getRawWordOrNull(address);
|
||||
if (temp == null)
|
||||
break;
|
||||
string += Binary.intToHexString(temp.intValue()) + " ";
|
||||
try {
|
||||
ProgramStatement ps = Globals.memory.getStatement(address);
|
||||
string += (ps.getPrintableBasicAssemblyStatement()+" ").substring(0,22);
|
||||
string += (((ps.getSource()=="") ? "" : new Integer(ps.getSourceLine()).toString())+" ").substring(0,5);
|
||||
string += ps.getSource();
|
||||
}
|
||||
catch (AddressErrorException aee) {
|
||||
}
|
||||
out.println(string);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,89 @@
|
||||
package mars.mips.hardware;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object provided to Observers of runtime access to MIPS memory or registers.
|
||||
* The access types READ and WRITE defined here; use subclasses defined for
|
||||
* MemoryAccessNotice and RegisterAccessNotice. This is abstract class.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version July 2005
|
||||
*/
|
||||
|
||||
|
||||
public abstract class AccessNotice {
|
||||
/** Indicates the purpose of access was to read. */
|
||||
public static final int READ = 0;
|
||||
/** Indicates the purpose of access was to write. */
|
||||
public static final int WRITE = 1;
|
||||
|
||||
private int accessType;
|
||||
private Thread thread;
|
||||
|
||||
protected AccessNotice(int type) {
|
||||
if (type != READ && type != WRITE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
accessType = type;
|
||||
thread = Thread.currentThread();
|
||||
}
|
||||
/** Get the access type: READ or WRITE.
|
||||
* @return Access type, either AccessNotice.READ or AccessNotice.WRITE
|
||||
*/
|
||||
public int getAccessType() {
|
||||
return accessType;
|
||||
}
|
||||
|
||||
/** Get reference to thread that created this notice
|
||||
* @return Return reference to the thread that created this notice.
|
||||
*/
|
||||
public Thread getThread() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
/** Query whether the access originated from MARS GUI (AWT event queue)
|
||||
* @return true if this access originated from MARS GUI, false otherwise
|
||||
*/
|
||||
// 'A' is the first character of the main AWT event queue thread name.
|
||||
// "AWT-EventQueue-0"
|
||||
public boolean accessIsFromGUI() {
|
||||
return thread.getName().startsWith("AWT");
|
||||
}
|
||||
|
||||
/** Query whether the access originated from executing MIPS program
|
||||
* @return true if this access originated from executing MIPS program, false otherwise
|
||||
*/
|
||||
// Thread to execute the MIPS program is instantiated in SwingWorker.java.
|
||||
// There it is given the name "MIPS" to replace the default "Thread-x".
|
||||
public boolean accessIsFromMIPS() {
|
||||
return thread.getName().startsWith("MIPS");
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,73 @@
|
||||
package mars.mips.hardware;
|
||||
import mars.util.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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 MIPS AddressErrorException. This is generated by the assembler when the
|
||||
* source code references a memory address not valid for the context.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version August 2003
|
||||
**/
|
||||
public class AddressErrorException extends Exception {
|
||||
private int address;
|
||||
private int type; // Exceptions.ADDRESS_EXCEPTION_LOAD,Exceptions.ADDRESS_EXCEPTION_STORE
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for the AddressErrorException class
|
||||
*
|
||||
* @param addr The erroneous memory address.
|
||||
**/
|
||||
|
||||
public AddressErrorException(String message, int exceptType, int addr) {
|
||||
super(message+Binary.intToHexString(addr));
|
||||
address = addr;
|
||||
type = exceptType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the erroneous memory address.
|
||||
*
|
||||
* @return The erroneous memory address.
|
||||
**/
|
||||
public int getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception type (load or store).
|
||||
*
|
||||
* @return Exception type: Exceptions.ADDRESS_EXCEPTION_LOAD, Exceptions.ADDRESS_EXCEPTION_STORE
|
||||
**/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,215 @@
|
||||
package mars.mips.hardware;
|
||||
import mars.Globals;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2009, 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 Coprocessor 0. We will use only its interrupt/exception registers.
|
||||
* @author Pete Sanderson
|
||||
* @version August 2005
|
||||
**/
|
||||
|
||||
public class Coprocessor0 {
|
||||
/** Coprocessor register names
|
||||
*/
|
||||
public static final int VADDR = 8;
|
||||
public static final int STATUS = 12;
|
||||
public static final int CAUSE = 13;
|
||||
public static final int EPC = 14;
|
||||
|
||||
public static final int EXCEPTION_LEVEL = 1; // bit position in STATUS register
|
||||
// bits 8-15 (mask for interrupt levels) all set, bit 4 (user mode) set,
|
||||
// bit 1 (exception level) not set, bit 0 (interrupt enable) set.
|
||||
public static final int DEFAULT_STATUS_VALUE = 0x0000FF11;
|
||||
|
||||
private static Register [] registers =
|
||||
{ new Register("$8 (vaddr)", 8, 0),
|
||||
new Register("$12 (status)", 12, DEFAULT_STATUS_VALUE),
|
||||
new Register("$13 (cause)", 13, 0),
|
||||
new Register("$14 (epc)", 14, 0)
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Method for displaying the register values for debugging.
|
||||
**/
|
||||
|
||||
public static void showRegisters(){
|
||||
for (int i=0; i< registers.length; i++){
|
||||
System.out.println("Name: " + registers[i].getName());
|
||||
System.out.println("Number: " + registers[i].getNumber());
|
||||
System.out.println("Value: " + registers[i].getValue());
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the register given to the value given.
|
||||
* @param n name of register to set the value of ($n, where n is reg number).
|
||||
* @param val The desired value for the register.
|
||||
* @return old value in register prior to update
|
||||
**/
|
||||
|
||||
public static int updateRegister(String n, int val){
|
||||
int oldValue = 0;
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(("$"+registers[i].getNumber()).equals(n) || registers[i].getName().equals(n)) {
|
||||
oldValue = registers[i].getValue();
|
||||
registers[i].setValue(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the register value who's number is num.
|
||||
* @param num Number of register to set the value of.
|
||||
* @param val The desired value for the register.
|
||||
* @return old value in register prior to update
|
||||
**/
|
||||
public static int updateRegister(int num, int val){
|
||||
int old = 0;
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(registers[i].getNumber()== num) {
|
||||
old = (Globals.getSettings().getBackSteppingEnabled())
|
||||
? Globals.program.getBackStepper().addCoprocessor0Restore(num,registers[i].setValue(val))
|
||||
: registers[i].setValue(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the register who's number is num.
|
||||
* @param num The register number.
|
||||
* @return The value of the given register. 0 for non-implemented registers
|
||||
**/
|
||||
|
||||
public static int getValue(int num){
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(registers[i].getNumber()== num) {
|
||||
return registers[i].getValue();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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. -1 if no match.
|
||||
**/
|
||||
|
||||
public static int getNumber(String n){
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(("$"+registers[i].getNumber()).equals(n) || registers[i].getName().equals(n)) {
|
||||
return registers[i].getNumber();
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* For returning the set of registers.
|
||||
* @return The set of registers.
|
||||
**/
|
||||
|
||||
public static Register[] getRegisters(){
|
||||
return registers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Coprocessor0 implements only selected registers, so the register number
|
||||
* (8, 12, 13, 14) does not correspond to its position in the list of registers
|
||||
* (0, 1, 2, 3).
|
||||
* @param r A coprocessor0 Register
|
||||
* @return the list position of given register, -1 if not found.
|
||||
**/
|
||||
|
||||
public static int getRegisterPosition(Register r){
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(registers[i]==r) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get register object corresponding to given name. If no match, return null.
|
||||
* @param rname The register name, in $0 format.
|
||||
* @return The register object,or null if not found.
|
||||
**/
|
||||
|
||||
public static Register getRegister(String rname) {
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(("$"+registers[i].getNumber()).equals(rname) || registers[i].getName().equals(rname)) {
|
||||
return registers[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to reinitialize the values of the registers.
|
||||
**/
|
||||
|
||||
public static void resetRegisters(){
|
||||
for(int i=0; i< registers.length; i++){
|
||||
registers[i].resetValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Each individual register is a separate object and Observable. This handy method
|
||||
* will add the given Observer to each one.
|
||||
*/
|
||||
public static void addRegistersObserver(Observer observer) {
|
||||
for (int i=0; i<registers.length; i++) {
|
||||
registers[i].addObserver(observer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Each individual register is a separate object and Observable. This handy method
|
||||
* will delete the given Observer from each one.
|
||||
*/
|
||||
public static void deleteRegistersObserver(Observer observer) {
|
||||
for (int i=0; i<registers.length; i++) {
|
||||
registers[i].deleteObserver(observer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,525 @@
|
||||
package mars.mips.hardware;
|
||||
import mars.util.*;
|
||||
import mars.Globals;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2009, 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 Coprocessor 1, the Floating Point Unit (FPU)
|
||||
* @author Pete Sanderson
|
||||
* @version July 2005
|
||||
**/
|
||||
|
||||
// Adapted from RegisterFile class developed by Bumgarner et al in 2003.
|
||||
// The FPU registers will be implemented by Register objects. Such objects
|
||||
// can only hold int values, but we can use Float.floatToIntBits() to translate
|
||||
// a 32 bit float value into its equivalent 32-bit int representation, and
|
||||
// Float.intBitsToFloat() to bring it back. More importantly, there are
|
||||
// similar methods Double.doubleToLongBits() and Double.LongBitsToDouble()
|
||||
// which can be used to extend a double value over 2 registers. The resulting
|
||||
// long is split into 2 int values (high order 32 bits, low order 32 bits) for
|
||||
// storing into registers, and reassembled upon retrieval.
|
||||
|
||||
public class Coprocessor1 {
|
||||
private static Register [] registers =
|
||||
{ new Register("$f0", 0, 0), new Register("$f1", 1, 0),
|
||||
new Register("$f2", 2, 0), new Register("$f3", 3, 0),
|
||||
new Register("$f4", 4, 0), new Register("$f5", 5, 0),
|
||||
new Register("$f6", 6, 0), new Register("$f7", 7, 0),
|
||||
new Register("$f8", 8, 0), new Register("$f9", 9, 0),
|
||||
new Register("$f10", 10, 0),new Register("$f11", 11, 0),
|
||||
new Register("$f12", 12, 0),new Register("$f13", 13, 0),
|
||||
new Register("$f14", 14, 0),new Register("$f15", 15, 0),
|
||||
new Register("$f16", 16, 0),new Register("$f17", 17, 0),
|
||||
new Register("$f18", 18, 0),new Register("$f19", 19, 0),
|
||||
new Register("$f20", 20, 0),new Register("$f21", 21, 0),
|
||||
new Register("$f22", 22, 0),new Register("$f23", 23, 0),
|
||||
new Register("$f24", 24, 0),new Register("$f25", 25, 0),
|
||||
new Register("$f26", 26, 0),new Register("$f27", 27, 0),
|
||||
new Register("$f28", 28, 0),new Register("$f29", 29, 0),
|
||||
new Register("$f30", 30, 0),new Register("$f31", 31, 0)
|
||||
};
|
||||
// The 8 condition flags will be stored in bits 0-7 for flags 0-7.
|
||||
private static Register condition = new Register("cf",32, 0);
|
||||
private static int numConditionFlags = 8;
|
||||
|
||||
/**
|
||||
* Method for displaying the register values for debugging.
|
||||
**/
|
||||
|
||||
public static void showRegisters(){
|
||||
for (int i=0; i< registers.length; i++){
|
||||
|
||||
System.out.println("Name: " + registers[i].getName());
|
||||
System.out.println("Number: " + registers[i].getNumber());
|
||||
System.out.println("Value: " + registers[i].getValue());
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register given to the value given.
|
||||
* @param reg Register to set the value of.
|
||||
* @param val The desired float value for the register.
|
||||
**/
|
||||
|
||||
public static void setRegisterToFloat(String reg, float val){
|
||||
setRegisterToFloat(getRegisterNumber(reg), val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register given to the value given.
|
||||
* @param reg Register to set the value of.
|
||||
* @param val The desired float value for the register.
|
||||
**/
|
||||
|
||||
public static void setRegisterToFloat(int reg, float val){
|
||||
if(reg >= 0 && reg < registers.length) {
|
||||
registers[reg].setValue(Float.floatToRawIntBits(val));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register given to the 32-bit
|
||||
* pattern given by the int parameter.
|
||||
* @param reg Register to set the value of.
|
||||
* @param val The desired int bit pattern for the register.
|
||||
**/
|
||||
|
||||
public static void setRegisterToInt(String reg, int val){
|
||||
setRegisterToInt(getRegisterNumber(reg), val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register given to the 32-bit
|
||||
* pattern given by the int parameter.
|
||||
* @param reg Register to set the value of.
|
||||
* @param val The desired int bit pattern for the register.
|
||||
**/
|
||||
|
||||
public static void setRegisterToInt(int reg, int val){
|
||||
if(reg >= 0 && reg < registers.length) {
|
||||
registers[reg].setValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register given to the double value given. The register
|
||||
* must be even-numbered, and the low order 32 bits are placed in it. The high order
|
||||
* 32 bits are placed in the (odd numbered) register that follows it.
|
||||
* @param reg Register to set the value of.
|
||||
* @param val The desired double value for the register.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
|
||||
public static void setRegisterPairToDouble(int reg, double val)
|
||||
throws InvalidRegisterAccessException {
|
||||
if (reg % 2 != 0) {
|
||||
throw new InvalidRegisterAccessException();
|
||||
}
|
||||
long bits = Double.doubleToRawLongBits(val);
|
||||
registers[reg+1].setValue(Binary.highOrderLongToInt(bits)); // high order 32 bits
|
||||
registers[reg].setValue(Binary.lowOrderLongToInt(bits)); // low order 32 bits
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register given to the double value given. The register
|
||||
* must be even-numbered, and the low order 32 bits are placed in it. The high order
|
||||
* 32 bits are placed in the (odd numbered) register that follows it.
|
||||
* @param reg Register to set the value of.
|
||||
* @param val The desired double value for the register.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
public static void setRegisterPairToDouble(String reg, double val)
|
||||
throws InvalidRegisterAccessException {
|
||||
setRegisterPairToDouble(getRegisterNumber(reg), val);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register pair given to the long value containing 64 bit pattern
|
||||
* given. The register
|
||||
* must be even-numbered, and the low order 32 bits from the long are placed in it. The high order
|
||||
* 32 bits from the long are placed in the (odd numbered) register that follows it.
|
||||
* @param reg Register to set the value of. Must be even register of even/odd pair.
|
||||
* @param val The desired double value for the register.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
|
||||
public static void setRegisterPairToLong(int reg, long val)
|
||||
throws InvalidRegisterAccessException {
|
||||
if (reg % 2 != 0) {
|
||||
throw new InvalidRegisterAccessException();
|
||||
}
|
||||
registers[reg+1].setValue(Binary.highOrderLongToInt(val)); // high order 32 bits
|
||||
registers[reg].setValue(Binary.lowOrderLongToInt(val)); // low order 32 bits
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of the FPU register pair given to the long value containing 64 bit pattern
|
||||
* given. The register
|
||||
* must be even-numbered, and the low order 32 bits from the long are placed in it. The high order
|
||||
* 32 bits from the long are placed in the (odd numbered) register that follows it.
|
||||
* @param reg Register to set the value of. Must be even register of even/odd pair.
|
||||
* @param val The desired long value containing the 64 bits for the register pair.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
public static void setRegisterPairToLong(String reg, long val)
|
||||
throws InvalidRegisterAccessException {
|
||||
setRegisterPairToLong(getRegisterNumber(reg), val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the float value stored in the given FPU register.
|
||||
* @param reg Register to get the value of.
|
||||
* @return The float value stored by that register.
|
||||
**/
|
||||
|
||||
public static float getFloatFromRegister(int reg){
|
||||
float result = 0F;
|
||||
if(reg >= 0 && reg < registers.length) {
|
||||
result = Float.intBitsToFloat(registers[reg].getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the float value stored in the given FPU register.
|
||||
* @param reg Register to get the value of.
|
||||
* @return The float value stored by that register.
|
||||
**/
|
||||
|
||||
public static float getFloatFromRegister(String reg) {
|
||||
return getFloatFromRegister(getRegisterNumber(reg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the 32-bit int bit pattern stored in the given FPU register.
|
||||
* @param reg Register to get the value of.
|
||||
* @return The int bit pattern stored by that register.
|
||||
**/
|
||||
|
||||
public static int getIntFromRegister(int reg){
|
||||
int result = 0;
|
||||
if(reg >= 0 && reg < registers.length) {
|
||||
result = registers[reg].getValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the 32-bit int bit pattern stored in the given FPU register.
|
||||
* @param reg Register to get the value of.
|
||||
* @return The int bit pattern stored by that register.
|
||||
**/
|
||||
|
||||
public static int getIntFromRegister(String reg) {
|
||||
return getIntFromRegister(getRegisterNumber(reg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the double value stored in the given FPU register. The register
|
||||
* must be even-numbered.
|
||||
* @param reg Register to get the value of. Must be even number of even/odd pair.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
|
||||
public static double getDoubleFromRegisterPair(int reg)
|
||||
throws InvalidRegisterAccessException {
|
||||
double result = 0.0;
|
||||
if (reg % 2 != 0) {
|
||||
throw new InvalidRegisterAccessException();
|
||||
}
|
||||
long bits = Binary.twoIntsToLong(registers[reg+1].getValue(),registers[reg].getValue());
|
||||
return Double.longBitsToDouble(bits);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the double value stored in the given FPU register. The register
|
||||
* must be even-numbered.
|
||||
* @param reg Register to get the value of. Must be even number of even/odd pair.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
|
||||
public static double getDoubleFromRegisterPair(String reg)
|
||||
throws InvalidRegisterAccessException {
|
||||
return getDoubleFromRegisterPair(getRegisterNumber(reg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a long representing the double value stored in the given double
|
||||
* precision FPU register.
|
||||
* The register must be even-numbered.
|
||||
* @param reg Register to get the value of. Must be even number of even/odd pair.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
|
||||
public static long getLongFromRegisterPair(int reg)
|
||||
throws InvalidRegisterAccessException {
|
||||
double result = 0.0;
|
||||
if (reg % 2 != 0) {
|
||||
throw new InvalidRegisterAccessException();
|
||||
}
|
||||
return Binary.twoIntsToLong(registers[reg+1].getValue(),registers[reg].getValue());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the double value stored in the given FPU register. The register
|
||||
* must be even-numbered.
|
||||
* @param reg Register to get the value of. Must be even number of even/odd pair.
|
||||
* @throws InvalidRegisterAccessException if register ID is invalid or odd-numbered.
|
||||
**/
|
||||
|
||||
public static long getLongFromRegisterPair(String reg)
|
||||
throws InvalidRegisterAccessException {
|
||||
return getLongFromRegisterPair(getRegisterNumber(reg));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method updates the FPU register value who's number is num. Note the
|
||||
* registers themselves hold an int value. There are helper methods available
|
||||
* to which you can give a float or double to store.
|
||||
* @param num FPU register to set the value of.
|
||||
* @param val The desired int value for the register.
|
||||
**/
|
||||
|
||||
public static int updateRegister(int num, int val){
|
||||
int old = 0;
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(registers[i].getNumber()== num) {
|
||||
old = (Globals.getSettings().getBackSteppingEnabled())
|
||||
? Globals.program.getBackStepper().addCoprocessor1Restore(num,registers[i].setValue(val))
|
||||
: registers[i].setValue(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the FPU register who's number is num. Returns the
|
||||
* raw int value actually stored there. If you need a float, use
|
||||
* Float.intBitsToFloat() to get the equivent float.
|
||||
* @param num The FPU register number.
|
||||
* @return The int value of the given register.
|
||||
**/
|
||||
|
||||
public static int getValue(int num){
|
||||
return registers[num].getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* For getting the number representation of the FPU register.
|
||||
* @param n The string formatted register name to look for.
|
||||
* @return The number of the register represented by the string.
|
||||
**/
|
||||
|
||||
public static int getRegisterNumber(String n){
|
||||
int j=-1;
|
||||
for (int i=0; i< registers.length; i++){
|
||||
if(registers[i].getName().equals(n)) {
|
||||
j= registers[i].getNumber();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
/**
|
||||
* For returning the set of registers.
|
||||
* @return The set of registers.
|
||||
**/
|
||||
|
||||
public static Register[] getRegisters(){
|
||||
return registers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get register object corresponding to given name. If no match, return null.
|
||||
* @param rName The FPU register name, must be "$f0" through "$f31".
|
||||
* @return The register object,or null if not found.
|
||||
**/
|
||||
|
||||
public static Register getRegister(String rName) {
|
||||
Register reg = null;
|
||||
if (rName.charAt(0) == '$' && rName.length() > 1 && rName.charAt(1) == 'f') {
|
||||
try {
|
||||
// check for register number 0-31.
|
||||
reg = registers[Binary.stringToInt(rName.substring(2))]; // KENV 1/6/05
|
||||
}
|
||||
catch (Exception e) {
|
||||
// handles both NumberFormat and ArrayIndexOutOfBounds
|
||||
reg = null;
|
||||
}
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to reinitialize the values of the registers.
|
||||
**/
|
||||
|
||||
public static void resetRegisters(){
|
||||
for(int i=0; i < registers.length; i++)
|
||||
registers[i].resetValue();
|
||||
clearConditionFlags();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Each individual register is a separate object and Observable. This handy method
|
||||
* will add the given Observer to each one.
|
||||
*/
|
||||
public static void addRegistersObserver(Observer observer) {
|
||||
for (int i=0; i<registers.length; i++) {
|
||||
registers[i].addObserver(observer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Each individual register is a separate object and Observable. This handy method
|
||||
* will delete the given Observer from each one.
|
||||
*/
|
||||
public static void deleteRegistersObserver(Observer observer) {
|
||||
for (int i=0; i<registers.length; i++) {
|
||||
registers[i].deleteObserver(observer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set condition flag to 1 (true).
|
||||
*
|
||||
* @param flag condition flag number (0-7)
|
||||
* @return previous flag setting (0 or 1)
|
||||
*/
|
||||
public static int setConditionFlag(int flag) {
|
||||
int old = 0;
|
||||
if (flag >= 0 && flag < numConditionFlags) {
|
||||
old = getConditionFlag(flag);
|
||||
condition.setValue(Binary.setBit(condition.getValue(),flag));
|
||||
if (Globals.getSettings().getBackSteppingEnabled())
|
||||
if (old==0) {
|
||||
Globals.program.getBackStepper().addConditionFlagClear(flag);
|
||||
}
|
||||
else {
|
||||
Globals.program.getBackStepper().addConditionFlagSet(flag);
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set condition flag to 0 (false).
|
||||
*
|
||||
* @param flag condition flag number (0-7)
|
||||
* @return previous flag setting (0 or 1)
|
||||
*/
|
||||
public static int clearConditionFlag(int flag) {
|
||||
int old = 0;
|
||||
if (flag >= 0 && flag < numConditionFlags) {
|
||||
old = getConditionFlag(flag);
|
||||
condition.setValue(Binary.clearBit(condition.getValue(),flag));
|
||||
if (Globals.getSettings().getBackSteppingEnabled())
|
||||
if (old==0) {
|
||||
Globals.program.getBackStepper().addConditionFlagClear(flag);
|
||||
}
|
||||
else {
|
||||
Globals.program.getBackStepper().addConditionFlagSet(flag);
|
||||
}
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get value of specified condition flag (0-7).
|
||||
*
|
||||
* @param flag condition flag number (0-7)
|
||||
* @return 0 if condition is false, 1 if condition is true
|
||||
*/
|
||||
public static int getConditionFlag(int flag) {
|
||||
if (flag < 0 || flag >= numConditionFlags)
|
||||
flag = 0;
|
||||
return Binary.bitValue(condition.getValue(), flag);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get array of condition flags (0-7).
|
||||
*
|
||||
* @return array of int condition flags
|
||||
*/
|
||||
public static int getConditionFlags() {
|
||||
return condition.getValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clear all condition flags (0-7).
|
||||
*
|
||||
*/
|
||||
public static void clearConditionFlags() {
|
||||
condition.setValue(0); // sets all 32 bits to 0.
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all condition flags (0-7).
|
||||
*
|
||||
*/
|
||||
public static void setConditionFlags() {
|
||||
condition.setValue(-1); // sets all 32 bits to 1.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count of condition flags.
|
||||
*
|
||||
* @return number of condition flags
|
||||
*/
|
||||
public static int getConditionFlagCount() {
|
||||
return numConditionFlags;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,51 @@
|
||||
package mars.mips.hardware;
|
||||
import mars.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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 attempt to access double precision register using an odd
|
||||
* (e.g. $f1, $f23) register name.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version July 2005
|
||||
**/
|
||||
|
||||
public class InvalidRegisterAccessException extends Exception {
|
||||
private ErrorList errs;
|
||||
|
||||
/**
|
||||
* Constructor for IllegalRegisterException.
|
||||
*
|
||||
**/
|
||||
public InvalidRegisterAccessException() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,79 @@
|
||||
package mars.mips.hardware;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object provided to Observers of runtime access to MIPS memory.
|
||||
* Observer can get the access type (R/W), address and length in bytes (4,2,1).
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version July 2005
|
||||
*/
|
||||
|
||||
public class MemoryAccessNotice extends AccessNotice {
|
||||
private int address;
|
||||
private int length;
|
||||
private int value;
|
||||
|
||||
/** Constructor will be called only within this package, so assume
|
||||
* address and length are in valid ranges.
|
||||
*/
|
||||
MemoryAccessNotice(int type, int address, int length, int value) {
|
||||
super(type);
|
||||
this.address = address;
|
||||
this.length = length;
|
||||
this.value = value;
|
||||
}
|
||||
/** Constructor will be called only within this package, so assume
|
||||
* address is in valid range.
|
||||
*/
|
||||
public MemoryAccessNotice(int type, int address, int value) {
|
||||
super(type);
|
||||
this.address = address;
|
||||
this.length = Memory.WORD_LENGTH_BYTES;
|
||||
this.value = value;
|
||||
}
|
||||
/** Fetch the memory address that was accessed. */
|
||||
public int getAddress() {
|
||||
return address;
|
||||
}
|
||||
/** Fetch the length in bytes of the access operation (4,2,1). */
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
/** Fetch the value of the access operation (the value read or written). */
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
/** String representation indicates access type, address and length in bytes */
|
||||
public String toString() {
|
||||
return ((this.getAccessType()==AccessNotice.READ) ? "R " : "W ") +
|
||||
"Mem " + address + " " + length + "B = "+value;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,157 @@
|
||||
package mars.mips.hardware;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2009, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Models the memory configuration for the simulated MIPS machine.
|
||||
* "configuration" refers to the starting memory addresses for
|
||||
* the various memory segments.
|
||||
* The default configuration is based on SPIM. Starting with MARS 3.7,
|
||||
* the configuration can be changed.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version August 2009
|
||||
*/
|
||||
|
||||
|
||||
public class MemoryConfiguration {
|
||||
// Identifier is used for saving setting; name is used for display
|
||||
private String configurationIdentifier, configurationName;
|
||||
private String[] configurationItemNames;
|
||||
private int[] configurationItemValues;
|
||||
|
||||
|
||||
public MemoryConfiguration(String ident, String name, String[] items, int[] values) {
|
||||
this.configurationIdentifier = ident;
|
||||
this.configurationName = name;
|
||||
this.configurationItemNames = items;
|
||||
this.configurationItemValues = values;
|
||||
}
|
||||
|
||||
public String getConfigurationIdentifier() {
|
||||
return configurationIdentifier;
|
||||
}
|
||||
|
||||
public String getConfigurationName() {
|
||||
return configurationName;
|
||||
}
|
||||
|
||||
public int[] getConfigurationItemValues() {
|
||||
return configurationItemValues;
|
||||
}
|
||||
|
||||
public String[] getConfigurationItemNames() {
|
||||
return configurationItemNames;
|
||||
}
|
||||
|
||||
public int getTextBaseAddress() {
|
||||
return configurationItemValues[0];
|
||||
}
|
||||
|
||||
public int getDataSegmentBaseAddress() {
|
||||
return configurationItemValues[1];
|
||||
}
|
||||
|
||||
public int getExternBaseAddress() {
|
||||
return configurationItemValues[2];
|
||||
}
|
||||
|
||||
public int getGlobalPointer() {
|
||||
return configurationItemValues[3];
|
||||
}
|
||||
|
||||
public int getDataBaseAddress() {
|
||||
return configurationItemValues[4];
|
||||
}
|
||||
|
||||
public int getHeapBaseAddress() {
|
||||
return configurationItemValues[5];
|
||||
}
|
||||
|
||||
public int getStackPointer() {
|
||||
return configurationItemValues[6];
|
||||
}
|
||||
|
||||
public int getStackBaseAddress() {
|
||||
return configurationItemValues[7];
|
||||
}
|
||||
|
||||
public int getUserHighAddress() {
|
||||
return configurationItemValues[8];
|
||||
}
|
||||
|
||||
public int getKernelBaseAddress() {
|
||||
return configurationItemValues[9];
|
||||
}
|
||||
|
||||
public int getKernelTextBaseAddress() {
|
||||
return configurationItemValues[10];
|
||||
}
|
||||
|
||||
public int getExceptionHandlerAddress() {
|
||||
return configurationItemValues[11];
|
||||
}
|
||||
|
||||
public int getKernelDataBaseAddress() {
|
||||
return configurationItemValues[12];
|
||||
}
|
||||
|
||||
public int getMemoryMapBaseAddress() {
|
||||
return configurationItemValues[13];
|
||||
}
|
||||
|
||||
public int getKernelHighAddress () {
|
||||
return configurationItemValues[14];
|
||||
}
|
||||
|
||||
public int getDataSegmentLimitAddress() {
|
||||
return configurationItemValues[15];
|
||||
}
|
||||
|
||||
public int getTextLimitAddress() {
|
||||
return configurationItemValues[16];
|
||||
}
|
||||
|
||||
public int getKernelDataSegmentLimitAddress() {
|
||||
return configurationItemValues[17];
|
||||
}
|
||||
|
||||
public int getKernelTextLimitAddress() {
|
||||
return configurationItemValues[18];
|
||||
}
|
||||
|
||||
public int getStackLimitAddress() {
|
||||
return configurationItemValues[19];
|
||||
}
|
||||
|
||||
public int getMemoryMapLimitAddress() {
|
||||
return configurationItemValues[20];
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,322 @@
|
||||
package mars.mips.hardware;
|
||||
import mars.Globals;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2009, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Models the collection of MIPS memory configurations.
|
||||
* The default configuration is based on SPIM. Starting with MARS 3.7,
|
||||
* the configuration can be changed.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version August 2009
|
||||
*/
|
||||
|
||||
|
||||
public class MemoryConfigurations {
|
||||
|
||||
private static ArrayList configurations = null;
|
||||
private static MemoryConfiguration defaultConfiguration;
|
||||
private static MemoryConfiguration currentConfiguration;
|
||||
|
||||
// Be careful, these arrays are parallel and position-sensitive.
|
||||
// The getters in this and in MemoryConfiguration depend on this
|
||||
// sequence. Should be refactored... The order comes from the
|
||||
// original listed order in Memory.java, where most of these were
|
||||
// "final" until Mars 3.7 and changeable memory configurations.
|
||||
private static final String[] configurationItemNames = {
|
||||
".text base address",
|
||||
"data segment base address",
|
||||
".extern base address",
|
||||
"global pointer $gp",
|
||||
".data base address",
|
||||
"heap base address",
|
||||
"stack pointer $sp",
|
||||
"stack base address",
|
||||
"user space high address",
|
||||
"kernel space base address",
|
||||
".ktext base address",
|
||||
"exception handler address",
|
||||
".kdata base address",
|
||||
"MMIO base address",
|
||||
"kernel space high address",
|
||||
"data segment limit address",
|
||||
"text limit address",
|
||||
"kernel data segment limit address",
|
||||
"kernel text limit address",
|
||||
"stack limit address",
|
||||
"memory map limit address"
|
||||
};
|
||||
|
||||
// Default configuration comes from SPIM
|
||||
private static int[] defaultConfigurationItemValues = {
|
||||
0x00400000, // .text Base Address
|
||||
0x10000000, // Data Segment base address
|
||||
0x10000000, // .extern Base Address
|
||||
0x10008000, // Global Pointer $gp)
|
||||
0x10010000, // .data base Address
|
||||
0x10040000, // heap base address
|
||||
0x7fffeffc, // stack pointer $sp (from SPIM not MIPS)
|
||||
0x7ffffffc, // stack base address
|
||||
0x7fffffff, // highest address in user space
|
||||
0x80000000, // lowest address in kernel space
|
||||
0x80000000, // .ktext base address
|
||||
0x80000180, // exception handler address
|
||||
0x90000000, // .kdata base address
|
||||
0xffff0000, // MMIO base address
|
||||
0xffffffff, // highest address in kernel (and memory)
|
||||
0x7fffffff, // data segment limit address
|
||||
0x0ffffffc, // text limit address
|
||||
0xfffeffff, // kernel data segment limit address
|
||||
0x8ffffffc, // kernel text limit address
|
||||
0x10040000, // stack limit address
|
||||
0xffffffff // memory map limit address
|
||||
};
|
||||
|
||||
// Compact allows 16 bit addressing, data segment starts at 0
|
||||
private static int[] dataBasedCompactConfigurationItemValues = {
|
||||
0x00003000, // .text Base Address
|
||||
0x00000000, // Data Segment base address
|
||||
0x00001000, // .extern Base Address
|
||||
0x00001800, // Global Pointer $gp)
|
||||
0x00000000, // .data base Address
|
||||
0x00002000, // heap base address
|
||||
0x00002ffc, // stack pointer $sp
|
||||
0x00002ffc, // stack base address
|
||||
0x00003fff, // highest address in user space
|
||||
0x00004000, // lowest address in kernel space
|
||||
0x00004000, // .ktext base address
|
||||
0x00004180, // exception handler address
|
||||
0x00005000, // .kdata base address
|
||||
0x00007f00, // MMIO base address
|
||||
0x00007fff, // highest address in kernel (and memory)
|
||||
0x00002fff, // data segment limit address
|
||||
0x00003ffc, // text limit address
|
||||
0x00007eff, // kernel data segment limit address
|
||||
0x00004ffc, // kernel text limit address
|
||||
0x00002000, // stack limit address
|
||||
0x00007fff // memory map limit address
|
||||
};
|
||||
|
||||
// Compact allows 16 bit addressing, text segment starts at 0
|
||||
private static int[] textBasedCompactConfigurationItemValues = {
|
||||
0x00000000, // .text Base Address
|
||||
0x00001000, // Data Segment base address
|
||||
0x00001000, // .extern Base Address
|
||||
0x00001800, // Global Pointer $gp)
|
||||
0x00002000, // .data base Address
|
||||
0x00003000, // heap base address
|
||||
0x00003ffc, // stack pointer $sp
|
||||
0x00003ffc, // stack base address
|
||||
0x00003fff, // highest address in user space
|
||||
0x00004000, // lowest address in kernel space
|
||||
0x00004000, // .ktext base address
|
||||
0x00004180, // exception handler address
|
||||
0x00005000, // .kdata base address
|
||||
0x00007f00, // MMIO base address
|
||||
0x00007fff, // highest address in kernel (and memory)
|
||||
0x00003fff, // data segment limit address
|
||||
0x00000ffc, // text limit address
|
||||
0x00007eff, // kernel data segment limit address
|
||||
0x00004ffc, // kernel text limit address
|
||||
0x00003000, // stack limit address
|
||||
0x00007fff // memory map limit address
|
||||
};
|
||||
|
||||
|
||||
|
||||
public MemoryConfigurations() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void buildConfigurationCollection() {
|
||||
if (configurations == null) {
|
||||
configurations = new ArrayList();
|
||||
configurations.add(new MemoryConfiguration("Default", "Default", configurationItemNames, defaultConfigurationItemValues));
|
||||
configurations.add(new MemoryConfiguration("CompactDataAtZero", "Compact, Data at Address 0", configurationItemNames, dataBasedCompactConfigurationItemValues));
|
||||
configurations.add(new MemoryConfiguration("CompactTextAtZero", "Compact, Text at Address 0", configurationItemNames, textBasedCompactConfigurationItemValues));
|
||||
defaultConfiguration = (MemoryConfiguration) configurations.get(0);
|
||||
currentConfiguration = defaultConfiguration;
|
||||
// Get current config from settings
|
||||
//String currentConfigurationIdentifier = Globals.getSettings().getMemoryConfiguration();
|
||||
setCurrentConfiguration(getConfigurationByName(Globals.getSettings().getMemoryConfiguration()));
|
||||
// Iterator configurationsIterator = getConfigurationsIterator();
|
||||
// while (configurationsIterator.hasNext()) {
|
||||
// MemoryConfiguration config = (MemoryConfiguration)configurationsIterator.next();
|
||||
// if (currentConfigurationIdentifier.equals(config.getConfigurationIdentifier())) {
|
||||
// setCurrentConfiguration(config);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
public static Iterator getConfigurationsIterator() {
|
||||
if (configurations == null) {
|
||||
buildConfigurationCollection();
|
||||
}
|
||||
return configurations.iterator();
|
||||
|
||||
}
|
||||
|
||||
public static MemoryConfiguration getConfigurationByName(String name) {
|
||||
Iterator configurationsIterator = getConfigurationsIterator();
|
||||
while (configurationsIterator.hasNext()) {
|
||||
MemoryConfiguration config = (MemoryConfiguration)configurationsIterator.next();
|
||||
if (name.equals(config.getConfigurationIdentifier())) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static MemoryConfiguration getDefaultConfiguration() {
|
||||
if (defaultConfiguration == null) {
|
||||
buildConfigurationCollection();
|
||||
}
|
||||
return defaultConfiguration;
|
||||
}
|
||||
|
||||
public static MemoryConfiguration getCurrentConfiguration() {
|
||||
if (currentConfiguration == null) {
|
||||
buildConfigurationCollection();
|
||||
}
|
||||
return currentConfiguration;
|
||||
}
|
||||
|
||||
public static boolean setCurrentConfiguration(MemoryConfiguration config) {
|
||||
if (config == null)
|
||||
return false;
|
||||
if (config != currentConfiguration) {
|
||||
currentConfiguration = config;
|
||||
Globals.memory.clear();
|
||||
RegisterFile.getUserRegister("$gp").changeResetValue(config.getGlobalPointer());
|
||||
RegisterFile.getUserRegister("$sp").changeResetValue(config.getStackPointer());
|
||||
RegisterFile.getProgramCounterRegister().changeResetValue(config.getTextBaseAddress());
|
||||
RegisterFile.initializeProgramCounter(config.getTextBaseAddress());
|
||||
RegisterFile.resetRegisters();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// Use these to intialize Memory static variables at launch
|
||||
|
||||
public static int getDefaultTextBaseAddress() {
|
||||
return defaultConfigurationItemValues[0];
|
||||
}
|
||||
|
||||
public static int getDefaultDataSegmentBaseAddress() {
|
||||
return defaultConfigurationItemValues[1];
|
||||
}
|
||||
|
||||
public static int getDefaultExternBaseAddress() {
|
||||
return defaultConfigurationItemValues[2];
|
||||
}
|
||||
|
||||
public static int getDefaultGlobalPointer() {
|
||||
return defaultConfigurationItemValues[3];
|
||||
}
|
||||
|
||||
public static int getDefaultDataBaseAddress() {
|
||||
return defaultConfigurationItemValues[4];
|
||||
}
|
||||
|
||||
public static int getDefaultHeapBaseAddress() {
|
||||
return defaultConfigurationItemValues[5];
|
||||
}
|
||||
|
||||
public static int getDefaultStackPointer() {
|
||||
return defaultConfigurationItemValues[6];
|
||||
}
|
||||
|
||||
public static int getDefaultStackBaseAddress() {
|
||||
return defaultConfigurationItemValues[7];
|
||||
}
|
||||
|
||||
public static int getDefaultUserHighAddress() {
|
||||
return defaultConfigurationItemValues[8];
|
||||
}
|
||||
|
||||
public static int getDefaultKernelBaseAddress() {
|
||||
return defaultConfigurationItemValues[9];
|
||||
}
|
||||
|
||||
public static int getDefaultKernelTextBaseAddress() {
|
||||
return defaultConfigurationItemValues[10];
|
||||
}
|
||||
|
||||
public static int getDefaultExceptionHandlerAddress() {
|
||||
return defaultConfigurationItemValues[11];
|
||||
}
|
||||
|
||||
public static int getDefaultKernelDataBaseAddress() {
|
||||
return defaultConfigurationItemValues[12];
|
||||
}
|
||||
|
||||
public static int getDefaultMemoryMapBaseAddress() {
|
||||
return defaultConfigurationItemValues[13];
|
||||
}
|
||||
|
||||
public static int getDefaultKernelHighAddress () {
|
||||
return defaultConfigurationItemValues[14];
|
||||
}
|
||||
|
||||
public int getDefaultDataSegmentLimitAddress() {
|
||||
return defaultConfigurationItemValues[15];
|
||||
}
|
||||
|
||||
public int getDefaultTextLimitAddress() {
|
||||
return defaultConfigurationItemValues[16];
|
||||
}
|
||||
|
||||
public int getDefaultKernelDataSegmentLimitAddress() {
|
||||
return defaultConfigurationItemValues[17];
|
||||
}
|
||||
|
||||
public int getDefaultKernelTextLimitAddress() {
|
||||
return defaultConfigurationItemValues[18];
|
||||
}
|
||||
|
||||
public int getDefaultStackLimitAddress() {
|
||||
return defaultConfigurationItemValues[19];
|
||||
}
|
||||
|
||||
public int getMemoryMapLimitAddress() {
|
||||
return defaultConfigurationItemValues[20];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,154 @@
|
||||
package mars.mips.hardware;
|
||||
import mars.*;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstraction to represent a register of a MIPS Assembler.
|
||||
* @author Jason Bumgarner, Jason Shrewsbury, Ben Sherman
|
||||
* @version June 2003
|
||||
**/
|
||||
|
||||
public class Register extends Observable {
|
||||
private String name;
|
||||
private int number, resetValue;
|
||||
// volatile should be enough to allow safe multi-threaded 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.
|
||||
private volatile int value;
|
||||
|
||||
/**
|
||||
* Creates a new register with specified name, number, and value.
|
||||
* @param n The name of the register.
|
||||
* @param num The number of the register.
|
||||
* @param val The inital (and reset) value of the register.
|
||||
*/
|
||||
|
||||
public Register(String n, int num, int val){
|
||||
name= n;
|
||||
number=num;
|
||||
value= val;
|
||||
resetValue = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the Register.
|
||||
* @return name The name of the Register.
|
||||
*/
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the Register. Observers are notified
|
||||
* of the READ operation.
|
||||
* @return value The value of the Register.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the reset value of the Register.
|
||||
* @return The reset (initial) value of the Register.
|
||||
*/
|
||||
|
||||
public int getResetValue(){
|
||||
return resetValue;
|
||||
}
|
||||
/**
|
||||
* Returns the number of the Register.
|
||||
* @return number The number of the Register.
|
||||
*/
|
||||
|
||||
public int getNumber(){
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the register to the val passed to it.
|
||||
* Observers are notified of the WRITE operation.
|
||||
* @param val Value to set the Register to.
|
||||
* @return previous value of register
|
||||
*/
|
||||
|
||||
public synchronized int setValue(int val){
|
||||
int old = value;
|
||||
value = val;
|
||||
notifyAnyObservers(AccessNotice.WRITE);
|
||||
return old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the value of the register to the value it was constructed with.
|
||||
* Observers are not notified.
|
||||
*/
|
||||
|
||||
public synchronized void resetValue(){
|
||||
value = resetValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the register's reset value; the value to which it will be
|
||||
* set when <tt>resetValue()</tt> is called.
|
||||
*/
|
||||
|
||||
public synchronized void changeResetValue(int reset) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
package mars.mips.hardware;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Object provided to Observers of runtime access to MIPS register.
|
||||
* Observer can get the access type (R/W) and register number.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version July 2005
|
||||
*/
|
||||
|
||||
public class RegisterAccessNotice extends AccessNotice {
|
||||
private String registerName;
|
||||
|
||||
/** Constructor will be called only within this package, so assume
|
||||
* register number is in valid range.
|
||||
*/
|
||||
RegisterAccessNotice(int type, String registerName) {
|
||||
super(type);
|
||||
this.registerName = registerName;
|
||||
}
|
||||
/** Fetch the register number of register accessed. */
|
||||
public String getRegisterName() {
|
||||
return registerName;
|
||||
}
|
||||
/** String representation indicates access type and which register */
|
||||
public String toString() {
|
||||
return ((this.getAccessType()==AccessNotice.READ) ? "R " : "W ") +
|
||||
"Reg " + registerName;
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,339 @@
|
||||
package mars.mips.hardware;
|
||||
|
||||
import java.util.Observer;
|
||||
|
||||
import mars.Globals;
|
||||
import mars.assembler.SymbolTable;
|
||||
import mars.mips.instructions.Instruction;
|
||||
import mars.util.Binary;
|
||||
|
||||
/*
|
||||
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 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 Register programCounter= new Register("pc", 32, Memory.textBaseAddress);
|
||||
private static Register hi= new Register("hi", 33, 0);//this is an internal register with arbitrary number
|
||||
private static 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.
|
||||
* <b>NOTE:</b> Should <i>not</i> 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
|
||||
* <code>AbstractMarsToolAndApplication</code>.
|
||||
**/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,142 @@
|
||||
package mars.mips.instructions;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2013, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class to represent a basic instruction in the MIPS instruction set.
|
||||
* Basic instruction means it translates directly to a 32-bit binary machine
|
||||
* instruction.
|
||||
*
|
||||
* @author Pete Sanderson and Ken Vollmar
|
||||
* @version August 2003
|
||||
*/
|
||||
public class BasicInstruction extends Instruction {
|
||||
|
||||
private String instructionName;
|
||||
private BasicInstructionFormat instructionFormat;
|
||||
private String operationMask;
|
||||
private SimulationCode simulationCode;
|
||||
|
||||
private int opcodeMask; // integer with 1's where constants required (0/1 become 1, f/s/t become 0)
|
||||
private int opcodeMatch; // integer matching constants required (0/1 become 0/1, f/s/t become 0)
|
||||
/**
|
||||
* BasicInstruction constructor.
|
||||
*
|
||||
* @param example An example usage of the instruction, as a String.
|
||||
* @param instrFormat The format is R, I, I-branch or J.
|
||||
* @param operMask The opcode mask is a 32 character string that contains the opcode in binary in the appropriate bit positions and codes for operand positions ('f', 's', 't') in the remainding positions.
|
||||
* @param simCode The inline definition of an object and class which anonymously implements the SimulationCode interface.
|
||||
* @see SimulationCode
|
||||
**/
|
||||
/* codes for operand positions are:
|
||||
* f == First operand
|
||||
* s == Second operand
|
||||
* t == Third operand
|
||||
* example: "add rd,rs,rt" is R format with fields in this order: opcode, rs, rt, rd, shamt, funct.
|
||||
* Its opcode is 0, shamt is 0, funct is 0x40. Based on operand order, its mask is
|
||||
* "000000ssssstttttfffff00000100000", split into
|
||||
* opcode | rs | rt | rd | shamt | funct
|
||||
* 000000 | sssss | ttttt | fffff | 00000 | 100000
|
||||
* This mask can be used at code generation time to map the assembly component to its
|
||||
* correct bit positions in the binary machine instruction.
|
||||
* It can also be used at runtime to match a binary machine instruction to the correct
|
||||
* instruction simulator -- it needs to match all and only the 0's and 1's.
|
||||
*/
|
||||
public BasicInstruction(String example, String description, BasicInstructionFormat instrFormat,
|
||||
String operMask, SimulationCode simCode) {
|
||||
this.exampleFormat = example;
|
||||
this.mnemonic = this.extractOperator(example);
|
||||
this.description = description;
|
||||
this.instructionFormat = instrFormat;
|
||||
this.operationMask = operMask.replaceAll(" ",""); // squeeze out any/all spaces
|
||||
if (operationMask.length() != Instruction.INSTRUCTION_LENGTH_BITS) {
|
||||
System.out.println(example+" mask not "+Instruction.INSTRUCTION_LENGTH_BITS+" bits!");
|
||||
}
|
||||
this.simulationCode = simCode;
|
||||
|
||||
this.opcodeMask = (int) Long.parseLong(this.operationMask.replaceAll("[01]", "1").replaceAll("[^01]", "0"), 2);
|
||||
this.opcodeMatch = (int) Long.parseLong(this.operationMask.replaceAll("[^1]", "0"), 2);
|
||||
}
|
||||
|
||||
// Temporary constructor so that instructions without description yet will compile.
|
||||
|
||||
public BasicInstruction(String example, BasicInstructionFormat instrFormat,
|
||||
String operMask, SimulationCode simCode) {
|
||||
this(example,"",instrFormat,operMask,simCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 32-character operation mask. Each mask position represents a
|
||||
* bit position in the 32-bit machine instruction. Operation codes and
|
||||
* unused bits are represented in the mask by 1's and 0's. Operand codes
|
||||
* are represented by 'f', 's', and 't' for bits occupied by first, secon
|
||||
* and third operand, respectively.
|
||||
*
|
||||
* @return The 32 bit mask, as a String
|
||||
*/
|
||||
public String getOperationMask() {
|
||||
return operationMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the operand format of the instruction. MIPS defines 3 of these
|
||||
* R-format, I-format, and J-format. R-format is all registers. I-format
|
||||
* is address formed from register base with immediate offset. J-format
|
||||
* is for jump destination addresses. I have added one more:
|
||||
* I-branch-format, for branch destination addresses. These are a variation
|
||||
* of the I-format in that the computed value is address relative to the
|
||||
* Program Counter. All four formats are represented by static objects.
|
||||
*
|
||||
* @return The machine instruction format, R, I, J or I-branch.
|
||||
*/
|
||||
public BasicInstructionFormat getInstructionFormat() {
|
||||
return instructionFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SimulationCode object. It is really an object of an anonymous
|
||||
* class that implements the SimulationCode interface. Such an object has but one
|
||||
* method: Simulate().
|
||||
*
|
||||
* @return the SimulationCode object for this instruction.
|
||||
* @see SimulationCode
|
||||
**/
|
||||
|
||||
public SimulationCode getSimulationCode() {
|
||||
return simulationCode;
|
||||
}
|
||||
|
||||
public int getOpcodeMask() {
|
||||
return this.opcodeMask;
|
||||
}
|
||||
|
||||
public int getOpcodeMatch() {
|
||||
return this.opcodeMatch;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,51 @@
|
||||
package mars.mips.instructions;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* These are the MIPS-defined formats of basic machine instructions. The R-format indicates
|
||||
* the instruction works only with registers. The I-format indicates the instruction
|
||||
* works with an immediate value (e.g. constant). The J-format indicates this is a Jump
|
||||
* instruction. The I-branch-format is defined by me, not MIPS, to to indicate this is
|
||||
* a Branch instruction, specifically to distinguish immediate
|
||||
* values used as target addresses.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version August 2003
|
||||
*/
|
||||
public class BasicInstructionFormat {
|
||||
public static final BasicInstructionFormat R_FORMAT = new BasicInstructionFormat();
|
||||
public static final BasicInstructionFormat I_FORMAT = new BasicInstructionFormat();
|
||||
public static final BasicInstructionFormat I_BRANCH_FORMAT = new BasicInstructionFormat();
|
||||
public static final BasicInstructionFormat J_FORMAT = new BasicInstructionFormat();
|
||||
|
||||
// private default constructor prevents objects of this class other than those above.
|
||||
private BasicInstructionFormat() {
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,638 @@
|
||||
package mars.mips.instructions;
|
||||
import mars.*;
|
||||
import mars.util.*;
|
||||
import mars.assembler.*;
|
||||
import mars.mips.hardware.*;
|
||||
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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* ExtendedInstruction represents a MIPS extended (a.k.a pseudo) instruction. This
|
||||
* assembly language instruction does not have a corresponding machine instruction. Instead
|
||||
* it is translated by the extended assembler into one or more basic instructions (operations
|
||||
* that have a corresponding machine instruction). The TranslationCode object is
|
||||
* responsible for performing the translation.
|
||||
*
|
||||
* @author Pete Sanderson
|
||||
* @version August 2003
|
||||
*/
|
||||
public class ExtendedInstruction extends Instruction {
|
||||
|
||||
private ArrayList translationStrings, compactTranslationStrings;
|
||||
/**
|
||||
* Constructor for ExtendedInstruction.
|
||||
*
|
||||
* @param example A String containing example use of the MIPS extended instruction.
|
||||
* @param translation Specifications for translating this instruction into a sequence
|
||||
* of one or more MIPS basic instructions.
|
||||
* @param compactTranslation Alternative translation that can be used if running under
|
||||
* a compact (16 bit) memory configuration.
|
||||
* @param description a helpful description to be included on help requests
|
||||
*
|
||||
* The presence of an alternative "compact translation" can optimize code generation
|
||||
* by assuming that data label addresses are 16 bits instead of 32
|
||||
**/
|
||||
|
||||
public ExtendedInstruction(String example, String translation, String compactTranslation, String description) {
|
||||
this.exampleFormat = example;
|
||||
this.description = description;
|
||||
this.mnemonic = this.extractOperator(example);
|
||||
this.createExampleTokenList();
|
||||
this.translationStrings = buildTranslationList(translation);
|
||||
this.compactTranslationStrings = buildTranslationList(compactTranslation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for ExtendedInstruction. No compact translation is provided.
|
||||
*
|
||||
* @param example A String containing example use of the MIPS extended instruction.
|
||||
* @param translation Specifications for translating this instruction into a sequence
|
||||
* of one or more MIPS basic instructions.
|
||||
* @param description a helpful description to be included on help requests
|
||||
**/
|
||||
|
||||
public ExtendedInstruction(String example, String translation, String description) {
|
||||
this.exampleFormat = example;
|
||||
this.description = description;
|
||||
this.mnemonic = this.extractOperator(example);
|
||||
this.createExampleTokenList();
|
||||
this.translationStrings = buildTranslationList(translation);
|
||||
this.compactTranslationStrings = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for ExtendedInstruction, where no instruction description or
|
||||
* compact translation is provided.
|
||||
*
|
||||
* @param example A String containing example use of the MIPS extended instruction.
|
||||
* @param translation Specifications for translating this instruction into a sequence
|
||||
* of one or more MIPS basic instructions.
|
||||
**/
|
||||
|
||||
public ExtendedInstruction(String example, String translation) {
|
||||
this(example, translation, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length in bytes that this extended instruction requires in its
|
||||
* binary form. The answer depends on how many basic instructions it
|
||||
* expands to. This may vary, if expansion includes a nop, depending on
|
||||
* whether or not delayed branches are enabled. Each requires 4 bytes.
|
||||
* @return int length in bytes of corresponding binary instruction(s).
|
||||
*/
|
||||
|
||||
public int getInstructionLength() {
|
||||
return getInstructionLength(translationStrings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get ArrayList of Strings that represent list of templates for
|
||||
* basic instructions generated by this extended instruction.
|
||||
* @return ArrayList of Strings.
|
||||
*/
|
||||
|
||||
public ArrayList getBasicIntructionTemplateList() {
|
||||
return translationStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length in bytes that this extended instruction requires in its
|
||||
* binary form if it includes an alternative expansion for compact
|
||||
* memory (16 bit addressing) configuration. The answer depends on
|
||||
* how many basic instructions it expands to. This may vary, if
|
||||
* expansion includes a nop, depending on whether or not delayed
|
||||
* branches are enabled. Each requires 4 bytes.
|
||||
* @return int length in bytes of corresponding binary instruction(s).
|
||||
* Returns 0 if an alternative expansion is not defined for this
|
||||
* instruction.
|
||||
*/
|
||||
|
||||
public int getCompactInstructionLength() {
|
||||
return getInstructionLength(compactTranslationStrings);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not this pseudo-instruction has a second
|
||||
* translation optimized for 16 bit address space: a compact version.
|
||||
*/
|
||||
public boolean hasCompactTranslation() {
|
||||
return compactTranslationStrings != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get ArrayList of Strings that represent list of templates for
|
||||
* basic instructions generated by the "compact" or 16-bit version
|
||||
* of this extended instruction.
|
||||
* @return ArrayList of Strings. Returns null if the instruction does not
|
||||
* have a compact alternative.
|
||||
*/
|
||||
|
||||
public ArrayList getCompactBasicIntructionTemplateList() {
|
||||
return compactTranslationStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a basic instruction template and the list of tokens from an extended
|
||||
* instruction statement, substitute operands from the token list appropriately into the
|
||||
* template to generate the basic statement. Assumes the extended instruction statement has
|
||||
* been translated from source form to basic assembly form (e.g. register mnemonics
|
||||
* translated to corresponding register numbers).
|
||||
* Operand format of source statement is already verified correct.
|
||||
* Assume the template has correct number and positions of operands.
|
||||
* Template is String with special markers. In the list below, n represents token position (1,2,3,etc)
|
||||
* in source statement (operator is token 0, parentheses count but commas don't):
|
||||
* <UL>
|
||||
* <LI>RGn means substitute register found in n'th token of source statement
|
||||
* <LI>NRn means substitute next higher register than the one in n'th token of source code
|
||||
* <LI>OPn means substitute n'th token of source code as is
|
||||
* <LI>LLn means substitute low order 16 bits from label address in source token n.
|
||||
* <LI>LLnU means substitute low order 16 bits (unsigned) from label address in source token n.
|
||||
* <LI>LLnPm (m=1,2,3,4) means substitute low order 16 bits from label address in source token n, after adding m.
|
||||
* <LI>LHn means substitute high order 16 bits from label address in source token n. Must add 1 if address bit 15 is 1.
|
||||
* <LI>LHnPm (m=1,2,3,4) means substitute high order 16 bits from label address in source token n, after adding m. Must then add 1 if bit 15 is 1.
|
||||
* <LI>VLn means substitute low order 16 bits from 32 bit value in source token n.
|
||||
* <LI>VLnU means substitute low order 16 bits (unsigned) from 32 bit value in source token n.
|
||||
* <LI>VLnPm (m=1,2,3,4) means substitute low order 16 bits from 32 bit value in source token n, after adding m to value.
|
||||
* <LI>VLnPmU (m=1,2,3,4) means substitute low order 16 bits (unsigned) from 32 bit value in source token n, after adding m to value.
|
||||
* <LI>VHLn means substitute high order 16 bits from 32 bit value in source token n. Use this if later combined with low order 16 bits using "ori $1,$1,VLn". See logical and branch operations.
|
||||
* <LI>VHn means substitute high order 16 bits from 32 bit value in source token n, then add 1 if value's bit 15 is 1. Use this only if later instruction uses VLn($1) to calculate 32 bit address. See loads and stores.
|
||||
* <LI>VHLnPm (m=1,2,3,4) means substitute high order 16 bits from 32 bit value in source token n, after adding m. See VHLn.
|
||||
* <LI>VHnPm (m=1,2,3,4) means substitute high order 16 bits from 32 bit value in source token n, after adding m. Must then add 1 if bit 15 is 1. See VHn.
|
||||
* <LI>LLP is similar to LLn, but is needed for "label+100000" address offset. Immediate is added before taking low order 16.
|
||||
* <LI>LLPU is similar to LLnU, but is needed for "label+100000" address offset. Immediate is added before taking low order 16 (unsigned).
|
||||
* <LI>LLPPm (m=1,2,3,4) is similar to LLP except m is added along with mmediate before taking low order 16.
|
||||
* <LI>LHPA is similar to LHn, but is needed for "label+100000" address offset. Immediate is added before taking high order 16.
|
||||
* <LI>LHPN is similar to LHPA, used only by "la" instruction. Address resolved by "ori" so do not add 1 if bit 15 is 1.
|
||||
* <LI>LHPAPm (m=1,2,3,4) is similar to LHPA except value m is added along with immediate before taking high order 16.
|
||||
* <LI>LHL means substitute high order 16 bits from label address in token 2 of "la" (load address) source statement.
|
||||
* <LI>LAB means substitute textual label from last token of source statement. Used for various branches.
|
||||
* <LI>S32 means substitute the result of subtracting the constant value in last token from 32. Used by "ror", "rol".
|
||||
* <LI>DBNOP means Delayed Branching NOP - generate a "nop" instruction but only if delayed branching is enabled. Added in 3.4.1 release.
|
||||
* <LI>BROFFnm means substitute n if delayed branching is NOT enabled otherwise substitute m. n and m are single digit numbers indicating constant branch offset (in words). Added in 3.4.1 release.
|
||||
* </UL>
|
||||
* @param template a String containing template for basic statement.
|
||||
* @param tokenList a TokenList containing tokens from extended instruction.
|
||||
* @return String representing basic assembler statement.
|
||||
*/
|
||||
|
||||
public static String makeTemplateSubstitutions(MIPSprogram program, String template, TokenList theTokenList) {
|
||||
String instruction = template;
|
||||
int index;
|
||||
// Added 22 Jan 2008 by DPS. The DBNOP template means to generate a "nop" instruction if delayed branching
|
||||
// is enabled and generate no instruction otherwise.
|
||||
|
||||
//This is the goal, but it leads to a cascade of
|
||||
// additional changes, so for now I will generate "nop" in either case, then come back to it for the
|
||||
// next major release.
|
||||
if (instruction.indexOf("DBNOP")>=0) {
|
||||
return Globals.getSettings().getDelayedBranchingEnabled() ? "nop" : "";
|
||||
}
|
||||
// substitute first operand token for template's RG1 or OP1, second for RG2 or OP2, etc
|
||||
for (int op=1; op<theTokenList.size(); op++) {
|
||||
instruction = substitute(instruction, "RG"+op,theTokenList.get(op).getValue());
|
||||
instruction = substitute(instruction, "OP"+op,theTokenList.get(op).getValue());
|
||||
// substitute upper 16 bits of label address, after adding singe digit constant following P
|
||||
if ((index=instruction.indexOf("LH"+op+"P"))>=0) {
|
||||
// Label, last operand, has already been translated to address by symtab lookup
|
||||
String label = theTokenList.get(op).getValue();
|
||||
int addr = 0;
|
||||
int add = instruction.charAt(index+4)-48; // extract the digit following P
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + add; // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
// If bit 15 is 1, that means lower 16 bits will become a negative offset! To
|
||||
// compensate if that is the case, we need to add 1 to the high 16 bits.
|
||||
int extra = Binary.bitValue(addr,15);
|
||||
instruction = substitute(instruction,"LH"+op+"P"+add,String.valueOf((addr >> 16)+extra));
|
||||
}
|
||||
// substitute upper 16 bits of label address
|
||||
// NOTE: form LHnPm will not match here since it is discovered and substituted above.
|
||||
if (instruction.indexOf("LH"+op)>=0) {
|
||||
// Label, last operand, has already been translated to address by symtab lookup
|
||||
String label = theTokenList.get(op).getValue();
|
||||
int addr = 0;
|
||||
try {
|
||||
addr = Binary.stringToInt(label); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
// If bit 15 is 1, that means lower 16 bits will become a negative offset! To
|
||||
// compensate if that is the case, we need to add 1 to the high 16 bits.
|
||||
int extra = Binary.bitValue(addr,15);
|
||||
instruction = substitute(instruction,"LH"+op,String.valueOf((addr >> 16)+extra));
|
||||
}
|
||||
// substitute lower 16 bits of label address, after adding single digit that follows P
|
||||
if ((index=instruction.indexOf("LL"+op+"P"))>=0) {
|
||||
// label has already been translated to address by symtab lookup.
|
||||
String label = theTokenList.get(op).getValue();
|
||||
int addr = 0;
|
||||
int add = instruction.charAt(index+4)-48; // digit that follows P
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + add; // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"LL"+op+"P"+add,String.valueOf(addr << 16 >> 16));//addr & 0xffff));
|
||||
}
|
||||
// substitute lower 16 bits of label address.
|
||||
// NOTE: form LLnPm will not match here since it is discovered and substituted above.
|
||||
if ((index=instruction.indexOf("LL"+op))>=0) {
|
||||
// label has already been translated to address by symtab lookup.
|
||||
String label = theTokenList.get(op).getValue();
|
||||
int addr = 0;
|
||||
try {
|
||||
addr = Binary.stringToInt(label); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
if ((instruction.length() > index+3) && (instruction.charAt(index+3) == 'U')) {
|
||||
instruction = substitute(instruction,"LL"+op+"U",String.valueOf(addr & 0xffff));
|
||||
}
|
||||
else {
|
||||
instruction = substitute(instruction,"LL"+op,String.valueOf(addr << 16 >> 16));//addr & 0xffff));
|
||||
}
|
||||
}
|
||||
// Substitute upper 16 bits of value after adding 1,2,3,4, (any single digit)
|
||||
// Added by DPS on 22 Jan 2008 to fix "ble" and "bgt" bug [do not adjust for bit 15==1]
|
||||
if ((index=instruction.indexOf("VHL"+op+"P"))>=0) {
|
||||
String value = theTokenList.get(op).getValue();
|
||||
int val = 0;
|
||||
int add = instruction.charAt(index+5)-'0'; // amount to add: 1,2,3,4 (any single digit)
|
||||
try { // KENV 1/6/05
|
||||
val = Binary.stringToInt(value) + add;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"VHL"+op+"P"+add,String.valueOf(val >> 16));
|
||||
}
|
||||
// substitute upper 16 bits of value after adding 1,2,3,4, then adjust
|
||||
// if necessary, if resulting bit 15 is 1 (see "extra" below)
|
||||
if ((index=instruction.indexOf("VH"+op+"P"))>=0) {
|
||||
String value = theTokenList.get(op).getValue();
|
||||
int val = 0;
|
||||
int add = instruction.charAt(index+4)-'0'; // amount to add: 1,2,3,4 (any single digit)
|
||||
try { // KENV 1/6/05
|
||||
val = Binary.stringToInt(value) + add;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
// If bit 15 is 1, that means lower 16 bits will become a negative offset! To
|
||||
// compensate if that is the case, we need to add 1 to the high 16 bits.
|
||||
int extra = Binary.bitValue(val,15);
|
||||
instruction = substitute(instruction,"VH"+op+"P"+add,String.valueOf((val >> 16)+extra));
|
||||
}
|
||||
// substitute upper 16 bits of value, adjusted if necessary (see "extra" below)
|
||||
// NOTE: if VHnPm appears it will not match here; already substituted by code above
|
||||
if (instruction.indexOf("VH"+op)>=0) {
|
||||
String value = theTokenList.get(op).getValue();
|
||||
int val = 0;
|
||||
try {
|
||||
val = Binary.stringToInt(value); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
// If bit 15 is 1, that means lower 16 bits will become a negative offset! To
|
||||
// compensate if that is the case, we need to add 1 to the high 16 bits.
|
||||
int extra = Binary.bitValue(val,15);
|
||||
instruction = substitute(instruction,"VH"+op,String.valueOf((val >> 16)+extra));
|
||||
}
|
||||
// substitute lower 16 bits of value after adding specified amount (1,2,3,4)
|
||||
if ((index=instruction.indexOf("VL"+op+"P"))>=0) {
|
||||
String value = theTokenList.get(op).getValue();
|
||||
int val = 0;
|
||||
int add = instruction.charAt(index+4)-'0'; // P is followed by 1,2,3,4(any single digit OK)
|
||||
try { // KENV 1/6/05
|
||||
val = Binary.stringToInt(value) + add;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
if ((instruction.length() > index+5) && (instruction.charAt(index+5) == 'U')) {
|
||||
instruction = substitute(instruction,"VL"+op+"P"+add+"U",String.valueOf(val & 0xffff));
|
||||
}
|
||||
else {
|
||||
instruction = substitute(instruction,"VL"+op+"P"+add,String.valueOf(val << 16 >> 16));//val & 0xffff));
|
||||
}
|
||||
}
|
||||
// substitute lower 16 bits of value. NOTE: VLnPm already substituted by above code.
|
||||
if ((index=instruction.indexOf("VL"+op))>=0) {
|
||||
String value = theTokenList.get(op).getValue();
|
||||
int val = 0;
|
||||
try {
|
||||
val = Binary.stringToInt(value); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
if ((instruction.length() > index+3) && (instruction.charAt(index+3) == 'U')) {
|
||||
instruction = substitute(instruction,"VL"+op+"U",String.valueOf(val & 0xffff));
|
||||
}
|
||||
else {
|
||||
instruction = substitute(instruction,"VL"+op,String.valueOf(val << 16 >> 16));//val & 0xffff));
|
||||
}
|
||||
}
|
||||
// substitute upper 16 bits of 32 bit value
|
||||
if (instruction.indexOf("VHL"+op)>=0) {
|
||||
// value has to be second operand token.
|
||||
String value = theTokenList.get(op).getValue(); // has to be token 2 position
|
||||
int val = 0;
|
||||
try {
|
||||
val = Binary.stringToInt(value); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"VHL"+op,String.valueOf(val >> 16));
|
||||
}
|
||||
}
|
||||
// substitute upper 16 bits of label address for "la"
|
||||
if (instruction.indexOf("LHL")>=0) {
|
||||
// Label has already been translated to address by symtab lookup
|
||||
String label = theTokenList.get(2).getValue(); // has to be token 2 position
|
||||
int addr = 0;
|
||||
try {
|
||||
addr = Binary.stringToInt(label); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"LHL",String.valueOf(addr >> 16));
|
||||
}
|
||||
|
||||
// substitute upper 16 bits of label address after adding the digit that follows "P" and
|
||||
// also adding the immediate e.g. here+44($s0)
|
||||
// Address will be resolved using addition, so need to add 1 to upper half if bit 15 is 1.
|
||||
if ((index=instruction.indexOf("LHPAP"))>=0) {
|
||||
// Label has already been translated to address by symtab lookup
|
||||
String label = theTokenList.get(2).getValue(); // 2 is only possible token position
|
||||
String addend= theTokenList.get(4).getValue(); // 4 is only possible token position
|
||||
int addr = 0;
|
||||
int add = instruction.charAt(index+5)-48; // extract digit following P
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + // KENV 1/6/05
|
||||
Binary.stringToInt(addend) + add;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
// If bit 15 is 1, that means lower 16 bits will become a negative offset! To
|
||||
// compensate if that is the case, we need to add 1 to the high 16 bits.
|
||||
int extra = Binary.bitValue(addr,15);
|
||||
instruction = substitute(instruction,"LHPAP"+add,String.valueOf((addr >> 16) + extra));
|
||||
}
|
||||
// substitute upper 16 bits of label address after adding constant e.g. here+4($s0)
|
||||
// Address will be resolved using addition, so need to add 1 to upper half if bit 15 is 1.
|
||||
// NOTE: format LHPAPm is recognized and substituted by the code above.
|
||||
if (instruction.indexOf("LHPA")>=0) {
|
||||
// Label has already been translated to address by symtab lookup
|
||||
String label = theTokenList.get(2).getValue(); // 2 is only possible token position
|
||||
String addend= theTokenList.get(4).getValue(); // 4 is only possible token position
|
||||
int addr = 0;
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + // KENV 1/6/05
|
||||
Binary.stringToInt(addend);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
// If bit 15 is 1, that means lower 16 bits will become a negative offset! To
|
||||
// compensate if that is the case, we need to add 1 to the high 16 bits.
|
||||
int extra = Binary.bitValue(addr,15);
|
||||
instruction = substitute(instruction,"LHPA",String.valueOf((addr >> 16) + extra));
|
||||
}
|
||||
// substitute upper 16 bits of label address after adding constant e.g. here+4($s0)
|
||||
// Address will be resolved using "ori", so DO NOT adjust upper 16 if bit 15 is 1.
|
||||
// This only happens in the "la" (load address) instruction.
|
||||
if (instruction.indexOf("LHPN")>=0) {
|
||||
// Label has already been translated to address by symtab lookup
|
||||
String label = theTokenList.get(2).getValue(); // 2 is only possible token position
|
||||
String addend= theTokenList.get(4).getValue(); // 4 is only possible token position
|
||||
int addr = 0;
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + // KENV 1/6/05
|
||||
Binary.stringToInt(addend);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"LHPN",String.valueOf(addr >> 16));
|
||||
}
|
||||
// substitute lower 16 bits of label address after adding immediate value e.g. here+44($s0)
|
||||
// and also adding the digit following LLPP in the spec.
|
||||
if ((index=instruction.indexOf("LLPP"))>=0) {
|
||||
// label has already been translated to address by symtab lookup.
|
||||
String label = theTokenList.get(2).getValue(); // 2 is only possible token position
|
||||
String addend= theTokenList.get(4).getValue(); // 4 is only possible token position
|
||||
int addr = 0;
|
||||
int add = instruction.charAt(index+4)-48; // extract digit following P
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + // KENV 1/6/05
|
||||
Binary.stringToInt(addend) + add;
|
||||
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"LLPP"+add,String.valueOf(addr << 16 >> 16));//addr & 0xffff));
|
||||
}
|
||||
// substitute lower 16 bits of label address after adding immediate value e.g. here+44($s0)
|
||||
// NOTE: format LLPPm is recognized and substituted by the code above
|
||||
if ((index=instruction.indexOf("LLP"))>=0) {
|
||||
// label has already been translated to address by symtab lookup.
|
||||
String label = theTokenList.get(2).getValue(); // 2 is only possible token position
|
||||
String addend= theTokenList.get(4).getValue(); // 4 is only possible token position
|
||||
int addr = 0;
|
||||
try {
|
||||
addr = Binary.stringToInt(label) + // KENV 1/6/05
|
||||
Binary.stringToInt(addend);
|
||||
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
if ((instruction.length() > index+3) && (instruction.charAt(index+3) == 'U')) {
|
||||
instruction = substitute(instruction,"LLPU",String.valueOf(addr & 0xffff));
|
||||
}
|
||||
else {
|
||||
instruction = substitute(instruction,"LLP",String.valueOf(addr << 16 >> 16));//addr & 0xffff));
|
||||
}
|
||||
}
|
||||
// 23-Jan-2008 DPS. Substitute correct constant branch offset depending on whether or not
|
||||
// delayed branching is enabled. BROFF is followed by 2 digits. The first is branch offset
|
||||
// to substitute if delayed branching is DISABLED, second is offset if ENABLED.
|
||||
if ((index=instruction.indexOf("BROFF"))>=0) {
|
||||
try {
|
||||
String disabled = instruction.substring(index+5, index+6);
|
||||
String enabled = instruction.substring(index+6, index+7);
|
||||
instruction = substitute(instruction,"BROFF"+disabled+enabled,
|
||||
Globals.getSettings().getDelayedBranchingEnabled() ? enabled : disabled );
|
||||
}
|
||||
catch (IndexOutOfBoundsException iooe) {
|
||||
instruction = substitute(instruction,"BROFF", "BAD_PSEUDO_OP_SPEC");
|
||||
}
|
||||
}
|
||||
// substitute Next higher Register for registers in token list (for "mfc1.d","mtc1.d")
|
||||
if (instruction.indexOf("NR")>=0) {
|
||||
for (int op=1; op<theTokenList.size(); op++) {
|
||||
String token = theTokenList.get(op).getValue();
|
||||
int regNumber;
|
||||
try { // if token is a RegisterFile register, substitute next higher register
|
||||
regNumber = RegisterFile.getUserRegister(token).getNumber();
|
||||
if (regNumber>=0) {
|
||||
instruction = substitute(instruction, "NR"+op,"$"+(regNumber+1));
|
||||
}
|
||||
}
|
||||
catch (NullPointerException e) { // not in RegisterFile, must be Coprocessor1 register
|
||||
regNumber = Coprocessor1.getRegisterNumber(token);
|
||||
if (regNumber>=0) {
|
||||
instruction = substitute(instruction, "NR"+op,"$f"+(regNumber+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// substitute result of subtracting last token from 32 (rol and ror constant rotate amount)
|
||||
if (instruction.indexOf("S32")>=0) {
|
||||
String value = theTokenList.get(theTokenList.size()-1).getValue();
|
||||
int val = 0;
|
||||
try {
|
||||
val = Binary.stringToInt(value); // KENV 1/6/05
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
// this won't happen...
|
||||
}
|
||||
instruction = substitute(instruction,"S32",Integer.toString(32-val));
|
||||
}
|
||||
|
||||
// substitute label if necessary
|
||||
if (instruction.indexOf("LAB")>=0) {
|
||||
// label has to be last token. It has already been translated to address
|
||||
// by symtab lookup, so I need to get the text label back so parseLine() won't puke.
|
||||
String label = theTokenList.get(theTokenList.size()-1).getValue();
|
||||
Symbol sym = program.getLocalSymbolTable().getSymbolGivenAddressLocalOrGlobal(label);
|
||||
if (sym!=null) {
|
||||
// should never be null, since there would not be an address if label were not in symtab!
|
||||
// DPS 9 Dec 2007: The "substitute()" method will substitute for ALL matches. Here
|
||||
// we want to substitute only for the first match, for two reasons: (1) a statement
|
||||
// can only contain one label reference, its last operand, and (2) If the user's label
|
||||
// contains the substring "LAB", then substitute() will go into an infinite loop because
|
||||
// it will keep matching the substituted string!
|
||||
instruction = substituteFirst(instruction,"LAB",sym.getName());
|
||||
}
|
||||
}
|
||||
return instruction;
|
||||
}
|
||||
|
||||
// Performs a String substitution. Java 1.5 adds an overloaded String.replace method to
|
||||
// do this directly but I wanted to stay 1.4 compatible.
|
||||
// Modified 12 July 2006 to "substitute all occurances", not just the first.
|
||||
private static String substitute(String original, String find, String replacement) {
|
||||
if (original.indexOf(find)<0 || find.equals(replacement)) {
|
||||
return original; // second condition prevents infinite loop below
|
||||
}
|
||||
int i;
|
||||
String modified = original;
|
||||
while ((i=modified.indexOf(find))>=0) {
|
||||
modified = modified.substring(0, i) + replacement + modified.substring(i + find.length());
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
// Performs a String substitution, but will only substitute for the first match.
|
||||
// Java 1.5 adds an overloaded String.replace method to do this directly but I
|
||||
// wanted to stay 1.4 compatible.
|
||||
private static String substituteFirst(String original, String find, String replacement) {
|
||||
if (original.indexOf(find)<0 || find.equals(replacement)) {
|
||||
return original; // second condition prevents infinite loop below
|
||||
}
|
||||
int i;
|
||||
String modified = original;
|
||||
if ((i=modified.indexOf(find))>=0) {
|
||||
modified = modified.substring(0, i) + replacement + modified.substring(i + find.length());
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
// Takes list of basic instructions that this extended instruction
|
||||
// expands to, which is a string, and breaks out into separate
|
||||
// instructions. They are separated by '\n' character.
|
||||
|
||||
private ArrayList buildTranslationList(String translation) {
|
||||
if (translation == null || translation.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
ArrayList translationList = new ArrayList();
|
||||
StringTokenizer st = new StringTokenizer(translation,"\n");
|
||||
while (st.hasMoreTokens()) {
|
||||
translationList.add(st.nextToken());
|
||||
}
|
||||
return translationList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get length in bytes that this extended instruction requires in its
|
||||
* binary form. The answer depends on how many basic instructions it
|
||||
* expands to. This may vary, if expansion includes a nop, depending on
|
||||
* whether or not delayed branches are enabled. Each requires 4 bytes.
|
||||
* Returns length in bytes of corresponding binary instruction(s).
|
||||
* Returns 0 if the ArrayList is null or empty.
|
||||
*/
|
||||
private int getInstructionLength(ArrayList translationList) {
|
||||
if (translationList == null || translationList.size() == 0) {
|
||||
return 0;
|
||||
}
|
||||
// If instruction template is DBNOP, that means generate a "nop" instruction but only
|
||||
// if Delayed branching is enabled. Otherwise generate nothing. If generating nothing,
|
||||
// then don't count the nop in the instruction length. DPS 23-Jan-2008
|
||||
int instructionCount = 0;
|
||||
for (int i=0; i<translationList.size(); i++) {
|
||||
if (((String)translationList.get(i)).indexOf("DBNOP")>=0 && !Globals.getSettings().getDelayedBranchingEnabled())
|
||||
continue;
|
||||
instructionCount++;
|
||||
}
|
||||
return 4 * instructionCount;
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,135 @@
|
||||
package mars.mips.instructions;
|
||||
import mars.assembler.*;
|
||||
import mars.*;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2006, 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)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class to represent member of MIPS instruction set.
|
||||
*
|
||||
* @author Pete Sanderson and Ken Vollmar
|
||||
* @version August 2003
|
||||
*/
|
||||
|
||||
public abstract class Instruction {
|
||||
/**
|
||||
* Length in bytes of a machine instruction. MIPS is a RISC architecture
|
||||
* so all instructions are the same length. Currently set to 4.
|
||||
*/
|
||||
public static final int INSTRUCTION_LENGTH = 4;
|
||||
public static final int INSTRUCTION_LENGTH_BITS = 32;
|
||||
/** Characters used in instruction mask to indicate bit positions
|
||||
* for 'f'irst, 's'econd, and 't'hird operands.
|
||||
**/
|
||||
public static char[] operandMask = { 'f', 's', 't'};
|
||||
/** The instruction name. **/
|
||||
protected String mnemonic;
|
||||
/** Example usage of this instruction. Is provided as subclass constructor argument. **/
|
||||
protected String exampleFormat;
|
||||
/** Description of instruction for display to user **/
|
||||
protected String description;
|
||||
/** List of tokens generated by tokenizing example usage (see <tt>exampleFormat</tt>). **/
|
||||
protected TokenList tokenList;
|
||||
|
||||
|
||||
/**
|
||||
* Get operation mnemonic
|
||||
*
|
||||
* @return operation mnemonic (e.g. addi, sw)
|
||||
*/
|
||||
public String getName() {
|
||||
return mnemonic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string descriptor of instruction's format. This is an example MIPS
|
||||
* assembler instruction usage which contains the operator and all operands.
|
||||
* Operands are separated by commas, an operand that begins with a '$'
|
||||
* represents a register, and an integer operand represents an immediate value
|
||||
* or address. Here are two examples: "nor $1,$2,$3" and "sw $1,100($2)"
|
||||
*
|
||||
* @return String representing example instruction format.
|
||||
*/
|
||||
public String getExampleFormat() {
|
||||
return exampleFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string describing the instruction. This is not used internally by
|
||||
* MARS, but is for display to the user.
|
||||
*
|
||||
* @return String describing the instruction.
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TokenList corresponding to correct instruction syntax.
|
||||
* For example, the instruction with format "sw $1,100($2)" yields token list
|
||||
* <operator><register_number><integer><left_paren><register_number><right_parent>
|
||||
*
|
||||
* @return TokenList object representing correct instruction usage.
|
||||
*/
|
||||
|
||||
public TokenList getTokenList() {
|
||||
return tokenList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get length in bytes that this instruction requires in its binary form.
|
||||
* Default is 4 (holds for all basic instructions), but can be overridden
|
||||
* in subclass.
|
||||
* @return int length in bytes of corresponding binary instruction(s).
|
||||
*/
|
||||
|
||||
public int getInstructionLength() {
|
||||
return INSTRUCTION_LENGTH;
|
||||
}
|
||||
|
||||
/** Used by subclass constructors to extract operator mnemonic from the
|
||||
instruction example. **/
|
||||
|
||||
protected String extractOperator(String example) {
|
||||
StringTokenizer st = new StringTokenizer(example, " ,\t");
|
||||
return st.nextToken();
|
||||
}
|
||||
|
||||
/** Used to build a token list from the example instruction
|
||||
provided as constructor argument. Parser uses this for syntax checking. **/
|
||||
protected void createExampleTokenList() {
|
||||
try {
|
||||
tokenList = ((new Tokenizer()).tokenizeExampleInstruction(exampleFormat));
|
||||
} catch (ProcessingException pe) {
|
||||
System.out.println("CONFIGURATION ERROR: Instruction example \""+exampleFormat+"\" contains invalid token(s).");
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user