ARM: Make native trace only print when registers are changing value.
When registers have incorrect values but aren't actively changing, it's likely they're not being modified at all. The fact that they're still wrong isn't very important.
This commit is contained in:
@@ -36,39 +36,92 @@
|
||||
|
||||
namespace Trace {
|
||||
|
||||
#if TRACING_ON
|
||||
static const char *regNames[] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
|
||||
"cpsr"
|
||||
};
|
||||
#endif
|
||||
|
||||
void
|
||||
Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
|
||||
{
|
||||
oldState = state[current];
|
||||
current = (current + 1) % 2;
|
||||
newState = state[current];
|
||||
|
||||
parent->read(newState, sizeof(newState[0]) * STATE_NUMVALS);
|
||||
for (int i = 0; i < STATE_NUMVALS; i++) {
|
||||
newState[i] = ArmISA::gtoh(newState[i]);
|
||||
changed[i] = (oldState[i] != newState[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
|
||||
{
|
||||
oldState = state[current];
|
||||
current = (current + 1) % 2;
|
||||
newState = state[current];
|
||||
|
||||
// Regular int regs
|
||||
for (int i = 0; i < 15; i++) {
|
||||
newState[i] = tc->readIntReg(i);
|
||||
changed[i] = (oldState[i] != newState[i]);
|
||||
}
|
||||
|
||||
//R15, aliased with the PC
|
||||
newState[STATE_PC] = tc->readNextPC();
|
||||
changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]);
|
||||
|
||||
//CPSR
|
||||
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR);
|
||||
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
|
||||
}
|
||||
|
||||
void
|
||||
Trace::ArmNativeTrace::check(NativeTraceRecord *record)
|
||||
{
|
||||
ThreadContext *tc = record->getThread();
|
||||
nState.update(this);
|
||||
mState.update(record->getThread());
|
||||
|
||||
uint32_t regVal, realRegVal;
|
||||
|
||||
const char **regName = regNames;
|
||||
// Regular int regs
|
||||
for (int i = 0; i < 15; i++) {
|
||||
regVal = tc->readIntReg(i);
|
||||
read(&realRegVal, sizeof(realRegVal));
|
||||
realRegVal = ArmISA::gtoh(realRegVal);
|
||||
checkReg(*(regName++), regVal, realRegVal);
|
||||
for (int i = 0; i < STATE_NUMVALS; i++) {
|
||||
if (nState.changed[i] || mState.changed[i]) {
|
||||
const char *vergence = " ";
|
||||
if (mState.oldState[i] == nState.oldState[i] &&
|
||||
mState.newState[i] != nState.newState[i]) {
|
||||
vergence = "<>";
|
||||
} else if (mState.oldState[i] != nState.oldState[i] &&
|
||||
mState.newState[i] == nState.newState[i]) {
|
||||
vergence = "><";
|
||||
}
|
||||
if (!nState.changed[i]) {
|
||||
DPRINTF(ExecRegDelta, "%s [%5s] "\
|
||||
"Native: %#010x "\
|
||||
"M5: %#010x => %#010x\n",
|
||||
vergence, regNames[i],
|
||||
nState.newState[i],
|
||||
mState.oldState[i], mState.newState[i]);
|
||||
} else if (!mState.changed[i]) {
|
||||
DPRINTF(ExecRegDelta, "%s [%5s] "\
|
||||
"Native: %#010x => %#010x "\
|
||||
"M5: %#010x \n",
|
||||
vergence, regNames[i],
|
||||
nState.oldState[i], nState.newState[i],
|
||||
mState.newState[i]);
|
||||
} else if (mState.oldState[i] != nState.oldState[i] ||
|
||||
mState.newState[i] != nState.newState[i]) {
|
||||
DPRINTF(ExecRegDelta, "%s [%5s] "\
|
||||
"Native: %#010x => %#010x "\
|
||||
"M5: %#010x => %#010x\n",
|
||||
vergence, regNames[i],
|
||||
nState.oldState[i], nState.newState[i],
|
||||
mState.oldState[i], mState.newState[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//R15, aliased with the PC
|
||||
regVal = tc->readNextPC();
|
||||
read(&realRegVal, sizeof(realRegVal));
|
||||
realRegVal = ArmISA::gtoh(realRegVal);
|
||||
checkReg(*(regName++), regVal, realRegVal);
|
||||
|
||||
//CPSR
|
||||
regVal = tc->readMiscReg(MISCREG_CPSR);
|
||||
read(&realRegVal, sizeof(realRegVal));
|
||||
realRegVal = ArmISA::gtoh(realRegVal);
|
||||
checkReg(*(regName++), regVal, realRegVal);
|
||||
}
|
||||
|
||||
} /* namespace Trace */
|
||||
|
||||
@@ -38,6 +38,56 @@ namespace Trace {
|
||||
|
||||
class ArmNativeTrace : public NativeTrace
|
||||
{
|
||||
public:
|
||||
enum StateID {
|
||||
STATE_R0,
|
||||
STATE_R1,
|
||||
STATE_R2,
|
||||
STATE_R3,
|
||||
STATE_R4,
|
||||
STATE_R5,
|
||||
STATE_R6,
|
||||
STATE_R7,
|
||||
STATE_R8,
|
||||
STATE_R9,
|
||||
STATE_R10,
|
||||
STATE_R11,
|
||||
STATE_FP = STATE_R11,
|
||||
STATE_R12,
|
||||
STATE_R13,
|
||||
STATE_SP = STATE_R13,
|
||||
STATE_R14,
|
||||
STATE_LR = STATE_R14,
|
||||
STATE_R15,
|
||||
STATE_PC = STATE_R15,
|
||||
STATE_CPSR,
|
||||
STATE_NUMVALS
|
||||
};
|
||||
|
||||
protected:
|
||||
struct ThreadState {
|
||||
bool changed[STATE_NUMVALS];
|
||||
uint32_t state[2][STATE_NUMVALS];
|
||||
uint32_t *newState;
|
||||
uint32_t *oldState;
|
||||
int current;
|
||||
void update(NativeTrace *parent);
|
||||
void update(ThreadContext *tc);
|
||||
|
||||
ThreadState()
|
||||
{
|
||||
for (int i = 0; i < STATE_NUMVALS; i++) {
|
||||
changed[i] = false;
|
||||
state[0][i] = state[1][i] = 0;
|
||||
current = 0;
|
||||
newState = state[0];
|
||||
oldState = state[1];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ThreadState nState, mState;
|
||||
|
||||
public:
|
||||
ArmNativeTrace(const Params *p) : NativeTrace(p)
|
||||
{}
|
||||
|
||||
Reference in New Issue
Block a user