0da1c5dcca
First commit of the 4.5 version (latest version available)
239 lines
8.1 KiB
Java
239 lines
8.1 KiB
Java
/*
|
|
Copyright (c) 2009, Ingo Kofler, ITEC, Klagenfurt University, Austria
|
|
|
|
Developed by Ingo Kofler (ingo.kofler@itec.uni-klu.ac.at)
|
|
|
|
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;//.bhtsim;
|
|
|
|
import java.util.Vector;
|
|
|
|
import javax.swing.table.AbstractTableModel;
|
|
|
|
/**
|
|
* Simulates the actual functionality of a Branch History Table (BHT).
|
|
* <p>
|
|
* The BHT consists of a number of BHT entries which are used to perform branch prediction.
|
|
* The entries of the BHT are stored as a Vector of BHTEntry objects.
|
|
* The number of entries is configurable but has to be a power of 2.
|
|
* The history kept by each BHT entry is also configurable during run-time.
|
|
* A change of the configuration however causes a complete reset of the BHT.
|
|
* <p>
|
|
* The typical interaction is as follows:
|
|
* <ul>
|
|
* <li>Construction of a BHT with a certain number of entries with a given history size.</li>
|
|
* <li>When encountering a branch instruction the index of the relevant BHT entry is calculated via the {@link BHTableModel#getIdxForAddress(int)} method.</li>
|
|
* <li>The current prediction of the BHT entry at the calculated index is obtained via the {@link BHTableModel#getPredictionAtIdx(int)} method.</li>
|
|
* <li>After detecting if the branch was really taken or not, this feedback is provided to the BHT by the {@link BHTableModel#updatePredictionAtIdx(int, boolean)} method.</li>
|
|
* </ul>
|
|
* <p>
|
|
* Additionally it serves as TableModel that can be directly used to render the state of the BHT in a JTable.
|
|
* Feedback provided to the BHT causes a change of the internal state and a repaint of the table(s) associated to this model.
|
|
*
|
|
* @author ingo.kofler@itec.uni-klu.ac.at
|
|
*/
|
|
|
|
//@SuppressWarnings("serial")
|
|
public class BHTableModel extends AbstractTableModel {
|
|
|
|
/** vector holding the entries of the BHT */
|
|
private Vector m_entries;
|
|
|
|
/** number of entries in the BHT */
|
|
private int m_entryCnt;
|
|
|
|
/** number of past branch events to remember */
|
|
private int m_historySize;
|
|
|
|
/** name of the table columns */
|
|
private String m_columnNames[] = { "Index", "History", "Prediction", "Correct", "Incorrect", "Precision"};
|
|
|
|
/** type of the table columns */
|
|
//@SuppressWarnings("unchecked")
|
|
private Class m_columnClasses[] = { Integer.class, String.class, String.class, Integer.class, Integer.class, Double.class};
|
|
|
|
|
|
/**
|
|
* Constructs a new BHT with given number of entries and history size.
|
|
*
|
|
* @param numEntries number of entries in the BHT
|
|
* @param historySize size of the history (in bits/number of past branches)
|
|
*/
|
|
public BHTableModel (int numEntries, int historySize, boolean initVal) {
|
|
initBHT(numEntries, historySize, initVal);
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the name of the i-th column of the table.
|
|
* Required by the TableModel interface.
|
|
*
|
|
* @param i the index of the column
|
|
* @return name of the i-th column
|
|
*/
|
|
public String getColumnName(int i) {
|
|
if (i < 0 || i > m_columnNames.length)
|
|
throw new IllegalArgumentException("Illegal column index " + i + " (must be in range 0.." + (m_columnNames.length-1) + ")");
|
|
|
|
return m_columnNames[i];
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the class/type of the i-th column of the table.
|
|
* Required by the TableModel interface.
|
|
*
|
|
* @param i the index of the column
|
|
* @return class representing the type of the i-th column
|
|
*/
|
|
public Class getColumnClass(int i) {
|
|
if (i < 0 || i > m_columnClasses.length)
|
|
throw new IllegalArgumentException("Illegal column index " + i + " (must be in range 0.." + (m_columnClasses.length-1) + ")");
|
|
|
|
return m_columnClasses[i];
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the number of columns.
|
|
* Required by the TableModel interface.
|
|
*
|
|
* @return currently the constant 6
|
|
*/
|
|
public int getColumnCount() {
|
|
return 6;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the number of entries of the BHT.
|
|
* Required by the TableModel interface.
|
|
*
|
|
* @return number of rows / entries of the BHT
|
|
*/
|
|
public int getRowCount() {
|
|
return m_entryCnt;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the value of the cell at the given row and column
|
|
* Required by the TableModel interface.
|
|
*
|
|
* @param row the row index
|
|
* @param col the column index
|
|
* @return the value of the cell
|
|
*/
|
|
public Object getValueAt(int row, int col) {
|
|
|
|
BHTEntry e = (BHTEntry) m_entries.elementAt(row);
|
|
if (e==null) return "";
|
|
|
|
if (col==0) return new Integer(row);
|
|
if (col==1) return e.getHistoryAsStr();
|
|
if (col==2) return e.getPredictionAsStr();
|
|
if (col==3) return new Integer(e.getStatsPredCorrect());
|
|
if (col==4) return new Integer(e.getStatsPredIncorrect());
|
|
if (col==5) return new Double(e.getStatsPredPrecision());
|
|
|
|
return "";
|
|
}
|
|
|
|
|
|
/**
|
|
* Initializes the BHT with the given size and history.
|
|
* All previous data like the BHT entries' history and statistics will get lost.
|
|
* A refresh of the table that use this BHT as model will be triggered.
|
|
*
|
|
* @param numEntries number of entries in the BHT (has to be a power of 2)
|
|
* @param historySize size of the history to consider
|
|
* @param initVal initial value for each entry (true means take branch, false do not take branch)
|
|
*/
|
|
public void initBHT(int numEntries, int historySize, boolean initVal) {
|
|
|
|
if (numEntries <= 0 || (numEntries & (numEntries-1)) != 0)
|
|
throw new IllegalArgumentException("Number of entries must be a positive power of 2.");
|
|
if (historySize < 1 || historySize > 2)
|
|
throw new IllegalArgumentException("Only history sizes of 1 or 2 supported.");
|
|
|
|
m_entryCnt = numEntries;
|
|
m_historySize = historySize;
|
|
|
|
m_entries = new Vector();
|
|
|
|
for (int i=0; i < m_entryCnt; i++) {
|
|
m_entries.add(new BHTEntry(m_historySize, initVal));
|
|
}
|
|
|
|
// refresh the table(s)
|
|
fireTableStructureChanged();
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the index into the BHT for a given branch instruction address.
|
|
* A simple direct mapping is used.
|
|
*
|
|
* @param address the address of the branch instruction
|
|
* @return the index into the BHT
|
|
*/
|
|
public int getIdxForAddress(int address) {
|
|
if (address < 0)
|
|
throw new IllegalArgumentException("No negative addresses supported");
|
|
|
|
return (address >> 2) % m_entryCnt;
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieve the prediction for the i-th BHT entry.
|
|
*
|
|
* @param index the index of the entry in the BHT
|
|
* @return the prediction to take (true) or do not take (false) the branch
|
|
*/
|
|
public boolean getPredictionAtIdx(int index) {
|
|
if (index < 0 || index > m_entryCnt)
|
|
throw new IllegalArgumentException("Only indexes in the range 0 to " + (m_entryCnt-1) + " allowed");
|
|
|
|
return ((BHTEntry) m_entries.elementAt(index)).getPrediction();
|
|
}
|
|
|
|
|
|
/**
|
|
* Updates the BHT entry with the outcome of the branch instruction.
|
|
* This causes a change in the model and signals to update the connected table(s).
|
|
*
|
|
* @param index the index of the entry in the BHT
|
|
* @param branchTaken
|
|
*/
|
|
public void updatePredictionAtIdx(int index, boolean branchTaken) {
|
|
if (index < 0 || index > m_entryCnt)
|
|
throw new IllegalArgumentException("Only indexes in the range 0 to " + (m_entryCnt-1) + " allowed");
|
|
|
|
((BHTEntry) m_entries.elementAt(index)).updatePrediction(branchTaken);
|
|
fireTableRowsUpdated(index, index);
|
|
}
|
|
|
|
}
|