package se.sics.mspsim.util;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.core.RegisterMonitor;
import se.sics.mspsim.core.Memory.AccessMode;
import se.sics.mspsim.profiler.SimpleProfiler;
public class StackMonitor {
private int heapStartAddress;
private int stackStartAddress;
private int stackMin = 0;
private int stackMax = 0;
private int stack = 0;
private int profStackMax = 0;
private DataSource maxDataSource = new DataSource() {
public int getValue() {
int tmp = stackMax;
stackMax = stack;
return tmp;
}
public double getDoubleValue() {
return getValue();
}
};
private DataSource minDataSource = new DataSource() {
public int getValue() {
int tmp = stackMin;
stackMin = stack;
return tmp;
}
public double getDoubleValue() {
return getValue();
}
};
private DataSource dataSource = new DataSource() {
public int getValue() {
return stack;
}
public double getDoubleValue() {
return getValue();
}
};
public StackMonitor(MSP430 cpu) {
SimpleProfiler profiler = cpu.getRegistry().getComponent(SimpleProfiler.class);
if (profiler != null) {
profiler.setStackMonitor(this);
System.out.println("Found simple profiler!!!: " + profiler);
} else {
System.out.println("Could not find any suitable profiler");
}
if (cpu.getDisAsm() != null) {
MapTable mapTable = cpu.getDisAsm().getMap();
if (mapTable != null) {
this.heapStartAddress = mapTable.heapStartAddress;
this.stackStartAddress = mapTable.stackStartAddress;
}
}
cpu.addRegisterWriteMonitor(MSP430.SP, new RegisterMonitor.Adapter() {
@Override
public void notifyWriteBefore(int reg, int data, AccessMode mode) {
// TODO add support for 20 bit addresses
stack = ((stackStartAddress - data) + 0xffff) & 0xffff;
if (stack > stackMax) {
stackMax = stack;
}
if (stack < stackMin) {
stackMin = stack;
}
if (stack > profStackMax) {
profStackMax = stack;
}
}
});
}
public int getStackStart() {
return stackStartAddress;
}
public int getHeapStart() {
return heapStartAddress;
}
public DataSource getMaxSource() {
return maxDataSource;
}
public DataSource getMinSource() {
return minDataSource;
}
public DataSource getSource() {
return dataSource;
}
/* specialized profiler support for the stack */
/* set current profiler Stack max to this value */
public void setProfStackMax(int max) {
profStackMax = max;
}
/* get profiler stack max */
public int getProfStackMax() {
return profStackMax;
}
public int getStack() {
return stack;
}
}