diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/arm/nativetrace.cc | 85 | ||||
-rw-r--r-- | src/arch/arm/nativetrace.hh | 50 |
2 files changed, 119 insertions, 16 deletions
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 78e0447f9..2dd0b8575 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -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::check(NativeTraceRecord *record) +Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent) { - ThreadContext *tc = record->getThread(); + oldState = state[current]; + current = (current + 1) % 2; + newState = state[current]; - uint32_t regVal, realRegVal; + 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]; - 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); + newState[i] = tc->readIntReg(i); + changed[i] = (oldState[i] != newState[i]); } //R15, aliased with the PC - regVal = tc->readNextPC(); - read(&realRegVal, sizeof(realRegVal)); - realRegVal = ArmISA::gtoh(realRegVal); - checkReg(*(regName++), regVal, realRegVal); + newState[STATE_PC] = tc->readNextPC(); + changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); //CPSR - regVal = tc->readMiscReg(MISCREG_CPSR); - read(&realRegVal, sizeof(realRegVal)); - realRegVal = ArmISA::gtoh(realRegVal); - checkReg(*(regName++), regVal, realRegVal); + newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR); + changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); +} + +void +Trace::ArmNativeTrace::check(NativeTraceRecord *record) +{ + nState.update(this); + mState.update(record->getThread()); + + // Regular int regs + 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]); + } + } + } } } /* namespace Trace */ diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh index a347040fb..d39bdcfa8 100644 --- a/src/arch/arm/nativetrace.hh +++ b/src/arch/arm/nativetrace.hh @@ -39,6 +39,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) {} |