X86: Reorganize the native tracing code.
Ignore different values or rcx and r11 after a syscall until either the local or remote value changes. Also change the codes organization somewhat.

--HG--
extra : convert_revision : 2c1f69d4e55b443e68bfc7b43e8387b02cf0b6b5
diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc
index 90a0e1a..fe524e2 100644
--- a/src/cpu/nativetrace.cc
+++ b/src/cpu/nativetrace.cc
@@ -60,119 +60,122 @@
     }
     ccprintf(cerr, "Listening for native process on port %d\n", port);
     fd = native_listener.accept();
+    checkRcx = true;
+    checkR11 = true;
 }
 
 bool
-NativeTraceRecord::checkIntReg(const char * regName, int index, int size)
+NativeTrace::checkRcxReg(const char * name, uint64_t &mVal, uint64_t &nVal)
 {
-    uint64_t regVal;
-    int res = read(parent->fd, &regVal, size);
-    if(res < 0)
-        panic("Read call failed! %s\n", strerror(errno));
-    regVal = TheISA::gtoh(regVal);
-    uint64_t realRegVal = thread->readIntReg(index);
-    if(regVal != realRegVal)
-    {
-        DPRINTFN("Register %s should be %#x but is %#x.\n",
-                regName, regVal, realRegVal);
-        return false;
-    }
+    if(!checkRcx)
+        checkRcx = (mVal != oldRcxVal || nVal != oldRealRcxVal);
+    if(checkRcx)
+        return checkReg(name, mVal, nVal);
     return true;
 }
 
-bool NativeTraceRecord::checkPC(const char * regName, int size)
+bool
+NativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
 {
-    uint64_t regVal;
-    int res = read(parent->fd, &regVal, size);
-    if(res < 0)
-        panic("Read call failed! %s\n", strerror(errno));
-    regVal = TheISA::gtoh(regVal);
-    uint64_t realRegVal = thread->readNextPC();
-    if(regVal != realRegVal)
-    {
-        DPRINTFN("%s should be %#x but is %#x.\n",
-                regName, regVal, realRegVal);
-        return false;
-    }
+    if(!checkR11)
+        checkR11 = (mVal != oldR11Val || nVal != oldRealR11Val);
+    if(checkR11)
+        return checkReg(name, mVal, nVal);
     return true;
 }
 
 void
 Trace::NativeTraceRecord::dump()
 {
-//    ostream &outs = Trace::output();
-
     //Don't print what happens for each micro-op, just print out
     //once at the last op, and for regular instructions.
     if(!staticInst->isMicroop() || staticInst->isLastMicroop())
+    parent->check(thread, staticInst->isSyscall());
+}
+
+void
+Trace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
+{
+//    ostream &outs = Trace::output();
+    nState.update(fd);
+    mState.update(tc);
+
+    if(isSyscall)
     {
-        checkIntReg("rax", INTREG_RAX, sizeof(uint64_t));
-        checkIntReg("rcx", INTREG_RCX, sizeof(uint64_t));
-        checkIntReg("rdx", INTREG_RDX, sizeof(uint64_t));
-        checkIntReg("rbx", INTREG_RBX, sizeof(uint64_t));
-        checkIntReg("rsp", INTREG_RSP, sizeof(uint64_t));
-        checkIntReg("rbp", INTREG_RBP, sizeof(uint64_t));
-        checkIntReg("rsi", INTREG_RSI, sizeof(uint64_t));
-        checkIntReg("rdi", INTREG_RDI, sizeof(uint64_t));
-        checkIntReg("r8", INTREG_R8, sizeof(uint64_t));
-        checkIntReg("r9", INTREG_R9, sizeof(uint64_t));
-        checkIntReg("r10", INTREG_R10, sizeof(uint64_t));
-        checkIntReg("r11", INTREG_R11, sizeof(uint64_t));
-        checkIntReg("r12", INTREG_R12, sizeof(uint64_t));
-        checkIntReg("r13", INTREG_R13, sizeof(uint64_t));
-        checkIntReg("r14", INTREG_R14, sizeof(uint64_t));
-        checkIntReg("r15", INTREG_R15, sizeof(uint64_t));
-        checkPC("rip", sizeof(uint64_t));
+        checkRcx = false;
+        checkR11 = false;
+        oldRcxVal = mState.rcx;
+        oldRealRcxVal = nState.rcx;
+        oldR11Val = mState.r11;
+        oldRealR11Val = nState.r11;
+    }
+
+    checkReg("rax", mState.rax, nState.rax);
+    checkRcxReg("rcx", mState.rcx, nState.rcx);
+    checkReg("rdx", mState.rdx, nState.rdx);
+    checkReg("rbx", mState.rbx, nState.rbx);
+    checkReg("rsp", mState.rsp, nState.rsp);
+    checkReg("rbp", mState.rbp, nState.rbp);
+    checkReg("rsi", mState.rsi, nState.rsi);
+    checkReg("rdi", mState.rdi, nState.rdi);
+    checkReg("r8",  mState.r8,  nState.r8);
+    checkReg("r9",  mState.r9,  nState.r9);
+    checkReg("r10", mState.r10, nState.r10);
+    checkR11Reg("r11", mState.r11, nState.r11);
+    checkReg("r12", mState.r12, nState.r12);
+    checkReg("r13", mState.r13, nState.r13);
+    checkReg("r14", mState.r14, nState.r14);
+    checkReg("r15", mState.r15, nState.r15);
+    checkReg("rip", mState.rip, nState.rip);
 #if THE_ISA == SPARC_ISA
-        /*for(int f = 0; f <= 62; f+=2)
-        {
-            uint64_t regVal;
-            int res = read(fd, &regVal, sizeof(regVal));
-            if(res < 0)
-                panic("First read call failed! %s\n", strerror(errno));
-            regVal = TheISA::gtoh(regVal);
-            uint64_t realRegVal = thread->readFloatRegBits(f, 64);
-            if(regVal != realRegVal)
-            {
-                DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
-            }
-        }*/
+    /*for(int f = 0; f <= 62; f+=2)
+    {
         uint64_t regVal;
         int res = read(fd, &regVal, sizeof(regVal));
         if(res < 0)
             panic("First read call failed! %s\n", strerror(errno));
         regVal = TheISA::gtoh(regVal);
-        uint64_t realRegVal = thread->readNextPC();
+        uint64_t realRegVal = thread->readFloatRegBits(f, 64);
         if(regVal != realRegVal)
         {
-            DPRINTF(ExecRegDelta,
-                    "Register pc should be %#x but is %#x.\n",
-                    regVal, realRegVal);
+            DPRINTF(ExecRegDelta, "Register f%d should be %#x but is %#x.\n", f, regVal, realRegVal);
         }
-        res = read(fd, &regVal, sizeof(regVal));
-        if(res < 0)
-            panic("First read call failed! %s\n", strerror(errno));
-        regVal = TheISA::gtoh(regVal);
-        realRegVal = thread->readNextNPC();
-        if(regVal != realRegVal)
-        {
-            DPRINTF(ExecRegDelta,
-                    "Register npc should be %#x but is %#x.\n",
-                    regVal, realRegVal);
-        }
-        res = read(fd, &regVal, sizeof(regVal));
-        if(res < 0)
-            panic("First read call failed! %s\n", strerror(errno));
-        regVal = TheISA::gtoh(regVal);
-        realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
-        if((regVal & 0xF) != (realRegVal & 0xF))
-        {
-            DPRINTF(ExecRegDelta,
-                    "Register ccr should be %#x but is %#x.\n",
-                    regVal, realRegVal);
-        }
-#endif
+    }*/
+    uint64_t regVal;
+    int res = read(fd, &regVal, sizeof(regVal));
+    if(res < 0)
+        panic("First read call failed! %s\n", strerror(errno));
+    regVal = TheISA::gtoh(regVal);
+    uint64_t realRegVal = thread->readNextPC();
+    if(regVal != realRegVal)
+    {
+        DPRINTF(ExecRegDelta,
+                "Register pc should be %#x but is %#x.\n",
+                regVal, realRegVal);
     }
+    res = read(fd, &regVal, sizeof(regVal));
+    if(res < 0)
+        panic("First read call failed! %s\n", strerror(errno));
+    regVal = TheISA::gtoh(regVal);
+    realRegVal = thread->readNextNPC();
+    if(regVal != realRegVal)
+    {
+        DPRINTF(ExecRegDelta,
+                "Register npc should be %#x but is %#x.\n",
+                regVal, realRegVal);
+    }
+    res = read(fd, &regVal, sizeof(regVal));
+    if(res < 0)
+        panic("First read call failed! %s\n", strerror(errno));
+    regVal = TheISA::gtoh(regVal);
+    realRegVal = thread->readIntReg(SparcISA::NumIntArchRegs + 2);
+    if((regVal & 0xF) != (realRegVal & 0xF))
+    {
+        DPRINTF(ExecRegDelta,
+                "Register ccr should be %#x but is %#x.\n",
+                regVal, realRegVal);
+    }
+#endif
 }
 
 /* namespace Trace */ }