summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2017-11-05 15:41:59 -0800
committerGabe Black <gabeblack@google.com>2017-11-20 07:49:48 +0000
commitd626f4f7aaa4d2c9f7ae1afc35577fa025b4de38 (patch)
tree0249e5f16b3603bb67a6bc3b09a4f4682cde7df2 /src/arch/sparc
parent205add5769e3978341cb9aa71d563dfb048e1f13 (diff)
downloadgem5-d626f4f7aaa4d2c9f7ae1afc35577fa025b4de38.tar.xz
sparc: Pull StaticInst base classes out of the ISA description.
Also, do some minor refactoring to use a BitUnion to pull apart condition codes, etc. Change-Id: I0c88878b07a731d0c0fe30f264f53dd795db99ae Reviewed-on: https://gem5-review.googlesource.com/5421 Reviewed-by: Jason Lowe-Power <jason@lowepower.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/insts/SConscript35
-rw-r--r--src/arch/sparc/insts/static_inst.cc372
-rw-r--r--src/arch/sparc/insts/static_inst.hh112
-rw-r--r--src/arch/sparc/isa/base.isa439
-rw-r--r--src/arch/sparc/isa/formats/basic.isa156
-rw-r--r--src/arch/sparc/isa/includes.isa1
6 files changed, 598 insertions, 517 deletions
diff --git a/src/arch/sparc/insts/SConscript b/src/arch/sparc/insts/SConscript
new file mode 100644
index 000000000..94996f6b2
--- /dev/null
+++ b/src/arch/sparc/insts/SConscript
@@ -0,0 +1,35 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2004-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
+# Steve Reinhardt
+
+Import('*')
+
+if env['TARGET_ISA'] == 'sparc':
+ Source('static_inst.cc')
diff --git a/src/arch/sparc/insts/static_inst.cc b/src/arch/sparc/insts/static_inst.cc
new file mode 100644
index 000000000..a1f5e60d7
--- /dev/null
+++ b/src/arch/sparc/insts/static_inst.cc
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2006-2007 The Regents of The University of Michigan
+ * All rights reserved
+ * Copyright 2017 Google Inc.
+ *
+ * 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
+ */
+
+#include "arch/sparc/insts/static_inst.hh"
+
+namespace SparcISA
+{
+
+const char *CondTestAbbrev[] =
+{
+ [Never] = "nev",
+ [Equal] = "e",
+ [LessOrEqual] = "le",
+ [Less] = "l",
+ [LessOrEqualUnsigned] = "leu",
+ [CarrySet] = "c",
+ [Negative] = "n",
+ [OverflowSet] = "o",
+ [Always] = "a",
+ [NotEqual] = "ne",
+ [Greater] = "g",
+ [GreaterOrEqual] = "ge",
+ [GreaterUnsigned] = "gu",
+ [CarryClear] = "cc",
+ [Positive] = "p",
+ [OverflowClear] = "oc"
+};
+
+void
+SparcStaticInst::printMnemonic(std::ostream &os, const char *mnemonic)
+{
+ ccprintf(os, "\t%s ", mnemonic);
+}
+
+void
+SparcStaticInst::printRegArray(std::ostream &os, const RegId 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::advancePC(SparcISA::PCState &pcState) const
+{
+ pcState.advance();
+}
+
+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, RegId reg)
+{
+ const int MaxGlobal = 8;
+ const int MaxOutput = 16;
+ const int MaxLocal = 24;
+ const int MaxInput = 32;
+ const int MaxMicroReg = 40;
+ RegIndex reg_idx = reg.index();
+ if (reg.isIntReg()) {
+ // If we used a register from the next or previous window,
+ // take out the offset.
+ while (reg_idx >= MaxMicroReg)
+ reg_idx -= MaxMicroReg;
+ if (reg_idx == FramePointerReg)
+ ccprintf(os, "%%fp");
+ else if (reg_idx == StackPointerReg)
+ ccprintf(os, "%%sp");
+ else if (reg_idx < MaxGlobal)
+ ccprintf(os, "%%g%d", reg_idx);
+ else if (reg_idx < MaxOutput)
+ ccprintf(os, "%%o%d", reg_idx - MaxGlobal);
+ else if (reg_idx < MaxLocal)
+ ccprintf(os, "%%l%d", reg_idx - MaxOutput);
+ else if (reg_idx < MaxInput)
+ ccprintf(os, "%%i%d", reg_idx - MaxLocal);
+ else if (reg_idx < MaxMicroReg)
+ ccprintf(os, "%%u%d", reg_idx - MaxInput);
+ // The fake int regs that are really control regs
+ else {
+ switch (reg_idx - MaxMicroReg) {
+ case 1:
+ ccprintf(os, "%%y");
+ break;
+ case 2:
+ ccprintf(os, "%%ccr");
+ break;
+ case 3:
+ ccprintf(os, "%%cansave");
+ break;
+ case 4:
+ ccprintf(os, "%%canrestore");
+ break;
+ case 5:
+ ccprintf(os, "%%cleanwin");
+ break;
+ case 6:
+ ccprintf(os, "%%otherwin");
+ break;
+ case 7:
+ ccprintf(os, "%%wstate");
+ break;
+ }
+ }
+ } else if (reg.isFloatReg()) {
+ ccprintf(os, "%%f%d", reg_idx);
+ } else {
+ switch (reg_idx) {
+ case MISCREG_ASI:
+ ccprintf(os, "%%asi");
+ break;
+ case MISCREG_FPRS:
+ ccprintf(os, "%%fprs");
+ break;
+ case MISCREG_PCR:
+ ccprintf(os, "%%pcr");
+ break;
+ case MISCREG_PIC:
+ ccprintf(os, "%%pic");
+ break;
+ case MISCREG_GSR:
+ ccprintf(os, "%%gsr");
+ break;
+ case MISCREG_SOFTINT:
+ ccprintf(os, "%%softint");
+ break;
+ case MISCREG_SOFTINT_SET:
+ ccprintf(os, "%%softint_set");
+ break;
+ case MISCREG_SOFTINT_CLR:
+ ccprintf(os, "%%softint_clr");
+ break;
+ case MISCREG_TICK_CMPR:
+ ccprintf(os, "%%tick_cmpr");
+ break;
+ case MISCREG_STICK:
+ ccprintf(os, "%%stick");
+ break;
+ case MISCREG_STICK_CMPR:
+ ccprintf(os, "%%stick_cmpr");
+ break;
+ case MISCREG_TPC:
+ ccprintf(os, "%%tpc");
+ break;
+ case MISCREG_TNPC:
+ ccprintf(os, "%%tnpc");
+ break;
+ case MISCREG_TSTATE:
+ ccprintf(os, "%%tstate");
+ break;
+ case MISCREG_TT:
+ ccprintf(os, "%%tt");
+ break;
+ case MISCREG_TICK:
+ ccprintf(os, "%%tick");
+ break;
+ case MISCREG_TBA:
+ ccprintf(os, "%%tba");
+ break;
+ case MISCREG_PSTATE:
+ ccprintf(os, "%%pstate");
+ break;
+ case MISCREG_TL:
+ ccprintf(os, "%%tl");
+ break;
+ case MISCREG_PIL:
+ ccprintf(os, "%%pil");
+ break;
+ case MISCREG_CWP:
+ ccprintf(os, "%%cwp");
+ break;
+ case MISCREG_GL:
+ ccprintf(os, "%%gl");
+ break;
+ case MISCREG_HPSTATE:
+ ccprintf(os, "%%hpstate");
+ break;
+ case MISCREG_HTSTATE:
+ ccprintf(os, "%%htstate");
+ break;
+ case MISCREG_HINTP:
+ ccprintf(os, "%%hintp");
+ break;
+ case MISCREG_HTBA:
+ ccprintf(os, "%%htba");
+ break;
+ case MISCREG_HSTICK_CMPR:
+ ccprintf(os, "%%hstick_cmpr");
+ break;
+ case MISCREG_HVER:
+ ccprintf(os, "%%hver");
+ break;
+ case MISCREG_STRAND_STS_REG:
+ ccprintf(os, "%%strand_sts_reg");
+ break;
+ case MISCREG_FSR:
+ ccprintf(os, "%%fsr");
+ break;
+ default:
+ ccprintf(os, "%%ctrl%d", reg_idx);
+ }
+ }
+}
+
+std::string
+SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+{
+ std::stringstream ss;
+
+ printMnemonic(ss, mnemonic);
+
+ // just print the first two source regs... if there's
+ // a third one, it's a read-modify-write dest (Rc),
+ // e.g. for CMOVxx
+ if (_numSrcRegs > 0)
+ printReg(ss, _srcRegIdx[0]);
+ if (_numSrcRegs > 1) {
+ ss << ",";
+ printReg(ss, _srcRegIdx[1]);
+ }
+
+ // just print the first dest... if there's a second one,
+ // it's generally implicit
+ if (_numDestRegs > 0) {
+ if (_numSrcRegs > 0)
+ ss << ",";
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ return ss.str();
+}
+
+bool
+SparcStaticInst::passesFpCondition(uint32_t fcc, uint32_t condition)
+{
+ bool u = (fcc == 3);
+ bool g = (fcc == 2);
+ bool l = (fcc == 1);
+ bool e = (fcc == 0);
+
+ switch (condition) {
+ case FAlways:
+ return 1;
+ case FNever:
+ return 0;
+ case FUnordered:
+ return u;
+ case FGreater:
+ return g;
+ case FUnorderedOrGreater:
+ return u || g;
+ case FLess:
+ return l;
+ case FUnorderedOrLess:
+ return u || l;
+ case FLessOrGreater:
+ return l || g;
+ case FNotEqual:
+ return l || g || u;
+ case FEqual:
+ return e;
+ case FUnorderedOrEqual:
+ return u || e;
+ case FGreaterOrEqual:
+ return g || e;
+ case FUnorderedOrGreaterOrEqual:
+ return u || g || e;
+ case FLessOrEqual:
+ return l || e;
+ case FUnorderedOrLessOrEqual:
+ return u || l || e;
+ case FOrdered:
+ return e || l || g;
+ }
+ panic("Tried testing condition nonexistant condition code %d", condition);
+}
+
+bool
+SparcStaticInst::passesCondition(uint32_t codes, uint32_t condition)
+{
+ BitUnion32(CondCodes)
+ Bitfield<0> c;
+ Bitfield<1> v;
+ Bitfield<2> z;
+ Bitfield<3> n;
+ EndBitUnion(CondCodes)
+ CondCodes condCodes = codes;
+
+ switch (condition) {
+ case Always:
+ return true;
+ case Never:
+ return false;
+ case NotEqual:
+ return !condCodes.z;
+ case Equal:
+ return condCodes.z;
+ case Greater:
+ return !(condCodes.z | (condCodes.n ^ condCodes.v));
+ case LessOrEqual:
+ return condCodes.z | (condCodes.n ^ condCodes.v);
+ case GreaterOrEqual:
+ return !(condCodes.n ^ condCodes.v);
+ case Less:
+ return (condCodes.n ^ condCodes.v);
+ case GreaterUnsigned:
+ return !(condCodes.c | condCodes.z);
+ case LessOrEqualUnsigned:
+ return (condCodes.c | condCodes.z);
+ case CarryClear:
+ return !condCodes.c;
+ case CarrySet:
+ return condCodes.c;
+ case Positive:
+ return !condCodes.n;
+ case Negative:
+ return condCodes.n;
+ case OverflowClear:
+ return !condCodes.v;
+ case OverflowSet:
+ return condCodes.v;
+ }
+ panic("Tried testing condition nonexistant "
+ "condition code %d", condition);
+}
+
+}
diff --git a/src/arch/sparc/insts/static_inst.hh b/src/arch/sparc/insts/static_inst.hh
new file mode 100644
index 000000000..cc5a60225
--- /dev/null
+++ b/src/arch/sparc/insts/static_inst.hh
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2006-2007 The Regents of The University of Michigan
+ * All rights reserved.
+ * Copyright 2017 Google Inc.
+ *
+ * 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_INSTS_STATIC_INST_HH__
+#define __ARCH_SPARC_INSTS_STATIC_INST_HH__
+
+#include <cstdint>
+
+#include "base/trace.hh"
+#include "cpu/exec_context.hh"
+#include "cpu/static_inst.hh"
+
+namespace SparcISA
+{
+
+enum CondTest
+{
+ Always=0x8,
+ Never=0x0,
+ NotEqual=0x9,
+ Equal=0x1,
+ Greater=0xA,
+ LessOrEqual=0x2,
+ GreaterOrEqual=0xB,
+ Less=0x3,
+ GreaterUnsigned=0xC,
+ LessOrEqualUnsigned=0x4,
+ CarryClear=0xD,
+ CarrySet=0x5,
+ Positive=0xE,
+ Negative=0x6,
+ OverflowClear=0xF,
+ OverflowSet=0x7
+};
+
+extern const char *CondTestAbbrev[];
+
+enum FpCondTest
+{
+ FAlways=0x8,
+ FNever=0x0,
+ FUnordered=0x7,
+ FGreater=0x6,
+ FUnorderedOrGreater=0x5,
+ FLess=0x4,
+ FUnorderedOrLess=0x3,
+ FLessOrGreater=0x2,
+ FNotEqual=0x1,
+ FEqual=0x9,
+ FUnorderedOrEqual=0xA,
+ FGreaterOrEqual=0xB,
+ FUnorderedOrGreaterOrEqual=0xC,
+ FLessOrEqual=0xD,
+ FUnorderedOrLessOrEqual=0xE,
+ FOrdered=0xF
+};
+
+/**
+ * Base class for all SPARC static instructions.
+ */
+class SparcStaticInst : public StaticInst
+{
+ protected:
+ using StaticInst::StaticInst;
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ static void printMnemonic(std::ostream &os, const char *mnemonic);
+ static void printReg(std::ostream &os, RegId reg);
+
+ void printSrcReg(std::ostream &os, int reg) const;
+ void printDestReg(std::ostream &os, int reg) const;
+
+ void printRegArray(std::ostream &os,
+ const RegId indexArray[], int num) const;
+
+ void advancePC(PCState &pcState) const;
+
+ static bool passesFpCondition(uint32_t fcc, uint32_t condition);
+ static bool passesCondition(uint32_t codes, uint32_t condition);
+};
+
+}
+
+#endif //__ARCH_SPARC_INSTS_STATIC_INST_HH__
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index 5d54d0ea9..8bcac0b05 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -28,128 +28,6 @@
// Gabe Black
// Steve Reinhardt
-////////////////////////////////////////////////////////////////////
-//
-// Base class for sparc instructions, and some support functions
-//
-
-output header {{
-
- union CondCodes
- {
- struct
- {
- uint8_t c:1;
- uint8_t v:1;
- uint8_t z:1;
- uint8_t n:1;
- };
- uint32_t bits;
- };
-
- enum CondTest
- {
- Always=0x8,
- Never=0x0,
- NotEqual=0x9,
- Equal=0x1,
- Greater=0xA,
- LessOrEqual=0x2,
- GreaterOrEqual=0xB,
- Less=0x3,
- GreaterUnsigned=0xC,
- LessOrEqualUnsigned=0x4,
- CarryClear=0xD,
- CarrySet=0x5,
- Positive=0xE,
- Negative=0x6,
- OverflowClear=0xF,
- OverflowSet=0x7
- };
-
- enum FpCondTest
- {
- FAlways=0x8,
- FNever=0x0,
- FUnordered=0x7,
- FGreater=0x6,
- FUnorderedOrGreater=0x5,
- FLess=0x4,
- FUnorderedOrLess=0x3,
- FLessOrGreater=0x2,
- FNotEqual=0x1,
- FEqual=0x9,
- FUnorderedOrEqual=0xA,
- FGreaterOrEqual=0xB,
- FUnorderedOrGreaterOrEqual=0xC,
- FLessOrEqual=0xD,
- FUnorderedOrLessOrEqual=0xE,
- FOrdered=0xF
- };
-
- extern const char *CondTestAbbrev[];
-
- /**
- * Base class for all SPARC static instructions.
- */
- class SparcStaticInst : public StaticInst
- {
- protected:
- // Constructor.
- SparcStaticInst(const char *mnem,
- ExtMachInst _machInst, OpClass __opClass)
- : StaticInst(mnem, _machInst, __opClass)
- {
- }
-
- std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
-
- void printReg(std::ostream &os, RegId reg) const;
- void printSrcReg(std::ostream &os, int reg) const;
- void printDestReg(std::ostream &os, int reg) const;
-
- void printRegArray(std::ostream &os,
- const RegId indexArray[], int num) const;
-
- void advancePC(SparcISA::PCState &pcState) const;
- };
-
- bool passesFpCondition(uint32_t fcc, uint32_t condition);
-
- bool passesCondition(uint32_t codes, uint32_t condition);
-
- inline int64_t
- sign_ext(uint64_t data, int origWidth)
- {
- int shiftAmount = 64 - origWidth;
- return (((int64_t)data) << shiftAmount) >> shiftAmount;
- }
-}};
-
-output decoder {{
-
- const char *CondTestAbbrev[] =
- {
- "nev", // Never
- "e", // Equal
- "le", // Less or Equal
- "l", // Less
- "leu", // Less or Equal Unsigned
- "c", // Carry set
- "n", // Negative
- "o", // Overflow set
- "a", // Always
- "ne", // Not Equal
- "g", // Greater
- "ge", // Greater or Equal
- "gu", // Greater Unsigned
- "cc", // Carry clear
- "p", // Positive
- "oc" // Overflow Clear
- };
-}};
-
def template ROrImmDecode {{
{
return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
@@ -243,322 +121,6 @@ let {{
return (True, code, imm_code, rString, iString)
}};
-output decoder {{
-
- inline void printMnemonic(std::ostream &os, const char * mnemonic)
- {
- ccprintf(os, "\t%s ", mnemonic);
- }
-
- void SparcStaticInst::printRegArray(std::ostream &os,
- const RegId 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::advancePC(SparcISA::PCState &pcState) const
- {
- pcState.advance();
- }
-
- 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, RegId reg) const
- {
- const int MaxGlobal = 8;
- const int MaxOutput = 16;
- const int MaxLocal = 24;
- const int MaxInput = 32;
- const int MaxMicroReg = 40;
- RegIndex reg_idx = reg.index();
- if (reg.isIntReg()) {
- // If we used a register from the next or previous window,
- // take out the offset.
- while (reg_idx >= MaxMicroReg)
- reg_idx -= MaxMicroReg;
- if (reg_idx == FramePointerReg)
- ccprintf(os, "%%fp");
- else if (reg_idx == StackPointerReg)
- ccprintf(os, "%%sp");
- else if (reg_idx < MaxGlobal)
- ccprintf(os, "%%g%d", reg_idx);
- else if (reg_idx < MaxOutput)
- ccprintf(os, "%%o%d", reg_idx - MaxGlobal);
- else if (reg_idx < MaxLocal)
- ccprintf(os, "%%l%d", reg_idx - MaxOutput);
- else if (reg_idx < MaxInput)
- ccprintf(os, "%%i%d", reg_idx - MaxLocal);
- else if (reg_idx < MaxMicroReg)
- ccprintf(os, "%%u%d", reg_idx - MaxInput);
- // The fake int regs that are really control regs
- else {
- switch (reg_idx - MaxMicroReg) {
- case 1:
- ccprintf(os, "%%y");
- break;
- case 2:
- ccprintf(os, "%%ccr");
- break;
- case 3:
- ccprintf(os, "%%cansave");
- break;
- case 4:
- ccprintf(os, "%%canrestore");
- break;
- case 5:
- ccprintf(os, "%%cleanwin");
- break;
- case 6:
- ccprintf(os, "%%otherwin");
- break;
- case 7:
- ccprintf(os, "%%wstate");
- break;
- }
- }
- } else if (reg.isFloatReg()) {
- ccprintf(os, "%%f%d", reg_idx);
- } else {
- switch (reg_idx) {
- case MISCREG_ASI:
- ccprintf(os, "%%asi");
- break;
- case MISCREG_FPRS:
- ccprintf(os, "%%fprs");
- break;
- case MISCREG_PCR:
- ccprintf(os, "%%pcr");
- break;
- case MISCREG_PIC:
- ccprintf(os, "%%pic");
- break;
- case MISCREG_GSR:
- ccprintf(os, "%%gsr");
- break;
- case MISCREG_SOFTINT:
- ccprintf(os, "%%softint");
- break;
- case MISCREG_SOFTINT_SET:
- ccprintf(os, "%%softint_set");
- break;
- case MISCREG_SOFTINT_CLR:
- ccprintf(os, "%%softint_clr");
- break;
- case MISCREG_TICK_CMPR:
- ccprintf(os, "%%tick_cmpr");
- break;
- case MISCREG_STICK:
- ccprintf(os, "%%stick");
- break;
- case MISCREG_STICK_CMPR:
- ccprintf(os, "%%stick_cmpr");
- break;
- case MISCREG_TPC:
- ccprintf(os, "%%tpc");
- break;
- case MISCREG_TNPC:
- ccprintf(os, "%%tnpc");
- break;
- case MISCREG_TSTATE:
- ccprintf(os, "%%tstate");
- break;
- case MISCREG_TT:
- ccprintf(os, "%%tt");
- break;
- case MISCREG_TICK:
- ccprintf(os, "%%tick");
- break;
- case MISCREG_TBA:
- ccprintf(os, "%%tba");
- break;
- case MISCREG_PSTATE:
- ccprintf(os, "%%pstate");
- break;
- case MISCREG_TL:
- ccprintf(os, "%%tl");
- break;
- case MISCREG_PIL:
- ccprintf(os, "%%pil");
- break;
- case MISCREG_CWP:
- ccprintf(os, "%%cwp");
- break;
- case MISCREG_GL:
- ccprintf(os, "%%gl");
- break;
- case MISCREG_HPSTATE:
- ccprintf(os, "%%hpstate");
- break;
- case MISCREG_HTSTATE:
- ccprintf(os, "%%htstate");
- break;
- case MISCREG_HINTP:
- ccprintf(os, "%%hintp");
- break;
- case MISCREG_HTBA:
- ccprintf(os, "%%htba");
- break;
- case MISCREG_HSTICK_CMPR:
- ccprintf(os, "%%hstick_cmpr");
- break;
- case MISCREG_HVER:
- ccprintf(os, "%%hver");
- break;
- case MISCREG_STRAND_STS_REG:
- ccprintf(os, "%%strand_sts_reg");
- break;
- case MISCREG_FSR:
- ccprintf(os, "%%fsr");
- break;
- default:
- ccprintf(os, "%%ctrl%d", reg_idx);
- }
- }
- }
-
- std::string
- SparcStaticInst::generateDisassembly(Addr pc,
- const SymbolTable *symtab) const
- {
- std::stringstream ss;
-
- printMnemonic(ss, mnemonic);
-
- // just print the first two source regs... if there's
- // a third one, it's a read-modify-write dest (Rc),
- // e.g. for CMOVxx
- if (_numSrcRegs > 0)
- printReg(ss, _srcRegIdx[0]);
- if (_numSrcRegs > 1) {
- ss << ",";
- printReg(ss, _srcRegIdx[1]);
- }
-
- // just print the first dest... if there's a second one,
- // it's generally implicit
- if (_numDestRegs > 0) {
- if (_numSrcRegs > 0)
- ss << ",";
- printReg(ss, _destRegIdx[0]);
- }
-
- return ss.str();
- }
-
- bool
- passesFpCondition(uint32_t fcc, uint32_t condition)
- {
- bool u = (fcc == 3);
- bool g = (fcc == 2);
- bool l = (fcc == 1);
- bool e = (fcc == 0);
- switch (condition) {
- case FAlways:
- return 1;
- case FNever:
- return 0;
- case FUnordered:
- return u;
- case FGreater:
- return g;
- case FUnorderedOrGreater:
- return u || g;
- case FLess:
- return l;
- case FUnorderedOrLess:
- return u || l;
- case FLessOrGreater:
- return l || g;
- case FNotEqual:
- return l || g || u;
- case FEqual:
- return e;
- case FUnorderedOrEqual:
- return u || e;
- case FGreaterOrEqual:
- return g || e;
- case FUnorderedOrGreaterOrEqual:
- return u || g || e;
- case FLessOrEqual:
- return l || e;
- case FUnorderedOrLessOrEqual:
- return u || l || e;
- case FOrdered:
- return e || l || g;
- }
- panic("Tried testing condition nonexistant "
- "condition code %d", condition);
- }
-
- bool
- passesCondition(uint32_t codes, uint32_t condition)
- {
- CondCodes condCodes;
- condCodes.bits = 0;
- condCodes.c = codes & 0x1 ? 1 : 0;
- condCodes.v = codes & 0x2 ? 1 : 0;
- condCodes.z = codes & 0x4 ? 1 : 0;
- condCodes.n = codes & 0x8 ? 1 : 0;
-
- switch (condition) {
- case Always:
- return true;
- case Never:
- return false;
- case NotEqual:
- return !condCodes.z;
- case Equal:
- return condCodes.z;
- case Greater:
- return !(condCodes.z | (condCodes.n ^ condCodes.v));
- case LessOrEqual:
- return condCodes.z | (condCodes.n ^ condCodes.v);
- case GreaterOrEqual:
- return !(condCodes.n ^ condCodes.v);
- case Less:
- return (condCodes.n ^ condCodes.v);
- case GreaterUnsigned:
- return !(condCodes.c | condCodes.z);
- case LessOrEqualUnsigned:
- return (condCodes.c | condCodes.z);
- case CarryClear:
- return !condCodes.c;
- case CarrySet:
- return condCodes.c;
- case Positive:
- return !condCodes.n;
- case Negative:
- return condCodes.n;
- case OverflowClear:
- return !condCodes.v;
- case OverflowSet:
- return condCodes.v;
- }
- panic("Tried testing condition nonexistant "
- "condition code %d", condition);
- }
-}};
-
output exec {{
/// Check "FP enabled" machine status bit. Called when executing any FP
/// instruction.
@@ -578,6 +140,7 @@ output exec {{
return NoFault;
}
}
+
static inline Fault
checkVecEnableFault(ExecContext *xc)
{
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 63f3e4a6c..a6b15388d 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -30,121 +30,119 @@
// Basic instruction class declaration template.
def template BasicDeclare {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- // Constructor.
- %(class_name)s(ExtMachInst machInst);
- Fault execute(ExecContext *, Trace::InstRecord *) const;
- };
+/**
+ * Static instruction class for "%(mnemonic)s".
+ */
+class %(class_name)s : public %(base_class)s
+{
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+};
}};
// Basic instruction class declaration template.
def template FpBasicDeclare {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- // Constructor.
- %(class_name)s(ExtMachInst machInst);
- Fault execute(ExecContext *, Trace::InstRecord *) const;
- Fault doFpOp(ExecContext *,
- Trace::InstRecord *) const M5_NO_INLINE;
- };
+/**
+ * Static instruction class for "%(mnemonic)s".
+ */
+class %(class_name)s : public %(base_class)s
+{
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+ Fault doFpOp(ExecContext *, Trace::InstRecord *) const M5_NO_INLINE;
+};
}};
// Basic instruction class declaration template.
def template BasicDeclareWithMnemonic {{
- /**
- * Static instruction class for "%(mnemonic)s".
- */
- class %(class_name)s : public %(base_class)s
- {
- public:
- // Constructor.
- %(class_name)s(const char * mnemonic, ExtMachInst machInst);
- Fault execute(ExecContext *, Trace::InstRecord *) const;
- };
+/**
+ * Static instruction class for "%(mnemonic)s".
+ */
+class %(class_name)s : public %(base_class)s
+{
+ public:
+ // Constructor.
+ %(class_name)s(const char *mnemonic, ExtMachInst machInst);
+ Fault execute(ExecContext *, Trace::InstRecord *) const;
+};
}};
// Basic instruction class constructor template.
def template BasicConstructor {{
- %(class_name)s::%(class_name)s(ExtMachInst machInst)
- : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
- {
- %(constructor)s;
- }
+%(class_name)s::%(class_name)s(ExtMachInst machInst) :
+ %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
+{
+ %(constructor)s;
+}
}};
// Basic instruction class constructor template.
def template BasicConstructorWithMnemonic {{
- %(class_name)s::%(class_name)s(const char * mnemonic,
- ExtMachInst machInst)
- : %(base_class)s(mnemonic, machInst, %(op_class)s)
- {
- %(constructor)s;
- }
+%(class_name)s::%(class_name)s(const char *mnemonic, ExtMachInst machInst) :
+ %(base_class)s(mnemonic, machInst, %(op_class)s)
+{
+ %(constructor)s;
+}
}};
// Basic instruction class execute method template.
def template BasicExecute {{
- Fault
- %(class_name)s::execute(ExecContext *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
+Fault
+%(class_name)s::execute(ExecContext *xc,
+ Trace::InstRecord *traceData) const
+{
+ Fault fault = NoFault;
- %(fp_enable_check)s;
- %(op_decl)s;
- %(op_rd)s;
- %(code)s;
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
- if (fault == NoFault) {
- %(op_wb)s;
- }
- return fault;
- }
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ return fault;
+}
}};
def template DoFpOpExecute {{
- Fault
- %(class_name)s::doFpOp(ExecContext *xc,
- Trace::InstRecord *traceData) const
- {
- Fault fault = NoFault;
- %(op_decl)s;
- %(op_rd)s;
- %(fp_code)s;
- if (fault == NoFault) {
- %(op_wb)s;
- }
- return fault;
- }
+Fault
+%(class_name)s::doFpOp(ExecContext *xc, Trace::InstRecord *traceData) const
+{
+ Fault fault = NoFault;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(fp_code)s;
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+ return fault;
+}
}};
// Basic decode template.
def template BasicDecode {{
- return new %(class_name)s(machInst);
+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);
+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) {{
- code = filterDoubles(code)
- iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecode.subst(iop)
- exec_output = BasicExecute.subst(iop)
+ code = filterDoubles(code)
+ iop = InstObjParams(name, Name, 'SparcStaticInst', code, flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+
}};
def format FpBasic(code, *flags) {{
@@ -168,7 +166,7 @@ def format FpBasic(code, *flags) {{
"""
fp_code = filterDoubles(code)
iop = InstObjParams(name, Name, 'SparcStaticInst',
- { "code" : exec_code, "fp_code" : fp_code }, flags)
+ { "code" : exec_code, "fp_code" : fp_code }, flags)
header_output = FpBasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index 79c90a50e..4b745f4c0 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -39,6 +39,7 @@ output header {{
#include <sstream>
#include "arch/sparc/faults.hh"
+#include "arch/sparc/insts/static_inst.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/registers.hh"
#include "base/condcodes.hh"