ARM: Add vfpv3 support to native trace.
This commit is contained in:
parent
632cf8dd80
commit
48f7fda706
4 changed files with 77 additions and 13 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -56,23 +56,28 @@ ARMTraceChild::ARMTraceChild()
|
|||
{
|
||||
foundMvn = false;
|
||||
|
||||
memset(®s, 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(®s, 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 &
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue