isaspec: Add support for templates
authorChristian Gmeiner <cgmeiner@igalia.com>
Wed, 16 Aug 2023 09:56:03 +0000 (11:56 +0200)
committerMarge Bot <emma+marge@anholt.net>
Tue, 3 Oct 2023 12:07:04 +0000 (12:07 +0000)
If you have a repeating <display> substring you can replace this
substring with a template and reference the template name instead.

Saves from doing lot of copy&paste and makes general changes to the
substring much easier.

Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25451>

docs/isaspec.rst
src/compiler/isaspec/isa.py

index 34e01e7..b6eae5b 100644 (file)
@@ -208,6 +208,9 @@ some other bitfield (or combination of bitfields).  In this example it is
 used to cover the cases where ``SRCn_R`` has a different meaning and a
 different disassembly syntax depending on whether ``REPEAT`` equals zero.
 
+The ``<template>`` element can be used to represent a placeholder for a more
+complex ``<display>`` substring.
+
 Overrides
 ---------
 
index 2d40b4c..67fae5e 100644 (file)
@@ -381,6 +381,15 @@ class BitSet(object):
             return self.isa.bitsets[self.extends].get_root()
         return self
 
+class BitSetTemplate(object):
+    """Class that encapsulates a template declaration
+    """
+    def __init__(self, isa, xml):
+        self.isa = isa
+        self.name = xml.attrib['name']
+        self.display = xml.text.strip()
+        dbg("found template '{}: {}'".format(self.name, self.display))
+
 class BitSetEnum(object):
     """Class that encapsulates an enum declaration
     """
@@ -427,6 +436,9 @@ class ISA(object):
         # Table of (globally defined) expressions:
         self.expressions = {}
 
+        # Table of templates:
+        self.templates = {}
+
         # Table of enums:
         self.enums = {}
 
@@ -468,6 +480,11 @@ class ISA(object):
         # Extract expressions:
         self.parse_expressions(root)
 
+        # Extract templates:
+        for template in root.findall('template'):
+            t = BitSetTemplate(self, template)
+            self.templates[t.name] = t
+
         # Extract enums:
         for enum in root.findall('enum'):
             e = BitSetEnum(self, enum)
@@ -485,6 +502,12 @@ class ISA(object):
             self.bitsets[b.name] = b
             self.leafs.setdefault(b.name, []).append(b)
 
+        # Resolve all templates:
+        for _, bitset in self.bitsets.items():
+            for case in bitset.cases:
+                if case.display:
+                    case.display = self.resolve_templates(case.display)
+
     def validate_isa(self):
         # We only support multiples of 32 bits for now
         assert self.bitsize % 32 == 0
@@ -593,3 +616,11 @@ class ISA(object):
                 continue
             for bitset in bitsets:
                 yield name, bitset
+
+    def resolve_templates(self, display_string):
+        matches = re.findall(r'\{([^\}]+)\}', display_string)
+        for m in matches:
+            if m in self.templates:
+                display_string = display_string.replace("{" + m + "}", self.templates[m].display)
+
+        return display_string