start decoding EXTRA2/3
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 23 Jan 2021 16:01:02 +0000 (16:01 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 23 Jan 2021 16:01:02 +0000 (16:01 +0000)
src/soc/sv/trans/svp64.py

index 42f0963952c965557b5fa034a840f912db305fde..b1b59f18a1b7682e1fa98e77d8b4e760d57553b4 100644 (file)
@@ -15,11 +15,13 @@ Bugtracker: https://bugs.libre-soc.org/show_bug.cgi?id=578
 """
 
 import os, sys
+from collections import OrderedDict
 
 from soc.decoder.pseudo.pagereader import ISA
 from soc.decoder.power_enums import get_csv, find_wiki_dir
 
 
+# identifies register by type
 def is_CR_3bit(regname):
     return regname in ['BF', 'BFA']
 
@@ -28,7 +30,7 @@ def is_CR_5bit(regname):
 
 def is_GPR(regname):
     return regname in ['RA', 'RB', 'RC', 'RS', 'RT']
+
 def get_regtype(regname):
     if is_CR_3bit(regname):
         return "CR_3bit"
@@ -38,6 +40,7 @@ def get_regtype(regname):
         return "GPR"
 
 
+# gets SVP64 ReMap information
 class SVP64RM:
     def __init__(self):
         self.instrs = {}
@@ -48,6 +51,7 @@ class SVP64RM:
                     self.instrs[entry['insn']] = entry
 
 
+# decodes svp64 assembly listings and creates EXT001 svp64 prefixes
 class SVP64:
     def __init__(self, lst):
         self.lst = lst
@@ -115,14 +119,59 @@ class SVP64:
             opregfields = zip(fields, v30b_regs) # err that was easy
 
             # now for each of those find its place in the EXTRA encoding
-            extras = {}
-            for field, regname in opregfields:
-                extra = svp64_reg_byname[regname]
+            extras = OrderedDict()
+            for idx, (field, regname) in enumerate(opregfields):
+                extra = svp64_reg_byname.get(regname, None)
                 regtype = get_regtype(regname)
-                extras[extra] = (field, regname, regtype)
+                extras[extra] = (idx, field, regname, regtype)
                 print ("    ", extra, extras[extra])
 
+            # great! got the extra fields in their associated positions:
+            # also we know the register type. now to create the EXTRA encodings
             etype = rm['Etype'] # Extra type: EXTRA3/EXTRA2
+            extra_bits = 0
+            v30b_newfields = []
+            for extra_idx, (idx, field, regname, regtype) in extras.items():
+                # is it a field we don't alter/examine?  if so just put it
+                # into newfields
+                if regtype is None:
+                    v30b_newfields.append(field)
+
+                # first, decode the field number. "5.v" or "3.s" or "9"
+                field = field.split(".")
+                regmode = 'scalar' # default
+                if len(field) == 2:
+                    if field[1] == 's':
+                        regmode = 'scalar'
+                    elif field[1] == 'v':
+                        regmode = 'vector'
+                field = int(field[0]) # actual register number
+                print ("    ", regmode, field)
+                if regtype == 'GPR':
+                    if regmode == 'scalar':
+                        # cut into 2-bits 5-bits SS FFFFF
+                        sv_extra = field >> 5
+                        field = field & 0b11111
+                    else:
+                        # cut into 5-bits 2-bits FFFFF SS
+                        sv_extra = field & 0b11
+                        field = field >> 2
+                    # now sanity-check. EXTRA3 is ok, EXTRA2 has limits
+                    if etype == 'EXTRA2':
+                        if regmode == 'scalar':
+                            assert sv_extra & 0b10 == 0, \
+                                "scalar field %s cannot fit into EXTRA2 %s" % \
+                                    (regname, str(extras[extra_idx]))
+                        else:
+                            assert sv_extra & 0b01 == 0, \
+                                "vector field %s cannot fit into EXTRA2 %s" % \
+                                    (regname, str(extras[extra_idx]))
+
+                # append altered field value to v3.0b
+                v30b_newfields.append(str(field))
+
+            print ("new v3.0B fields", v30b_op, v30b_newfields)
+            print ()
 
         return res
 
@@ -130,7 +179,8 @@ if __name__ == '__main__':
     isa = SVP64(['slw 3, 1, 4',
                  'extsw 5, 3',
                  'sv.extsw 5, 3',
+                 'sv.cmpi 5, 1, 3, 2',
                  'sv.setb 5, 3',
-                 'sv.isel 5, 3, 2, 0'
+                 'sv.isel 64.v, 3, 2, 0'
                 ])
     csvs = SVP64RM()