From a41e1320077fc12869827899d034d5e3de155ffd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:01 -0700 Subject: 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. --- src/arch/arm/nativetrace.cc | 85 ++++++++++++++++++++++++++++++++++++--------- 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 @@ -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) {} -- cgit v1.2.3