X86/StateTrace: Make m5 and statetrace track mmx and xmm registers, and actually...
authorGabe Black <gblack@eecs.umich.edu>
Wed, 5 Sep 2007 06:39:57 +0000 (23:39 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 5 Sep 2007 06:39:57 +0000 (23:39 -0700)
--HG--
extra : convert_revision : 02c6641200edb133c9bc11f1fdf3c1a0b1c87e77

src/cpu/nativetrace.cc
src/cpu/nativetrace.hh
util/statetrace/arch/tracechild_amd64.cc
util/statetrace/arch/tracechild_amd64.hh

index 0db61af2c997350945538cfac5ac8d6eb0aa0684..7152602fe8c8a02f8f0b101ad49128fb424a83a0 100644 (file)
@@ -84,6 +84,19 @@ NativeTrace::checkR11Reg(const char * name, uint64_t &mVal, uint64_t &nVal)
     return true;
 }
 
+bool
+NativeTrace::checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[])
+{
+    if (mXmmBuf[num * 2]     != nXmmBuf[num * 2] ||
+        mXmmBuf[num * 2 + 1] != nXmmBuf[num * 2 + 1]) {
+        DPRINTFN("Register xmm%d should be 0x%016x%016x but is 0x%016x%016x.\n",
+                num, nXmmBuf[num * 2 + 1], nXmmBuf[num * 2],
+                     mXmmBuf[num * 2 + 1], mXmmBuf[num * 2]);
+        return false;
+    }
+    return true;
+}
+
 void
 Trace::NativeTraceRecord::dump()
 {
@@ -127,6 +140,22 @@ Trace::NativeTrace::check(ThreadContext * tc, bool isSyscall)
     checkReg("r14", mState.r14, nState.r14);
     checkReg("r15", mState.r15, nState.r15);
     checkReg("rip", mState.rip, nState.rip);
+    checkXMM(0, mState.xmm, nState.xmm);
+    checkXMM(1, mState.xmm, nState.xmm);
+    checkXMM(2, mState.xmm, nState.xmm);
+    checkXMM(3, mState.xmm, nState.xmm);
+    checkXMM(4, mState.xmm, nState.xmm);
+    checkXMM(5, mState.xmm, nState.xmm);
+    checkXMM(6, mState.xmm, nState.xmm);
+    checkXMM(7, mState.xmm, nState.xmm);
+    checkXMM(8, mState.xmm, nState.xmm);
+    checkXMM(9, mState.xmm, nState.xmm);
+    checkXMM(10, mState.xmm, nState.xmm);
+    checkXMM(11, mState.xmm, nState.xmm);
+    checkXMM(12, mState.xmm, nState.xmm);
+    checkXMM(13, mState.xmm, nState.xmm);
+    checkXMM(14, mState.xmm, nState.xmm);
+    checkXMM(15, mState.xmm, nState.xmm);
 #if THE_ISA == SPARC_ISA
     /*for(int f = 0; f <= 62; f+=2)
     {
index 6fd6242118baac367d1d13824505fd47153d074d..ab038c4c3ff6eae9b302a943b3f0cd57a414189f 100644 (file)
@@ -37,6 +37,7 @@
 #include "sim/host.hh"
 #include "sim/insttracer.hh"
 #include "arch/x86/intregs.hh"
+#include "arch/x86/floatregs.hh"
 
 class ThreadContext;
 
@@ -91,6 +92,9 @@ class NativeTrace : public InstTracer
         uint64_t r14;
         uint64_t r15;
         uint64_t rip;
+        //This should be expanded to 16 if x87 registers are considered
+        uint64_t mmx[8];
+        uint64_t xmm[32];
 
         void update(int fd)
         {
@@ -121,6 +125,11 @@ class NativeTrace : public InstTracer
             r14 = TheISA::gtoh(r14);
             r15 = TheISA::gtoh(r15);
             rip = TheISA::gtoh(rip);
+            //This should be expanded if x87 registers are considered
+            for (int i = 0; i < 8; i++)
+                mmx[i] = TheISA::gtoh(mmx[i]);
+            for (int i = 0; i < 32; i++)
+                xmm[i] = TheISA::gtoh(xmm[i]);
         }
 
         void update(ThreadContext * tc)
@@ -142,6 +151,11 @@ class NativeTrace : public InstTracer
             r14 = tc->readIntReg(X86ISA::INTREG_R14);
             r15 = tc->readIntReg(X86ISA::INTREG_R15);
             rip = tc->readNextPC();
+            //This should be expanded if x87 registers are considered
+            for (int i = 0; i < 8; i++)
+                mmx[i] = tc->readFloatRegBits(X86ISA::FLOATREG_MMX(i));
+            for (int i = 0; i < 32; i++)
+                xmm[i] = tc->readFloatRegBits(X86ISA::FLOATREG_XMM_BASE + i);
         }
 
     };
@@ -171,6 +185,9 @@ class NativeTrace : public InstTracer
     bool
     checkR11Reg(const char * regName, uint64_t &, uint64_t &);
 
+    bool
+    checkXMM(int num, uint64_t mXmmBuf[], uint64_t nXmmBuf[]);
+
     NativeTrace(const Params *p);
 
     NativeTraceRecord *
index 112ee793e2072ad66a05ce5f18ec304e389a753d..2809bf4c85dadabc316df8a76c9827f2573346ac 100644 (file)
@@ -52,83 +52,219 @@ char * AMD64TraceChild::regNames[numregs] = {
                 //PC
                 "rip",
                 //Flags
-                "eflags"};
+                "eflags",
+                //MMX
+                "mmx0_0", "mmx0_1",
+                "mmx1_0", "mmx1_1",
+                "mmx2_0", "mmx2_1",
+                "mmx3_0", "mmx3_1",
+                "mmx4_0", "mmx4_1",
+                "mmx5_0", "mmx5_1",
+                "mmx6_0", "mmx6_1",
+                "mmx7_0", "mmx7_1",
+                //XMM
+                "xmm0_0",  "xmm0_1",  "xmm0_2",  "xmm0_3",
+                "xmm1_0",  "xmm1_1",  "xmm1_2",  "xmm1_3",
+                "xmm2_0",  "xmm2_1",  "xmm2_2",  "xmm2_3",
+                "xmm3_0",  "xmm3_1",  "xmm3_2",  "xmm3_3",
+                "xmm4_0",  "xmm4_1",  "xmm4_2",  "xmm4_3",
+                "xmm5_0",  "xmm5_1",  "xmm5_2",  "xmm5_3",
+                "xmm6_0",  "xmm6_1",  "xmm6_2",  "xmm6_3",
+                "xmm7_0",  "xmm7_1",  "xmm7_2",  "xmm7_3",
+                "xmm8_0",  "xmm8_1",  "xmm8_2",  "xmm8_3",
+                "xmm9_0",  "xmm9_1",  "xmm9_2",  "xmm9_3",
+                "xmm10_0", "xmm10_1", "xmm10_2", "xmm10_3",
+                "xmm11_0", "xmm11_1", "xmm11_2", "xmm11_3",
+                "xmm12_0", "xmm12_1", "xmm12_2", "xmm12_3",
+                "xmm13_0", "xmm13_1", "xmm13_2", "xmm13_3",
+                "xmm14_0", "xmm14_1", "xmm14_2", "xmm14_3",
+                "xmm15_0", "xmm15_1", "xmm15_2", "xmm15_3"};
 
 bool AMD64TraceChild::sendState(int socket)
 {
-    uint64_t regVal = 0;
+    uint64_t regVal64 = 0;
+    uint32_t regVal32 = 0;
     for(int x = 0; x <= R15; x++)
     {
-        regVal = getRegVal(x);
-        if(write(socket, &regVal, sizeof(regVal)) == -1)
+        regVal64 = getRegVal(x);
+        if(write(socket, &regVal64, sizeof(regVal64)) == -1)
         {
             cerr << "Write failed! " << strerror(errno) << endl;
             tracing = false;
             return false;
         }
     }
-    regVal = getRegVal(RIP);
-    if(write(socket, &regVal, sizeof(regVal)) == -1)
+    regVal64 = getRegVal(RIP);
+    if(write(socket, &regVal64, sizeof(regVal64)) == -1)
     {
         cerr << "Write failed! " << strerror(errno) << endl;
         tracing = false;
         return false;
     }
+    for(int x = MMX0_0; x <= MMX7_1; x++)
+    {
+        regVal32 = getRegVal(x);
+        if(write(socket, &regVal32, sizeof(regVal32)) == -1)
+        {
+            cerr << "Write failed! " << strerror(errno) << endl;
+            tracing = false;
+            return false;
+        }
+    }
+    for(int x = XMM0_0; x <= XMM15_3; x++)
+    {
+        regVal32 = getRegVal(x);
+        if(write(socket, &regVal32, sizeof(regVal32)) == -1)
+        {
+            cerr << "Write failed! " << strerror(errno) << endl;
+            tracing = false;
+            return false;
+        }
+    }
     return true;
 }
 
-int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs, int num)
+int64_t AMD64TraceChild::getRegs(user_regs_struct & myregs,
+        user_fpregs_struct & myfpregs, int num)
 {
-        assert(num < numregs && num >= 0);
-        switch(num)
-        {
-                //GPRs
-                case RAX: return myregs.rax;
-                case RBX: return myregs.rbx;
-                case RCX: return myregs.rcx;
-                case RDX: return myregs.rdx;
-                //Index registers
-                case RSI: return myregs.rsi;
-                case RDI: return myregs.rdi;
-                //Base pointer and stack pointer
-                case RBP: return myregs.rbp;
-                case RSP: return myregs.rsp;
-                //New 64 bit mode registers
-                case R8: return myregs.r8;
-                case R9: return myregs.r9;
-                case R10: return myregs.r10;
-                case R11: return myregs.r11;
-                case R12: return myregs.r12;
-                case R13: return myregs.r13;
-                case R14: return myregs.r14;
-                case R15: return myregs.r15;
-                //Segmentation registers
-                case CS: return myregs.cs;
-                case DS: return myregs.ds;
-                case ES: return myregs.es;
-                case FS: return myregs.fs;
-                case GS: return myregs.gs;
-                case SS: return myregs.ss;
-                case FS_BASE: return myregs.fs_base;
-                case GS_BASE: return myregs.gs_base;
-                //PC
-                case RIP: return myregs.rip;
-                //Flags
-                case EFLAGS: return myregs.eflags;
-                default:
-                        assert(0);
-                        return 0;
-        }
+    assert(num < numregs && num >= 0);
+    switch(num)
+    {
+        //GPRs
+        case RAX: return myregs.rax;
+        case RBX: return myregs.rbx;
+        case RCX: return myregs.rcx;
+        case RDX: return myregs.rdx;
+        //Index registers
+        case RSI: return myregs.rsi;
+        case RDI: return myregs.rdi;
+        //Base pointer and stack pointer
+        case RBP: return myregs.rbp;
+        case RSP: return myregs.rsp;
+        //New 64 bit mode registers
+        case R8: return myregs.r8;
+        case R9: return myregs.r9;
+        case R10: return myregs.r10;
+        case R11: return myregs.r11;
+        case R12: return myregs.r12;
+        case R13: return myregs.r13;
+        case R14: return myregs.r14;
+        case R15: return myregs.r15;
+        //Segmentation registers
+        case CS: return myregs.cs;
+        case DS: return myregs.ds;
+        case ES: return myregs.es;
+        case FS: return myregs.fs;
+        case GS: return myregs.gs;
+        case SS: return myregs.ss;
+        case FS_BASE: return myregs.fs_base;
+        case GS_BASE: return myregs.gs_base;
+        //PC
+        case RIP: return myregs.rip;
+        //Flags
+        case EFLAGS: return myregs.eflags;
+        //MMX
+        case MMX0_0: return myfpregs.st_space[0];
+        case MMX0_1: return myfpregs.st_space[1];
+        case MMX1_0: return myfpregs.st_space[2];
+        case MMX1_1: return myfpregs.st_space[3];
+        case MMX2_0: return myfpregs.st_space[4];
+        case MMX2_1: return myfpregs.st_space[5];
+        case MMX3_0: return myfpregs.st_space[6];
+        case MMX3_1: return myfpregs.st_space[7];
+        case MMX4_0: return myfpregs.st_space[8];
+        case MMX4_1: return myfpregs.st_space[9];
+        case MMX5_0: return myfpregs.st_space[10];
+        case MMX5_1: return myfpregs.st_space[11];
+        case MMX6_0: return myfpregs.st_space[12];
+        case MMX6_1: return myfpregs.st_space[13];
+        case MMX7_0: return myfpregs.st_space[14];
+        case MMX7_1: return myfpregs.st_space[15];
+        //XMM
+        case XMM0_0: return myfpregs.xmm_space[0];
+        case XMM0_1: return myfpregs.xmm_space[1];
+        case XMM0_2: return myfpregs.xmm_space[2];
+        case XMM0_3: return myfpregs.xmm_space[3];
+        case XMM1_0: return myfpregs.xmm_space[4];
+        case XMM1_1: return myfpregs.xmm_space[5];
+        case XMM1_2: return myfpregs.xmm_space[6];
+        case XMM1_3: return myfpregs.xmm_space[7];
+        case XMM2_0: return myfpregs.xmm_space[8];
+        case XMM2_1: return myfpregs.xmm_space[9];
+        case XMM2_2: return myfpregs.xmm_space[10];
+        case XMM2_3: return myfpregs.xmm_space[11];
+        case XMM3_0: return myfpregs.xmm_space[12];
+        case XMM3_1: return myfpregs.xmm_space[13];
+        case XMM3_2: return myfpregs.xmm_space[14];
+        case XMM3_3: return myfpregs.xmm_space[15];
+        case XMM4_0: return myfpregs.xmm_space[16];
+        case XMM4_1: return myfpregs.xmm_space[17];
+        case XMM4_2: return myfpregs.xmm_space[18];
+        case XMM4_3: return myfpregs.xmm_space[19];
+        case XMM5_0: return myfpregs.xmm_space[20];
+        case XMM5_1: return myfpregs.xmm_space[21];
+        case XMM5_2: return myfpregs.xmm_space[22];
+        case XMM5_3: return myfpregs.xmm_space[23];
+        case XMM6_0: return myfpregs.xmm_space[24];
+        case XMM6_1: return myfpregs.xmm_space[25];
+        case XMM6_2: return myfpregs.xmm_space[26];
+        case XMM6_3: return myfpregs.xmm_space[27];
+        case XMM7_0: return myfpregs.xmm_space[28];
+        case XMM7_1: return myfpregs.xmm_space[29];
+        case XMM7_2: return myfpregs.xmm_space[30];
+        case XMM7_3: return myfpregs.xmm_space[31];
+        case XMM8_0: return myfpregs.xmm_space[32];
+        case XMM8_1: return myfpregs.xmm_space[33];
+        case XMM8_2: return myfpregs.xmm_space[34];
+        case XMM8_3: return myfpregs.xmm_space[35];
+        case XMM9_0: return myfpregs.xmm_space[36];
+        case XMM9_1: return myfpregs.xmm_space[37];
+        case XMM9_2: return myfpregs.xmm_space[38];
+        case XMM9_3: return myfpregs.xmm_space[39];
+        case XMM10_0: return myfpregs.xmm_space[40];
+        case XMM10_1: return myfpregs.xmm_space[41];
+        case XMM10_2: return myfpregs.xmm_space[42];
+        case XMM10_3: return myfpregs.xmm_space[43];
+        case XMM11_0: return myfpregs.xmm_space[44];
+        case XMM11_1: return myfpregs.xmm_space[45];
+        case XMM11_2: return myfpregs.xmm_space[46];
+        case XMM11_3: return myfpregs.xmm_space[47];
+        case XMM12_0: return myfpregs.xmm_space[48];
+        case XMM12_1: return myfpregs.xmm_space[49];
+        case XMM12_2: return myfpregs.xmm_space[50];
+        case XMM12_3: return myfpregs.xmm_space[51];
+        case XMM13_0: return myfpregs.xmm_space[52];
+        case XMM13_1: return myfpregs.xmm_space[53];
+        case XMM13_2: return myfpregs.xmm_space[54];
+        case XMM13_3: return myfpregs.xmm_space[55];
+        case XMM14_0: return myfpregs.xmm_space[56];
+        case XMM14_1: return myfpregs.xmm_space[57];
+        case XMM14_2: return myfpregs.xmm_space[58];
+        case XMM14_3: return myfpregs.xmm_space[59];
+        case XMM15_0: return myfpregs.xmm_space[60];
+        case XMM15_1: return myfpregs.xmm_space[61];
+        case XMM15_2: return myfpregs.xmm_space[62];
+        case XMM15_3: return myfpregs.xmm_space[63];
+        default:
+                assert(0);
+                return 0;
+    }
 }
 
 bool AMD64TraceChild::update(int pid)
 {
     oldregs = regs;
+    oldfpregs = fpregs;
     if(ptrace(PTRACE_GETREGS, pid, 0, &regs) != 0)
     {
         cerr << "update: " << strerror(errno) << endl;
         return false;
     }
+    if(ptrace(PTRACE_GETFPREGS, pid, 0, &fpregs) != 0)
+    {
+        cerr << "update: " << strerror(errno) << endl;
+        return false;
+    }
     for(unsigned int x = 0; x < numregs; x++)
         regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
     return true;
@@ -142,12 +278,12 @@ AMD64TraceChild::AMD64TraceChild()
 
 int64_t AMD64TraceChild::getRegVal(int num)
 {
-        return getRegs(regs, num);
+        return getRegs(regs, fpregs, num);
 }
 
 int64_t AMD64TraceChild::getOldRegVal(int num)
 {
-        return getRegs(oldregs, num);
+        return getRegs(oldregs, oldfpregs, num);
 }
 
 char * AMD64TraceChild::printReg(int num)
index e7457f6776738c8a8395f28e38525a6f0166a64a..1ab11d767ff4565b8d742e6261a654fa8bf2c533 100644 (file)
@@ -58,14 +58,43 @@ class AMD64TraceChild : public TraceChild
         RIP,
         //Flags
         EFLAGS,
+        //MMX
+        MMX0_0, MMX0_1,
+        MMX1_0, MMX1_1,
+        MMX2_0, MMX2_1,
+        MMX3_0, MMX3_1,
+        MMX4_0, MMX4_1,
+        MMX5_0, MMX5_1,
+        MMX6_0, MMX6_1,
+        MMX7_0, MMX7_1,
+        //XMM
+        XMM0_0,  XMM0_1,  XMM0_2,  XMM0_3,
+        XMM1_0,  XMM1_1,  XMM1_2,  XMM1_3,
+        XMM2_0,  XMM2_1,  XMM2_2,  XMM2_3,
+        XMM3_0,  XMM3_1,  XMM3_2,  XMM3_3,
+        XMM4_0,  XMM4_1,  XMM4_2,  XMM4_3,
+        XMM5_0,  XMM5_1,  XMM5_2,  XMM5_3,
+        XMM6_0,  XMM6_1,  XMM6_2,  XMM6_3,
+        XMM7_0,  XMM7_1,  XMM7_2,  XMM7_3,
+        XMM8_0,  XMM8_1,  XMM8_2,  XMM8_3,
+        XMM9_0,  XMM9_1,  XMM9_2,  XMM9_3,
+        XMM10_0, XMM10_1, XMM10_2, XMM10_3,
+        XMM11_0, XMM11_1, XMM11_2, XMM11_3,
+        XMM12_0, XMM12_1, XMM12_2, XMM12_3,
+        XMM13_0, XMM13_1, XMM13_2, XMM13_3,
+        XMM14_0, XMM14_1, XMM14_2, XMM14_3,
+        XMM15_0, XMM15_1, XMM15_2, XMM15_3,
         numregs
     };
   private:
     char printBuffer [256];
     static char * regNames[numregs];
-    int64_t getRegs(user_regs_struct & myregs, int num);
+    int64_t getRegs(user_regs_struct & myregs,
+            user_fpregs_struct &myfpregs,int num);
     user_regs_struct regs;
     user_regs_struct oldregs;
+    user_fpregs_struct fpregs;
+    user_fpregs_struct oldfpregs;
     bool regDiffSinceUpdate[numregs];
 
     uint64_t findSyscall();