summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2011-05-04 20:38:26 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2011-05-04 20:38:26 -0500
commit48f7fda706b854f053d66df5e14e0084df775910 (patch)
tree7a2c8ecf89e5c4530ada1453cfe756edaa8799be
parent632cf8dd80f29f85097aa90cd704ca01cc57ff39 (diff)
downloadgem5-48f7fda706b854f053d66df5e14e0084df775910.tar.xz
ARM: Add vfpv3 support to native trace.
-rw-r--r--src/arch/arm/nativetrace.cc18
-rw-r--r--src/arch/arm/nativetrace.hh12
-rw-r--r--util/statetrace/arch/arm/tracechild.cc45
-rw-r--r--util/statetrace/arch/arm/tracechild.hh15
4 files changed, 77 insertions, 13 deletions
diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc
index 2dd225e80..a8d01a0f2 100644
--- a/src/arch/arm/nativetrace.cc
+++ b/src/arch/arm/nativetrace.cc
@@ -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
diff --git a/src/arch/arm/nativetrace.hh b/src/arch/arm/nativetrace.hh
index 221d40e2f..d3f96f3ad 100644
--- a/src/arch/arm/nativetrace.hh
+++ b/src/arch/arm/nativetrace.hh
@@ -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);
diff --git a/util/statetrace/arch/arm/tracechild.cc b/util/statetrace/arch/arm/tracechild.cc
index 5dde3d567..79670bc8b 100644
--- a/util/statetrace/arch/arm/tracechild.cc
+++ b/util/statetrace/arch/arm/tracechild.cc
@@ -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 &
diff --git a/util/statetrace/arch/arm/tracechild.hh b/util/statetrace/arch/arm/tracechild.hh
index 9a4dc1921..06d7b0d4f 100644
--- a/util/statetrace/arch/arm/tracechild.hh
+++ b/util/statetrace/arch/arm/tracechild.hh
@@ -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;