cpu: Implement a flat register interface in thread contexts

Some architectures map registers differently depending on their mode
of operations. There is currently no architecture independent way of
accessing all registers. This patch introduces a flat register
interface to the ThreadContext class. This interface is useful, for
example, when serializing or copying thread contexts.
This commit is contained in:
Andreas Sandberg
2013-01-07 13:05:44 -05:00
parent 17b47d35e1
commit e2dad8236a
7 changed files with 189 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 ARM Limited
* Copyright (c) 2011-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -302,6 +302,24 @@ class CheckerThreadContext : public ThreadContext
bool misspeculating() { return actualTC->misspeculating(); }
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
uint64_t readIntRegFlat(int idx)
{ return actualTC->readIntRegFlat(idx); }
void setIntRegFlat(int idx, uint64_t val)
{ actualTC->setIntRegFlat(idx, val); }
FloatReg readFloatRegFlat(int idx)
{ return actualTC->readFloatRegFlat(idx); }
void setFloatRegFlat(int idx, FloatReg val)
{ actualTC->setFloatRegFlat(idx, val); }
FloatRegBits readFloatRegBitsFlat(int idx)
{ return actualTC->readFloatRegBitsFlat(idx); }
void setFloatRegBitsFlat(int idx, FloatRegBits val)
{ actualTC->setFloatRegBitsFlat(idx, val); }
};
#endif // __CPU_CHECKER_EXEC_CONTEXT_HH__

View File

@@ -1,4 +1,16 @@
/*
* Copyright (c) 2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
@@ -249,3 +261,46 @@ InOrderThreadContext::setMiscReg(int misc_reg, const MiscReg &val)
{
cpu->setMiscReg(misc_reg, val, thread->threadId());
}
uint64_t
InOrderThreadContext::readIntRegFlat(int idx)
{
const ThreadID tid = thread->threadId();
return cpu->readIntReg(idx, tid);
}
void
InOrderThreadContext::setIntRegFlat(int idx, uint64_t val)
{
const ThreadID tid = thread->threadId();
cpu->setIntReg(idx, val, tid);
}
FloatReg
InOrderThreadContext::readFloatRegFlat(int idx)
{
const ThreadID tid = thread->threadId();
return cpu->readFloatReg(idx, tid);
}
void
InOrderThreadContext::setFloatRegFlat(int idx, FloatReg val)
{
const ThreadID tid = thread->threadId();
cpu->setFloatReg(idx, val, tid);
}
FloatRegBits
InOrderThreadContext::readFloatRegBitsFlat(int idx)
{
const ThreadID tid = thread->threadId();
return cpu->readFloatRegBits(idx, tid);
}
void
InOrderThreadContext::setFloatRegBitsFlat(int idx, FloatRegBits val)
{
const ThreadID tid = thread->threadId();
cpu->setFloatRegBits(idx, val, tid);
}

View File

@@ -1,4 +1,16 @@
/*
* Copyright (c) 2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
* not be construed as granting a license to any other intellectual
* property including but not limited to intellectual property relating
* to a hardware implementation of the functionality of the software
* licensed hereunder. You may use the software subject to the license
* terms below provided that you ensure that this notice is replicated
* unmodified and in its entirety in all distributions of the software,
* modified or unmodified, in source code or in binary form.
*
* Copyright (c) 2007 MIPS Technologies, Inc.
* All rights reserved.
*
@@ -292,6 +304,15 @@ class InOrderThreadContext : public ThreadContext
void changeRegFileContext(unsigned param,
unsigned val)
{ panic("Not supported!"); }
uint64_t readIntRegFlat(int idx);
void setIntRegFlat(int idx, uint64_t val);
FloatReg readFloatRegFlat(int idx);
void setFloatRegFlat(int idx, FloatReg val);
FloatRegBits readFloatRegBitsFlat(int idx);
void setFloatRegBitsFlat(int idx, FloatRegBits val);
};
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011 ARM Limited
* Copyright (c) 2011-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -175,18 +175,30 @@ class O3ThreadContext : public ThreadContext
virtual void clearArchRegs();
/** Reads an integer register. */
virtual uint64_t readIntReg(int reg_idx);
virtual uint64_t readIntReg(int reg_idx) {
return readIntRegFlat(flattenIntIndex(reg_idx));
}
virtual FloatReg readFloatReg(int reg_idx);
virtual FloatReg readFloatReg(int reg_idx) {
return readFloatRegFlat(flattenFloatIndex(reg_idx));
}
virtual FloatRegBits readFloatRegBits(int reg_idx);
virtual FloatRegBits readFloatRegBits(int reg_idx) {
return readFloatRegBitsFlat(flattenFloatIndex(reg_idx));
}
/** Sets an integer register to a value. */
virtual void setIntReg(int reg_idx, uint64_t val);
virtual void setIntReg(int reg_idx, uint64_t val) {
setIntRegFlat(flattenIntIndex(reg_idx), val);
}
virtual void setFloatReg(int reg_idx, FloatReg val);
virtual void setFloatReg(int reg_idx, FloatReg val) {
setFloatRegFlat(flattenFloatIndex(reg_idx), val);
}
virtual void setFloatRegBits(int reg_idx, FloatRegBits val);
virtual void setFloatRegBits(int reg_idx, FloatRegBits val) {
setFloatRegBitsFlat(flattenFloatIndex(reg_idx), val);
}
/** Reads this thread's PC state. */
virtual TheISA::PCState pcState()
@@ -268,6 +280,14 @@ class O3ThreadContext : public ThreadContext
cpu->squashFromTC(thread->threadId());
}
virtual uint64_t readIntRegFlat(int idx);
virtual void setIntRegFlat(int idx, uint64_t val);
virtual FloatReg readFloatRegFlat(int idx);
virtual void setFloatRegFlat(int idx, FloatReg val);
virtual FloatRegBits readFloatRegBitsFlat(int idx);
virtual void setFloatRegBitsFlat(int idx, FloatRegBits val);
};
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2011 ARM Limited
* Copyright (c) 2010-2012 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -224,33 +224,29 @@ O3ThreadContext<Impl>::clearArchRegs()
template <class Impl>
uint64_t
O3ThreadContext<Impl>::readIntReg(int reg_idx)
O3ThreadContext<Impl>::readIntRegFlat(int reg_idx)
{
reg_idx = cpu->isa[thread->threadId()]->flattenIntIndex(reg_idx);
return cpu->readArchIntReg(reg_idx, thread->threadId());
}
template <class Impl>
TheISA::FloatReg
O3ThreadContext<Impl>::readFloatReg(int reg_idx)
O3ThreadContext<Impl>::readFloatRegFlat(int reg_idx)
{
reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
return cpu->readArchFloatReg(reg_idx, thread->threadId());
}
template <class Impl>
TheISA::FloatRegBits
O3ThreadContext<Impl>::readFloatRegBits(int reg_idx)
O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
{
reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
}
template <class Impl>
void
O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
{
reg_idx = cpu->isa[thread->threadId()]->flattenIntIndex(reg_idx);
cpu->setArchIntReg(reg_idx, val, thread->threadId());
conditionalSquash();
@@ -258,9 +254,8 @@ O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val)
template <class Impl>
void
O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
O3ThreadContext<Impl>::setFloatRegFlat(int reg_idx, FloatReg val)
{
reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
cpu->setArchFloatReg(reg_idx, val, thread->threadId());
conditionalSquash();
@@ -268,9 +263,8 @@ O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val)
template <class Impl>
void
O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
{
reg_idx = cpu->isa[thread->threadId()]->flattenFloatIndex(reg_idx);
cpu->setArchFloatRegInt(reg_idx, val, thread->threadId());
conditionalSquash();

View File

@@ -237,7 +237,7 @@ class SimpleThread : public ThreadState
{
int flatIndex = isa->flattenIntIndex(reg_idx);
assert(flatIndex < TheISA::NumIntRegs);
uint64_t regVal = intRegs[flatIndex];
uint64_t regVal(readIntRegFlat(flatIndex));
DPRINTF(IntRegs, "Reading int reg %d (%d) as %#x.\n",
reg_idx, flatIndex, regVal);
return regVal;
@@ -247,7 +247,7 @@ class SimpleThread : public ThreadState
{
int flatIndex = isa->flattenFloatIndex(reg_idx);
assert(flatIndex < TheISA::NumFloatRegs);
FloatReg regVal = floatRegs.f[flatIndex];
FloatReg regVal(readFloatRegFlat(flatIndex));
DPRINTF(FloatRegs, "Reading float reg %d (%d) as %f, %#x.\n",
reg_idx, flatIndex, regVal, floatRegs.i[flatIndex]);
return regVal;
@@ -257,7 +257,7 @@ class SimpleThread : public ThreadState
{
int flatIndex = isa->flattenFloatIndex(reg_idx);
assert(flatIndex < TheISA::NumFloatRegs);
FloatRegBits regVal = floatRegs.i[flatIndex];
FloatRegBits regVal(readFloatRegBitsFlat(flatIndex));
DPRINTF(FloatRegs, "Reading float reg %d (%d) bits as %#x, %f.\n",
reg_idx, flatIndex, regVal, floatRegs.f[flatIndex]);
return regVal;
@@ -269,14 +269,14 @@ class SimpleThread : public ThreadState
assert(flatIndex < TheISA::NumIntRegs);
DPRINTF(IntRegs, "Setting int reg %d (%d) to %#x.\n",
reg_idx, flatIndex, val);
intRegs[flatIndex] = val;
setIntRegFlat(flatIndex, val);
}
void setFloatReg(int reg_idx, FloatReg val)
{
int flatIndex = isa->flattenFloatIndex(reg_idx);
assert(flatIndex < TheISA::NumFloatRegs);
floatRegs.f[flatIndex] = val;
setFloatRegFlat(flatIndex, val);
DPRINTF(FloatRegs, "Setting float reg %d (%d) to %f, %#x.\n",
reg_idx, flatIndex, val, floatRegs.i[flatIndex]);
}
@@ -288,7 +288,7 @@ class SimpleThread : public ThreadState
// XXX: Fix array out of bounds compiler error for gem5.fast
// when checkercpu enabled
if (flatIndex < TheISA::NumFloatRegs)
floatRegs.i[flatIndex] = val;
setFloatRegBitsFlat(flatIndex, val);
DPRINTF(FloatRegs, "Setting float reg %d (%d) bits to %#x, %#f.\n",
reg_idx, flatIndex, val, floatRegs.f[flatIndex]);
}
@@ -384,6 +384,18 @@ class SimpleThread : public ThreadState
{
process->syscall(callnum, tc);
}
uint64_t readIntRegFlat(int idx) { return intRegs[idx]; }
void setIntRegFlat(int idx, uint64_t val) { intRegs[idx] = val; }
FloatReg readFloatRegFlat(int idx) { return floatRegs.f[idx]; }
void setFloatRegFlat(int idx, FloatReg val) { floatRegs.f[idx] = val; }
FloatRegBits readFloatRegBitsFlat(int idx) { return floatRegs.i[idx]; }
void setFloatRegBitsFlat(int idx, FloatRegBits val) {
floatRegs.i[idx] = val;
}
};

View File

@@ -264,6 +264,30 @@ class ThreadContext
/** function to compare two thread contexts (for debugging) */
static void compare(ThreadContext *one, ThreadContext *two);
/** @{ */
/**
* Flat register interfaces
*
* Some architectures have different registers visible in
* different modes. Such architectures "flatten" a register (see
* flattenIntIndex() and flattenFloatIndex()) to map it into the
* gem5 register file. This interface provides a flat interface to
* the underlying register file, which allows for example
* serialization code to access all registers.
*/
virtual uint64_t readIntRegFlat(int idx) = 0;
virtual void setIntRegFlat(int idx, uint64_t val) = 0;
virtual FloatReg readFloatRegFlat(int idx) = 0;
virtual void setFloatRegFlat(int idx, FloatReg val) = 0;
virtual FloatRegBits readFloatRegBitsFlat(int idx) = 0;
virtual void setFloatRegBitsFlat(int idx, FloatRegBits val) = 0;
/** @} */
};
/**
@@ -429,6 +453,24 @@ class ProxyThreadContext : public ThreadContext
{ actualTC->syscall(callnum); }
Counter readFuncExeInst() { return actualTC->readFuncExeInst(); }
uint64_t readIntRegFlat(int idx)
{ return actualTC->readIntRegFlat(idx); }
void setIntRegFlat(int idx, uint64_t val)
{ actualTC->setIntRegFlat(idx, val); }
FloatReg readFloatRegFlat(int idx)
{ return actualTC->readFloatRegFlat(idx); }
void setFloatRegFlat(int idx, FloatReg val)
{ actualTC->setFloatRegFlat(idx, val); }
FloatRegBits readFloatRegBitsFlat(int idx)
{ return actualTC->readFloatRegBitsFlat(idx); }
void setFloatRegBitsFlat(int idx, FloatRegBits val)
{ actualTC->setFloatRegBitsFlat(idx, val); }
};
#endif