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

Change subject: arch-x86: Simplify and reorganize the grammar for the ucode asm.
......................................................................

arch-x86: Simplify and reorganize the grammar for the ucode asm.

Change-Id: Ibee8d548c1d7ef6ff0ee1612bf547ea53f2e3d54
---
M src/arch/micro_asm.py
M src/arch/x86/isa/macroop.isa
M src/arch/x86/isa/rom.isa
3 files changed, 119 insertions(+), 160 deletions(-)



diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py
index 0bf9caa..da52a61 100644
--- a/src/arch/micro_asm.py
+++ b/src/arch/micro_asm.py
@@ -53,6 +53,9 @@
         microop.micropc = len(self.microops)
         self.microops.append(microop)

+    def add_label(self, label):
+        self.labels[label.name] = len(self.microops)
+
     def __str__(self):
         string = "%s:\n" % self.name
         for microop in self.microops:
@@ -75,39 +78,68 @@
         super().__init__(name)
         self.externs = {}

+    def add_label(self, label):
+        super().add_label(label)
+        if label.is_extern:
+            self.externs[label.name] = len(self.microops)
+
 ##########################################################################
 #
 # Support classes
 #
 ##########################################################################

-class Label(object):
-    def __init__(self):
-        self.extern = False
-        self.name = ""
-
-class Block(object):
+class Block:
     def __init__(self):
         self.statements = []

-class Statement(object):
-    def __init__(self):
-        self.is_microop = False
-        self.is_directive = False
-        self.name = ""
-        self.params = ""
+class Statement:
+    def __init__(self, name, is_directive=False):
+        self.name = name
+        self.is_directive = is_directive

 class Microop(Statement):
-    def __init__(self):
-        super().__init__()
-        self.labels = []
-        self.is_microop = True
+    def __init__(self, name, params):
+        super().__init__(name)
+        self.params = params
+
+    def handle(self, parser, container):
+        microop = parser.microops.get(self.name, None)
+        if not microop:
+            raise Exception(f'Unrecongized mnemonic: "{self.name}"')
+
+        try:
+            microop = eval(f'_cls({self.params})',
+                    {'_cls': microop}, parser.symbols)
+        except:
+            print_error(f'Error instantiating microop "{self.name}"')
+            raise
+
+        container.add_microop(self.name, microop)

 class Directive(Statement):
-    def __init__(self):
-        super().__init__()
-        self.name = ""
-        self.is_directive = True
+    def __init__(self, name, params):
+        super().__init__(name, True)
+        self.params = params
+
+    def handle(self, parser, container):
+        directive = container.directives.get(self.name, None)
+        if not directive:
+            raise Exception(f'Unrecognized directive: "{self.name}"')
+        local = {'_dir': directive}
+        try:
+ eval(f'_dir({self.params})', {'_dir': directive}, parser.symbols)
+        except:
+            print_error(f'Error executing directive "{self.name}"')
+            raise
+
+class Label(Statement):
+    def __init__(self, name, is_extern):
+        super().__init__(name)
+        self.is_extern = is_extern
+
+    def handle(self, parser, container):
+        container.add_label(self)

 ##########################################################################
 #
@@ -120,38 +152,6 @@
     print("*** %s" % message)
     print()

-def handle_statement(parser, container, statement):
-    name = statement.name
-    params = statement.params
-
-    if statement.is_microop:
-        if name not in parser.microops:
-            raise Exception(f'Unrecognized mnemonic: "{name}"')
-        local = {'_cls': parser.microops[name]}
-        try:
-            microop = eval(f'_cls({params})', local, parser.symbols)
-        except:
-            print_error(f'Error creating "{name}" microop object.')
-            raise
-
-        for label in statement.labels:
-            container.labels[label.text] = microop
-            if label.is_extern:
-                container.externs[label.text] = microop
-        container.add_microop(name, microop)
-
-    elif statement.is_directive:
-        if name not in container.directives:
-            raise Exception(f'Unrecognized directive: "{name}"')
-        local = {'_dir': container.directives[name]}
-        try:
-            eval(f'_dir({params})', local, parser.symbols)
-        except:
-            print_error(f'Error executing directive "{name}".')
-            raise
-    else:
- raise Exception(f"Didn't recognize the type of statement {statement}")
-
 ##########################################################################
 #
 # Lexer specification
@@ -310,39 +310,37 @@
 #
 ##########################################################################

-# Start symbol for a file which may have more than one macroop or rom
-# specification.
+# Start symbol for a file which may have more than one "object" defined in it.
 def p_file(t):
-    'file : opt_rom_or_macros'
+    'file : opt_objects'

-def p_opt_rom_or_macros_0(t):
-    'opt_rom_or_macros : '
+# The objects are optional.
+def p_opt_objects(t):
+    '''opt_objects : objects
+                   |'''

-def p_opt_rom_or_macros_1(t):
-    'opt_rom_or_macros : rom_or_macros'
+# One or more objects.
+def p_objects(t):
+    '''objects : objects object
+               | object'''

-def p_rom_or_macros_0(t):
-    'rom_or_macros : rom_or_macro'
+# Objects can be of various types.
+def p_object(t):
+    '''object : rom_block
+              | macroop_def'''

-def p_rom_or_macros_1(t):
-    'rom_or_macros : rom_or_macros rom_or_macro'
-
-def p_rom_or_macro_0(t):
-    '''rom_or_macro : rom_block
-                    | macroop_def'''
-
-# Defines a section of microcode that should go in the current ROM
+# Defines a section of microcode that should go in the current ROM.
 def p_rom_block(t):
     'rom_block : DEF ROM block SEMI'
     if not t.parser.rom:
         print_error("Rom block found, but no Rom object specified.")
raise TypeError("Rom block found, but no Rom object was specified.")
     for statement in t[3].statements:
-        handle_statement(t.parser, t.parser.rom, statement)
+        statement.handle(t.parser, t.parser.rom)
     t[0] = t.parser.rom

-# Defines a macroop that jumps to an external label in the ROM
-def p_macroop_def_0(t):
+# Defines a macroop that jumps to an external label in the ROM.
+def p_macroop_jump(t):
     'macroop_def : DEF MACROOP ID LPAREN ID RPAREN SEMI'
     if not t.parser.rom_macroop_type:
         print_error("ROM based macroop found, but no ROM macroop " +
@@ -353,8 +351,8 @@
     t.parser.macroops[t[3]] = macroop


-# Defines a macroop that is combinationally generated
-def p_macroop_def_1(t):
+# Defines a macroop that is combinationally generated.
+def p_macroop_def(t):
     'macroop_def : DEF MACROOP ID block SEMI'
     try:
         curop = t.parser.macro_type(t[3])
@@ -362,7 +360,7 @@
         print_error("Error creating macroop object.")
         raise
     for statement in t[4].statements:
-        handle_statement(t.parser, curop, statement)
+        statement.handle(t.parser, curop)
     t.parser.macroops[t[3]] = curop

 # A block of statements
@@ -372,12 +370,10 @@
     block.statements = t[2]
     t[0] = block

+# One or more statements
 def p_statements_0(t):
     'statements : statement'
-    if t[1]:
-        t[0] = [t[1]]
-    else:
-        t[0] = []
+    t[0] = [t[1]] if t[1] else []

 def p_statements_1(t):
     'statements : statements statement'
@@ -385,98 +381,52 @@
         t[1].append(t[2])
     t[0] = t[1]

+# A statement can be of various types.
 def p_statement(t):
-    'statement : content_of_statement end_of_statement'
+    '''statement : empty_statement
+                 | label
+                 | microop
+                 | directive'''
     t[0] = t[1]

-# A statement can be a microop or an assembler directive
-def p_content_of_statement_0(t):
-    '''content_of_statement : microop
-                            | directive'''
+# Parameters are optional.
+def p_opt_params_0(t):
+    'opt_params : PARAMS'
     t[0] = t[1]

-# Ignore empty statements
-def p_content_of_statement_1(t):
-    'content_of_statement : '
-    pass
+def p_opt_params_1(t):
+    'opt_params :'
+    t[0] = ""

-# Statements are ended by newlines or a semi colon
+# Statements are often ended by newlines or a semi colon.
 def p_end_of_statement(t):
     '''end_of_statement : NEWLINE
                         | SEMI'''
     pass

-# Different flavors of microop to avoid shift/reduce errors
-def p_microop_0(t):
-    'microop : labels ID'
-    microop = Microop()
-    microop.labels = t[1]
-    microop.name = t[2]
-    t[0] = microop
+# Ignore empty statements.
+def p_empty_statement(t):
+    'empty_statement : end_of_statement'
+    pass

-def p_microop_1(t):
-    'microop : ID'
-    microop = Microop()
-    microop.name = t[1]
-    t[0] = microop
-
-def p_microop_2(t):
-    'microop : labels ID PARAMS'
-    microop = Microop()
-    microop.labels = t[1]
-    microop.name = t[2]
-    microop.params = t[3]
-    t[0] = microop
-
-def p_microop_3(t):
-    'microop : ID PARAMS'
-    microop = Microop()
-    microop.name = t[1]
-    microop.params = t[2]
-    t[0] = microop
-
-# Labels in the microcode
-def p_labels_0(t):
-    'labels : label'
-    t[0] = [t[1]]
-
-def p_labels_1(t):
-    'labels : labels label'
-    t[1].append(t[2])
-    t[0] = t[1]
-
-# labels on lines by themselves are attached to the following instruction.
-def p_labels_2(t):
-    'labels : labels NEWLINE'
-    t[0] = t[1]
-
+# A label in the microcode.
 def p_label_0(t):
-    'label : ID COLON'
-    label = Label()
-    label.is_extern = False
-    label.text = t[1]
-    t[0] = label
+    'label : EXTERN ID COLON'
+    t[0] = Label(t[2], True)

 def p_label_1(t):
-    'label : EXTERN ID COLON'
-    label = Label()
-    label.is_extern = True
-    label.text = t[2]
-    t[0] = label
+    'label : ID COLON'
+    t[0] = Label(t[1], False)

-# Directives for the macroop
-def p_directive_0(t):
-    'directive : DOT ID'
-    directive = Directive()
-    directive.name = t[2]
-    t[0] = directive
+# A microop with optional parameters.
+def p_microop(t):
+    'microop : ID opt_params end_of_statement'
+    t[0] = Microop(t[1], t[2])

-def p_directive_1(t):
-    'directive : DOT ID PARAMS'
-    directive = Directive()
-    directive.name = t[2]
-    directive.params = t[3]
-    t[0] = directive
+# Directives for the macroop.
+def p_directive(t):
+    'directive : DOT ID opt_params end_of_statement'
+    t[0] = Directive(t[2], t[3])

 # Parse error handler.  Note that the argument here is the offending
 # *token*, not a grammar symbol (hence the need to use t.value)
diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa
index 8bd3b7e..07f8a02 100644
--- a/src/arch/x86/isa/macroop.isa
+++ b/src/arch/x86/isa/macroop.isa
@@ -197,9 +197,9 @@
             #FIXME This first parameter should be the mnemonic. I need to
             #write some code which pulls that out
             declareLabels = ""
-            for (label, microop) in self.labels.items():
+            for (label, micropc) in self.labels.items():
                 declareLabels += "const static uint64_t label_%s = %d;\n" \
-                                  % (label, microop.micropc)
+                                  % (label, micropc)
             iop = InstObjParams(self.getMnemonic(), self.name, "Macroop",
                     {"code" : "",
                      "declareLabels" : declareLabels
diff --git a/src/arch/x86/isa/rom.isa b/src/arch/x86/isa/rom.isa
index 93f4401..d53c9de 100644
--- a/src/arch/x86/isa/rom.isa
+++ b/src/arch/x86/isa/rom.isa
@@ -30,13 +30,13 @@
     class X86MicrocodeRom(Rom):
         def getDeclaration(self):
             declareLabels = "namespace rom_labels\n{\n"
-            for (label, microop) in self.labels.items():
+            for (label, micropc) in self.labels.items():
                 declareLabels += "const static uint64_t label_%s = %d;\n" \
-                                  % (label, microop.micropc)
-            for (label, microop) in self.externs.items():
+                                  % (label, micropc)
+            for (label, micropc) in self.externs.items():
                 declareLabels += \
                     "const static MicroPC extern_label_%s = %d;\n" \
-                        % (label, microop.micropc)
+                        % (label, micropc)
             declareLabels += "}\n"
             return declareLabels;


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