sparc: Clean up some code in base.isa.
authorGabe Black <gabeblack@google.com>
Mon, 28 Sep 2020 06:41:02 +0000 (23:41 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 7 Oct 2020 23:00:05 +0000 (23:00 +0000)
This includes the filterDoubles function which adds code to combine 32
bit values into doubles or 64 bit values for floating point, and the
splitOutImm function which detects if the code that implements an
instruction has a register and immediate variant, and generates code for
each.

Change-Id: I5524b9acd6e610b51fd91fe70276c34c23be9f85
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/35235
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/sparc/isa/base.isa
src/arch/sparc/isa/formats/branch.isa
src/arch/sparc/isa/formats/integerop.isa
src/arch/sparc/isa/formats/priv.isa

index 4c9bd25b70be985f4c78710dc811d16585770c18..5be3940214c1166d11746cf9e98df21e1907c7dc 100644 (file)
@@ -52,69 +52,69 @@ output header {{
 let {{
     def filterDoubles(code):
         assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
-        for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
-            next_pos = 0
-            operandsREString = (r'''
-            (?<!\w)             # neg. lookbehind assertion: prevent partial matches
-            ((%s)(?:_([^\W_]+))?)   # match: operand with optional '.' then suffix
-            (?!\w)             # neg. lookahead assertion: prevent partial matches
-            ''' % opName)
-            operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
-            is_src = False
-            is_dest = False
-            extension = None
-            foundOne = False
-            while 1:
-                match = operandsRE.search(code, next_pos)
-                if not match:
-                    break
-                foundOne = True
-                op = match.groups()
-                (op_full, op_base, op_ext) = op
-                is_dest_local = (assignRE.match(code, match.end()) != None)
-                is_dest = is_dest or is_dest_local
-                is_src = is_src or not is_dest_local
-                if extension and extension != op_ext:
-                    raise Exception("Inconsistent extensions in double filter")
-                extension = op_ext
-                next_pos = match.end()
-            if foundOne:
-                # Get rid of any unwanted extension
-                code = operandsRE.sub(op_base, code)
-                is_int = False
-                member = "d"
-                if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
-                    is_int = True
-                    member = "ui"
-                if is_src:
-                    code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
-                        (opName, opName, opName, member)) + code
-                if is_dest:
-                    code += '''
-                        %s_low = DoubleSingle(%s).s[1];
-                        %s_high = DoubleSingle(%s).s[0];''' % \
-                             (opName, opName, opName, opName)
-                if is_int:
-                    code = ("uint64_t %s;" % opName) + code
-                else:
-                    code = ("double %s;" % opName) + code
+
+        int_extensions = ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw")
+        operand_names = ("Frd", "Frs1", "Frs2", "Frd_N")
+
+        class Operand(object):
+            def __init__(self, name, ext):
+                self.name = name
+                self.ext = ext
+                self.src = False
+                self.dest = False
+
+        operands = {}
+
+        operandsREString = (r'''
+        # neg. lookbehind assertion: prevent partial matches
+        (?<!\w)
+        # match: operand with optional '.' then suffix
+        ((?P<name>%s)(_(?P<ext>[^\W_]+))?)
+        # neg. lookahead assertion: prevent partial matches
+        (?!\w)
+        ''' % '|'.join(operand_names))
+        operandsRE = re.compile(operandsREString, re.MULTILINE | re.VERBOSE)
+
+        for match in operandsRE.finditer(code):
+            name = match.group('name')
+            ext = match.group('ext')
+            operand = operands.setdefault(name, Operand(name, ext))
+            if assignRE.match(code, match.end()):
+                operand.dest = True
+            else:
+                operand.src = True
+            if operand.ext != ext:
+                raise Exception("Inconsistent extensions in double filter")
+
+        # Get rid of any unwanted extension
+        code = operandsRE.sub('\g<name>', code)
+
+        for op in operands.values():
+            is_int = op.ext in int_extensions
+            member, type = ('ui', 'uint64_t') if is_int else ('d', 'double')
+            if op.src:
+                code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
+                    (op.name, op.name, op.name, member)) + code
+            if op.dest:
+                code += '''
+                    %s_low = DoubleSingle(%s).s[1];
+                    %s_high = DoubleSingle(%s).s[0];''' % \
+                         (op.name, op.name, op.name, op.name)
+            code = ("%s %s;" % (type, op.name)) + code
         return code
 }};
 
 let {{
     def splitOutImm(code):
-        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
+        matcher = re.compile(
+                r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
         rOrImmMatch = matcher.search(code)
-        if (rOrImmMatch == None):
-            return (False, code, '', '', '')
-        rString = rOrImmMatch.group("rNum")
-        if (rOrImmMatch.group("typeQual") != None):
-            rString += rOrImmMatch.group("typeQual")
-        iString = rOrImmMatch.group("iNum")
+        if rOrImmMatch == None:
+            return code, None, None
         orig_code = code
-        code = matcher.sub('Rs' + rString, orig_code)
-        imm_code = matcher.sub('imm', orig_code)
-        return (True, code, imm_code, rString, iString)
+        reg_code = matcher.sub('Rs\g<rNum>\g<typeQual>', code)
+        imm_code = matcher.sub('imm', code)
+        return reg_code, imm_code, rOrImmMatch.group('iNum')
 }};
 
 output exec {{
index 015df475b384d77b43d955d6512fd8b9317887ff..d1107e64bdc2655e9b9215cd0708ca6bebe69b4f 100644 (file)
@@ -86,13 +86,12 @@ def template BranchDecode {{
 // Primary format for branch instructions:
 def format Branch(code, *opt_flags) {{
     code = 'NNPC = NNPC;\n' + code
-    (usesImm, code, immCode,
-     rString, iString) = splitOutImm(code)
+    code, immCode, iString = splitOutImm(code)
     iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
     header_output = BasicDeclare.subst(iop)
     decoder_output = BasicConstructor.subst(iop)
     exec_output = JumpExecute.subst(iop)
-    if usesImm:
+    if immCode is not None:
         imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
                 immCode, opt_flags)
         header_output += BasicDeclare.subst(imm_iop)
index a43d1b2878f710b1d611aee738964bd682b06787..a8e0374d0f6b63d9e70dbc9ac5d560cdb5eaab02 100644 (file)
@@ -59,15 +59,14 @@ def template IntOpExecute {{
 
 let {{
     def doIntFormat(code, ccCode, name, Name, opt_flags):
-        (usesImm, code, immCode,
-         rString, iString) = splitOutImm(code)
+        code, immCode, iString = splitOutImm(code)
         iop = InstObjParams(name, Name, 'IntOp',
                 {"code": code, "cc_code": ccCode},
                 opt_flags)
         header_output = BasicDeclare.subst(iop)
         decoder_output = BasicConstructor.subst(iop)
         exec_output = IntOpExecute.subst(iop)
-        if usesImm:
+        if immCode is not None:
             imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
                     {"code": immCode, "cc_code": ccCode}, opt_flags)
             header_output += BasicDeclare.subst(imm_iop)
index 266e7f94007beb72e736b501e7b2cc2010a48b86..7530cdfe2084483d7f96bb6be3edeb6ca9e9393c 100644 (file)
@@ -64,7 +64,7 @@ let {{
 '''
 
     def doPrivFormat(code, check_code, name, Name, opt_flags, check_tl=False):
-        (uses_imm, code, imm_code, r_string, i_string) = splitOutImm(code)
+        code, imm_code, _ = splitOutImm(code)
         tl_check = tl_check_code if check_tl else ''
         # If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions,
         # cut any other info out of the mnemonic. Also pick a different
@@ -93,7 +93,7 @@ let {{
         else:
             decoder_output = ControlRegConstructor.subst(iop)
         exec_output = PrivExecute.subst(iop)
-        if uses_imm:
+        if imm_code is not None:
             imm_iop = InstObjParams(name, Name + 'Imm', reg_base + 'Imm',
                     {"code": imm_code, "check": check_code,
                      "tl_check": tl_check, "reg_name": reg_name},