ARM: Add vfpv3 support to native trace.

This commit is contained in:
Ali Saidi 2011-05-04 20:38:26 -05:00
parent 632cf8dd80
commit 48f7fda706
4 changed files with 77 additions and 13 deletions

View file

@ -54,7 +54,11 @@ namespace Trace {
static const char *regNames[] = { static const char *regNames[] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc", "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 #endif
@ -67,7 +71,7 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
memcpy(newState, oldState, sizeof(state[0])); memcpy(newState, oldState, sizeof(state[0]));
uint32_t diffVector; uint64_t diffVector;
parent->read(&diffVector, sizeof(diffVector)); parent->read(&diffVector, sizeof(diffVector));
diffVector = ArmISA::gtoh(diffVector); diffVector = ArmISA::gtoh(diffVector);
@ -82,7 +86,7 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
diffVector >>= 1; diffVector >>= 1;
} }
uint32_t values[changes]; uint64_t values[changes];
parent->read(values, sizeof(values)); parent->read(values, sizeof(values));
int pos = 0; int pos = 0;
for (int i = 0; i < STATE_NUMVALS; i++) { 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) | newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
tc->readIntReg(INTREG_CONDCODES); tc->readIntReg(INTREG_CONDCODES);
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); 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 void

View file

@ -62,15 +62,21 @@ class ArmNativeTrace : public NativeTrace
STATE_R15, STATE_R15,
STATE_PC = STATE_R15, STATE_PC = STATE_R15,
STATE_CPSR, 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 STATE_NUMVALS
}; };
protected: protected:
struct ThreadState { struct ThreadState {
bool changed[STATE_NUMVALS]; bool changed[STATE_NUMVALS];
uint32_t state[2][STATE_NUMVALS]; uint64_t state[2][STATE_NUMVALS];
uint32_t *newState; uint64_t *newState;
uint32_t *oldState; uint64_t *oldState;
int current; int current;
void update(NativeTrace *parent); void update(NativeTrace *parent);
void update(ThreadContext *tc); void update(ThreadContext *tc);

View file

@ -56,23 +56,28 @@ ARMTraceChild::ARMTraceChild()
{ {
foundMvn = false; 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++) { for (int x = 0; x < numregs; x++) {
memset(&regs, 0, sizeof(regs));
memset(&oldregs, 0, sizeof(regs));
regDiffSinceUpdate[x] = false; regDiffSinceUpdate[x] = false;
} }
assert(sizeof(regs.uregs)/sizeof(regs.uregs[0]) > CPSR);
} }
bool bool
ARMTraceChild::sendState(int socket) ARMTraceChild::sendState(int socket)
{ {
uint32_t regVal = 0; uint32_t regVal = 0;
uint32_t message[numregs + 1]; uint64_t message[numregs + 1];
int pos = 1; int pos = 1;
message[0] = 0; message[0] = 0;
for (int x = 0; x < numregs; x++) { for (int x = 0; x < numregs; x++) {
if (regDiffSinceUpdate[x]) { if (regDiffSinceUpdate[x]) {
message[0] = message[0] | (1 << x); message[0] = message[0] | (1ULL << x);
message[pos++] = getRegVal(x); message[pos++] = getRegVal(x);
} }
} }
@ -97,10 +102,21 @@ ARMTraceChild::sendState(int socket)
uint32_t uint32_t
ARMTraceChild::getRegs(user_regs &myregs, int num) ARMTraceChild::getRegs(user_regs &myregs, int num)
{ {
assert(num < numregs && num >= 0); assert(num <= CPSR && num >= 0);
return myregs.uregs[num]; 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 bool
ARMTraceChild::update(int pid) ARMTraceChild::update(int pid)
{ {
@ -110,21 +126,36 @@ ARMTraceChild::update(int pid)
return false; 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++) for (unsigned int x = 0; x < numregs; x++)
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x)); regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
return true; return true;
} }
int64_t int64_t
ARMTraceChild::getRegVal(int num) ARMTraceChild::getRegVal(int num)
{ {
return getRegs(regs, num); if (num <= CPSR)
return getRegs(regs, num);
else
return (int64_t)getFpRegs(fpregs, num);
} }
int64_t int64_t
ARMTraceChild::getOldRegVal(int num) ARMTraceChild::getOldRegVal(int num)
{ {
return getRegs(oldregs, num); if (num <= CPSR)
return getRegs(oldregs, num);
else
return (int64_t)getFpRegs(oldfpregs, num);
} }
ostream & ostream &

View file

@ -67,12 +67,27 @@ class ARMTraceChild : public TraceChild
R0, R1, R2, R3, R4, R5, R6, R7, R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, FP, R12, SP, LR, PC, 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,
numregs numregs
}; };
struct vfp_regs {
uint64_t fpregs[32];
uint32_t fpscr;
};
private: private:
uint32_t getRegs(user_regs& myregs, int num); uint32_t getRegs(user_regs& myregs, int num);
uint64_t getFpRegs(vfp_regs &myfpregs, int num);
user_regs regs; user_regs regs;
user_regs oldregs; user_regs oldregs;
vfp_regs fpregs;
vfp_regs oldfpregs;
bool regDiffSinceUpdate[numregs]; bool regDiffSinceUpdate[numregs];
bool foundMvn; bool foundMvn;