ARM: Add vfpv3 support to native trace.
authorAli Saidi <Ali.Saidi@ARM.com>
Thu, 5 May 2011 01:38:26 +0000 (20:38 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Thu, 5 May 2011 01:38:26 +0000 (20:38 -0500)
src/arch/arm/nativetrace.cc
src/arch/arm/nativetrace.hh
util/statetrace/arch/arm/tracechild.cc
util/statetrace/arch/arm/tracechild.hh

index 2dd225e800b85b80e2b7b2806f22be1a4ed44fcb..a8d01a0f2c4664abd43b2ed511d469f8f754a966 100644 (file)
@@ -54,7 +54,11 @@ namespace Trace {
 static const char *regNames[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     "r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
-    "cpsr"
+    "cpsr", "f0", "f1", "f2", "f3", "f4", "f5", "f6",
+    "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14",
+    "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22",
+    "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",
+    "f31", "fpscr"
 };
 #endif
 
@@ -67,7 +71,7 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
 
     memcpy(newState, oldState, sizeof(state[0]));
 
-    uint32_t diffVector;
+    uint64_t diffVector;
     parent->read(&diffVector, sizeof(diffVector));
     diffVector = ArmISA::gtoh(diffVector);
 
@@ -82,7 +86,7 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
         diffVector >>= 1;
     }
 
-    uint32_t values[changes];
+    uint64_t values[changes];
     parent->read(values, sizeof(values));
     int pos = 0;
     for (int i = 0; i < STATE_NUMVALS; i++) {
@@ -114,6 +118,14 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
     newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
                            tc->readIntReg(INTREG_CONDCODES);
     changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
+
+    for (int i = 0; i < NumFloatArchRegs; i += 2) {
+        newState[STATE_F0 + (i >> 1)] =
+            static_cast<uint64_t>(tc->readFloatRegBits(i + 1)) << 32 |
+            tc->readFloatRegBits(i);
+    }
+    newState[STATE_FPSCR] = tc->readMiscRegNoEffect(MISCREG_FPSCR) |
+                            tc->readIntReg(INTREG_FPCONDCODES);
 }
 
 void
index 221d40e2fc63f6eb9842fbd9085cfeed7f303b27..d3f96f3ad4dc7cd14dd0fd9d46cf28c03e052385 100644 (file)
@@ -62,15 +62,21 @@ class ArmNativeTrace : public NativeTrace
         STATE_R15,
         STATE_PC = STATE_R15,
         STATE_CPSR,
+        STATE_F0, STATE_F1, STATE_F2, STATE_F3, STATE_F4, STATE_F5, STATE_F6,
+        STATE_F7, STATE_F8, STATE_F9, STATE_F10, STATE_F11, STATE_F12,
+        STATE_F13, STATE_F14, STATE_F15, STATE_F16, STATE_F17, STATE_F18,
+        STATE_F19, STATE_F20, STATE_F21, STATE_F22, STATE_F23, STATE_F24,
+        STATE_F25, STATE_F26, STATE_F27, STATE_F28, STATE_F29, STATE_F30,
+        STATE_F31, STATE_FPSCR,
         STATE_NUMVALS
     };
 
   protected:
     struct ThreadState {
         bool changed[STATE_NUMVALS];
-        uint32_t state[2][STATE_NUMVALS];
-        uint32_t *newState;
-        uint32_t *oldState;
+        uint64_t state[2][STATE_NUMVALS];
+        uint64_t *newState;
+        uint64_t *oldState;
         int current;
         void update(NativeTrace *parent);
         void update(ThreadContext *tc);
index 5dde3d567a2ef169713608b8769bd2204d06e632..79670bc8b5e4c8dd5429b2c8a3fbafe00d32c7be 100644 (file)
@@ -56,23 +56,28 @@ ARMTraceChild::ARMTraceChild()
 {
     foundMvn = false;
 
+    memset(&regs, 0, sizeof(regs));
+    memset(&oldregs, 0, sizeof(regs));
+    memset(&fpregs, 0, sizeof(vfp_regs));
+    memset(&oldfpregs, 0, sizeof(vfp_regs));
+
     for (int x = 0; x < numregs; x++) {
-        memset(&regs, 0, sizeof(regs));
-        memset(&oldregs, 0, sizeof(regs));
         regDiffSinceUpdate[x] = false;
     }
+
+    assert(sizeof(regs.uregs)/sizeof(regs.uregs[0]) > CPSR);
 }
 
 bool
 ARMTraceChild::sendState(int socket)
 {
     uint32_t regVal = 0;
-    uint32_t message[numregs + 1];
+    uint64_t message[numregs + 1];
     int pos = 1;
     message[0] = 0;
     for (int x = 0; x < numregs; x++) {
         if (regDiffSinceUpdate[x]) {
-            message[0] = message[0] | (1 << x);
+            message[0] = message[0] | (1ULL << x);
             message[pos++] = getRegVal(x);
         }
     }
@@ -97,10 +102,21 @@ ARMTraceChild::sendState(int socket)
 uint32_t
 ARMTraceChild::getRegs(user_regs &myregs, int num)
 {
-    assert(num < numregs && num >= 0);
+    assert(num <= CPSR && num >= 0);
     return myregs.uregs[num];
 }
 
+uint64_t
+ARMTraceChild::getFpRegs(vfp_regs &my_fp_regs, int num)
+{
+    assert(num >= F0 && num < numregs);
+    if (num == FPSCR)
+        return my_fp_regs.fpscr;
+
+    num -= F0;
+    return my_fp_regs.fpregs[num];
+}
+
 bool
 ARMTraceChild::update(int pid)
 {
@@ -110,21 +126,36 @@ ARMTraceChild::update(int pid)
         return false;
     }
 
+    const uint32_t get_vfp_regs = 32;
+
+    oldfpregs = fpregs;
+    if (ptrace((__ptrace_request)get_vfp_regs, 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;
 }
 
 int64_t
 ARMTraceChild::getRegVal(int num)
 {
-    return getRegs(regs, num);
+    if (num <= CPSR)
+        return getRegs(regs, num);
+    else
+        return (int64_t)getFpRegs(fpregs, num);
 }
 
 int64_t
 ARMTraceChild::getOldRegVal(int num)
 {
-    return getRegs(oldregs,  num);
+    if (num <= CPSR)
+        return getRegs(oldregs, num);
+    else
+        return (int64_t)getFpRegs(oldfpregs, num);
 }
 
 ostream &
index 9a4dc1921d9c4ce1637128eb2857ce0ff94edc79..06d7b0d4ff3bd83cc844a85de6ef4087f58f0aff 100644 (file)
@@ -67,12 +67,27 @@ class ARMTraceChild : public TraceChild
         R0, R1, R2, R3, R4, R5, R6, R7,
         R8, R9, R10, FP, R12, SP, LR, PC,
         CPSR,
+        F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
+        F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29,
+        F30, F31, FPSCR,
         numregs
     };
+
+    struct vfp_regs {
+        uint64_t fpregs[32];
+        uint32_t fpscr;
+    };
+
   private:
     uint32_t getRegs(user_regs& myregs, int num);
+    uint64_t getFpRegs(vfp_regs &myfpregs, int num);
+
     user_regs regs;
     user_regs oldregs;
+
+    vfp_regs fpregs;
+    vfp_regs oldfpregs;
+
     bool regDiffSinceUpdate[numregs];
     bool foundMvn;