sparc: Pull StaticInst base classes out of the ISA description.
authorGabe Black <gabeblack@google.com>
Sun, 5 Nov 2017 23:41:59 +0000 (15:41 -0800)
committerGabe Black <gabeblack@google.com>
Mon, 20 Nov 2017 07:49:48 +0000 (07:49 +0000)
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>

src/arch/sparc/insts/SConscript [new file with mode: 0644]
src/arch/sparc/insts/static_inst.cc [new file with mode: 0644]
src/arch/sparc/insts/static_inst.hh [new file with mode: 0644]
src/arch/sparc/isa/base.isa
src/arch/sparc/isa/formats/basic.isa
src/arch/sparc/isa/includes.isa

diff --git a/src/arch/sparc/insts/SConscript b/src/arch/sparc/insts/SConscript
new file mode 100644 (file)
index 0000000..94996f6
--- /dev/null
@@ -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 (file)
index 0000000..a1f5e60
--- /dev/null
@@ -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 (file)
index 0000000..cc5a602
--- /dev/null
@@ -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__
index 5d54d0ea96888488ef272be8d61b53160f985b7d..8bcac0b0553b92f91b6220c01fdb0dd8826e012d 100644 (file)
 //          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)
     {
index 63f3e4a6c7dfc1e25ebd611b70bbbcdb94c35ead..a6b15388d38dcafc313515e9194ec40ecbfaf672 100644 (file)
 
 // 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)
index 79c90a50e85af872ad8d74da570c4c400838bc81..4b745f4c04b6323929ef794b19d0a1482270b3a1 100644 (file)
@@ -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"