Enable register windows.
arch/alpha/isa_traits.hh: arch/mips/isa_traits.cc: Turned the integer register file into a class instead of a typedef to an array. arch/alpha/regfile.hh: Changed the integer register file into a class instead of a typedef to an array. Also put the parts of the register file, ie the int, float, and misc register files, pc, npc, and nnpc, behind accessor functions. Added a changeContext function, and ContextParam and ContextVal types, so that things like the register window can be changed through call backs. arch/mips/isa_traits.hh: Turned the integer register file into a class instead of a typedef to an array. Also moved a "using namespace" into the namespace definition. arch/sparc/isa_traits.hh: Turned the integer register file into a class instead of a typedef to an array. Also "fixed" the max number of src and dest regs. They may need to be even larger. arch/sparc/regfile.hh: Changed the integer register file into a class instead of a typedef to an array. Also put the parts of the register file, ie the int, float, and misc register files, pc, npc, and nnpc, behind accessor functions. Added a changeContext function, and ContextParam and ContextVal types, so that things like the register window can be changed through call backs. Created setCWP and setAltGlobals functions for the IntRegFile. cpu/cpu_exec_context.hh: Used the accessor functions for the register file, and added a changeRegFileContext function to call back into the RegFile. Used the RegFile clear function rather than memsetting it to 0. cpu/exec_context.hh: Added the changeRegFileContext function. cpu/exetrace.cc: Use the TheISA::NumIntRegs constant, and use readReg now that the integer register file is a class instead of an array. cpu/exetrace.hh: Get the address of the regs object, now that it isn't an array. --HG-- extra : convert_revision : ea2dd81be1c2e66b3c684af319eb58f8a77fd49c
This commit is contained in:
parent
adeb458b87
commit
a4b31e8f6b
10 changed files with 695 additions and 135 deletions
|
@ -98,12 +98,12 @@ extern const int reg_redir[NumIntRegs];
|
|||
// return value itself in the standard return value reg (v0).
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
regs->intRegFile[SyscallSuccessReg] = 0;
|
||||
regs->intRegFile[ReturnValueReg] = return_value.value();
|
||||
regs->setIntReg(SyscallSuccessReg, 0);
|
||||
regs->setIntReg(ReturnValueReg, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
regs->intRegFile[SyscallSuccessReg] = (IntReg) -1;
|
||||
regs->intRegFile[ReturnValueReg] = -return_value.value();
|
||||
regs->setIntReg(SyscallSuccessReg, (IntReg)-1);
|
||||
regs->setIntReg(ReturnValueReg, -return_value.value());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,62 +38,39 @@ class ExecContext;
|
|||
|
||||
namespace AlphaISA
|
||||
{
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
IntReg regs[NumIntRegs];
|
||||
|
||||
typedef IntReg IntRegFile[NumIntRegs];
|
||||
public:
|
||||
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
|
||||
Fault setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
class FloatRegFile
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
|
||||
union {
|
||||
uint64_t q[NumFloatRegs]; // integer qword view
|
||||
double d[NumFloatRegs]; // double-precision floating point view
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
FloatReg readReg(int floatReg)
|
||||
{
|
||||
return d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg readReg(int floatReg, int width)
|
||||
{
|
||||
return readReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg)
|
||||
{
|
||||
return q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg, int width)
|
||||
{
|
||||
return readRegBits(floatReg);
|
||||
}
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
d[floatReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
return setReg(floatReg, val);
|
||||
}
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
q[floatReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
return setRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
@ -110,17 +87,18 @@ namespace AlphaISA
|
|||
public:
|
||||
MiscReg readReg(int misc_reg);
|
||||
|
||||
MiscReg readRegWithEffect(int misc_reg, Fault &fault,
|
||||
ExecContext *xc);
|
||||
|
||||
//These functions should be removed once the simplescalar cpu model
|
||||
//has been replaced.
|
||||
int getInstAsid();
|
||||
int getDataAsid();
|
||||
|
||||
MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
|
||||
|
||||
Fault setReg(int misc_reg, const MiscReg &val);
|
||||
|
||||
Fault setRegWithEffect(int misc_reg, const MiscReg &val,
|
||||
ExecContext *xc);
|
||||
ExecContext *xc);
|
||||
|
||||
#if FULL_SYSTEM
|
||||
protected:
|
||||
|
@ -136,14 +114,51 @@ namespace AlphaISA
|
|||
friend class RegFile;
|
||||
};
|
||||
|
||||
struct RegFile {
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegs; // control register file
|
||||
class RegFile {
|
||||
|
||||
protected:
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc;
|
||||
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return nnpc;
|
||||
}
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{
|
||||
nnpc = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
|
||||
#if FULL_SYSTEM
|
||||
int intrflag; // interrupt flag
|
||||
inline int instAsid()
|
||||
|
@ -152,8 +167,103 @@ namespace AlphaISA
|
|||
{ return miscRegs.getDataAsid(); }
|
||||
#endif // FULL_SYSTEM
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(&intRegFile, sizeof(intRegFile));
|
||||
bzero(&floatRegFile, sizeof(floatRegFile));
|
||||
bzero(&miscRegFile, sizeof(miscRegFile));
|
||||
}
|
||||
|
||||
MiscReg readMiscReg(int miscReg)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int miscReg,
|
||||
Fault &fault, ExecContext *xc)
|
||||
{
|
||||
fault = NoFault;
|
||||
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int miscReg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setReg(miscReg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ExecContext * xc)
|
||||
{
|
||||
return miscRegFile.setRegWithEffect(miscReg, val, xc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.d[floatReg];
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.q[floatReg];
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
floatRegFile.d[floatReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
return setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
floatRegFile.q[floatReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
return setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
Fault setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
return intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
enum ContextParam
|
||||
{
|
||||
CONTEXT_PALMODE
|
||||
};
|
||||
|
||||
typedef bool ContextVal;
|
||||
|
||||
void changeContext(ContextParam param, ContextVal val)
|
||||
{
|
||||
//This would be an alternative place to call/implement
|
||||
//the swapPALShadow function
|
||||
}
|
||||
};
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
|
|
@ -274,10 +274,22 @@ static inline Addr
|
|||
RoundPage(Addr addr)
|
||||
{ return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); }
|
||||
|
||||
void
|
||||
IntRegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
void
|
||||
IntRegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(regs, NumIntRegs);
|
||||
}
|
||||
|
||||
void
|
||||
RegFile::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_ARRAY(intRegFile, NumIntRegs);
|
||||
intRegFile.serialize(os);
|
||||
//SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
||||
//SERIALIZE_SCALAR(miscRegs.fpcr);
|
||||
//SERIALIZE_SCALAR(miscRegs.uniq);
|
||||
|
@ -298,7 +310,7 @@ RegFile::serialize(std::ostream &os)
|
|||
void
|
||||
RegFile::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_ARRAY(intRegFile, NumIntRegs);
|
||||
intRegFile.unserialize(cp, section);
|
||||
//UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs);
|
||||
//UNSERIALIZE_SCALAR(miscRegs.fpcr);
|
||||
//UNSERIALIZE_SCALAR(miscRegs.uniq);
|
||||
|
|
|
@ -43,7 +43,6 @@ class Checkpoint;
|
|||
class ExecContext;
|
||||
|
||||
namespace LittleEndianGuest {};
|
||||
using namespace LittleEndianGuest;
|
||||
|
||||
#define TARGET_MIPS
|
||||
|
||||
|
@ -92,6 +91,8 @@ class SyscallReturn {
|
|||
|
||||
namespace MipsISA
|
||||
{
|
||||
using namespace LittleEndianGuest;
|
||||
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint32_t MachInst;
|
||||
typedef uint64_t ExtMachInst;
|
||||
|
@ -163,7 +164,29 @@ namespace MipsISA
|
|||
};
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
typedef IntReg IntRegFile[NumIntRegs];
|
||||
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
IntReg regs[NumIntRegs];
|
||||
|
||||
public:
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
return regs[intReg];
|
||||
}
|
||||
|
||||
Fault setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
regs[intReg] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
/* floating point register file entry type
|
||||
typedef union {
|
||||
|
@ -483,17 +506,130 @@ extern const Addr PageOffset;
|
|||
MiscReg ctrlreg;
|
||||
} AnyReg;
|
||||
|
||||
struct RegFile {
|
||||
class RegFile {
|
||||
protected:
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegs; // control register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(&intRegFile, sizeof(intRegFile));
|
||||
bzero(&floatRegFile, sizeof(floatRegFile));
|
||||
bzero(&miscRegFile, sizeof(miscRegFile));
|
||||
}
|
||||
|
||||
MiscReg readMiscReg(int miscReg)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int miscReg,
|
||||
Fault &fault, ExecContext *xc)
|
||||
{
|
||||
fault = NoFault;
|
||||
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int miscReg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setReg(miscReg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ExecContext * xc)
|
||||
{
|
||||
return miscRegFile.setRegWithEffect(miscReg, val, xc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
return floatRegFile.readReg(floatReg);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return readFloatReg(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
return floatRegFile.readRegBits(floatReg);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return readFloatRegBits(floatReg);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
return floatRegFile.setReg(floatReg, val);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
return setFloatReg(floatReg, val);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
return floatRegFile.setRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
return setFloatRegBits(floatReg, val);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
Fault setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
return intRegFile.setReg(intReg, val);
|
||||
}
|
||||
protected:
|
||||
|
||||
Addr pc; // program counter
|
||||
Addr npc; // next-cycle program counter
|
||||
Addr nnpc; // next-next-cycle program counter
|
||||
// used to implement branch delay slot
|
||||
// not real register
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return nnpc;
|
||||
}
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{
|
||||
nnpc = val;
|
||||
}
|
||||
|
||||
MiscReg hi; // MIPS HI Register
|
||||
MiscReg lo; // MIPS LO Register
|
||||
|
@ -514,6 +650,13 @@ extern const Addr PageOffset;
|
|||
|
||||
void createCP0Regs();
|
||||
void coldReset();
|
||||
|
||||
typedef int ContextParam;
|
||||
typedef int ContextVal;
|
||||
|
||||
void changeContext(ContextParam param, ContextVal val)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
StaticInstPtr decodeInst(ExtMachInst);
|
||||
|
@ -594,12 +737,12 @@ extern const Addr PageOffset;
|
|||
// return value itself in the standard return value reg (v0).
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
regs->intRegFile[ReturnValueReg1] = 0;
|
||||
regs->intRegFile[ReturnValueReg2] = return_value.value();
|
||||
regs->setIntReg(ReturnValueReg1, 0);
|
||||
regs->setIntReg(ReturnValueReg2, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
regs->intRegFile[ReturnValueReg1] = (IntReg) -1;
|
||||
regs->intRegFile[ReturnValueReg2] = -return_value.value();
|
||||
regs->setIntReg(ReturnValueReg1, (IntReg) -1);
|
||||
regs->setIntReg(ReturnValueReg2, -return_value.value());
|
||||
}
|
||||
|
||||
//regs->intRegFile[ReturnValueReg1] = (IntReg)return_value;
|
||||
|
|
|
@ -123,8 +123,8 @@ namespace SparcISA
|
|||
const int SyscallPseudoReturnReg = ArgumentReg1;
|
||||
|
||||
//XXX These numbers are bogus
|
||||
const int MaxInstSrcRegs = 3;
|
||||
const int MaxInstDestRegs = 2;
|
||||
const int MaxInstSrcRegs = 8;
|
||||
const int MaxInstDestRegs = 3;
|
||||
|
||||
typedef uint64_t IntReg;
|
||||
|
||||
|
@ -174,12 +174,12 @@ namespace SparcISA
|
|||
// and put the return value itself in the standard return value reg ().
|
||||
if (return_value.successful()) {
|
||||
// no error
|
||||
regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 0);
|
||||
regs->intRegFile[ReturnValueReg] = return_value.value();
|
||||
regs->setMiscReg(MISCREG_CCR_ICC_C, 0);
|
||||
regs->setIntReg(ReturnValueReg, return_value.value());
|
||||
} else {
|
||||
// got an error, return details
|
||||
regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 1);
|
||||
regs->intRegFile[ReturnValueReg] = -return_value.value();
|
||||
regs->setMiscReg(MISCREG_CCR_ICC_C, 1);
|
||||
regs->setIntReg(ReturnValueReg, return_value.value());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define __ARCH_SPARC_REGFILE_HH__
|
||||
|
||||
#include "arch/sparc/faults.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/host.hh"
|
||||
|
||||
|
@ -40,11 +41,110 @@ namespace SparcISA
|
|||
|
||||
typedef uint8_t RegIndex;
|
||||
|
||||
// Maximum trap level
|
||||
// MAXTL - maximum trap level
|
||||
const int MaxTL = 4;
|
||||
|
||||
//For right now, let's pretend the register file is flat
|
||||
typedef IntReg IntRegFile[NumIntRegs];
|
||||
// NWINDOWS - number of register windows, can be 3 to 32
|
||||
const int NWindows = 6;
|
||||
|
||||
class IntRegFile
|
||||
{
|
||||
protected:
|
||||
static const int FrameOffsetBits = 3;
|
||||
static const int FrameNumBits = 2;
|
||||
|
||||
static const int RegsPerFrame = 1 << FrameOffsetBits;
|
||||
static const int FrameNumMask =
|
||||
(FrameNumBits == sizeof(int)) ?
|
||||
(unsigned int)(-1) :
|
||||
(1 << FrameNumBits) - 1;
|
||||
static const int FrameOffsetMask =
|
||||
(FrameOffsetBits == sizeof(int)) ?
|
||||
(unsigned int)(-1) :
|
||||
(1 << FrameOffsetBits) - 1;
|
||||
|
||||
IntReg regGlobals[RegsPerFrame];
|
||||
IntReg altGlobals[RegsPerFrame];
|
||||
IntReg regSegments[2 * NWindows][RegsPerFrame];
|
||||
|
||||
enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
|
||||
|
||||
IntReg * regView[NumFrames];
|
||||
|
||||
static const int RegGlobalOffset = 0;
|
||||
static const int AltGlobalOffset = 8;
|
||||
static const int FrameOffset = 16;
|
||||
int offset[NumFrames];
|
||||
|
||||
public:
|
||||
|
||||
int flattenIndex(int reg)
|
||||
{
|
||||
int flatIndex = offset[reg >> FrameOffsetBits]
|
||||
| (reg & FrameOffsetMask);
|
||||
DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
|
||||
return flatIndex;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(regGlobals, sizeof(regGlobals));
|
||||
bzero(altGlobals, sizeof(altGlobals));
|
||||
for(int x = 0; x < 2 * NWindows; x++)
|
||||
bzero(regSegments[x], sizeof(regSegments[x]));
|
||||
}
|
||||
|
||||
IntRegFile()
|
||||
{
|
||||
offset[Globals] = 0;
|
||||
regView[Globals] = regGlobals;
|
||||
setCWP(0);
|
||||
clear();
|
||||
}
|
||||
|
||||
IntReg readReg(int intReg)
|
||||
{
|
||||
IntReg val =
|
||||
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
|
||||
DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
Fault setReg(int intReg, const IntReg &val)
|
||||
{
|
||||
if(intReg)
|
||||
DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val);
|
||||
regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val;
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
//This doesn't effect the actual CWP register.
|
||||
//It's purpose is to adjust the view of the register file
|
||||
//to what it would be if CWP = cwp.
|
||||
void setCWP(int cwp)
|
||||
{
|
||||
int index = ((NWindows - cwp) % NWindows) * 2;
|
||||
offset[Outputs] = FrameOffset + (index * RegsPerFrame);
|
||||
offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame);
|
||||
offset[Inputs] = FrameOffset +
|
||||
(((index+2) % (NWindows * 2)) * RegsPerFrame);
|
||||
regView[Outputs] = regSegments[index];
|
||||
regView[Locals] = regSegments[index+1];
|
||||
regView[Inputs] = regSegments[(index+2) % (NWindows * 2)];
|
||||
|
||||
DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp);
|
||||
}
|
||||
|
||||
void setAltGlobals(bool useAlt)
|
||||
{
|
||||
regView[Globals] = useAlt ? altGlobals : regGlobals;
|
||||
offset[Globals] = useAlt ? AltGlobalOffset : RegGlobalOffset;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
typedef float float32_t;
|
||||
typedef double float64_t;
|
||||
|
@ -54,11 +154,13 @@ namespace SparcISA
|
|||
|
||||
class FloatRegFile
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
static const int SingleWidth = 32;
|
||||
static const int DoubleWidth = 64;
|
||||
static const int QuadWidth = 128;
|
||||
|
||||
protected:
|
||||
|
||||
//Since the floating point registers overlap each other,
|
||||
//A generic storage space is used. The float to be returned is
|
||||
//pulled from the appropriate section of this region.
|
||||
|
@ -66,6 +168,11 @@ namespace SparcISA
|
|||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
bzero(regSpace, sizeof(regSpace));
|
||||
}
|
||||
|
||||
FloatReg readReg(int floatReg, int width)
|
||||
{
|
||||
//In each of these cases, we have to copy the value into a temporary
|
||||
|
@ -90,12 +197,6 @@ namespace SparcISA
|
|||
}
|
||||
}
|
||||
|
||||
FloatReg readReg(int floatReg)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return readReg(floatReg, SingleWidth);
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg, int width)
|
||||
{
|
||||
//In each of these cases, we have to copy the value into a temporary
|
||||
|
@ -120,12 +221,6 @@ namespace SparcISA
|
|||
}
|
||||
}
|
||||
|
||||
FloatRegBits readRegBits(int floatReg)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return readRegBits(floatReg, SingleWidth);
|
||||
}
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
//In each of these cases, we have to copy the value into a temporary
|
||||
|
@ -148,12 +243,6 @@ namespace SparcISA
|
|||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return setReg(floatReg, val, SingleWidth);
|
||||
}
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
//In each of these cases, we have to copy the value into a temporary
|
||||
|
@ -176,12 +265,6 @@ namespace SparcISA
|
|||
return NoFault;
|
||||
}
|
||||
|
||||
Fault setRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return setReg(floatReg, val, SingleWidth);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
@ -474,14 +557,59 @@ namespace SparcISA
|
|||
};
|
||||
|
||||
public:
|
||||
|
||||
void reset()
|
||||
{
|
||||
pstateFields.pef = 0; //No FPU
|
||||
//pstateFields.pef = 1; //FPU
|
||||
#if FULL_SYSTEM
|
||||
//For SPARC, when a system is first started, there is a power
|
||||
//on reset Trap which sets the processor into the following state.
|
||||
//Bits that aren't set aren't defined on startup.
|
||||
tl = MaxTL;
|
||||
tt[tl] = PowerOnReset.trapType();
|
||||
pstateFields.mm = 0; //Total Store Order
|
||||
pstateFields.red = 1; //Enter RED_State
|
||||
pstateFields.am = 0; //Address Masking is turned off
|
||||
pstateFields.priv = 1; //Processor enters privileged mode
|
||||
pstateFields.ie = 0; //Interrupts are disabled
|
||||
pstateFields.ag = 1; //Globals are replaced with alternate globals
|
||||
pstateFields.tle = 0; //Big Endian mode for traps
|
||||
pstateFields.cle = 0; //Big Endian mode for non-traps
|
||||
tickFields.npt = 1; //The TICK register is unreadable by
|
||||
//non-priveleged software
|
||||
#else
|
||||
//This sets up the initial state of the processor for usermode processes
|
||||
pstateFields.priv = 0; //Process runs in user mode
|
||||
pstateFields.ie = 1; //Interrupts are enabled
|
||||
fsrFields.rd = 0; //Round to nearest
|
||||
fsrFields.tem = 0; //Floating point traps not enabled
|
||||
fsrFields.ns = 0; //Non standard mode off
|
||||
fsrFields.qne = 0; //Floating point queue is empty
|
||||
fsrFields.aexc = 0; //No accrued exceptions
|
||||
fsrFields.cexc = 0; //No current exceptions
|
||||
|
||||
//Register window management registers
|
||||
otherwin = 0; //No windows contain info from other programs
|
||||
canrestore = 0; //There are no windows to pop
|
||||
cansave = MaxTL - 2; //All windows are available to save into
|
||||
cleanwin = MaxTL;
|
||||
#endif
|
||||
}
|
||||
|
||||
MiscRegFile()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
MiscReg readReg(int miscReg);
|
||||
|
||||
MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc);
|
||||
|
||||
Fault setReg(int miscReg, const MiscReg &val);
|
||||
|
||||
Fault setRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ExecContext *xc);
|
||||
Fault setRegWithEffect(int miscReg,
|
||||
const MiscReg &val, ExecContext * xc);
|
||||
|
||||
void serialize(std::ostream & os);
|
||||
|
||||
|
@ -497,18 +625,169 @@ namespace SparcISA
|
|||
MiscReg ctrlreg;
|
||||
} AnyReg;
|
||||
|
||||
struct RegFile
|
||||
class RegFile
|
||||
{
|
||||
IntRegFile intRegFile; // (signed) integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegs; // control register file
|
||||
|
||||
protected:
|
||||
Addr pc; // Program Counter
|
||||
Addr npc; // Next Program Counter
|
||||
Addr nnpc;
|
||||
|
||||
public:
|
||||
Addr readPC()
|
||||
{
|
||||
return pc;
|
||||
}
|
||||
|
||||
void setPC(Addr val)
|
||||
{
|
||||
pc = val;
|
||||
}
|
||||
|
||||
Addr readNextPC()
|
||||
{
|
||||
return npc;
|
||||
}
|
||||
|
||||
void setNextPC(Addr val)
|
||||
{
|
||||
npc = val;
|
||||
}
|
||||
|
||||
Addr readNextNPC()
|
||||
{
|
||||
return nnpc;
|
||||
}
|
||||
|
||||
void setNextNPC(Addr val)
|
||||
{
|
||||
nnpc = val;
|
||||
}
|
||||
|
||||
protected:
|
||||
IntRegFile intRegFile; // integer register file
|
||||
FloatRegFile floatRegFile; // floating point register file
|
||||
MiscRegFile miscRegFile; // control register file
|
||||
|
||||
public:
|
||||
|
||||
void clear()
|
||||
{
|
||||
intRegFile.clear();
|
||||
floatRegFile.clear();
|
||||
}
|
||||
|
||||
int flattenIntIndex(int reg)
|
||||
{
|
||||
return intRegFile.flattenIndex(reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscReg(int miscReg)
|
||||
{
|
||||
return miscRegFile.readReg(miscReg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int miscReg,
|
||||
Fault &fault, ExecContext *xc)
|
||||
{
|
||||
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int miscReg, const MiscReg &val)
|
||||
{
|
||||
return miscRegFile.setReg(miscReg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ExecContext * xc)
|
||||
{
|
||||
return miscRegFile.setRegWithEffect(miscReg, val, xc);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg, int width)
|
||||
{
|
||||
return floatRegFile.readReg(floatReg, width);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int floatReg)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg, int width)
|
||||
{
|
||||
return floatRegFile.readRegBits(floatReg, width);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int floatReg)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return floatRegFile.readRegBits(floatReg,
|
||||
FloatRegFile::SingleWidth);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
|
||||
{
|
||||
return floatRegFile.setReg(floatReg, val, width);
|
||||
}
|
||||
|
||||
Fault setFloatReg(int floatReg, const FloatReg &val)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
|
||||
{
|
||||
return floatRegFile.setRegBits(floatReg, val, width);
|
||||
}
|
||||
|
||||
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
|
||||
{
|
||||
//Use the "natural" width of a single float
|
||||
return floatRegFile.setRegBits(floatReg, val,
|
||||
FloatRegFile::SingleWidth);
|
||||
}
|
||||
|
||||
IntReg readIntReg(int intReg)
|
||||
{
|
||||
return intRegFile.readReg(intReg);
|
||||
}
|
||||
|
||||
Fault setIntReg(int intReg, const IntReg &val)
|
||||
{
|
||||
return intRegFile.setReg(intReg, val);
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
public:
|
||||
|
||||
enum ContextParam
|
||||
{
|
||||
CONTEXT_CWP,
|
||||
CONTEXT_GLOBALS
|
||||
};
|
||||
|
||||
union ContextVal
|
||||
{
|
||||
MiscReg reg;
|
||||
bool altGlobals;
|
||||
};
|
||||
|
||||
void changeContext(ContextParam param, ContextVal val)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case CONTEXT_CWP:
|
||||
intRegFile.setCWP(val.reg);
|
||||
case CONTEXT_GLOBALS:
|
||||
intRegFile.setAltGlobals(val.altGlobals);
|
||||
default:
|
||||
panic("Tried to set illegal context parameter in the SPARC regfile.\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void copyRegs(ExecContext *src, ExecContext *dest);
|
||||
|
|
|
@ -373,103 +373,103 @@ class CPUExecContext
|
|||
//
|
||||
uint64_t readIntReg(int reg_idx)
|
||||
{
|
||||
return regs.intRegFile[reg_idx];
|
||||
return regs.readIntReg(reg_idx);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int reg_idx, int width)
|
||||
{
|
||||
return regs.floatRegFile.readReg(reg_idx, width);
|
||||
return regs.readFloatReg(reg_idx, width);
|
||||
}
|
||||
|
||||
FloatReg readFloatReg(int reg_idx)
|
||||
{
|
||||
return regs.floatRegFile.readReg(reg_idx);
|
||||
return regs.readFloatReg(reg_idx);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int reg_idx, int width)
|
||||
{
|
||||
return regs.floatRegFile.readRegBits(reg_idx, width);
|
||||
return regs.readFloatRegBits(reg_idx, width);
|
||||
}
|
||||
|
||||
FloatRegBits readFloatRegBits(int reg_idx)
|
||||
{
|
||||
return regs.floatRegFile.readRegBits(reg_idx);
|
||||
return regs.readFloatRegBits(reg_idx);
|
||||
}
|
||||
|
||||
void setIntReg(int reg_idx, uint64_t val)
|
||||
{
|
||||
regs.intRegFile[reg_idx] = val;
|
||||
regs.setIntReg(reg_idx, val);
|
||||
}
|
||||
|
||||
void setFloatReg(int reg_idx, FloatReg val, int width)
|
||||
{
|
||||
regs.floatRegFile.setReg(reg_idx, val, width);
|
||||
regs.setFloatReg(reg_idx, val, width);
|
||||
}
|
||||
|
||||
void setFloatReg(int reg_idx, FloatReg val)
|
||||
{
|
||||
regs.floatRegFile.setReg(reg_idx, val);
|
||||
regs.setFloatReg(reg_idx, val);
|
||||
}
|
||||
|
||||
void setFloatRegBits(int reg_idx, FloatRegBits val, int width)
|
||||
{
|
||||
regs.floatRegFile.setRegBits(reg_idx, val, width);
|
||||
regs.setFloatRegBits(reg_idx, val, width);
|
||||
}
|
||||
|
||||
void setFloatRegBits(int reg_idx, FloatRegBits val)
|
||||
{
|
||||
regs.floatRegFile.setRegBits(reg_idx, val);
|
||||
regs.setFloatRegBits(reg_idx, val);
|
||||
}
|
||||
|
||||
uint64_t readPC()
|
||||
{
|
||||
return regs.pc;
|
||||
return regs.readPC();
|
||||
}
|
||||
|
||||
void setPC(uint64_t val)
|
||||
{
|
||||
regs.pc = val;
|
||||
regs.setPC(val);
|
||||
}
|
||||
|
||||
uint64_t readNextPC()
|
||||
{
|
||||
return regs.npc;
|
||||
return regs.readNextPC();
|
||||
}
|
||||
|
||||
void setNextPC(uint64_t val)
|
||||
{
|
||||
regs.npc = val;
|
||||
regs.setNextPC(val);
|
||||
}
|
||||
|
||||
uint64_t readNextNPC()
|
||||
{
|
||||
return regs.nnpc;
|
||||
return regs.readNextNPC();
|
||||
}
|
||||
|
||||
void setNextNPC(uint64_t val)
|
||||
{
|
||||
regs.nnpc = val;
|
||||
regs.setNextNPC(val);
|
||||
}
|
||||
|
||||
|
||||
MiscReg readMiscReg(int misc_reg)
|
||||
{
|
||||
return regs.miscRegs.readReg(misc_reg);
|
||||
return regs.readMiscReg(misc_reg);
|
||||
}
|
||||
|
||||
MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault)
|
||||
{
|
||||
return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy);
|
||||
return regs.readMiscRegWithEffect(misc_reg, fault, proxy);
|
||||
}
|
||||
|
||||
Fault setMiscReg(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return regs.miscRegs.setReg(misc_reg, val);
|
||||
return regs.setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val)
|
||||
{
|
||||
return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy);
|
||||
return regs.setMiscRegWithEffect(misc_reg, val, proxy);
|
||||
}
|
||||
|
||||
unsigned readStCondFailures() { return storeCondFailures; }
|
||||
|
@ -477,7 +477,7 @@ class CPUExecContext
|
|||
void setStCondFailures(unsigned sc_failures)
|
||||
{ storeCondFailures = sc_failures; }
|
||||
|
||||
void clearArchRegs() { memset(®s, 0, sizeof(regs)); }
|
||||
void clearArchRegs() { regs.clear(); }
|
||||
|
||||
#if FULL_SYSTEM
|
||||
int readIntrFlag() { return regs.intrflag; }
|
||||
|
@ -490,13 +490,13 @@ class CPUExecContext
|
|||
#if !FULL_SYSTEM
|
||||
TheISA::IntReg getSyscallArg(int i)
|
||||
{
|
||||
return regs.intRegFile[TheISA::ArgumentReg0 + i];
|
||||
return regs.readIntReg(TheISA::ArgumentReg0 + i);
|
||||
}
|
||||
|
||||
// used to shift args for indirect syscall
|
||||
void setSyscallArg(int i, TheISA::IntReg val)
|
||||
{
|
||||
regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
|
||||
regs.setIntReg(TheISA::ArgumentReg0 + i, val);
|
||||
}
|
||||
|
||||
void setSyscallReturn(SyscallReturn return_value)
|
||||
|
@ -513,6 +513,12 @@ class CPUExecContext
|
|||
|
||||
void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; }
|
||||
#endif
|
||||
|
||||
void changeRegFileContext(RegFile::ContextParam param,
|
||||
RegFile::ContextVal val)
|
||||
{
|
||||
regs.changeContext(param, val);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -233,6 +233,9 @@ class ExecContext
|
|||
|
||||
virtual void setFuncExeInst(Counter new_val) = 0;
|
||||
#endif
|
||||
|
||||
virtual void changeRegFileContext(RegFile::ContextParam param,
|
||||
RegFile::ContextVal val) = 0;
|
||||
};
|
||||
|
||||
template <class XC>
|
||||
|
@ -422,6 +425,12 @@ class ProxyExecContext : public ExecContext
|
|||
void setFuncExeInst(Counter new_val)
|
||||
{ return actualXC->setFuncExeInst(new_val); }
|
||||
#endif
|
||||
|
||||
void changeRegFileContext(RegFile::ContextParam param,
|
||||
RegFile::ContextVal val)
|
||||
{
|
||||
actualXC->changeRegFileContext(param, val);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -128,10 +128,11 @@ Trace::InstRecord::dump(ostream &outs)
|
|||
outs << " A=0x" << hex << addr;
|
||||
|
||||
if (flags[PRINT_INT_REGS] && regs_valid) {
|
||||
for (int i = 0; i < 32;)
|
||||
for (int i = 0; i < TheISA::NumIntRegs;)
|
||||
for (int j = i + 1; i <= j; i++)
|
||||
ccprintf(outs, "r%02d = %#018x%s", i, iregs->regs[i],
|
||||
((i == j) ? "\n" : " "));
|
||||
ccprintf(outs, "r%02d = %#018x%s", i,
|
||||
iregs->regs.readReg(i),
|
||||
((i == j) ? "\n" : " "));
|
||||
outs << "\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ InstRecord::setRegs(const IntRegFile ®s)
|
|||
if (!iregs)
|
||||
iregs = new iRegFile;
|
||||
|
||||
memcpy(&iregs->regs, regs, sizeof(IntRegFile));
|
||||
memcpy(&iregs->regs, ®s, sizeof(IntRegFile));
|
||||
regs_valid = true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue