Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/56470 )

Change subject: arch-x86: Move the macroop type into pure python.
......................................................................

arch-x86: Move the macroop type into pure python.

Also expose it to the microcode assembler directly by making it part of
the ucasmlib namespace package.

Change-Id: I86e5193a35fc770363e6dbc6e2386880af312a1f
---
M src/arch/x86/isa/macroop.isa
M src/arch/x86/isa/microasm.isa
M src/arch/x86/ucasmlib/arch/x86/__init__.py
A src/arch/x86/ucasmlib/arch/x86/macroop.py
4 files changed, 228 insertions(+), 198 deletions(-)



diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index bc5effc..8331d94 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -35,202 +35,6 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Basic instruction class declaration template.
-def template MacroDeclare {{
-    GEM5_DEPRECATED_NAMESPACE(X86Macroop, x86_macroop);
-    namespace x86_macroop
-    {
-        /**
-         * Static instruction class for "%(mnemonic)s".
-         */
-        class %(class_name)s : public %(base_class)s
-        {
-          private:
-            %(declareLabels)s
-          public:
-            // Constructor.
-            %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv _env);
-
-            std::string generateDisassembly(
- Addr pc, const loader::SymbolTable *symtab) const override;
-        };
-    }
-}};
-
-def template MacroDisassembly {{
-    std::string
-    x86_macroop::%(class_name)s::generateDisassembly(
-            Addr pc, const loader::SymbolTable *symtab) const
-    {
-        std::stringstream out;
-        out << mnemonic << "\t";
-
-        int regSize = %(regSize)s;
-        %(disassembly)s
-        // Shut up gcc.
-        regSize = regSize;
-        return out.str();
-    }
-}};
-
-// Basic instruction class constructor template.
-def template MacroConstructor {{
-        x86_macroop::%(class_name)s::%(class_name)s(
-                ExtMachInst machInst, EmulEnv _env)
- : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, _env)
-        {
-            %(adjust_env)s;
-            %(adjust_imm)s;
-            %(adjust_disp)s;
-            %(init_env)s;
-            %(constructor)s;
-            const char *macrocodeBlock = "%(class_name)s";
-            //alloc_microops is the code that sets up the microops
-            //array in the parent class.
-            %(alloc_microops)s;
-        }
-}};
-
-let {{
-    from ucasmlib.containers import Macroop
-    class X86Macroop(Macroop):
-        def setAdjustEnv(self, val):
-            self.adjust_env = val
-        def adjustImm(self, val):
-            self.adjust_imm += val
-        def adjustDisp(self, val):
-            self.adjust_disp += val
-        def serializeBefore(self):
-            self.serialize_before = True
-        def serializeAfter(self):
-            self.serialize_after = True
-
-        def function_call(self):
-            self.function_call = True
-        def function_return(self):
-            self.function_return = True
-        def control_direct(self):
-            self.control_direct = True
-        def control_indirect(self):
-            self.control_indirect = True
-
-        def __init__(self, name):
-            super().__init__(name)
-            self.directives = {
-                "adjust_env" : self.setAdjustEnv,
-                "adjust_imm" : self.adjustImm,
-                "adjust_disp" : self.adjustDisp,
-                "serialize_before" : self.serializeBefore,
-                "serialize_after" : self.serializeAfter,
-                "function_call" : self.function_call,
-                "function_return" : self.function_return,
-                "control_direct" : self.control_direct,
-                "control_indirect" : self.control_indirect
-            }
-            self.declared = False
-            self.adjust_env = ""
-            self.init_env = ""
-            self.adjust_imm = '''
-                uint64_t adjustedImm = IMMEDIATE;
-                //This is to pacify gcc in case the immediate isn't used.
-                adjustedImm = adjustedImm;
-            '''
-            self.adjust_disp = '''
-                uint64_t adjustedDisp = DISPLACEMENT;
- //This is to pacify gcc in case the displacement isn't used.
-                adjustedDisp = adjustedDisp;
-            '''
-            self.serialize_before = False
-            self.serialize_after = False
-            self.function_call = False
-            self.function_return = False
-            self.control_direct = False
-            self.control_indirect = False
-
-        def getAllocator(self, env):
-            return "new x86_macroop::%s(machInst, %s)" % \
-                    (self.name, env.getAllocator())
-        def getMnemonic(self):
-            mnemonic = self.name.lower()
-            mnemonic = re.match(r'[^_]*', mnemonic).group(0)
-            return mnemonic
-        def getDeclaration(self):
-            #FIXME This first parameter should be the mnemonic. I need to
-            #write some code which pulls that out
-            declareLabels = ""
-            for (label, micropc) in self.labels.items():
-                declareLabels += "const static uint64_t label_%s = %d;\n" \
-                                  % (label, micropc)
-            iop = InstObjParams(self.getMnemonic(), self.name,
-                    "X86ISA::MacroopBase",
-                    {"code" : "",
-                     "declareLabels" : declareLabels
-                    })
-            return MacroDeclare.subst(iop);
-        def getDefinition(self, env):
-            #FIXME This first parameter should be the mnemonic. I need to
-            #write some code which pulls that out
-            numMicroops = len(self.microops)
-            allocMicroops = ''
-            micropc = 0
-            for op in self.microops:
-                flags = ["IsMicroop"]
-                if micropc == 0:
-                    flags.append("IsFirstMicroop")
-
-                    if self.serialize_before:
-                        flags.append("IsSerializing")
-                        flags.append("IsSerializeBefore")
-
-                if micropc == numMicroops - 1:
-                    flags.append("IsLastMicroop")
-
-                    if self.serialize_after:
-                        flags.append("IsSerializing")
-                        flags.append("IsSerializeAfter")
-
-                    if self.function_call:
-                        flags.append("IsCall")
-                        flags.append("IsUncondControl")
-                    if self.function_return:
-                        flags.append("IsReturn")
-                        flags.append("IsUncondControl")
-                    if self.control_direct:
-                        flags.append("IsDirectControl")
-                    if self.control_indirect:
-                        flags.append("IsIndirectControl")
-                else:
-                    flags.append("IsDelayedCommit")
-
-                allocMicroops += \
-                    "microops[%d] = %s;\n" % \
-                    (micropc, op.getAllocator(flags))
-                micropc += 1
-            if env.useStackSize:
-                useStackSize = "true"
-            else:
-                useStackSize = "false"
-            if env.memoryInst:
-                memoryInst = "true"
-            else:
-                memoryInst = "false"
-            regSize = '''(%s || (env.base == INTREG_RSP && %s) ?
-                         env.stackSize :
-                         env.dataSize)''' % (useStackSize, memoryInst)
-            iop = InstObjParams(self.getMnemonic(), self.name,
-                                "X86ISA::MacroopBase",
-                                {"code" : "", "num_microops" : numMicroops,
-                                 "alloc_microops" : allocMicroops,
-                                 "adjust_env" : self.adjust_env,
-                                 "adjust_imm" : self.adjust_imm,
-                                 "adjust_disp" : self.adjust_disp,
-                                 "disassembly" : env.disassembly,
-                                 "regSize" : regSize,
-                                 "init_env" : self.initEnv})
-            return MacroConstructor.subst(iop) + \
-                   MacroDisassembly.subst(iop);
-}};
-
 let {{
     class EmulEnv(object):
         def __init__(self):
diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa
index 5293410..cb16e4a 100644
--- a/src/arch/x86/isa/microasm.isa
+++ b/src/arch/x86/isa/microasm.isa
@@ -52,11 +52,11 @@
     from insts import microcode
     sys.path[0:0] = ["src/arch/x86/"]
     from ucasmlib.assembler import MicroAssembler
-    from ucasmlib.arch.x86 import Rom
+    from ucasmlib.arch.x86 import Rom, Macroop
     sys.path = old_path

     mainRom = Rom('main ROM')
-    assembler = MicroAssembler(X86Macroop, microopClasses, mainRom)
+    assembler = MicroAssembler(Macroop, microopClasses, mainRom)

     def gpRegIdx(idx):
         return "X86ISA::GpRegIndex(%s)" % idx
diff --git a/src/arch/x86/ucasmlib/arch/x86/__init__.py b/src/arch/x86/ucasmlib/arch/x86/__init__.py
index 6a1bdd7..d4cb77c 100644
--- a/src/arch/x86/ucasmlib/arch/x86/__init__.py
+++ b/src/arch/x86/ucasmlib/arch/x86/__init__.py
@@ -24,3 +24,4 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 from .rom import Rom
+from .macroop import Macroop
diff --git a/src/arch/x86/ucasmlib/arch/x86/macroop.py b/src/arch/x86/ucasmlib/arch/x86/macroop.py
new file mode 100644
index 0000000..249d47e
--- /dev/null
+++ b/src/arch/x86/ucasmlib/arch/x86/macroop.py
@@ -0,0 +1,213 @@
+# Copyright (c) 2007 The Hewlett-Packard Development Company
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder.  You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# 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.
+
+import re
+
+# Basic instruction class declaration template.
+MacroDeclare = """
+    GEM5_DEPRECATED_NAMESPACE(X86Macroop, x86_macroop);
+    namespace x86_macroop
+    {{
+        /**
+         * Static instruction class for "{mnemonic}".
+         */
+        class {class_name} : public X86ISA::MacroopBase
+        {{
+          private:
+            {declare_labels}
+          public:
+            // Constructor.
+            {class_name}(ExtMachInst machInst, X86ISA::EmulEnv _env);
+
+            std::string generateDisassembly(
+ Addr pc, const loader::SymbolTable *symtab) const override;
+        }};
+    }}
+"""
+
+MacroDisassembly = """
+    std::string
+    x86_macroop::{class_name}::generateDisassembly(
+            Addr pc, const loader::SymbolTable *symtab) const
+    {{
+        std::stringstream out;
+        out << mnemonic << "\\t";
+
+        [[maybe_unused]] int regSize = {reg_size};
+        {disassembly}
+        return out.str();
+    }}
+"""
+
+# Basic instruction class constructor template.
+MacroConstructor = """
+    x86_macroop::{class_name}::{class_name}(
+            ExtMachInst machInst, EmulEnv _env) :
+        X86ISA::MacroopBase("{mnemonic}", machInst, {num_microops}, _env)
+    {{
+        {adjust_env};
+        {adjust_imm};
+        {adjust_disp};
+        {init_env};
+        const char *macrocodeBlock = "{class_name}";
+        //alloc_microops is the code that sets up the microops
+        //array in the parent class.
+        {alloc_microops};
+    }}
+"""
+
+from ucasmlib.containers import Macroop
+class Macroop(Macroop):
+    def setAdjustEnv(self, val):
+        self.adjust_env = val
+    def adjustImm(self, val):
+        self.adjust_imm += val
+    def adjustDisp(self, val):
+        self.adjust_disp += val
+    def serializeBefore(self):
+        self.serialize_before = True
+    def serializeAfter(self):
+        self.serialize_after = True
+
+    def function_call(self):
+        self.function_call = True
+    def function_return(self):
+        self.function_return = True
+    def control_direct(self):
+        self.control_direct = True
+    def control_indirect(self):
+        self.control_indirect = True
+
+    def __init__(self, name):
+        super().__init__(name)
+        self.directives = {
+            "adjust_env" : self.setAdjustEnv,
+            "adjust_imm" : self.adjustImm,
+            "adjust_disp" : self.adjustDisp,
+            "serialize_before" : self.serializeBefore,
+            "serialize_after" : self.serializeAfter,
+            "function_call" : self.function_call,
+            "function_return" : self.function_return,
+            "control_direct" : self.control_direct,
+            "control_indirect" : self.control_indirect
+        }
+        self.declared = False
+        self.adjust_env = ""
+        self.init_env = ""
+ self.adjust_imm = '[[maybe_unused]] uint64_t adjustedImm = IMMEDIATE;'
+        self.adjust_disp = \
+                '[[maybe_unused]] uint64_t adjustedDisp = DISPLACEMENT;'
+        self.serialize_before = False
+        self.serialize_after = False
+        self.function_call = False
+        self.function_return = False
+        self.control_direct = False
+        self.control_indirect = False
+
+    def getAllocator(self, env):
+ return f"new x86_macroop::{self.name}(machInst, {env.getAllocator()})"
+    def getMnemonic(self):
+        return  re.split(r'_', self.name)[0].lower()
+    def getDeclaration(self):
+        declare_labels = '\n'.join(
+                f"const static uint64_t label_{label} = {micropc};" for
+                (label, micropc) in self.labels.items())
+        return MacroDeclare.format(
+            class_name = self.name,
+            mnemonic = self.getMnemonic(),
+            declare_labels = declare_labels
+        )
+    def getDefinition(self, env):
+        num_microops = len(self.microops)
+        alloc_microops = ''
+        micropc = 0
+        for op in self.microops:
+            flags = ["IsMicroop"]
+            if micropc == 0:
+                flags.append("IsFirstMicroop")
+
+                if self.serialize_before:
+                    flags.append("IsSerializing")
+                    flags.append("IsSerializeBefore")
+
+            if micropc == num_microops - 1:
+                flags.append("IsLastMicroop")
+
+                if self.serialize_after:
+                    flags.append("IsSerializing")
+                    flags.append("IsSerializeAfter")
+
+                if self.function_call:
+                    flags.append("IsCall")
+                    flags.append("IsUncondControl")
+                if self.function_return:
+                    flags.append("IsReturn")
+                    flags.append("IsUncondControl")
+                if self.control_direct:
+                    flags.append("IsDirectControl")
+                if self.control_indirect:
+                    flags.append("IsIndirectControl")
+            else:
+                flags.append("IsDelayedCommit")
+
+            alloc_microops += \
+                    f"microops[{micropc}] = {op.getAllocator(flags)};\n"
+            micropc += 1
+        if env.useStackSize:
+            use_stack_size = "true"
+        else:
+            use_stack_size = "false"
+        if env.memoryInst:
+            memory_inst = "true"
+        else:
+            memory_inst = "false"
+        reg_size = f'''({use_stack_size} ||
+                        (env.base == INTREG_RSP && {memory_inst}) ?
+                      env.stackSize : env.dataSize)'''
+
+        subst = {
+            'class_name': self.name,
+            'mnemonic': self.getMnemonic(),
+            'num_microops' : num_microops,
+            'alloc_microops' : alloc_microops,
+            'adjust_env' : self.adjust_env,
+            'adjust_imm' : self.adjust_imm,
+            'adjust_disp' : self.adjust_disp,
+            'disassembly' : env.disassembly,
+            'reg_size' : reg_size,
+            'init_env' : self.initEnv
+        }
+        return MacroConstructor.format(**subst) + \
+                MacroDisassembly.format(**subst)

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/56470
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I86e5193a35fc770363e6dbc6e2386880af312a1f
Gerrit-Change-Number: 56470
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to