summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/SConscript11
-rw-r--r--src/arch/sparc/floatregfile.cc174
-rw-r--r--src/arch/sparc/floatregfile.hh83
-rw-r--r--src/arch/sparc/intregfile.cc133
-rw-r--r--src/arch/sparc/intregfile.hh103
-rw-r--r--src/arch/sparc/isa/base.isa32
-rw-r--r--src/arch/sparc/isa/decoder.isa305
-rw-r--r--src/arch/sparc/isa/formats/basic.isa6
-rw-r--r--src/arch/sparc/isa/formats/branch.isa109
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa145
-rw-r--r--src/arch/sparc/isa/formats/priv.isa20
-rw-r--r--src/arch/sparc/isa/includes.isa6
-rw-r--r--src/arch/sparc/isa/operands.isa45
-rw-r--r--src/arch/sparc/isa_traits.hh106
-rw-r--r--src/arch/sparc/linux/linux.cc1
-rw-r--r--src/arch/sparc/linux/process.cc4
-rw-r--r--src/arch/sparc/linux/process.hh1
-rw-r--r--src/arch/sparc/miscregfile.cc540
-rw-r--r--src/arch/sparc/miscregfile.hh410
-rw-r--r--src/arch/sparc/process.cc65
-rw-r--r--src/arch/sparc/regfile.cc279
-rw-r--r--src/arch/sparc/regfile.hh825
-rw-r--r--src/arch/sparc/solaris/solaris.cc2
-rw-r--r--src/arch/sparc/stacktrace.hh6
-rw-r--r--src/arch/sparc/syscallreturn.hh92
-rw-r--r--src/arch/sparc/system.cc4
-rw-r--r--src/arch/sparc/types.hh63
-rw-r--r--src/arch/sparc/ua2005.cc10
28 files changed, 2407 insertions, 1173 deletions
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index e7a8278db..66f2b57e0 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -45,22 +45,25 @@ Import('env')
# Base sources used by all configurations.
base_sources = Split('''
faults.cc
- isa_traits.cc
+ floatregfile.cc
+ intregfile.cc
+ miscregfile.cc
+ regfile.cc
''')
# Full-system sources
full_system_sources = Split('''
- vtophys.cc
ua2005.cc
+ vtophys.cc
''')
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
linux/linux.cc
linux/process.cc
- solaris/solaris.cc
- solaris/process.cc
process.cc
+ solaris/process.cc
+ solaris/solaris.cc
''')
sources = base_sources
diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc
new file mode 100644
index 000000000..3cacbb278
--- /dev/null
+++ b/src/arch/sparc/floatregfile.cc
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#include "arch/sparc/floatregfile.hh"
+#include "base/trace.hh"
+#include "sim/byteswap.hh"
+#include "sim/serialize.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+string SparcISA::getFloatRegName(RegIndex index)
+{
+ static std::string floatRegName[NumFloatRegs] =
+ {"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",
+ "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
+ "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
+ "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
+ "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"};
+ return floatRegName[index];
+}
+
+void FloatRegFile::clear()
+{
+ bzero(regSpace, sizeof(regSpace));
+}
+
+FloatReg FloatRegFile::readReg(int floatReg, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ float32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
+ return htog(result32);
+ case DoubleWidth:
+ float64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
+ return htog(result64);
+ case QuadWidth:
+ float128_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+}
+
+FloatRegBits FloatRegFile::readRegBits(int floatReg, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32));
+ return htog(result32);
+ case DoubleWidth:
+ uint64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64));
+ return htog(result64);
+ case QuadWidth:
+ uint64_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128));
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+}
+
+Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+
+ uint32_t result32;
+ uint64_t result64;
+ DPRINTF(Sparc, "Setting floating point register %d\n", floatReg);
+ switch(width)
+ {
+ case SingleWidth:
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ break;
+ case DoubleWidth:
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ break;
+ case QuadWidth:
+ panic("Quad width FP not implemented.");
+ break;
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+}
+
+Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ uint32_t result32;
+ uint64_t result64;
+ switch(width)
+ {
+ case SingleWidth:
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32));
+ break;
+ case DoubleWidth:
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64));
+ break;
+ case QuadWidth:
+ panic("Quad width FP not implemented.");
+ break;
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+}
+
+void FloatRegFile::serialize(std::ostream &os)
+{
+ SERIALIZE_ARRAY((unsigned char *)regSpace,
+ SingleWidth / 8 * NumFloatRegs);
+}
+
+void FloatRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ UNSERIALIZE_ARRAY((unsigned char *)regSpace,
+ SingleWidth / 8 * NumFloatRegs);
+}
+
diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh
new file mode 100644
index 000000000..9d760c9ff
--- /dev/null
+++ b/src/arch/sparc/floatregfile.hh
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_FLOATREGFILE_HH__
+#define __ARCH_SPARC_FLOATREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+ std::string getFloatRegName(RegIndex);
+
+ typedef float float32_t;
+ typedef double float64_t;
+ //FIXME long double refers to a 10 byte float, rather than a
+ //16 byte float as required. This data type may have to be emulated.
+ typedef double float128_t;
+
+ class FloatRegFile
+ {
+ 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.
+ char regSpace[(SingleWidth / 8) * NumFloatRegs];
+
+ public:
+
+ void clear();
+
+ FloatReg readReg(int floatReg, int width);
+
+ FloatRegBits readRegBits(int floatReg, int width);
+
+ Fault setReg(int floatReg, const FloatReg &val, int width);
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc
new file mode 100644
index 000000000..0cc0a886a
--- /dev/null
+++ b/src/arch/sparc/intregfile.cc
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#include "arch/sparc/intregfile.hh"
+#include "base/trace.hh"
+#include "sim/serialize.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+string SparcISA::getIntRegName(RegIndex index)
+{
+ static std::string intRegName[NumIntRegs] =
+ {"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
+ "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"};
+ return intRegName[index];
+}
+
+int IntRegFile::flattenIndex(int reg)
+{
+ int flatIndex = offset[reg >> FrameOffsetBits]
+ | (reg & FrameOffsetMask);
+ DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex);
+ return flatIndex;
+}
+
+void IntRegFile::clear()
+{
+ int x;
+ for (x = 0; x < MaxGL; x++)
+ memset(regGlobals[x], 0, sizeof(regGlobals[x]));
+ for(int x = 0; x < 2 * NWindows; x++)
+ bzero(regSegments[x], sizeof(regSegments[x]));
+}
+
+IntRegFile::IntRegFile()
+{
+ offset[Globals] = 0;
+ regView[Globals] = regGlobals[0];
+ setCWP(0);
+ clear();
+}
+
+IntReg IntRegFile::readReg(int intReg)
+{
+ IntReg val =
+ regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask];
+ DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val);
+ return val;
+}
+
+Fault IntRegFile::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 IntRegFile::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 IntRegFile::setGlobals(int gl)
+{
+ DPRINTF(Sparc, "Now using %d globals", gl);
+
+ regView[Globals] = regGlobals[gl];
+ offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
+}
+
+void IntRegFile::serialize(std::ostream &os)
+{
+ unsigned int x;
+ for(x = 0; x < MaxGL; x++)
+ SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
+ for(x = 0; x < 2 * NWindows; x++)
+ SERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
+}
+
+void IntRegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ unsigned int x;
+ for(x = 0; x < MaxGL; x++)
+ UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame);
+ for(unsigned int x = 0; x < 2 * NWindows; x++)
+ UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame);
+}
diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh
new file mode 100644
index 000000000..d305c753b
--- /dev/null
+++ b/src/arch/sparc/intregfile.hh
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_INTREGFILE_HH__
+#define __ARCH_SPARC_INTREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+ class RegFile;
+
+ //This function translates integer register file indices into names
+ std::string getIntRegName(RegIndex);
+
+ class IntRegFile
+ {
+ private:
+ friend class RegFile;
+ 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[MaxGL][RegsPerFrame];
+ IntReg regSegments[2 * NWindows][RegsPerFrame];
+
+ enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
+
+ IntReg * regView[NumFrames];
+
+ static const int RegGlobalOffset = 0;
+ static const int FrameOffset = MaxGL * RegsPerFrame;
+ int offset[NumFrames];
+
+ public:
+
+ int flattenIndex(int reg);
+
+ void clear();
+
+ IntRegFile();
+
+ IntReg readReg(int intReg);
+
+ Fault setReg(int intReg, const IntReg &val);
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+
+ protected:
+ //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);
+
+ void setGlobals(int gl);
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 02f7cf61a..b518265aa 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -86,6 +86,11 @@ output header {{
const SymbolTable *symtab) const;
void printReg(std::ostream &os, int reg) const;
+ void printSrcReg(std::ostream &os, int reg) const;
+ void printDestReg(std::ostream &os, int reg) const;
+
+ void printRegArray(std::ostream &os,
+ const RegIndex indexArray[], int num) const;
};
bool passesCondition(uint32_t codes, uint32_t condition);
@@ -150,6 +155,33 @@ output decoder {{
ccprintf(os, "\t%s ", mnemonic);
}
+ void SparcStaticInst::printRegArray(std::ostream &os,
+ const RegIndex indexArray[], int num) const
+ {
+ if(num <= 0)
+ return;
+ printReg(os, indexArray[0]);
+ for(int x = 1; x < num; x++)
+ {
+ os << ", ";
+ printReg(os, indexArray[x]);
+ }
+ }
+
+ void
+ SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
+ {
+ if(_numSrcRegs > reg)
+ printReg(os, _srcRegIdx[reg]);
+ }
+
+ void
+ SparcStaticInst::printDestReg(std::ostream &os, int reg) const
+ {
+ if(_numDestRegs > reg)
+ printReg(os, _destRegIdx[reg]);
+ }
+
void
SparcStaticInst::printReg(std::ostream &os, int reg) const
{
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index fa8832920..0c2729833 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -39,30 +39,30 @@ decode OP default Unknown::unknown()
{
//Throw an illegal instruction acception
0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
- 0x1: decode BPCC
+ format BranchN
{
- format Branch19
+ 0x1: decode BPCC
{
- 0x0: bpcci({{
+ 0x0: bpcci(19, {{
if(passesCondition(Ccr<3:0>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
- 0x2: bpccx({{
+ 0x2: bpccx(19, {{
if(passesCondition(Ccr<7:4>, COND2))
NNPC = xc->readPC() + disp;
else
handle_annul
}});
}
+ 0x2: bicc(22, {{
+ if(passesCondition(Ccr<3:0>, COND2))
+ NNPC = xc->readPC() + disp;
+ else
+ handle_annul
+ }});
}
- 0x2: Branch22::bicc({{
- if(passesCondition(Ccr<3:0>, COND2))
- NNPC = xc->readPC() + disp;
- else
- handle_annul
- }});
0x3: decode RCOND2
{
format BranchSplit
@@ -110,22 +110,22 @@ decode OP default Unknown::unknown()
0x5: Trap::fbpfcc({{fault = new FpDisabled;}});
0x6: Trap::fbfcc({{fault = new FpDisabled;}});
}
- 0x1: Branch30::call({{
+ 0x1: BranchN::call(30, {{
R15 = xc->readPC();
NNPC = R15 + disp;
}});
0x2: decode OP3 {
format IntOp {
0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}});
- 0x01: and({{Rd = Rs1.udw & Rs2_or_imm13;}});
- 0x02: or({{Rd = Rs1.udw | Rs2_or_imm13;}});
- 0x03: xor({{Rd = Rs1.udw ^ Rs2_or_imm13;}});
+ 0x01: and({{Rd = Rs1.sdw & Rs2_or_imm13;}});
+ 0x02: or({{Rd = Rs1.sdw | Rs2_or_imm13;}});
+ 0x03: xor({{Rd = Rs1.sdw ^ Rs2_or_imm13;}});
0x04: sub({{Rd = Rs1.sdw - Rs2_or_imm13;}});
- 0x05: andn({{Rd = Rs1.udw & ~Rs2_or_imm13;}});
- 0x06: orn({{Rd = Rs1.udw | ~Rs2_or_imm13;}});
- 0x07: xnor({{Rd = ~(Rs1.udw ^ Rs2_or_imm13);}});
+ 0x05: andn({{Rd = Rs1.sdw & ~Rs2_or_imm13;}});
+ 0x06: orn({{Rd = Rs1.sdw | ~Rs2_or_imm13;}});
+ 0x07: xnor({{Rd = ~(Rs1.sdw ^ Rs2_or_imm13);}});
0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm13 + Ccr<0:0>;}});
- 0x09: mulx({{Rd = Rs1 * Rs2_or_imm13;}});
+ 0x09: mulx({{Rd = Rs1.sdw * Rs2_or_imm13;}});
0x0A: umul({{
Rd = Rs1.udw<31:0> * Rs2_or_imm13<31:0>;
Y = Rd<63:32>;
@@ -134,7 +134,7 @@ decode OP default Unknown::unknown()
Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm13<31:0>;
Y = Rd.sdw;
}});
- 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 + Ccr<0:0>}});
+ 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm13) + 1 - Ccr<0:0>}});
0x0D: udivx({{
if(Rs2_or_imm13 == 0) fault = new DivisionByZero;
else Rd.udw = Rs1.udw / Rs2_or_imm13;
@@ -208,7 +208,7 @@ decode OP default Unknown::unknown()
0x1C: subccc({{
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = Ccr<0:0>;
- Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
+ Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}},
{{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
{{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
@@ -272,8 +272,9 @@ decode OP default Unknown::unknown()
);
0x22: taddcctv({{
int64_t resTemp, val2 = Rs2_or_imm13;
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ Rd = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> ||
+ (Rs1<31:> == val2<31:> && val2<31:> != Rd<31:>);
if(overflow) fault = new TagOverflow;}},
{{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
{{overflow}},
@@ -322,15 +323,21 @@ decode OP default Unknown::unknown()
0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});
}
// XXX might want a format rdipr thing here
- 0x28: rdasr({{
+ 0x28: decode RS1 {
+ 0xF: decode I {
+ 0x0: Nop::stbar({{/*stuff*/}});
+ 0x1: Nop::membar({{/*stuff*/}});
+ }
+ default: rdasr({{
Rd = xc->readMiscRegWithEffect(RS1 + AsrStart, fault);
- }});
- 0x29: rdhpr({{
+ }});
+ }
+ 0x29: HPriv::rdhpr({{
// XXX Need to protect with format that traps non-priv/priv
// access
Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault);
}});
- 0x2A: rdpr({{
+ 0x2A: Priv::rdpr({{
// XXX Need to protect with format that traps non-priv
// access
Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault);
@@ -397,18 +404,233 @@ decode OP default Unknown::unknown()
0x0: BasicOperate::saved({{/*Boogy Boogy*/}});
0x1: BasicOperate::restored({{/*Boogy Boogy*/}});
}
- 0x32: wrpr({{
+ 0x32: Priv::wrpr({{
// XXX Need to protect with format that traps non-priv
// access
- xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
+ fault = xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13);
}});
- 0x33: wrhpr({{
+ 0x33: HPriv::wrhpr({{
// XXX Need to protect with format that traps non-priv/priv
// access
- xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
+ fault = xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13);
}});
- 0x34: Trap::fpop1({{fault = new FpDisabled;}});
+ 0x34: decode OPF{
+ format BasicOperate{
+ 0x01: fmovs({{
+ Frd.sf = Frs2.sf;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x02: fmovd({{
+ Frd.df = Frs2.df;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x03: Trap::fmovq({{fault = new FpDisabled;}});
+ 0x05: fnegs({{
+ //XXX might want to explicitly flip the sign bit
+ //So cases with Nan and +/-0 don't do weird things
+ Frd.sf = -Frs2.sf;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x06: fnegd({{
+ //XXX might want to explicitly flip the sign bit
+ //So cases with Nan and +/-0 don't do weird things
+ Frd.df = -Frs2.df;
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x07: Trap::fnegq({{fault = new FpDisabled;}});
+ 0x09: fabss({{
+ //XXX this instruction should be tested individually
+ //Clear the sign bit
+ Frd.sf = (float)(~(1 << 31) & ((uint32_t)Frs2.sf));
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x0A: fabsd({{
+ //XXX this instruction should be tested individually
+ //Clear the sign bit
+ Frd.df = (float)(~((uint64_t)1 << 63) & ((uint64_t)Frs2.df));
+ //fsr.ftt = fsr.cexc = 0
+ Fsr &= ~(7 << 14);
+ Fsr &= ~(0x1F);
+ }});
+ 0x0B: Trap::fabsq({{fault = new FpDisabled;}});
+ 0x29: fsqrts({{Frd.sf = sqrt(Frs2.sf);}});
+ 0x2A: fsqrtd({{Frd.df = sqrt(Frs2.df);}});
+ 0x2B: Trap::fsqrtq({{fault = new FpDisabled;}});
+ 0x41: fadds({{Frd.sf = Frs1.sf + Frs2.sf;}});
+ 0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
+ 0x43: Trap::faddq({{fault = new FpDisabled;}});
+ 0x45: fsubs({{Frd.sf = Frs1.sf - Frs2.sf;}});
+ 0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}});
+ 0x47: Trap::fsubq({{fault = new FpDisabled;}});
+ 0x49: fmuls({{Frd.sf = Frs1.sf * Frs2.sf;}});
+ 0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
+ 0x4B: Trap::fmulq({{fault = new FpDisabled;}});
+ 0x4D: fdivs({{Frd.sf = Frs1.sf / Frs2.sf;}});
+ 0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}});
+ 0x4F: Trap::fdivq({{fault = new FpDisabled;}});
+ 0x69: fsmuld({{Frd.df = Frs1.sf * Frs2.sf;}});
+ 0x6E: Trap::fdmulq({{fault = new FpDisabled;}});
+ 0x81: fstox({{
+ Frd.df = (double)static_cast<int64_t>(Frs2.sf);
+ }});
+ 0x82: fdtox({{
+ Frd.df = (double)static_cast<int64_t>(Frs2.df);
+ }});
+ 0x83: Trap::fqtox({{fault = new FpDisabled;}});
+ 0x84: fxtos({{
+ Frd.sf = static_cast<float>((int64_t)Frs2.df);
+ }});
+ 0x88: fxtod({{
+ Frd.df = static_cast<double>((int64_t)Frs2.df);
+ }});
+ 0x8C: Trap::fxtoq({{fault = new FpDisabled;}});
+ 0xC4: fitos({{
+ Frd.sf = static_cast<float>((int32_t)Frs2.sf);
+ }});
+ 0xC6: fdtos({{Frd.sf = Frs2.df;}});
+ 0xC7: Trap::fqtos({{fault = new FpDisabled;}});
+ 0xC8: fitod({{
+ Frd.df = static_cast<double>((int32_t)Frs2.sf);
+ }});
+ 0xC9: fstod({{Frd.df = Frs2.sf;}});
+ 0xCB: Trap::fqtod({{fault = new FpDisabled;}});
+ 0xCC: Trap::fitoq({{fault = new FpDisabled;}});
+ 0xCD: Trap::fstoq({{fault = new FpDisabled;}});
+ 0xCE: Trap::fdtoq({{fault = new FpDisabled;}});
+ 0xD1: fstoi({{
+ Frd.sf = (float)static_cast<int32_t>(Frs2.sf);
+ }});
+ 0xD2: fdtoi({{
+ Frd.sf = (float)static_cast<int32_t>(Frs2.df);
+ }});
+ 0xD3: Trap::fqtoi({{fault = new FpDisabled;}});
+ default: Trap::fpop1({{fault = new FpDisabled;}});
+ }
+ }
0x35: Trap::fpop2({{fault = new FpDisabled;}});
+ //This used to be just impdep1, but now it's a whole bunch
+ //of instructions
+ 0x36: decode OPF{
+ 0x00: Trap::edge8({{fault = new IllegalInstruction;}});
+ 0x01: Trap::edge8n({{fault = new IllegalInstruction;}});
+ 0x02: Trap::edge8l({{fault = new IllegalInstruction;}});
+ 0x03: Trap::edge8ln({{fault = new IllegalInstruction;}});
+ 0x04: Trap::edge16({{fault = new IllegalInstruction;}});
+ 0x05: Trap::edge16n({{fault = new IllegalInstruction;}});
+ 0x06: Trap::edge16l({{fault = new IllegalInstruction;}});
+ 0x07: Trap::edge16ln({{fault = new IllegalInstruction;}});
+ 0x08: Trap::edge32({{fault = new IllegalInstruction;}});
+ 0x09: Trap::edge32n({{fault = new IllegalInstruction;}});
+ 0x0A: Trap::edge32l({{fault = new IllegalInstruction;}});
+ 0x0B: Trap::edge32ln({{fault = new IllegalInstruction;}});
+ 0x10: Trap::array8({{fault = new IllegalInstruction;}});
+ 0x12: Trap::array16({{fault = new IllegalInstruction;}});
+ 0x14: Trap::array32({{fault = new IllegalInstruction;}});
+ 0x18: BasicOperate::alignaddress({{
+ uint64_t sum = Rs1 + Rs2;
+ Frd = sum & ~7;
+ Gsr = (Gsr & ~7) | (sum & 7);
+ }});
+ 0x19: Trap::bmask({{fault = new IllegalInstruction;}});
+ 0x1A: BasicOperate::alignaddresslittle({{
+ uint64_t sum = Rs1 + Rs2;
+ Frd = sum & ~7;
+ Gsr = (Gsr & ~7) | ((~sum + 1) & 7);
+ }});
+ 0x20: Trap::fcmple16({{fault = new IllegalInstruction;}});
+ 0x22: Trap::fcmpne16({{fault = new IllegalInstruction;}});
+ 0x24: Trap::fcmple32({{fault = new IllegalInstruction;}});
+ 0x26: Trap::fcmpne32({{fault = new IllegalInstruction;}});
+ 0x28: Trap::fcmpgt16({{fault = new IllegalInstruction;}});
+ 0x2A: Trap::fcmpeq16({{fault = new IllegalInstruction;}});
+ 0x2C: Trap::fcmpgt32({{fault = new IllegalInstruction;}});
+ 0x2E: Trap::fcmpeq32({{fault = new IllegalInstruction;}});
+ 0x31: Trap::fmul8x16({{fault = new IllegalInstruction;}});
+ 0x33: Trap::fmul8x16au({{fault = new IllegalInstruction;}});
+ 0x35: Trap::fmul8x16al({{fault = new IllegalInstruction;}});
+ 0x36: Trap::fmul8sux16({{fault = new IllegalInstruction;}});
+ 0x37: Trap::fmul8ulx16({{fault = new IllegalInstruction;}});
+ 0x38: Trap::fmuld8sux16({{fault = new IllegalInstruction;}});
+ 0x39: Trap::fmuld8ulx16({{fault = new IllegalInstruction;}});
+ 0x3A: Trap::fpack32({{fault = new IllegalInstruction;}});
+ 0x3B: Trap::fpack16({{fault = new IllegalInstruction;}});
+ 0x3D: Trap::fpackfix({{fault = new IllegalInstruction;}});
+ 0x3E: Trap::pdist({{fault = new IllegalInstruction;}});
+ 0x48: BasicOperate::faligndata({{
+ uint64_t msbX = (uint64_t)Frs1;
+ uint64_t lsbX = (uint64_t)Frs2;
+ uint64_t msbShift = Gsr<2:0> * 8;
+ uint64_t lsbShift = (8 - Gsr<2:0>) * 8;
+ uint64_t msbMask = ((uint64_t)(-1)) << msbShift;
+ uint64_t lsbMask = ((uint64_t)(-1)) << lsbShift;
+ Frd = ((msbX << msbShift) & msbMask) |
+ ((lsbX << lsbShift) & lsbMask);
+ }});
+ 0x4B: Trap::fpmerge({{fault = new IllegalInstruction;}});
+ 0x4C: Trap::bshuffle({{fault = new IllegalInstruction;}});
+ 0x4D: Trap::fexpand({{fault = new IllegalInstruction;}});
+ 0x50: Trap::fpadd16({{fault = new IllegalInstruction;}});
+ 0x51: Trap::fpadd16s({{fault = new IllegalInstruction;}});
+ 0x52: Trap::fpadd32({{fault = new IllegalInstruction;}});
+ 0x53: Trap::fpadd32s({{fault = new IllegalInstruction;}});
+ 0x54: Trap::fpsub16({{fault = new IllegalInstruction;}});
+ 0x55: Trap::fpsub16s({{fault = new IllegalInstruction;}});
+ 0x56: Trap::fpsub32({{fault = new IllegalInstruction;}});
+ 0x57: Trap::fpsub32s({{fault = new IllegalInstruction;}});
+ 0x60: BasicOperate::fzero({{Frd.df = 0;}});
+ 0x61: BasicOperate::fzeros({{Frd.sf = 0;}});
+ 0x62: Trap::fnor({{fault = new IllegalInstruction;}});
+ 0x63: Trap::fnors({{fault = new IllegalInstruction;}});
+ 0x64: Trap::fandnot2({{fault = new IllegalInstruction;}});
+ 0x65: Trap::fandnot2s({{fault = new IllegalInstruction;}});
+ 0x66: BasicOperate::fnot2({{
+ Frd.df = (double)(~((uint64_t)Frs2.df));
+ }});
+ 0x67: BasicOperate::fnot2s({{
+ Frd.sf = (float)(~((uint32_t)Frs2.sf));
+ }});
+ 0x68: Trap::fandnot1({{fault = new IllegalInstruction;}});
+ 0x69: Trap::fandnot1s({{fault = new IllegalInstruction;}});
+ 0x6A: BasicOperate::fnot1({{
+ Frd.df = (double)(~((uint64_t)Frs1.df));
+ }});
+ 0x6B: BasicOperate::fnot1s({{
+ Frd.sf = (float)(~((uint32_t)Frs1.sf));
+ }});
+ 0x6C: Trap::fxor({{fault = new IllegalInstruction;}});
+ 0x6D: Trap::fxors({{fault = new IllegalInstruction;}});
+ 0x6E: Trap::fnand({{fault = new IllegalInstruction;}});
+ 0x6F: Trap::fnands({{fault = new IllegalInstruction;}});
+ 0x70: Trap::fand({{fault = new IllegalInstruction;}});
+ 0x71: Trap::fands({{fault = new IllegalInstruction;}});
+ 0x72: Trap::fxnor({{fault = new IllegalInstruction;}});
+ 0x73: Trap::fxnors({{fault = new IllegalInstruction;}});
+ 0x74: BasicOperate::fsrc1({{Frd.df = Frs1.df;}});
+ 0x75: BasicOperate::fsrc1s({{Frd.sf = Frs1.sf;}});
+ 0x76: Trap::fornot2({{fault = new IllegalInstruction;}});
+ 0x77: Trap::fornot2s({{fault = new IllegalInstruction;}});
+ 0x78: BasicOperate::fsrc2({{Frd.df = Frs2.df;}});
+ 0x79: BasicOperate::fsrc2s({{Frd.sf = Frs2.sf;}});
+ 0x7A: Trap::fornot1({{fault = new IllegalInstruction;}});
+ 0x7B: Trap::fornot1s({{fault = new IllegalInstruction;}});
+ 0x7C: Trap::for({{fault = new IllegalInstruction;}});
+ 0x7D: Trap::fors({{fault = new IllegalInstruction;}});
+ 0x7E: Trap::fone({{fault = new IllegalInstruction;}});
+ 0x7F: Trap::fones({{fault = new IllegalInstruction;}});
+ 0x80: Trap::shutdown({{fault = new IllegalInstruction;}});
+ 0x81: Trap::siam({{fault = new IllegalInstruction;}});
+ }
+ 0x37: Trap::impdep2({{fault = new IllegalInstruction;}});
0x38: Branch::jmpl({{
Addr target = Rs1 + Rs2_or_imm13;
if(target & 0x3)
@@ -549,7 +771,7 @@ decode OP default Unknown::unknown()
NNPC = Tnpc + 4;
Tl = Tl - 1;
}});
- 0x1: BasicOperate::retry({{
+ 0x1: Priv::retry({{
if(Tl == 0)
return new IllegalInstruction;
Cwp = Tstate<4:0>;
@@ -630,27 +852,28 @@ decode OP default Unknown::unknown()
Mem = temp;
}}, {{32}});
format Trap {
- 0x20: ldf({{fault = new FpDisabled;}});
+ 0x20: Load::ldf({{Frd.sf = ((float)Mem);}}, {{32}});
0x21: decode X {
0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}});
0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}});
}
0x22: ldqf({{fault = new FpDisabled;}});
- 0x23: lddf({{fault = new FpDisabled;}});
- 0x24: stf({{fault = new FpDisabled;}});
+ 0x23: Load::lddf({{Frd.df = ((double)Mem);}}, {{64}});
+ 0x24: Store::stf({{Mem = ((int32_t)Frd.sf);}}, {{32}});
0x25: decode X {
0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}});
0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}});
}
0x26: stqf({{fault = new FpDisabled;}});
- 0x27: stdf({{fault = new FpDisabled;}});
+ 0x27: Store::stdf({{Mem = ((int64_t)Frd.df);}}, {{64}});
0x2D: Nop::prefetch({{ }});
- 0x30: ldfa({{return new FpDisabled;}});
+ 0x30: Load::ldfa({{Frd.sf = ((float)Mem);}}, {{32}});
0x32: ldqfa({{fault = new FpDisabled;}});
- 0x33: lddfa({{fault = new FpDisabled;}});
- 0x34: stfa({{fault = new FpDisabled;}});
- 0x35: stqfa({{fault = new FpDisabled;}});
- 0x36: stdfa({{fault = new FpDisabled;}});
+ 0x33: Load::lddfa({{Frd.df = ((double)Mem);}}, {{64}});
+ 0x34: Store::stfa({{Mem = ((int32_t)Frd.sf);}}, {{32}});
+ 0x36: stqfa({{fault = new FpDisabled;}});
+ //XXX need to work in the ASI thing
+ 0x37: Store::stdfa({{Mem = ((uint64_t)Frd.df);}}, {{64}});
0x3C: Cas::casa({{
uint64_t val = Mem.uw;
if(Rs2.uw == val)
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 60432cb6b..0a47a7ffe 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -63,7 +63,6 @@ def template BasicExecute {{
{
Fault fault = NoFault;
- %(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
@@ -81,11 +80,6 @@ def template BasicDecode {{
return new %(class_name)s(machInst);
}};
-// Basic decode template, passing mnemonic in as string arg to constructor.
-def template BasicDecodeWithMnemonic {{
- return new %(class_name)s("%(mnemonic)s", machInst);
-}};
-
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst',
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 7d46ce739..8a3f05173 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -69,47 +69,18 @@ output header {{
};
/**
- * Base class for branches with 19 bit displacements.
+ * Base class for branches with n bit displacements.
*/
- class Branch19 : public BranchDisp
+ template<int bits>
+ class BranchNBits : public BranchDisp
{
protected:
// Constructor
- Branch19(const char *mnem, MachInst _machInst,
+ BranchNBits(const char *mnem, MachInst _machInst,
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext(DISP19 << 2, 21);
- }
- };
-
- /**
- * Base class for branches with 22 bit displacements.
- */
- class Branch22 : public BranchDisp
- {
- protected:
- // Constructor
- Branch22(const char *mnem, MachInst _machInst,
- OpClass __opClass) :
- BranchDisp(mnem, _machInst, __opClass)
- {
- disp = sign_ext(DISP22 << 2, 24);
- }
- };
-
- /**
- * Base class for branches with 30 bit displacements.
- */
- class Branch30 : public BranchDisp
- {
- protected:
- // Constructor
- Branch30(const char *mnem, MachInst _machInst,
- OpClass __opClass) :
- BranchDisp(mnem, _machInst, __opClass)
- {
- disp = sign_ext(DISP30 << 2, 32);
+ disp = sign_ext(_machInst << 2, bits + 2);
}
};
@@ -149,29 +120,23 @@ output header {{
}};
output decoder {{
+
+ template class BranchNBits<19>;
+
+ template class BranchNBits<22>;
+
+ template class BranchNBits<30>;
+
std::string Branch::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
std::stringstream response;
printMnemonic(response, mnemonic);
-
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numDestRegs && _numSrcRegs)
response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
-
- if (_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
+ printDestReg(response, 0);
return response.str();
}
@@ -182,27 +147,13 @@ output decoder {{
std::stringstream response;
printMnemonic(response, mnemonic);
-
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
-
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
if(_numSrcRegs > 0)
response << ", ";
-
ccprintf(response, "0x%x", imm);
-
if (_numDestRegs > 0)
- {
response << ", ";
- printReg(response, _destRegIdx[0]);
- }
+ printDestReg(response, 0);
return response.str();
}
@@ -292,32 +243,10 @@ def format Branch(code, *opt_flags) {{
}};
// Primary format for branch instructions:
-def format Branch19(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
-}};
-
-// Primary format for branch instructions:
-def format Branch22(code, *opt_flags) {{
- code = re.sub(r'handle_annul', handle_annul, code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- exec_output = BranchExecute.subst(iop)
- decode_block = BasicDecode.subst(iop)
-}};
-
-// Primary format for branch instructions:
-def format Branch30(code, *opt_flags) {{
+def format BranchN(bits, code, *opt_flags) {{
code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
+ iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 1894ce541..27616216e 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -132,7 +132,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = (IMM22 << 10) & 0xFFFFFC00;
+ imm = (IMM22 & 0x3FFFFF) << 10;
}
std::string generateDisassembly(Addr pc,
@@ -157,12 +157,9 @@ output decoder {{
if(!strcmp(mnemonic, "or") && _srcRegIdx[0] == 0)
{
printMnemonic(os, "mov");
- if(_numSrcRegs > 0)
- printReg(os, _srcRegIdx[1]);
+ printSrcReg(os, 1);
ccprintf(os, ", ");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
-
+ printDestReg(os, 0);
return true;
}
return false;
@@ -173,32 +170,24 @@ output decoder {{
{
if(!strcmp(mnemonic, "or"))
{
- if(_srcRegIdx[0] == 0)
+ if(_numSrcRegs > 0 && _srcRegIdx[0] == 0)
{
if(imm == 0)
- {
printMnemonic(os, "clr");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
- return true;
- }
else
{
printMnemonic(os, "mov");
- ccprintf(os, ", 0x%x, ", imm);
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
- return true;
+ ccprintf(os, " 0x%x, ", imm);
}
+ printDestReg(os, 0);
+ return true;
}
else if(imm == 0)
{
printMnemonic(os, "mov");
- if(_numSrcRegs > 0)
- printReg(os, _srcRegIdx[0]);
+ printSrcReg(os, 0);
ccprintf(os, ", ");
- if(_numDestRegs > 0)
- printReg(os, _destRegIdx[0]);
+ printDestReg(os, 0);
return true;
}
}
@@ -210,25 +199,13 @@ output decoder {{
{
std::stringstream response;
- if(!printPseudoOps(response, pc, symtab))
- {
- printMnemonic(response, mnemonic);
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
- if (_numDestRegs > 0)
- {
- if(_numSrcRegs > 0)
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
- }
+ if(printPseudoOps(response, pc, symtab))
+ return response.str();
+ printMnemonic(response, mnemonic);
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numDestRegs && _numSrcRegs)
+ response << ", ";
+ printDestReg(response, 0);
return response.str();
}
@@ -237,27 +214,16 @@ output decoder {{
{
std::stringstream response;
- if(!printPseudoOps(response, pc, symtab))
- {
- printMnemonic(response, mnemonic);
- if (_numSrcRegs > 0)
- {
- printReg(response, _srcRegIdx[0]);
- for(int x = 1; x < _numSrcRegs - 1; x++)
- {
- response << ", ";
- printReg(response, _srcRegIdx[x]);
- }
- }
- if(_numSrcRegs > 0)
- response << ", ";
- ccprintf(response, "0x%x", imm);
- if (_numDestRegs > 0)
- {
- response << ", ";
- printReg(response, _destRegIdx[0]);
- }
- }
+ if(printPseudoOps(response, pc, symtab))
+ return response.str();
+ printMnemonic(response, mnemonic);
+ printRegArray(response, _srcRegIdx, _numSrcRegs);
+ if(_numSrcRegs > 0)
+ response << ", ";
+ ccprintf(response, "0x%x", imm);
+ if(_numDestRegs > 0)
+ response << ", ";
+ printDestReg(response, 0);
return response.str();
}
@@ -267,10 +233,8 @@ output decoder {{
std::stringstream response;
printMnemonic(response, mnemonic);
- if(_numSrcRegs > 0)
- response << ", ";
ccprintf(response, "%%hi(0x%x), ", imm);
- printReg(response, _destRegIdx[0]);
+ printDestReg(response, 0);
return response.str();
}
}};
@@ -316,38 +280,29 @@ let {{
return (header_output, decoder_output, exec_output, decode_block)
calcCcCode = '''
- uint8_t tmp_ccriccc;
- uint8_t tmp_ccriccv;
- uint8_t tmp_ccriccz;
- uint8_t tmp_ccriccn;
- uint8_t tmp_ccrxccc;
- uint8_t tmp_ccrxccv;
- uint8_t tmp_ccrxccz;
- uint8_t tmp_ccrxccn;
-
- tmp_ccriccn = (Rd >> 31) & 1;
- tmp_ccriccz = ((Rd & 0xFFFFFFFF) == 0);
- tmp_ccrxccn = (Rd >> 63) & 1;
- tmp_ccrxccz = (Rd == 0);
- tmp_ccriccv = %(ivValue)s & 1;
- tmp_ccriccc = %(icValue)s & 1;
- tmp_ccrxccv = %(xvValue)s & 1;
- tmp_ccrxccc = %(xcValue)s & 1;
-
- Ccr = tmp_ccriccc | tmp_ccriccv << 1 |
- tmp_ccriccz << 2 | tmp_ccriccn << 3|
- tmp_ccrxccc << 4 | tmp_ccrxccv << 5|
- tmp_ccrxccz << 6| tmp_ccrxccn << 7;
-
-
- DPRINTF(Sparc, "in = %%d\\n", (uint16_t)tmp_ccriccn);
- DPRINTF(Sparc, "iz = %%d\\n", (uint16_t)tmp_ccriccz);
- DPRINTF(Sparc, "xn = %%d\\n", (uint16_t)tmp_ccrxccn);
- DPRINTF(Sparc, "xz = %%d\\n", (uint16_t)tmp_ccrxccz);
- DPRINTF(Sparc, "iv = %%d\\n", (uint16_t)tmp_ccriccv);
- DPRINTF(Sparc, "ic = %%d\\n", (uint16_t)tmp_ccriccc);
- DPRINTF(Sparc, "xv = %%d\\n", (uint16_t)tmp_ccrxccv);
- DPRINTF(Sparc, "xc = %%d\\n", (uint16_t)tmp_ccrxccc);
+ uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;
+
+ _in = (Rd >> 31) & 1;
+ _iz = ((Rd & 0xFFFFFFFF) == 0);
+ _xn = (Rd >> 63) & 1;
+ _xz = (Rd == 0);
+ _iv = %(ivValue)s & 1;
+ _ic = %(icValue)s & 1;
+ _xv = %(xvValue)s & 1;
+ _xc = %(xcValue)s & 1;
+
+ Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
+ _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;
+
+
+ DPRINTF(Sparc, "in = %%d\\n", _in);
+ DPRINTF(Sparc, "iz = %%d\\n", _iz);
+ DPRINTF(Sparc, "xn = %%d\\n", _xn);
+ DPRINTF(Sparc, "xz = %%d\\n", _xz);
+ DPRINTF(Sparc, "iv = %%d\\n", _iv);
+ DPRINTF(Sparc, "ic = %%d\\n", _ic);
+ DPRINTF(Sparc, "xv = %%d\\n", _xv);
+ DPRINTF(Sparc, "xc = %%d\\n", _xc);
'''
}};
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index 7df59d736..d7ee01519 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -72,7 +72,11 @@ output decoder {{
std::string Priv::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
- return "Privileged Instruction";
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ return response.str();
}
}};
@@ -87,9 +91,10 @@ def template PrivExecute {{
if(%(check)s)
return new PrivilegedAction;
+ Fault fault = NoFault;
%(code)s;
%(op_wb)s;
- return NoFault;
+ return fault;
}
}};
@@ -116,10 +121,17 @@ let {{
// Primary format for integer operate instructions:
def format Priv(code, *opt_flags) {{
- checkCode = "((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>)"
+ checkCode = '''((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>) ||
+ ((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)'''
(header_output, decoder_output,
exec_output, decode_block) = doPrivFormat(code,
- checkCode, name, Name, opt_flags)
+ checkCode, name, Name, opt_flags + ('IprAccessOp',))
}};
+def format HPriv(code, *opt_flags) {{
+ checkCode = "((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)"
+ (header_output, decoder_output,
+ exec_output, decode_block) = doPrivFormat(code,
+ checkCode, name, Name, opt_flags + ('IprAccessOp',))
+}};
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 40afb3722..3783051c4 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -36,7 +36,6 @@
output header {{
#include <sstream>
#include <iostream>
-#include <iomanip>
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
@@ -50,7 +49,6 @@ output decoder {{
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
-#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
@@ -59,14 +57,10 @@ using namespace SparcISA;
}};
output exec {{
-#include <math.h>
#if defined(linux)
#include <fenv.h>
#endif
-#ifdef FULL_SYSTEM
-//#include "sim/pseudo_inst.hh"
-#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 9e5c783e8..605816083 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -51,12 +51,12 @@ def operands {{
'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- #'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1),
- #'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2),
- #'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3),
- 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
- 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 4),
- 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 4),
+ 'Frd': ('FloatReg', 'df', 'RD', 'IsFloating', 10),
+ 'Frs1': ('FloatReg', 'df', 'RS1', 'IsFloating', 11),
+ 'Frs2': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
+ 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20),
+ 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
+ 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 6),
@@ -65,24 +65,25 @@ def operands {{
'R16': ('IntReg', 'udw', '16', None, 9),
# Control registers
- 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 12),
- 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 17),
- 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 26),
+ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40),
+ 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41),
+ 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42),
- 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28),
- 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 28),
- 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 28),
- 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
- 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 27),
+ 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 43),
+ 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44),
+ 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45),
+ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46),
+ 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 47),
- 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15),
- 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 34),
- 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 35),
- 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 37),
- 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36),
- 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 38),
- 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 12),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 48),
+ 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 49),
+ 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 50),
+ 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 51),
+ 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 52),
+ 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 53),
+ 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
- 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47)
+ 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55),
+ 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56)
}};
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 346f7b730..7f830eb28 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -25,13 +25,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Authors: Korey Sewell
- * Gabe Black
+ * Authors: Gabe Black
*/
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
+#include "arch/sparc/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
@@ -46,70 +46,45 @@ class StaticInstPtr;
namespace BigEndianGuest {}
-#if !FULL_SYSTEM
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s)
- {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
- private:
- uint64_t retval;
- bool success;
-};
-
-#endif
-
#if FULL_SYSTEM
#include "arch/sparc/isa_fullsys_traits.hh"
#endif
namespace SparcISA
{
+ class RegFile;
+
+ //This makes sure the big endian versions of certain functions are used.
+ using namespace BigEndianGuest;
+
+ //TODO this needs to be a SPARC Noop
+ // Alpha UNOP (ldq_u r31,0(r0))
+ const MachInst NoopMachInst = 0x2ffe0000;
+
+ const int NumIntRegs = 32;
+ const int NumFloatRegs = 64;
+ const int NumMiscRegs = 40;
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
// 0..31 are the integer regs 0..31
- // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
- FP_Base_DepTag = 32,
- Ctrl_Base_DepTag = 96,
+ // 32..95 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = NumIntRegs,
+ Ctrl_Base_DepTag = NumIntRegs + NumFloatRegs,
//XXX These are here solely to get compilation and won't work
Fpcr_DepTag = 0,
Uniq_DepTag = 0
};
- //This makes sure the big endian versions of certain functions are used.
- using namespace BigEndianGuest;
- typedef uint32_t MachInst;
- typedef uint64_t ExtMachInst;
+ // MAXTL - maximum trap level
+ const int MaxPTL = 2;
+ const int MaxTL = 6;
+ const int MaxGL = 3;
+ const int MaxPGL = 2;
- const int NumIntRegs = 32;
- const int NumFloatRegs = 64;
- const int NumMiscRegs = 32;
+ // NWINDOWS - number of register windows, can be 3 to 32
+ const int NWindows = 32;
// semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
@@ -131,14 +106,6 @@ namespace SparcISA
const int MaxInstSrcRegs = 8;
const int MaxInstDestRegs = 9;
- typedef uint64_t IntReg;
-
- // control register file contents
- typedef uint64_t MiscReg;
-
- typedef double FloatReg;
- typedef uint64_t FloatRegBits;
-
//8K. This value is implmentation specific; and should probably
//be somewhere else.
const int LogVMPageSize = 13;
@@ -165,29 +132,4 @@ namespace SparcISA
extern const MachInst NoopMachInst;
}
-#include "arch/sparc/regfile.hh"
-
-namespace SparcISA
-{
-
-#if !FULL_SYSTEM
- static inline void setSyscallReturn(SyscallReturn return_value,
- RegFile *regs)
- {
- // check for error condition. SPARC syscall convention is to
- // indicate success/failure in reg the carry bit of the ccr
- // and put the return value itself in the standard return value reg ().
- if (return_value.successful()) {
- // no error, clear XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
- regs->setIntReg(ReturnValueReg, return_value.value());
- } else {
- // got an error, set XCC.C
- regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
- regs->setIntReg(ReturnValueReg, return_value.value());
- }
- }
-#endif
-};
-
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
diff --git a/src/arch/sparc/linux/linux.cc b/src/arch/sparc/linux/linux.cc
index ae6ffbc2a..1211d5f65 100644
--- a/src/arch/sparc/linux/linux.cc
+++ b/src/arch/sparc/linux/linux.cc
@@ -29,6 +29,7 @@
*/
#include "arch/sparc/linux/linux.hh"
+#include <fcntl.h>
// open(2) flags translation table
OpenFlagTransTable SparcLinux::openFlagTable[] = {
diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc
index e27255e67..8c2de8ca3 100644
--- a/src/arch/sparc/linux/process.cc
+++ b/src/arch/sparc/linux/process.cc
@@ -199,7 +199,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 99 */ SyscallDesc("accept", unimplementedFunc),
/* 100 */ SyscallDesc("getpriority", unimplementedFunc),
/* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
- /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 102 */ SyscallDesc("rt_sigaction", ignoreFunc),
/* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
/* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
/* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
@@ -295,7 +295,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
/* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
/* 197 */ SyscallDesc("getppid", getppidFunc),
- /* 198 */ SyscallDesc("sigaction", unimplementedFunc),
+ /* 198 */ SyscallDesc("sigaction", ignoreFunc),
/* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
/* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
/* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh
index f4819ba84..4af8f0f75 100644
--- a/src/arch/sparc/linux/process.hh
+++ b/src/arch/sparc/linux/process.hh
@@ -32,6 +32,7 @@
#define __SPARC_LINUX_PROCESS_HH__
#include "arch/sparc/linux/linux.hh"
+#include "arch/sparc/syscallreturn.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
new file mode 100644
index 000000000..8041e45c0
--- /dev/null
+++ b/src/arch/sparc/miscregfile.cc
@@ -0,0 +1,540 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#include "arch/sparc/miscregfile.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/thread_context.hh"
+
+using namespace SparcISA;
+using namespace std;
+
+class Checkpoint;
+
+//These functions map register indices to names
+string SparcISA::getMiscRegName(RegIndex index)
+{
+ static::string miscRegName[NumMiscRegs] =
+ {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
+ "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
+ "stick", "stick_cmpr",
+ "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
+ "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
+ "wstate", "gl",
+ "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
+ "hstick_cmpr",
+ "fsr"};
+ return miscRegName[index];
+}
+
+#if FULL_SYSTEM
+
+//XXX These need an implementation someplace
+/** Fullsystem only register version of ReadRegWithEffect() */
+MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+/** Fullsystem only register version of SetRegWithEffect() */
+Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+#endif
+
+void MiscRegFile::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;
+ gl = MaxGL;
+
+ tickFields.counter = 0; //The TICK register is unreadable bya
+ tickFields.npt = 1; //The TICK register is unreadable by by !priv
+
+ softint = 0; // Clear all the soft interrupt bits
+ tick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+ stickFields.npt = 1; //The TICK register is unreadable by by !priv
+ stick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+
+
+ tt[tl] = power_on_reset;
+ pstate = 0; // fields 0 but pef
+ pstateFields.pef = 1;
+
+ hpstate = 0;
+ hpstateFields.red = 1;
+ hpstateFields.hpriv = 1;
+ hpstateFields.tlz = 0; // this is a guess
+ hintp = 0; // no interrupts pending
+ hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
+ hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
+#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
+}
+
+MiscReg MiscRegFile::readReg(int miscReg)
+{
+ switch (miscReg) {
+ case MISCREG_Y:
+ return y;
+ case MISCREG_CCR:
+ return ccr;
+ case MISCREG_ASI:
+ return asi;
+ case MISCREG_FPRS:
+ return fprs;
+ case MISCREG_TICK:
+ return tick;
+ case MISCREG_PCR:
+ case MISCREG_PIC:
+ panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ case MISCREG_GSR:
+ return gsr;
+ case MISCREG_SOFTINT:
+ return softint;
+ case MISCREG_TICK_CMPR:
+ return tick_cmpr;
+ case MISCREG_STICK:
+ return stick;
+ case MISCREG_STICK_CMPR:
+ return stick_cmpr;
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ return tpc[tl-1];
+ case MISCREG_TNPC:
+ return tnpc[tl-1];
+ case MISCREG_TSTATE:
+ return tstate[tl-1];
+ case MISCREG_TT:
+ return tt[tl-1];
+ case MISCREG_PRIVTICK:
+ panic("Priviliged access to tick registers not implemented\n");
+ case MISCREG_TBA:
+ return tba;
+ case MISCREG_PSTATE:
+ return pstate;
+ case MISCREG_TL:
+ return tl;
+ case MISCREG_PIL:
+ return pil;
+ case MISCREG_CWP:
+ return cwp;
+ case MISCREG_CANSAVE:
+ return cansave;
+ case MISCREG_CANRESTORE:
+ return canrestore;
+ case MISCREG_CLEANWIN:
+ return cleanwin;
+ case MISCREG_OTHERWIN:
+ return otherwin;
+ case MISCREG_WSTATE:
+ return wstate;
+ case MISCREG_GL:
+ return gl;
+
+ /** Hyper privileged registers */
+ case MISCREG_HPSTATE:
+ return hpstate;
+ case MISCREG_HTSTATE:
+ return htstate[tl-1];
+ case MISCREG_HINTP:
+ panic("HINTP not implemented\n");
+ case MISCREG_HTBA:
+ return htba;
+ case MISCREG_HVER:
+ return NWindows | MaxTL << 8 | MaxGL << 16;
+ case MISCREG_STRAND_STS_REG:
+ return strandStatusReg;
+ case MISCREG_HSTICK_CMPR:
+ return hstick_cmpr;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ return fsr;
+ default:
+ panic("Miscellaneous register %d not implemented\n", miscReg);
+ }
+}
+
+MiscReg MiscRegFile::readRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext * tc)
+{
+ fault = NoFault;
+ switch (miscReg) {
+ case MISCREG_Y:
+ case MISCREG_CCR:
+ case MISCREG_ASI:
+ return readReg(miscReg);
+
+ case MISCREG_TICK:
+ case MISCREG_PRIVTICK:
+ // Check for reading privilege
+ if (tickFields.npt && !isNonPriv()) {
+ fault = new PrivilegedAction;
+ return 0;
+ }
+ return tc->getCpuPtr()->curCycle() - tickFields.counter |
+ tickFields.npt << 63;
+ case MISCREG_PC:
+ return tc->readPC();
+ case MISCREG_FPRS:
+ fault = new UnimpFault("FPU not implemented\n");
+ return 0;
+ case MISCREG_PCR:
+ fault = new UnimpFault("Performance Instrumentation not impl\n");
+ return 0;
+ case MISCREG_PIC:
+ fault = new UnimpFault("Performance Instrumentation not impl\n");
+ return 0;
+ case MISCREG_GSR:
+ return readReg(miscReg);
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ case MISCREG_TNPC:
+ case MISCREG_TSTATE:
+ case MISCREG_TT:
+ if (tl == 0) {
+ fault = new IllegalInstruction;
+ return 0;
+ } // NOTE THE FALL THROUGH!
+ case MISCREG_PSTATE:
+ case MISCREG_TL:
+ return readReg(miscReg);
+
+ case MISCREG_TBA:
+ return readReg(miscReg) & ULL(~0x7FFF);
+
+ case MISCREG_PIL:
+
+ case MISCREG_CWP:
+ case MISCREG_CANSAVE:
+ case MISCREG_CANRESTORE:
+ case MISCREG_CLEANWIN:
+ case MISCREG_OTHERWIN:
+ case MISCREG_WSTATE:
+ case MISCREG_GL:
+ return readReg(miscReg);
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ panic("Floating Point not implemented\n");
+ default:
+#if FULL_SYSTEM
+ return readFSRegWithEffect(miscReg, fault, tc);
+#else
+ fault = new IllegalInstruction;
+ return 0;
+#endif
+ }
+}
+
+Fault MiscRegFile::setReg(int miscReg, const MiscReg &val)
+{
+ switch (miscReg) {
+ case MISCREG_Y:
+ y = val;
+ return NoFault;
+ case MISCREG_CCR:
+ ccr = val;
+ return NoFault;
+ case MISCREG_ASI:
+ asi = val;
+ return NoFault;
+ case MISCREG_FPRS:
+ fprs = val;
+ return NoFault;
+ case MISCREG_TICK:
+ tick = val;
+ return NoFault;
+ case MISCREG_PCR:
+ case MISCREG_PIC:
+ panic("ASR number %d not implemented\n", miscReg - AsrStart);
+ case MISCREG_GSR:
+ gsr = val;
+ case MISCREG_SOFTINT:
+ softint = val;
+ return NoFault;
+ case MISCREG_TICK_CMPR:
+ tick_cmpr = val;
+ return NoFault;
+ case MISCREG_STICK:
+ stick = val;
+ return NoFault;
+ case MISCREG_STICK_CMPR:
+ stick_cmpr = val;
+ return NoFault;
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ tpc[tl-1] = val;
+ return NoFault;
+ case MISCREG_TNPC:
+ tnpc[tl-1] = val;
+ return NoFault;
+ case MISCREG_TSTATE:
+ tstate[tl-1] = val;
+ return NoFault;
+ case MISCREG_TT:
+ tt[tl-1] = val;
+ return NoFault;
+ case MISCREG_PRIVTICK:
+ panic("Priviliged access to tick regesiters not implemented\n");
+ case MISCREG_TBA:
+ tba = val;
+ return NoFault;
+ case MISCREG_PSTATE:
+ pstate = val;
+ return NoFault;
+ case MISCREG_TL:
+ tl = val;
+ return NoFault;
+ case MISCREG_PIL:
+ pil = val;
+ return NoFault;
+ case MISCREG_CWP:
+ cwp = val;
+ return NoFault;
+ case MISCREG_CANSAVE:
+ cansave = val;
+ return NoFault;
+ case MISCREG_CANRESTORE:
+ canrestore = val;
+ return NoFault;
+ case MISCREG_CLEANWIN:
+ cleanwin = val;
+ return NoFault;
+ case MISCREG_OTHERWIN:
+ otherwin = val;
+ return NoFault;
+ case MISCREG_WSTATE:
+ wstate = val;
+ return NoFault;
+ case MISCREG_GL:
+ gl = val;
+ return NoFault;
+
+ /** Hyper privileged registers */
+ case MISCREG_HPSTATE:
+ hpstate = val;
+ return NoFault;
+ case MISCREG_HTSTATE:
+ htstate[tl-1] = val;
+ return NoFault;
+ case MISCREG_HINTP:
+ panic("HINTP not implemented\n");
+ case MISCREG_HTBA:
+ htba = val;
+ return NoFault;
+ case MISCREG_STRAND_STS_REG:
+ strandStatusReg = val;
+ return NoFault;
+ case MISCREG_HSTICK_CMPR:
+ hstick_cmpr = val;
+ return NoFault;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ fsr = val;
+ return NoFault;
+ default:
+ panic("Miscellaneous register %d not implemented\n", miscReg);
+ }
+}
+
+Fault MiscRegFile::setRegWithEffect(int miscReg,
+ const MiscReg &val, ThreadContext * tc)
+{
+ const uint64_t Bit64 = (1ULL << 63);
+ switch (miscReg) {
+ case MISCREG_Y:
+ case MISCREG_CCR:
+ case MISCREG_ASI:
+ setReg(miscReg, val);
+ return NoFault;
+ case MISCREG_PRIVTICK:
+ case MISCREG_TICK:
+ if (isNonPriv())
+ return new PrivilegedOpcode;
+ if (isPriv())
+ return new PrivilegedAction;
+ tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
+ tickFields.npt = val & Bit64 ? 1 : 0;
+ return NoFault;
+ case MISCREG_PC:
+ return new IllegalInstruction;
+ case MISCREG_FPRS:
+ return new UnimpFault("FPU not implemented\n");
+ case MISCREG_PCR:
+ return new UnimpFault("Performance Instrumentation not impl\n");
+ case MISCREG_PIC:
+ return new UnimpFault("Performance Instrumentation not impl\n");
+ case MISCREG_GSR:
+ return setReg(miscReg, val);
+
+ /** Privilged Registers */
+ case MISCREG_TPC:
+ case MISCREG_TNPC:
+ case MISCREG_TSTATE:
+ case MISCREG_TT:
+ if (tl == 0)
+ return new IllegalInstruction;
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_TBA:
+ // clear lower 7 bits on writes.
+ setReg(miscReg, val & ULL(~0x7FFF));
+ return NoFault;
+
+ case MISCREG_PSTATE:
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_TL:
+ if (isHyperPriv() && val > MaxTL)
+ setReg(miscReg, MaxTL);
+ else if (isPriv() && !isHyperPriv() && val > MaxPTL)
+ setReg(miscReg, MaxPTL);
+ else
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_CWP:
+ tc->changeRegFileContext(CONTEXT_CWP, val);
+ case MISCREG_CANSAVE:
+ case MISCREG_CANRESTORE:
+ case MISCREG_CLEANWIN:
+ case MISCREG_OTHERWIN:
+ case MISCREG_WSTATE:
+ setReg(miscReg, val);
+ return NoFault;
+
+ case MISCREG_GL:
+ int newval;
+ if (isHyperPriv() && val > MaxGL)
+ newval = MaxGL;
+ else if (isPriv() && !isHyperPriv() && val > MaxPGL)
+ newval = MaxPGL;
+ else
+ newval = val;
+ tc->changeRegFileContext(CONTEXT_GLOBALS, newval);
+ setReg(miscReg, newval);
+ return NoFault;
+
+ /** Floating Point Status Register */
+ case MISCREG_FSR:
+ panic("Floating Point not implemented\n");
+ default:
+#if FULL_SYSTEM
+ setFSRegWithEffect(miscReg, val, tc);
+#else
+ return new IllegalInstruction;
+#endif
+ }
+}
+
+void MiscRegFile::serialize(std::ostream & os)
+{
+ SERIALIZE_SCALAR(pstate);
+ SERIALIZE_SCALAR(tba);
+ SERIALIZE_SCALAR(y);
+ SERIALIZE_SCALAR(pil);
+ SERIALIZE_SCALAR(gl);
+ SERIALIZE_SCALAR(cwp);
+ SERIALIZE_ARRAY(tt, MaxTL);
+ SERIALIZE_SCALAR(ccr);
+ SERIALIZE_SCALAR(asi);
+ SERIALIZE_SCALAR(tl);
+ SERIALIZE_ARRAY(tpc, MaxTL);
+ SERIALIZE_ARRAY(tnpc, MaxTL);
+ SERIALIZE_ARRAY(tstate, MaxTL);
+ SERIALIZE_SCALAR(tick);
+ SERIALIZE_SCALAR(cansave);
+ SERIALIZE_SCALAR(canrestore);
+ SERIALIZE_SCALAR(otherwin);
+ SERIALIZE_SCALAR(cleanwin);
+ SERIALIZE_SCALAR(wstate);
+ SERIALIZE_SCALAR(fsr);
+ SERIALIZE_SCALAR(fprs);
+ SERIALIZE_SCALAR(hpstate);
+ SERIALIZE_ARRAY(htstate, MaxTL);
+ SERIALIZE_SCALAR(htba);
+ SERIALIZE_SCALAR(hstick_cmpr);
+}
+
+void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
+{
+ UNSERIALIZE_SCALAR(pstate);
+ UNSERIALIZE_SCALAR(tba);
+ UNSERIALIZE_SCALAR(y);
+ UNSERIALIZE_SCALAR(pil);
+ UNSERIALIZE_SCALAR(gl);
+ UNSERIALIZE_SCALAR(cwp);
+ UNSERIALIZE_ARRAY(tt, MaxTL);
+ UNSERIALIZE_SCALAR(ccr);
+ UNSERIALIZE_SCALAR(asi);
+ UNSERIALIZE_SCALAR(tl);
+ UNSERIALIZE_ARRAY(tpc, MaxTL);
+ UNSERIALIZE_ARRAY(tnpc, MaxTL);
+ UNSERIALIZE_ARRAY(tstate, MaxTL);
+ UNSERIALIZE_SCALAR(tick);
+ UNSERIALIZE_SCALAR(cansave);
+ UNSERIALIZE_SCALAR(canrestore);
+ UNSERIALIZE_SCALAR(otherwin);
+ UNSERIALIZE_SCALAR(cleanwin);
+ UNSERIALIZE_SCALAR(wstate);
+ UNSERIALIZE_SCALAR(fsr);
+ UNSERIALIZE_SCALAR(fprs);
+ UNSERIALIZE_SCALAR(hpstate);
+ UNSERIALIZE_ARRAY(htstate, MaxTL);
+ UNSERIALIZE_SCALAR(htba);
+ UNSERIALIZE_SCALAR(hstick_cmpr);
+}
+
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
new file mode 100644
index 000000000..be143311f
--- /dev/null
+++ b/src/arch/sparc/miscregfile.hh
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#ifndef __ARCH_SPARC_MISCREGFILE_HH__
+#define __ARCH_SPARC_MISCREGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/types.hh"
+
+#include <string>
+
+namespace SparcISA
+{
+
+ //These functions map register indices to names
+ std::string getMiscRegName(RegIndex);
+
+ const int AsrStart = 0;
+ const int PrStart = 32;
+ const int HprStart = 64;
+ const int MiscStart = 96;
+
+ enum MiscRegIndex
+ {
+ /** Ancillary State Registers */
+ MISCREG_Y = AsrStart + 0,
+ MISCREG_CCR = AsrStart + 2,
+ MISCREG_ASI = AsrStart + 3,
+ MISCREG_TICK = AsrStart + 4,
+ MISCREG_PC = AsrStart + 5,
+ MISCREG_FPRS = AsrStart + 6,
+ MISCREG_PCR = AsrStart + 16,
+ MISCREG_PIC = AsrStart + 17,
+ MISCREG_GSR = AsrStart + 19,
+ MISCREG_SOFTINT_SET = AsrStart + 20,
+ MISCREG_SOFTINT_CLR = AsrStart + 21,
+ MISCREG_SOFTINT = AsrStart + 22,
+ MISCREG_TICK_CMPR = AsrStart + 23,
+ MISCREG_STICK = AsrStart + 24,
+ MISCREG_STICK_CMPR = AsrStart + 25,
+
+ /** Privilged Registers */
+ MISCREG_TPC = PrStart + 0,
+ MISCREG_TNPC = PrStart + 1,
+ MISCREG_TSTATE = PrStart + 2,
+ MISCREG_TT = PrStart + 3,
+ MISCREG_PRIVTICK = PrStart + 4,
+ MISCREG_TBA = PrStart + 5,
+ MISCREG_PSTATE = PrStart + 6,
+ MISCREG_TL = PrStart + 7,
+ MISCREG_PIL = PrStart + 8,
+ MISCREG_CWP = PrStart + 9,
+ MISCREG_CANSAVE = PrStart + 10,
+ MISCREG_CANRESTORE = PrStart + 11,
+ MISCREG_CLEANWIN = PrStart + 12,
+ MISCREG_OTHERWIN = PrStart + 13,
+ MISCREG_WSTATE = PrStart + 14,
+ MISCREG_GL = PrStart + 16,
+
+ /** Hyper privileged registers */
+ MISCREG_HPSTATE = HprStart + 0,
+ MISCREG_HTSTATE = HprStart + 1,
+ MISCREG_HINTP = HprStart + 3,
+ MISCREG_HTBA = HprStart + 5,
+ MISCREG_HVER = HprStart + 6,
+ MISCREG_STRAND_STS_REG = HprStart + 16,
+ MISCREG_HSTICK_CMPR = HprStart + 31,
+
+ /** Floating Point Status Register */
+ MISCREG_FSR = MiscStart + 0
+
+ };
+
+ // The control registers, broken out into fields
+ class MiscRegFile
+ {
+ private:
+
+ /* ASR Registers */
+ union {
+ uint64_t y; // Y (used in obsolete multiplication)
+ struct {
+ uint64_t value:32; // The actual value stored in y
+ uint64_t :32; // reserved bits
+ } yFields;
+ };
+ union {
+ uint8_t ccr; // Condition Code Register
+ struct {
+ union {
+ uint8_t icc:4; // 32-bit condition codes
+ struct {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } iccFields;
+ };
+ union {
+ uint8_t xcc:4; // 64-bit condition codes
+ struct {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } xccFields;
+ };
+ } ccrFields;
+ };
+ uint8_t asi; // Address Space Identifier
+ union {
+ uint64_t tick; // Hardware clock-tick counter
+ struct {
+ int64_t counter:63; // Clock-tick count
+ uint64_t npt:1; // Non-priveleged trap
+ } tickFields;
+ };
+ union {
+ uint8_t fprs; // Floating-Point Register State
+ struct {
+ uint8_t dl:1; // Dirty lower
+ uint8_t du:1; // Dirty upper
+ uint8_t fef:1; // FPRS enable floating-Point
+ } fprsFields;
+ };
+ union {
+ uint64_t gsr; //General Status Register
+ struct {
+ uint64_t mask:32;
+ uint64_t :4;
+ uint64_t im:1;
+ uint64_t irnd:2;
+ uint64_t :17;
+ uint64_t scale:5;
+ uint64_t align:3;
+ } gsrFields;
+ };
+ union {
+ uint64_t softint;
+ struct {
+ uint64_t tm:1;
+ uint64_t int_level:14;
+ uint64_t sm:1;
+ } softintFields;
+ };
+ union {
+ uint64_t tick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } tick_cmprFields;
+ };
+ union {
+ uint64_t stick; // Hardware clock-tick counter
+ struct {
+ int64_t :63; // Not used, storage in SparcSystem
+ uint64_t npt:1; // Non-priveleged trap
+ } stickFields;
+ };
+ union {
+ uint64_t stick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } stick_cmprFields;
+ };
+
+
+ /* Privileged Registers */
+ uint64_t tpc[MaxTL]; // Trap Program Counter (value from
+ // previous trap level)
+ uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
+ // previous trap level)
+ union {
+ uint64_t tstate[MaxTL]; // Trap State
+ struct {
+ //Values are from previous trap level
+ uint64_t cwp:5; // Current Window Pointer
+ uint64_t :3; // Reserved bits
+ uint64_t pstate:13; // Process State
+ uint64_t :3; // Reserved bits
+ uint64_t asi:8; // Address Space Identifier
+ uint64_t ccr:8; // Condition Code Register
+ uint64_t gl:8; // Global level
+ } tstateFields[MaxTL];
+ };
+ uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
+ // on the previous level)
+ uint64_t tba; // Trap Base Address
+
+ union {
+ uint16_t pstate; // Process State Register
+ struct {
+ uint16_t :1; // reserved
+ uint16_t ie:1; // Interrupt enable
+ uint16_t priv:1; // Privelege mode
+ uint16_t am:1; // Address mask
+ uint16_t pef:1; // PSTATE enable floating-point
+ uint16_t :1; // reserved2
+ uint16_t mm:2; // Memory Model
+ uint16_t tle:1; // Trap little-endian
+ uint16_t cle:1; // Current little-endian
+ } pstateFields;
+ };
+ uint8_t tl; // Trap Level
+ uint8_t pil; // Process Interrupt Register
+ uint8_t cwp; // Current Window Pointer
+ uint8_t cansave; // Savable windows
+ uint8_t canrestore; // Restorable windows
+ uint8_t cleanwin; // Clean windows
+ uint8_t otherwin; // Other windows
+ union {
+ uint8_t wstate; // Window State
+ struct {
+ uint8_t normal:3; // Bits TT<4:2> are set to on a normal
+ // register window trap
+ uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
+ // register window trap
+ } wstateFields;
+ };
+ uint8_t gl; // Global level register
+
+
+ /** Hyperprivileged Registers */
+ union {
+ uint64_t hpstate; // Hyperprivileged State Register
+ struct {
+ uint8_t tlz: 1;
+ uint8_t :1;
+ uint8_t hpriv:1;
+ uint8_t :2;
+ uint8_t red:1;
+ uint8_t :4;
+ uint8_t ibe:1;
+ uint8_t id:1;
+ } hpstateFields;
+ };
+
+ uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
+ uint64_t hintp;
+ uint64_t htba; // Hyperprivileged Trap Base Address register
+ union {
+ uint64_t hstick_cmpr; // Hardware tick compare registers
+ struct {
+ uint64_t tick_cmpr:63; // Clock-tick count
+ uint64_t int_dis:1; // Non-priveleged trap
+ } hstick_cmprFields;
+ };
+
+ uint64_t strandStatusReg; // Per strand status register
+
+
+ /** Floating point misc registers. */
+ union {
+ uint64_t fsr; // Floating-Point State Register
+ struct {
+ union {
+ uint64_t cexc:5; // Current excpetion
+ struct {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } cexcFields;
+ };
+ union {
+ uint64_t aexc:5; // Accrued exception
+ struct {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } aexcFields;
+ };
+ uint64_t fcc0:2; // Floating-Point condtion codes
+ uint64_t :1; // Reserved bits
+ uint64_t qne:1; // Deferred trap queue not empty
+ // with no queue, it should read 0
+ uint64_t ftt:3; // Floating-Point trap type
+ uint64_t ver:3; // Version (of the FPU)
+ uint64_t :2; // Reserved bits
+ uint64_t ns:1; // Nonstandard floating point
+ union {
+ uint64_t tem:5; // Trap Enable Mask
+ struct {
+ uint64_t nxm:1; // Inexact
+ uint64_t dzm:1; // Divide by zero
+ uint64_t ufm:1; // Underflow
+ uint64_t ofm:1; // Overflow
+ uint64_t nvm:1; // Invalid operand
+ } temFields;
+ };
+ uint64_t :2; // Reserved bits
+ uint64_t rd:2; // Rounding direction
+ uint64_t fcc1:2; // Floating-Point condition codes
+ uint64_t fcc2:2; // Floating-Point condition codes
+ uint64_t fcc3:2; // Floating-Point condition codes
+ uint64_t :26; // Reserved bits
+ } fsrFields;
+ };
+
+ // These need to check the int_dis field and if 0 then
+ // set appropriate bit in softint and checkinterrutps on the cpu
+#if FULL_SYSTEM
+ /** Process a tick compare event and generate an interrupt on the cpu if
+ * appropriate. */
+ void processTickCompare(ThreadContext *tc);
+ void processSTickCompare(ThreadContext *tc);
+ void processHSTickCompare(ThreadContext *tc);
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processTickCompare> TickCompareEvent;
+ TickCompareEvent *tickCompare;
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processSTickCompare> STickCompareEvent;
+ STickCompareEvent *sTickCompare;
+
+ typedef CpuEventWrapper<MiscRegFile,
+ &MiscRegFile::processHSTickCompare> HSTickCompareEvent;
+ HSTickCompareEvent *hSTickCompare;
+
+ /** Fullsystem only register version of ReadRegWithEffect() */
+ MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+ /** Fullsystem only register version of SetRegWithEffect() */
+ Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc);
+#endif
+ public:
+
+ void reset();
+
+ MiscRegFile()
+ {
+ reset();
+ }
+
+ /** read a value out of an either an SE or FS IPR. No checking is done
+ * about SE vs. FS as this is mostly used to copy the regfile. Thus more
+ * register are copied that are necessary for FS. However this prevents
+ * a bunch of ifdefs and is rarely called so is not performance
+ * criticial. */
+ MiscReg readReg(int miscReg);
+
+ /** Read a value from an IPR. Only the SE iprs are here and the rest
+ * are are readFSRegWithEffect (which is called by readRegWithEffect()).
+ * Checking is done for permission based on state bits in the miscreg
+ * file. */
+ MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
+
+ /** write a value into an either an SE or FS IPR. No checking is done
+ * about SE vs. FS as this is mostly used to copy the regfile. Thus more
+ * register are copied that are necessary for FS. However this prevents
+ * a bunch of ifdefs and is rarely called so is not performance
+ * criticial.*/
+ Fault setReg(int miscReg, const MiscReg &val);
+
+ /** Write a value into an IPR. Only the SE iprs are here and the rest
+ * are are setFSRegWithEffect (which is called by setRegWithEffect()).
+ * Checking is done for permission based on state bits in the miscreg
+ * file. */
+ Fault setRegWithEffect(int miscReg,
+ const MiscReg &val, ThreadContext * tc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, const std::string & section);
+
+ void copyMiscRegs(ThreadContext * tc);
+
+ protected:
+
+ bool isHyperPriv() { return hpstateFields.hpriv; }
+ bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
+ bool isNonPriv() { return !isPriv(); }
+ };
+}
+
+#endif
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 75f01e038..70c7e719f 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -32,6 +32,7 @@
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "base/loader/object_file.hh"
+#include "base/loader/elf_object.hh"
#include "base/misc.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
@@ -129,7 +130,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
SPARC_AT_UID = 11,
SPARC_AT_EUID = 12,
SPARC_AT_GID = 13,
- SPARC_AT_EGID = 14
+ SPARC_AT_EGID = 14,
+ SPARC_AT_SECURE = 23
};
enum hardwareCaps
@@ -153,31 +155,42 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
M5_HWCAP_SPARC_V9 |
M5_HWCAP_SPARC_ULTRA3;
- //Setup the auxilliary vectors. These will already have
- //endian conversion.
- auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
- auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
- auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
- auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
- //This would work, but the entry point is a protected member
- //auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry));
- auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
- //This is the address of the elf "interpreter", which I don't
- //think we currently set up. It should be set to 0 (I think)
- //auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
- //This is the number of headers which were in the original elf
- //file. This information isn't avaibale by this point.
- //auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3));
- //This is the size of a program header entry. This isn't easy
- //to compute here.
- //auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah));
- //This is should be set to load_addr (whatever that is) +
- //e_phoff. I think it's a pointer to the program headers.
- //auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah));
- //This should be easy to get right, but I won't set it for now
- //auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah));
- auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
- auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+
+ //Setup the auxilliary vectors. These will already have endian conversion.
+ //Auxilliary vectors are loaded only for elf formatted executables.
+ ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile);
+ if(elfObject)
+ {
+ //Bits which describe the system hardware capabilities
+ auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+ //The system page size
+ auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ //Defined to be 100 in the kernel source.
+ //Frequency at which times() increments
+ auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, 100));
+ // For statically linked executables, this is the virtual address of the
+ // program header tables if they appear in the executable image
+ auxv.push_back(buildAuxVect(SPARC_AT_PHDR, elfObject->programHeaderTable()));
+ // This is the size of a program header entry from the elf file.
+ auxv.push_back(buildAuxVect(SPARC_AT_PHENT, elfObject->programHeaderSize()));
+ // This is the number of program headers from the original elf file.
+ auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, elfObject->programHeaderCount()));
+ //This is the address of the elf "interpreter", It should be set
+ //to 0 for regular executables. It should be something else
+ //(not sure what) for dynamic libraries.
+ auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
+ //This is hardwired to 0 in the elf loading code in the kernel
+ auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
+ //The entry point to the program
+ auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entryPoint()));
+ //Different user and group IDs
+ auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
+ //Whether to enable "secure mode" in the executable
+ auxv.push_back(buildAuxVect(SPARC_AT_SECURE, 0));
+ }
//Figure out how big the initial stack needs to be
diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc
new file mode 100644
index 000000000..747426781
--- /dev/null
+++ b/src/arch/sparc/regfile.cc
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ * Ali Saidi
+ */
+
+#include "arch/sparc/regfile.hh"
+#include "cpu/thread_context.hh"
+
+class Checkpoint;
+
+using namespace SparcISA;
+using namespace std;
+
+//RegFile class methods
+Addr RegFile::readPC()
+{
+ return pc;
+}
+
+void RegFile::setPC(Addr val)
+{
+ pc = val;
+}
+
+Addr RegFile::readNextPC()
+{
+ return npc;
+}
+
+void RegFile::setNextPC(Addr val)
+{
+ npc = val;
+}
+
+Addr RegFile::readNextNPC()
+{
+ return nnpc;
+}
+
+void RegFile::setNextNPC(Addr val)
+{
+ nnpc = val;
+}
+
+void RegFile::clear()
+{
+ intRegFile.clear();
+ floatRegFile.clear();
+}
+
+MiscReg RegFile::readMiscReg(int miscReg)
+{
+ return miscRegFile.readReg(miscReg);
+}
+
+MiscReg RegFile::readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc)
+{
+ return miscRegFile.readRegWithEffect(miscReg, fault, tc);
+}
+
+Fault RegFile::setMiscReg(int miscReg, const MiscReg &val)
+{
+ return miscRegFile.setReg(miscReg, val);
+}
+
+Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val,
+ ThreadContext * tc)
+{
+ return miscRegFile.setRegWithEffect(miscReg, val, tc);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg, int width)
+{
+ return floatRegFile.readReg(floatReg, width);
+}
+
+FloatReg RegFile::readFloatReg(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg, int width)
+{
+ return floatRegFile.readRegBits(floatReg, width);
+}
+
+FloatRegBits RegFile::readFloatRegBits(int floatReg)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.readRegBits(floatReg,
+ FloatRegFile::SingleWidth);
+}
+
+Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width)
+{
+ return floatRegFile.setReg(floatReg, val, width);
+}
+
+Fault RegFile::setFloatReg(int floatReg, const FloatReg &val)
+{
+ //Use the "natural" width of a single float
+ return setFloatReg(floatReg, val, FloatRegFile::SingleWidth);
+}
+
+Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
+{
+ return floatRegFile.setRegBits(floatReg, val, width);
+}
+
+Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val)
+{
+ //Use the "natural" width of a single float
+ return floatRegFile.setRegBits(floatReg, val,
+ FloatRegFile::SingleWidth);
+}
+
+IntReg RegFile::readIntReg(int intReg)
+{
+ return intRegFile.readReg(intReg);
+}
+
+Fault RegFile::setIntReg(int intReg, const IntReg &val)
+{
+ return intRegFile.setReg(intReg, val);
+}
+
+void RegFile::serialize(std::ostream &os)
+{
+ intRegFile.serialize(os);
+ floatRegFile.serialize(os);
+ miscRegFile.serialize(os);
+ SERIALIZE_SCALAR(pc);
+ SERIALIZE_SCALAR(npc);
+}
+
+void RegFile::unserialize(Checkpoint *cp, const std::string &section)
+{
+ intRegFile.unserialize(cp, section);
+ floatRegFile.unserialize(cp, section);
+ miscRegFile.unserialize(cp, section);
+ UNSERIALIZE_SCALAR(pc);
+ UNSERIALIZE_SCALAR(npc);
+}
+
+void RegFile::changeContext(RegContextParam param, RegContextVal val)
+{
+ switch(param)
+ {
+ case CONTEXT_CWP:
+ intRegFile.setCWP(val);
+ break;
+ case CONTEXT_GLOBALS:
+ intRegFile.setGlobals(val);
+ break;
+ default:
+ panic("Tried to set illegal context parameter in the SPARC regfile.\n");
+ }
+}
+
+int SparcISA::InterruptLevel(uint64_t softint)
+{
+ if (softint & 0x10000 || softint & 0x1)
+ return 14;
+
+ int level = 14;
+ while (level >= 0 && !(1 << (level + 1) & softint))
+ level--;
+ if (1 << (level + 1) & softint)
+ return level;
+ return 0;
+}
+
+void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest)
+{
+
+ uint8_t tl = src->readMiscReg(MISCREG_TL);
+
+ // Read all the trap level dependent registers and save them off
+ for(int i = 1; i <= MaxTL; i++)
+ {
+ src->setMiscReg(MISCREG_TL, i);
+ dest->setMiscReg(MISCREG_TL, i);
+
+ dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT));
+ dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC));
+ dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC));
+ dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE));
+ }
+
+ // Save off the traplevel
+ dest->setMiscReg(MISCREG_TL, tl);
+ src->setMiscReg(MISCREG_TL, tl);
+
+
+ // ASRs
+ dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y));
+ dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR));
+ dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI));
+ dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
+ dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS));
+ dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT));
+ dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR));
+ dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK));
+ dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR));
+
+ // Priv Registers
+ dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK));
+ dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA));
+ dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE));
+ dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL));
+ dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP));
+ dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE));
+ dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE));
+ dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN));
+ dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN));
+ dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE));
+ dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL));
+
+ // Hyperprivilged registers
+ dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE));
+ dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP));
+ dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA));
+ dest->setMiscReg(MISCREG_STRAND_STS_REG,
+ src->readMiscReg(MISCREG_STRAND_STS_REG));
+ dest->setMiscReg(MISCREG_HSTICK_CMPR,
+ src->readMiscReg(MISCREG_HSTICK_CMPR));
+
+ // FSR
+ dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR));
+}
+
+void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest)
+{
+ // First loop through the integer registers.
+ for (int i = 0; i < TheISA::NumIntRegs; ++i) {
+ dest->setIntReg(i, src->readIntReg(i));
+ }
+
+ // Then loop through the floating point registers.
+ for (int i = 0; i < TheISA::NumFloatRegs; ++i) {
+ dest->setFloatRegBits(i, src->readFloatRegBits(i));
+ }
+
+ // Copy misc. registers
+ copyMiscRegs(src, dest);
+
+ // Lastly copy PC/NPC
+ dest->setPC(src->readPC());
+ dest->setNextPC(src->readNextPC());
+ dest->setNextNPC(src->readNextNPC());
+}
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index cbeb3c7b9..500fbbba4 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.hh
@@ -32,833 +32,84 @@
#ifndef __ARCH_SPARC_REGFILE_HH__
#define __ARCH_SPARC_REGFILE_HH__
-#include "arch/sparc/exceptions.hh"
#include "arch/sparc/faults.hh"
-#include "base/trace.hh"
-#include "sim/byteswap.hh"
-#include "cpu/cpuevent.hh"
+#include "arch/sparc/floatregfile.hh"
+#include "arch/sparc/intregfile.hh"
+#include "arch/sparc/isa_traits.hh"
+#include "arch/sparc/miscregfile.hh"
+#include "arch/sparc/types.hh"
#include "sim/host.hh"
+#include <string>
+
class Checkpoint;
namespace SparcISA
{
-
- typedef uint8_t RegIndex;
-
- // MAXTL - maximum trap level
- const int MaxPTL = 2;
- const int MaxTL = 6;
- const int MaxGL = 3;
- const int MaxPGL = 2;
-
- // NWINDOWS - number of register windows, can be 3 to 32
- const int NWindows = 32;
-
-
- const int AsrStart = 0;
- const int PrStart = 32;
- const int HprStart = 64;
- const int MiscStart = 96;
-
- const uint64_t Bit64 = (1ULL << 63);
-
- class IntRegFile
+ class RegFile
{
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[MaxGL][RegsPerFrame];
- IntReg regSegments[2 * NWindows][RegsPerFrame];
-
- enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames};
-
- IntReg * regView[NumFrames];
-
- static const int RegGlobalOffset = 0;
- static const int FrameOffset = MaxGL * RegsPerFrame;
- int offset[NumFrames];
+ Addr pc; // Program Counter
+ Addr npc; // Next Program Counter
+ Addr nnpc;
public:
+ Addr readPC();
+ void setPC(Addr val);
- 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()
- {
- int x;
- for (x = 0; x < MaxGL; x++)
- memset(regGlobals[x], 0, sizeof(regGlobals[x]));
- for(int x = 0; x < 2 * NWindows; x++)
- bzero(regSegments[x], sizeof(regSegments[x]));
- }
-
- IntRegFile()
- {
- offset[Globals] = 0;
- regView[Globals] = regGlobals[0];
- 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 setGlobals(int gl)
- {
-
- DPRINTF(Sparc, "Now using %d globals", gl);
-
- regView[Globals] = regGlobals[gl];
- offset[Globals] = RegGlobalOffset + gl * RegsPerFrame;
- }
-
- void serialize(std::ostream &os);
-
- void unserialize(Checkpoint *cp, const std::string &section);
- };
-
- typedef float float32_t;
- typedef double float64_t;
- //FIXME long double refers to a 10 byte float, rather than a
- //16 byte float as required. This data type may have to be emulated.
- typedef double float128_t;
+ Addr readNextPC();
+ void setNextPC(Addr val);
- class FloatRegFile
- {
- public:
- static const int SingleWidth = 32;
- static const int DoubleWidth = 64;
- static const int QuadWidth = 128;
+ Addr readNextNPC();
+ void setNextNPC(Addr val);
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.
- char regSpace[SingleWidth / 8 * NumFloatRegs];
+ IntRegFile intRegFile; // integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegFile; // control register file
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
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- switch(width)
- {
- case SingleWidth:
- float32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, width);
- return htog(result32);
- case DoubleWidth:
- float64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, width);
- return htog(result64);
- case QuadWidth:
- float128_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, width);
- return htog(result128);
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- }
-
- FloatRegBits readRegBits(int floatReg, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- switch(width)
- {
- case SingleWidth:
- uint32_t result32;
- memcpy(&result32, regSpace + 4 * floatReg, width);
- return htog(result32);
- case DoubleWidth:
- uint64_t result64;
- memcpy(&result64, regSpace + 4 * floatReg, width);
- return htog(result64);
- case QuadWidth:
- uint64_t result128;
- memcpy(&result128, regSpace + 4 * floatReg, width);
- return htog(result128);
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- }
-
- Fault setReg(int floatReg, const FloatReg &val, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
-
- uint32_t result32;
- uint64_t result64;
- switch(width)
- {
- case SingleWidth:
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, width);
- break;
- case DoubleWidth:
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, width);
- break;
- case QuadWidth:
- panic("Quad width FP not implemented.");
- break;
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- return NoFault;
- }
-
- Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
- {
- //In each of these cases, we have to copy the value into a temporary
- //variable. This is because we may otherwise try to access an
- //unaligned portion of memory.
- uint32_t result32;
- uint64_t result64;
- switch(width)
- {
- case SingleWidth:
- result32 = gtoh((uint32_t)val);
- memcpy(regSpace + 4 * floatReg, &result32, width);
- break;
- case DoubleWidth:
- result64 = gtoh((uint64_t)val);
- memcpy(regSpace + 4 * floatReg, &result64, width);
- break;
- case QuadWidth:
- panic("Quad width FP not implemented.");
- break;
- default:
- panic("Attempted to read a %d bit floating point register!", width);
- }
- return NoFault;
- }
+ void clear();
- void serialize(std::ostream &os);
+ int FlattenIntIndex(int reg);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
+ MiscReg readMiscReg(int miscReg);
- enum MiscRegIndex
- {
- /** Ancillary State Registers */
- MISCREG_Y = AsrStart + 0,
- MISCREG_CCR = AsrStart + 2,
- MISCREG_ASI = AsrStart + 3,
- MISCREG_TICK = AsrStart + 4,
- MISCREG_PC = AsrStart + 5,
- MISCREG_FPRS = AsrStart + 6,
- MISCREG_PCR = AsrStart + 16,
- MISCREG_PIC = AsrStart + 17,
- MISCREG_GSR = AsrStart + 19,
- MISCREG_SOFTINT_SET = AsrStart + 20,
- MISCREG_SOFTINT_CLR = AsrStart + 21,
- MISCREG_SOFTINT = AsrStart + 22,
- MISCREG_TICK_CMPR = AsrStart + 23,
- MISCREG_STICK = AsrStart + 24,
- MISCREG_STICK_CMPR = AsrStart + 25,
-
- /** Privilged Registers */
- MISCREG_TPC = PrStart + 0,
- MISCREG_TNPC = PrStart + 1,
- MISCREG_TSTATE = PrStart + 2,
- MISCREG_TT = PrStart + 3,
- MISCREG_PRIVTICK = PrStart + 4,
- MISCREG_TBA = PrStart + 5,
- MISCREG_PSTATE = PrStart + 6,
- MISCREG_TL = PrStart + 7,
- MISCREG_PIL = PrStart + 8,
- MISCREG_CWP = PrStart + 9,
- MISCREG_CANSAVE = PrStart + 10,
- MISCREG_CANRESTORE = PrStart + 11,
- MISCREG_CLEANWIN = PrStart + 12,
- MISCREG_OTHERWIN = PrStart + 13,
- MISCREG_WSTATE = PrStart + 14,
- MISCREG_GL = PrStart + 16,
-
- /** Hyper privileged registers */
- MISCREG_HPSTATE = HprStart + 0,
- MISCREG_HTSTATE = HprStart + 1,
- MISCREG_HINTP = HprStart + 3,
- MISCREG_HTBA = HprStart + 5,
- MISCREG_HVER = HprStart + 6,
- MISCREG_STRAND_STS_REG = HprStart + 16,
- MISCREG_HSTICK_CMPR = HprStart + 31,
-
- /** Floating Point Status Register */
- MISCREG_FSR = MiscStart + 0
+ MiscReg readMiscRegWithEffect(int miscReg,
+ Fault &fault, ThreadContext *tc);
- };
+ Fault setMiscReg(int miscReg, const MiscReg &val);
- // The control registers, broken out into fields
- class MiscRegFile
- {
- private:
-
- /* ASR Registers */
- union {
- uint64_t y; // Y (used in obsolete multiplication)
- struct {
- uint64_t value:32; // The actual value stored in y
- uint64_t :32; // reserved bits
- } yFields;
- };
- union {
- uint8_t ccr; // Condition Code Register
- struct {
- union {
- uint8_t icc:4; // 32-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } iccFields;
- };
- union {
- uint8_t xcc:4; // 64-bit condition codes
- struct {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } xccFields;
- };
- } ccrFields;
- };
- uint8_t asi; // Address Space Identifier
- union {
- uint64_t tick; // Hardware clock-tick counter
- struct {
- int64_t counter:63; // Clock-tick count
- uint64_t npt:1; // Non-priveleged trap
- } tickFields;
- };
- union {
- uint8_t fprs; // Floating-Point Register State
- struct {
- uint8_t dl:1; // Dirty lower
- uint8_t du:1; // Dirty upper
- uint8_t fef:1; // FPRS enable floating-Point
- } fprsFields;
- };
- union {
- uint64_t softint;
- struct {
- uint64_t tm:1;
- uint64_t int_level:14;
- uint64_t sm:1;
- } softintFields;
- };
- union {
- uint64_t tick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } tick_cmprFields;
- };
- union {
- uint64_t stick; // Hardware clock-tick counter
- struct {
- int64_t :63; // Not used, storage in SparcSystem
- uint64_t npt:1; // Non-priveleged trap
- } stickFields;
- };
- union {
- uint64_t stick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } stick_cmprFields;
- };
-
-
- /* Privileged Registers */
- uint64_t tpc[MaxTL]; // Trap Program Counter (value from
- // previous trap level)
- uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
- // previous trap level)
- union {
- uint64_t tstate[MaxTL]; // Trap State
- struct {
- //Values are from previous trap level
- uint64_t cwp:5; // Current Window Pointer
- uint64_t :3; // Reserved bits
- uint64_t pstate:13; // Process State
- uint64_t :3; // Reserved bits
- uint64_t asi:8; // Address Space Identifier
- uint64_t ccr:8; // Condition Code Register
- uint64_t gl:8; // Global level
- } tstateFields[MaxTL];
- };
- uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
- // on the previous level)
- uint64_t tba; // Trap Base Address
-
- union {
- uint16_t pstate; // Process State Register
- struct {
- uint16_t :1; // reserved
- uint16_t ie:1; // Interrupt enable
- uint16_t priv:1; // Privelege mode
- uint16_t am:1; // Address mask
- uint16_t pef:1; // PSTATE enable floating-point
- uint16_t :1; // reserved2
- uint16_t mm:2; // Memory Model
- uint16_t tle:1; // Trap little-endian
- uint16_t cle:1; // Current little-endian
- } pstateFields;
- };
- uint8_t tl; // Trap Level
- uint8_t pil; // Process Interrupt Register
- uint8_t cwp; // Current Window Pointer
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t cleanwin; // Clean windows
- uint8_t otherwin; // Other windows
- union {
- uint8_t wstate; // Window State
- struct {
- uint8_t normal:3; // Bits TT<4:2> are set to on a normal
- // register window trap
- uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
- // register window trap
- } wstateFields;
- };
- uint8_t gl; // Global level register
-
-
- /** Hyperprivileged Registers */
- union {
- uint64_t hpstate; // Hyperprivileged State Register
- struct {
- uint8_t tlz: 1;
- uint8_t :1;
- uint8_t hpriv:1;
- uint8_t :2;
- uint8_t red:1;
- uint8_t :4;
- uint8_t ibe:1;
- uint8_t id:1;
- } hpstateFields;
- };
-
- uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register
- uint64_t hintp;
- uint64_t htba; // Hyperprivileged Trap Base Address register
- union {
- uint64_t hstick_cmpr; // Hardware tick compare registers
- struct {
- uint64_t tick_cmpr:63; // Clock-tick count
- uint64_t int_dis:1; // Non-priveleged trap
- } hstick_cmprFields;
- };
-
- uint64_t strandStatusReg; // Per strand status register
-
-
- /** Floating point misc registers. */
- union {
- uint64_t fsr; // Floating-Point State Register
- struct {
- union {
- uint64_t cexc:5; // Current excpetion
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } cexcFields;
- };
- union {
- uint64_t aexc:5; // Accrued exception
- struct {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } aexcFields;
- };
- uint64_t fcc0:2; // Floating-Point condtion codes
- uint64_t :1; // Reserved bits
- uint64_t qne:1; // Deferred trap queue not empty
- // with no queue, it should read 0
- uint64_t ftt:3; // Floating-Point trap type
- uint64_t ver:3; // Version (of the FPU)
- uint64_t :2; // Reserved bits
- uint64_t ns:1; // Nonstandard floating point
- union {
- uint64_t tem:5; // Trap Enable Mask
- struct {
- uint64_t nxm:1; // Inexact
- uint64_t dzm:1; // Divide by zero
- uint64_t ufm:1; // Underflow
- uint64_t ofm:1; // Overflow
- uint64_t nvm:1; // Invalid operand
- } temFields;
- };
- uint64_t :2; // Reserved bits
- uint64_t rd:2; // Rounding direction
- uint64_t fcc1:2; // Floating-Point condition codes
- uint64_t fcc2:2; // Floating-Point condition codes
- uint64_t fcc3:2; // Floating-Point condition codes
- uint64_t :26; // Reserved bits
- } fsrFields;
- };
-
- // These need to check the int_dis field and if 0 then
- // set appropriate bit in softint and checkinterrutps on the cpu
-#if FULL_SYSTEM
- /** Process a tick compare event and generate an interrupt on the cpu if
- * appropriate. */
- void processTickCompare(ThreadContext *tc);
- void processSTickCompare(ThreadContext *tc);
- void processHSTickCompare(ThreadContext *tc);
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processTickCompare> TickCompareEvent;
- TickCompareEvent *tickCompare;
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processSTickCompare> STickCompareEvent;
- STickCompareEvent *sTickCompare;
-
- typedef CpuEventWrapper<MiscRegFile,
- &MiscRegFile::processHSTickCompare> HSTickCompareEvent;
- HSTickCompareEvent *hSTickCompare;
-
- /** Fullsystem only register version of ReadRegWithEffect() */
- MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
- /** Fullsystem only register version of SetRegWithEffect() */
- Fault setFSRegWithEffect(int miscReg, const MiscReg &val,
+ Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
ThreadContext * tc);
-#endif
- 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;
- gl = MaxGL;
-
- tickFields.counter = 0; //The TICK register is unreadable bya
- tickFields.npt = 1; //The TICK register is unreadable by by !priv
-
- softint = 0; // Clear all the soft interrupt bits
- tick_cmprFields.int_dis = 1; // disable timer compare interrupts
- tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
- stickFields.npt = 1; //The TICK register is unreadable by by !priv
- stick_cmprFields.int_dis = 1; // disable timer compare interrupts
- stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-
- tt[tl] = power_on_reset;
- pstate = 0; // fields 0 but pef
- pstateFields.pef = 1;
-
- hpstate = 0;
- hpstateFields.red = 1;
- hpstateFields.hpriv = 1;
- hpstateFields.tlz = 0; // this is a guess
-
- hintp = 0; // no interrupts pending
- hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
- hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
-
-#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();
- }
-
- /** read a value out of an either an SE or FS IPR. No checking is done
- * about SE vs. FS as this is mostly used to copy the regfile. Thus more
- * register are copied that are necessary for FS. However this prevents
- * a bunch of ifdefs and is rarely called so is not performance
- * criticial. */
- MiscReg readReg(int miscReg);
-
- /** Read a value from an IPR. Only the SE iprs are here and the rest
- * are are readFSRegWithEffect (which is called by readRegWithEffect()).
- * Checking is done for permission based on state bits in the miscreg
- * file. */
- MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
-
- /** write a value into an either an SE or FS IPR. No checking is done
- * about SE vs. FS as this is mostly used to copy the regfile. Thus more
- * register are copied that are necessary for FS. However this prevents
- * a bunch of ifdefs and is rarely called so is not performance
- * criticial.*/
- Fault setReg(int miscReg, const MiscReg &val);
-
- /** Write a value into an IPR. Only the SE iprs are here and the rest
- * are are setFSRegWithEffect (which is called by setRegWithEffect()).
- * Checking is done for permission based on state bits in the miscreg
- * file. */
- Fault setRegWithEffect(int miscReg,
- const MiscReg &val, ThreadContext * tc);
-
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, const std::string & section);
-
- void copyMiscRegs(ThreadContext * tc);
-
- bool isHyperPriv() { return hpstateFields.hpriv; }
- bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; }
- bool isNonPriv() { return !isPriv(); }
- };
+ FloatReg readFloatReg(int floatReg, int width);
- typedef union
- {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
+ FloatReg readFloatReg(int floatReg);
- class RegFile
- {
- 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
+ FloatRegBits readFloatRegBits(int floatReg, int width);
- public:
+ FloatRegBits readFloatRegBits(int floatReg);
- void clear()
- {
- intRegFile.clear();
- floatRegFile.clear();
- }
+ Fault setFloatReg(int floatReg, const FloatReg &val, int width);
- int FlattenIntIndex(int reg)
- {
- return intRegFile.flattenIndex(reg);
- }
+ Fault setFloatReg(int floatReg, const FloatReg &val);
- MiscReg readMiscReg(int miscReg)
- {
- return miscRegFile.readReg(miscReg);
- }
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width);
- MiscReg readMiscRegWithEffect(int miscReg,
- Fault &fault, ThreadContext *tc)
- {
- return miscRegFile.readRegWithEffect(miscReg, fault, tc);
- }
+ Fault setFloatRegBits(int floatReg, const FloatRegBits &val);
- Fault setMiscReg(int miscReg, const MiscReg &val)
- {
- return miscRegFile.setReg(miscReg, val);
- }
+ IntReg readIntReg(int intReg);
- Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
- ThreadContext * tc)
- {
- return miscRegFile.setRegWithEffect(miscReg, val, tc);
- }
-
- 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);
- }
+ Fault setIntReg(int intReg, const IntReg &val);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
public:
- enum ContextParam
- {
- CONTEXT_CWP,
- CONTEXT_GLOBALS
- };
- typedef int ContextVal;
-
- void changeContext(ContextParam param, ContextVal val)
- {
- switch(param)
- {
- case CONTEXT_CWP:
- intRegFile.setCWP(val);
- break;
- case CONTEXT_GLOBALS:
- intRegFile.setGlobals(val);
- break;
- default:
- panic("Tried to set illegal context parameter in the SPARC regfile.\n");
- }
- }
+ void changeContext(RegContextParam param, RegContextVal val);
};
void copyRegs(ThreadContext *src, ThreadContext *dest);
diff --git a/src/arch/sparc/solaris/solaris.cc b/src/arch/sparc/solaris/solaris.cc
index c588925b0..c53caa72a 100644
--- a/src/arch/sparc/solaris/solaris.cc
+++ b/src/arch/sparc/solaris/solaris.cc
@@ -30,6 +30,8 @@
#include "arch/sparc/solaris/solaris.hh"
+#include <fcntl.h>
+
// open(2) flags translation table
OpenFlagTransTable SparcSolaris::openFlagTable[] = {
#ifdef _MSC_VER
diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh
index d12aee211..54d3d17be 100644
--- a/src/arch/sparc/stacktrace.hh
+++ b/src/arch/sparc/stacktrace.hh
@@ -28,8 +28,8 @@
* Authors: Nathan Binkert
*/
-#ifndef __ARCH_ALPHA_STACKTRACE_HH__
-#define __ARCH_ALPHA_STACKTRACE_HH__
+#ifndef __ARCH_SPARC_STACKTRACE_HH__
+#define __ARCH_SPARC_STACKTRACE_HH__
#include "base/trace.hh"
#include "cpu/static_inst.hh"
@@ -118,4 +118,4 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
return true;
}
-#endif // __ARCH_ALPHA_STACKTRACE_HH__
+#endif // __ARCH_SPARC_STACKTRACE_HH__
diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh
new file mode 100644
index 000000000..d850f4b65
--- /dev/null
+++ b/src/arch/sparc/syscallreturn.hh
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__
+#define __ARCH_SPARC_SYSCALLRETURN_HH__
+
+#include <inttypes.h>
+
+#include "arch/sparc/regfile.hh"
+
+class SyscallReturn
+{
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s)
+ {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+namespace SparcISA
+{
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ RegFile *regs)
+ {
+ // check for error condition. SPARC syscall convention is to
+ // indicate success/failure in reg the carry bit of the ccr
+ // and put the return value itself in the standard return value reg ().
+ if (return_value.successful()) {
+ // no error, clear XCC.C
+ regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ } else {
+ // got an error, set XCC.C
+ regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10);
+ regs->setIntReg(ReturnValueReg, return_value.value());
+ }
+ }
+};
+
+#endif
diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc
index e197e7918..63cbbe057 100644
--- a/src/arch/sparc/system.cc
+++ b/src/arch/sparc/system.cc
@@ -141,6 +141,7 @@ SparcSystem::unserialize(Checkpoint *cp, const std::string &section)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcSystem)
SimObjectParam<PhysicalMemory *> physmem;
+ SimpleEnumParam<System::MemoryMode> mem_mode;
Param<std::string> kernel;
Param<std::string> reset_bin;
@@ -161,6 +162,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SparcSystem)
INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
INIT_PARAM(physmem, "phsyical memory"),
+ INIT_ENUM_PARAM(mem_mode, "Memory Mode, (1=atomic, 2=timing)",
+ System::MemoryModeStrings),
INIT_PARAM(kernel, "file that contains the kernel code"),
INIT_PARAM(reset_bin, "file that contains the reset code"),
INIT_PARAM(hypervisor_bin, "file that contains the hypervisor code"),
@@ -183,6 +186,7 @@ CREATE_SIM_OBJECT(SparcSystem)
p->name = getInstanceName();
p->boot_cpu_frequency = boot_cpu_frequency;
p->physmem = physmem;
+ p->mem_mode = mem_mode;
p->kernel_path = kernel;
p->reset_bin = reset_bin;
p->hypervisor_bin = hypervisor_bin;
diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh
new file mode 100644
index 000000000..88fb24153
--- /dev/null
+++ b/src/arch/sparc/types.hh
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Gabe Black
+ */
+
+#ifndef __ARCH_SPARC_TYPES_HH__
+#define __ARCH_SPARC_TYPES_HH__
+
+#include <inttypes.h>
+
+namespace SparcISA
+{
+ typedef uint32_t MachInst;
+ typedef uint64_t ExtMachInst;
+
+ typedef uint64_t IntReg;
+ typedef uint64_t MiscReg;
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
+ typedef union
+ {
+ IntReg intReg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ enum RegContextParam
+ {
+ CONTEXT_CWP,
+ CONTEXT_GLOBALS
+ };
+
+ typedef int RegContextVal;
+
+ typedef uint8_t RegIndex;
+}
+
+#endif
diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc
index b89d48663..6493ddfd5 100644
--- a/src/arch/sparc/ua2005.cc
+++ b/src/arch/sparc/ua2005.cc
@@ -37,7 +37,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
int64_t time;
SparcSystem *sys;
switch (miscReg) {
- /** Full system only ASRs */
+ /* Full system only ASRs */
case MISCREG_SOFTINT:
if (isNonPriv())
return new PrivilegedOpcode;
@@ -94,7 +94,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
sTickCompare.schedule(time * Clock::Int::ns);
return NoFault;
- /** Fullsystem only Priv registers. */
+ /* Fullsystem only Priv registers. */
case MISCREG_PIL:
if (FULL_SYSTEM) {
setReg(miscReg, val);
@@ -104,7 +104,7 @@ SparcISA::MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
} else
panic("PIL not implemented for syscall emulation\n");
- /** Hyper privileged registers */
+ /* Hyper privileged registers */
case MISCREG_HPSTATE:
case MISCREG_HINTP:
setReg(miscReg, val);
@@ -147,7 +147,7 @@ MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc)
{
switch (miscReg) {
- /** Privileged registers. */
+ /* Privileged registers. */
case MISCREG_SOFTINT:
if (isNonPriv()) {
fault = new PrivilegedOpcode;
@@ -177,7 +177,7 @@ MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext * tc)
return readReg(miscReg);
- /** Hyper privileged registers */
+ /* Hyper privileged registers */
case MISCREG_HPSTATE:
case MISCREG_HINTP:
return readReg(miscReg);