From a4b31e8f6b3c8ea33a5dad3e194c9865b92b0962 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 6 Apr 2006 14:47:03 -0400 Subject: [PATCH] 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 --- arch/alpha/isa_traits.hh | 8 +- arch/alpha/regfile.hh | 216 ++++++++++++++++++------ arch/mips/isa_traits.cc | 16 +- arch/mips/isa_traits.hh | 159 +++++++++++++++++- arch/sparc/isa_traits.hh | 12 +- arch/sparc/regfile.hh | 349 +++++++++++++++++++++++++++++++++++---- cpu/cpu_exec_context.hh | 52 +++--- cpu/exec_context.hh | 9 + cpu/exetrace.cc | 7 +- cpu/exetrace.hh | 2 +- 10 files changed, 695 insertions(+), 135 deletions(-) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 842eea05a..65c72115b 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -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 diff --git a/arch/alpha/regfile.hh b/arch/alpha/regfile.hh index 8a11a8eb6..2a3312584 100644 --- a/arch/alpha/regfile.hh +++ b/arch/alpha/regfile.hh @@ -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); diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 849d3311d..c6cfb2a0f 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -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); diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 486a5d130..35c207828 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -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; diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index bbc66202c..57206c5e5 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -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 diff --git a/arch/sparc/regfile.hh b/arch/sparc/regfile.hh index 09b8e49d7..6186e3e45 100644 --- a/arch/sparc/regfile.hh +++ b/arch/sparc/regfile.hh @@ -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); diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh index 7ceb7f2d8..b023fdcf8 100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@ -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); + } }; diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 8f93875a1..2fd49b166 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -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 @@ -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 diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc index 4db72320c..0ed3b43c4 100644 --- a/cpu/exetrace.cc +++ b/cpu/exetrace.cc @@ -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"; } diff --git a/cpu/exetrace.hh b/cpu/exetrace.hh index 67d042ec8..a26cdc517 100644 --- a/cpu/exetrace.hh +++ b/cpu/exetrace.hh @@ -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; }