From a41e1320077fc12869827899d034d5e3de155ffd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Jul 2009 00:52:01 -0700 Subject: [PATCH] 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 | 95 +++++++++++++++++++++++++++++-------- src/arch/arm/nativetrace.hh | 50 +++++++++++++++++++ 2 files changed, 124 insertions(+), 21 deletions(-) diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 78e0447f96..2dd0b8575c 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::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 */ diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh index a347040fb1..d39bdcfa8e 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) {}