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

Change subject: arch-x86: Refactor fp uops to separate out C++ generation.
......................................................................

arch-x86: Refactor fp uops to separate out C++ generation.

With the C++ generation handled separately, it can be done at a
different time and in a different body of code from where the microops
themselves are defined. One can stay in the ISA description, while the
other moves to the microcode asm library.

Change-Id: I468d78b82e689c92d07a92abd0c26f44da0c9e2f
---
M src/arch/x86/isa/microops/fpop.isa
M src/arch/x86/ucasmlib/arch/x86/microops.py
2 files changed, 92 insertions(+), 87 deletions(-)



diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa
index 6fda08c..f73f181 100644
--- a/src/arch/x86/isa/microops/fpop.isa
+++ b/src/arch/x86/isa/microops/fpop.isa
@@ -100,100 +100,21 @@
 }};

 let {{
-
-    # Make these empty strings so that concatenating onto
-    # them will always work.
-    header_output = ""
-    decoder_output = ""
-    exec_output = ""
+    microopClasses.fpops = []

     class FpOpMeta(type):
-        def buildCppClasses(self, name, Name, suffix, code, flag_code,
-                cond_check, else_code, op_class, operand_types):
-
-            # Globals to stick the output in
-            global header_output
-            global decoder_output
-            global exec_output
-
-            # Stick all the code together so it can be searched at once
-            allCode = "|".join((code, flag_code, cond_check, else_code))
-
-            # If there's something optional to do with flags, generate
-            # a version without it and fix up this version to use it.
-            if flag_code != "" or cond_check != "true":
-                self.buildCppClasses(name, Name, suffix,
- code, "", "true", else_code, op_class, operand_types)
-                suffix = "Flags" + suffix
-
-            base = "X86ISA::InstOperands<" + \
-                ", ".join(["X86ISA::FpOp"] +
-                          [op.cxx_class() for op in operand_types]) + ">"
-
-            # Get everything ready for the substitution
-            iop_tag = InstObjParams(name, Name + suffix + "TopTag", base,
-                    {"code" : code,
-                     "flag_code" : flag_code,
-                     "cond_check" : cond_check,
-                     "else_code" : else_code,
-                     "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);",
-                     "top_code" : "TOP = (TOP + spm + 8) % 8;",
-                     "op_class" : op_class})
-            iop_top = InstObjParams(name, Name + suffix + "Top", base,
-                    {"code" : code,
-                     "flag_code" : flag_code,
-                     "cond_check" : cond_check,
-                     "else_code" : else_code,
-                     "tag_code" : ";",
-                     "top_code" : "TOP = (TOP + spm + 8) % 8;",
-                     "op_class" : op_class})
-            iop = InstObjParams(name, Name + suffix, base,
-                    {"code" : code,
-                     "flag_code" : flag_code,
-                     "cond_check" : cond_check,
-                     "else_code" : else_code,
-                     "tag_code" : ";",
-                     "top_code" : ";",
-                     "op_class" : op_class})
-
-            # Generate the actual code (finally!)
-            header_output += MicroFpOpDeclare.subst(iop_tag)
-            decoder_output += MicroFpOpConstructor.subst(iop_tag)
-            exec_output += MicroFpOpExecute.subst(iop_tag)
-            header_output += MicroFpOpDeclare.subst(iop_top)
-            decoder_output += MicroFpOpConstructor.subst(iop_top)
-            exec_output += MicroFpOpExecute.subst(iop_top)
-            header_output += MicroFpOpDeclare.subst(iop)
-            decoder_output += MicroFpOpConstructor.subst(iop)
-            exec_output += MicroFpOpExecute.subst(iop)
-
-
         def __new__(mcls, Name, bases, dict):
-            abstract = False
-            name = Name.lower()
-            if "abstract" in dict:
-                abstract = dict['abstract']
-                del dict['abstract']
+            dict.setdefault('abstract', False)
+            dict['className'] = Name
+            dict['mnemonic'] = Name.lower()

             cls = super().__new__(mcls, Name, bases, dict)
-            if not abstract:
-                cls.className = Name
-                cls.mnemonic = name
-                code = cls.code
-                flag_code = cls.flag_code
-                cond_check = cls.cond_check
-                else_code = cls.else_code
-                op_class = cls.op_class
-                operand_types = cls.operand_types

-                # Set up the C++ classes
-                mcls.buildCppClasses(cls, name, Name, "",
-                        code, flag_code, cond_check, else_code, op_class,
-                        operand_types)
-
+            if not cls.abstract:
                 # Hook into the microassembler dict
                 global microopClasses
-                microopClasses[name] = cls
+                microopClasses[cls.mnemonic] = cls
+                microopClasses.fpops.append(cls)

             return cls

@@ -430,4 +351,72 @@
     class Pop87(Fp0Op):
         code = ''
         op_class = 'IntAluOp'
+
+    def buildCppClasses(cls, suffix="", flag_code=None, cond_check=None):
+
+        if flag_code is None:
+            flag_code = cls.flag_code
+        if cond_check is None:
+            cond_check = cls.cond_check
+
+        # Stick all the code together so it can be searched at once
+ allCode = "|".join((cls.code, flag_code, cond_check, cls.else_code))
+
+        # If there's something optional to do with flags, generate
+        # a version without it and fix up this version to use it.
+        if flag_code != "" or cond_check != "true":
+            buildCppClasses(cls, suffix, "", "true")
+            suffix = "Flags" + suffix
+
+        base = "X86ISA::InstOperands<" + \
+            ", ".join(["X86ISA::FpOp"] +
+                      [op.cxx_class() for op in cls.operand_types]) + ">"
+
+        # Get everything ready for the substitution
+        iop_tag = InstObjParams(cls.mnemonic,
+                cls.className + suffix + "TopTag", base,
+                {"code" : cls.code,
+                 "flag_code" : flag_code,
+                 "cond_check" : cond_check,
+                 "else_code" : cls.else_code,
+                 "tag_code" : "FTW = genX87Tags(FTW, TOP, spm);",
+                 "top_code" : "TOP = (TOP + spm + 8) % 8;",
+                 "op_class" : cls.op_class})
+        iop_top = InstObjParams(cls.mnemonic,
+                cls.className + suffix + "Top", base,
+                {"code" : cls.code,
+                 "flag_code" : flag_code,
+                 "cond_check" : cond_check,
+                 "else_code" : cls.else_code,
+                 "tag_code" : ";",
+                 "top_code" : "TOP = (TOP + spm + 8) % 8;",
+                 "op_class" : cls.op_class})
+        iop = InstObjParams(cls.mnemonic,
+                cls.className + suffix, base,
+                {"code" : cls.code,
+                 "flag_code" : flag_code,
+                 "cond_check" : cond_check,
+                 "else_code" : cls.else_code,
+                 "tag_code" : ";",
+                 "top_code" : ";",
+                 "op_class" : cls.op_class})
+
+        # Globals to stick the output in
+        global header_output
+        global decoder_output
+        global exec_output
+
+        # Generate the actual code (finally!)
+        header_output += MicroFpOpDeclare.subst(iop_tag)
+        decoder_output += MicroFpOpConstructor.subst(iop_tag)
+        exec_output += MicroFpOpExecute.subst(iop_tag)
+        header_output += MicroFpOpDeclare.subst(iop_top)
+        decoder_output += MicroFpOpConstructor.subst(iop_top)
+        exec_output += MicroFpOpExecute.subst(iop_top)
+        header_output += MicroFpOpDeclare.subst(iop)
+        decoder_output += MicroFpOpConstructor.subst(iop)
+        exec_output += MicroFpOpExecute.subst(iop)
+
+    for cls in microopClasses.fpops:
+        buildCppClasses(cls)
 }};
diff --git a/src/arch/x86/ucasmlib/arch/x86/microops.py b/src/arch/x86/ucasmlib/arch/x86/microops.py
index ab6a14b..bcc432d 100644
--- a/src/arch/x86/ucasmlib/arch/x86/microops.py
+++ b/src/arch/x86/ucasmlib/arch/x86/microops.py
@@ -32,7 +32,9 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-classes = {}
+class ExpandableDict(dict):
+    pass
+classes = ExpandableDict()

 class X86Microop(object):
     def __init__(self, name):

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/56488
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: I468d78b82e689c92d07a92abd0c26f44da0c9e2f
Gerrit-Change-Number: 56488
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