Files
EMARS/mars/tools/InstructionCounter.java
T
adolphenom 0da1c5dcca Source code of MARS Assembler
First commit of the 4.5 version (latest version available)
2014-12-21 12:49:28 +01:00

271 lines
7.7 KiB
Java

/*
Copyright (c) 2008, Felipe Lessa
Developed by Felipe Lessa (felipe.lessa@gmail.com)
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)
*/
package mars.tools;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.Observable;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import mars.ProgramStatement;
import mars.mips.hardware.AccessNotice;
import mars.mips.hardware.AddressErrorException;
import mars.mips.hardware.Memory;
import mars.mips.hardware.MemoryAccessNotice;
import mars.mips.instructions.BasicInstruction;
import mars.mips.instructions.BasicInstructionFormat;
/**
*
* Instruction counter tool. Can be used to know how many instructions
* were executed to complete a given program.
*
* Code slightly based on MemoryReferenceVisualization.
*
* @author Felipe Lessa <felipe.lessa@gmail.com>
*
*/
//@SuppressWarnings("serial")
public class InstructionCounter extends AbstractMarsToolAndApplication {
private static String name = "Instruction Counter";
private static String version = "Version 1.0 (Felipe Lessa)";
private static String heading = "Counting the number of instructions executed";
/**
* Number of instructions executed until now.
*/
protected int counter = 0;
private JTextField counterField;
/**
* Number of instructions of type R.
*/
protected int counterR = 0;
private JTextField counterRField;
private JProgressBar progressbarR;
/**
* Number of instructions of type I.
*/
protected int counterI = 0;
private JTextField counterIField;
private JProgressBar progressbarI;
/**
* Number of instructions of type J.
*/
protected int counterJ = 0;
private JTextField counterJField;
private JProgressBar progressbarJ;
/**
* The last address we saw. We ignore it because the only way for a
* program to execute twice the same instruction is to enter an infinite
* loop, which is not insteresting in the POV of counting instructions.
*/
protected int lastAddress = -1;
/**
* Simple constructor, likely used to run a stand-alone memory reference visualizer.
* @param title String containing title for title bar
* @param heading String containing text for heading shown in upper part of window.
*/
public InstructionCounter(String title, String heading) {
super(title,heading);
}
/**
* Simple construction, likely used by the MARS Tools menu mechanism.
*/
public InstructionCounter() {
super(name + ", " + version, heading);
}
// @Override
public String getName() {
return name;
}
// @Override
protected JComponent buildMainDisplayArea() {
// Create everything
JPanel panel = new JPanel(new GridBagLayout());
counterField = new JTextField("0", 10);
counterField.setEditable(false);
counterRField = new JTextField("0", 10);
counterRField.setEditable(false);
progressbarR = new JProgressBar(JProgressBar.HORIZONTAL);
progressbarR.setStringPainted(true);
counterIField = new JTextField("0", 10);
counterIField.setEditable(false);
progressbarI = new JProgressBar(JProgressBar.HORIZONTAL);
progressbarI.setStringPainted(true);
counterJField = new JTextField("0", 10);
counterJField.setEditable(false);
progressbarJ = new JProgressBar(JProgressBar.HORIZONTAL);
progressbarJ.setStringPainted(true);
// Add them to the panel
// Fields
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.LINE_START;
c.gridheight = c.gridwidth = 1;
c.gridx = 3;
c.gridy = 1;
c.insets = new Insets(0, 0, 17, 0);
panel.add(counterField, c);
c.insets = new Insets(0, 0, 0, 0);
c.gridy++;
panel.add(counterRField, c);
c.gridy++;
panel.add(counterIField, c);
c.gridy++;
panel.add(counterJField, c);
// Labels
c.anchor = GridBagConstraints.LINE_END;
c.gridx = 1;
c.gridwidth = 2;
c.gridy = 1;
c.insets = new Insets(0, 0, 17, 0);
panel.add(new JLabel("Instructions so far: "), c);
c.insets = new Insets(0, 0, 0, 0);
c.gridx = 2;
c.gridwidth = 1;
c.gridy++;
panel.add(new JLabel("R-type: "), c);
c.gridy++;
panel.add(new JLabel("I-type: "), c);
c.gridy++;
panel.add(new JLabel("J-type: "), c);
// Progress bars
c.insets = new Insets(3, 3, 3, 3);
c.gridx = 4;
c.gridy = 2;
panel.add(progressbarR, c);
c.gridy++;
panel.add(progressbarI, c);
c.gridy++;
panel.add(progressbarJ, c);
return panel;
}
// @Override
protected void addAsObserver() {
addAsObserver(Memory.textBaseAddress, Memory.textLimitAddress);
}
// @Override
protected void processMIPSUpdate(Observable resource, AccessNotice notice) {
if (!notice.accessIsFromMIPS()) return;
if (notice.getAccessType() != AccessNotice.READ) return;
MemoryAccessNotice m = (MemoryAccessNotice) notice;
int a = m.getAddress();
if (a == lastAddress) return;
lastAddress = a;
counter++;
try {
ProgramStatement stmt = Memory.getInstance().getStatement(a);
BasicInstruction instr = (BasicInstruction) stmt.getInstruction();
BasicInstructionFormat format = instr.getInstructionFormat();
if (format == BasicInstructionFormat.R_FORMAT)
counterR++;
else if (format == BasicInstructionFormat.I_FORMAT
|| format == BasicInstructionFormat.I_BRANCH_FORMAT)
counterI++;
else if (format == BasicInstructionFormat.J_FORMAT)
counterJ++;
} catch (AddressErrorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateDisplay();
}
// @Override
protected void initializePreGUI() {
counter = counterR = counterI = counterJ = 0;
lastAddress = -1;
}
// @Override
protected void reset() {
counter = counterR = counterI = counterJ = 0;
lastAddress = -1;
updateDisplay();
}
// @Override
protected void updateDisplay() {
counterField.setText(String.valueOf(counter));
counterRField.setText(String.valueOf(counterR));
progressbarR.setMaximum(counter);
progressbarR.setValue(counterR);
counterIField.setText(String.valueOf(counterI));
progressbarI.setMaximum(counter);
progressbarI.setValue(counterI);
counterJField.setText(String.valueOf(counterJ));
progressbarJ.setMaximum(counter);
progressbarJ.setValue(counterJ);
if (counter == 0) {
progressbarR.setString("0%");
progressbarI.setString("0%");
progressbarJ.setString("0%");
} else {
progressbarR.setString((counterR * 100)/counter + "%");
progressbarI.setString((counterI * 100)/counter + "%");
progressbarJ.setString((counterJ * 100)/counter + "%");
}
}
}