start decoding sv EXTRAs and identifying them
[soc.git] / src / soc / sv / trans / svp64.py
index a95b21786a929ef3ec7a8311f6bf2f9a1ad5a329..42f0963952c965557b5fa034a840f912db305fde 100644 (file)
@@ -9,7 +9,11 @@ creates an EXT001-encoded "svp64 prefix" followed by a v3.0B opcode.
 
 It is very simple and straightforward, the only weirdness being the
 extraction of the register information and conversion to v3.0B numbering.
 
 It is very simple and straightforward, the only weirdness being the
 extraction of the register information and conversion to v3.0B numbering.
+
+Encoding format of svp64: https://libre-soc.org/openpower/sv/svp64/
+Bugtracker: https://bugs.libre-soc.org/show_bug.cgi?id=578
 """
 """
+
 import os, sys
 
 from soc.decoder.pseudo.pagereader import ISA
 import os, sys
 
 from soc.decoder.pseudo.pagereader import ISA
@@ -25,17 +29,23 @@ def is_CR_5bit(regname):
 def is_GPR(regname):
     return regname in ['RA', 'RB', 'RC', 'RS', 'RT']
  
 def is_GPR(regname):
     return regname in ['RA', 'RB', 'RC', 'RS', 'RT']
  
+def get_regtype(regname):
+    if is_CR_3bit(regname):
+        return "CR_3bit"
+    if is_CR_5bit(regname):
+        return "CR_5bit"
+    if is_GPR(regname):
+        return "GPR"
+
 
 class SVP64RM:
     def __init__(self):
         self.instrs = {}
         pth = find_wiki_dir()
 
 class SVP64RM:
     def __init__(self):
         self.instrs = {}
         pth = find_wiki_dir()
-        print (pth)
         for fname in os.listdir(pth):
         for fname in os.listdir(pth):
-            print (fname)
             if fname.startswith("RM"):
             if fname.startswith("RM"):
-                entries = get_csv(fname)
-                print (entries)
+                for entry in get_csv(fname):
+                    self.instrs[entry['insn']] = entry
 
 
 class SVP64:
 
 
 class SVP64:
@@ -49,6 +59,7 @@ class SVP64:
 
     def translate(self, lst):
         isa = ISA() # reads the v3.0B pseudo-code markdown files
 
     def translate(self, lst):
         isa = ISA() # reads the v3.0B pseudo-code markdown files
+        svp64 = SVP64RM() # reads the svp64 Remap entries for registers
         res = []
         for insn in lst:
             # find first space, to get opcode
         res = []
         for insn in lst:
             # find first space, to get opcode
@@ -70,11 +81,56 @@ class SVP64:
             if v30b_op not in isa.instr:
                 raise Exception("opcode %s of '%s' not supported" % \
                                 (v30b_op, insn))
             if v30b_op not in isa.instr:
                 raise Exception("opcode %s of '%s' not supported" % \
                                 (v30b_op, insn))
+            if v30b_op not in svp64.instrs:
+                raise Exception("opcode %s of '%s' not an svp64 instruction" % \
+                                (v30b_op, insn))
+            isa.instr[v30b_op].regs[0]
+            v30b_regs = isa.instr[v30b_op].regs[0]
+            rm = svp64.instrs[v30b_op]
+            print ("v3.0B regs", opcode, v30b_regs)
+            print (rm)
+
+            # right.  the first thing to do is identify the ordering of
+            # the registers, by name.  the EXTRA2/3 ordering is in
+            # rm['0']..rm['3'] but those fields contain the names RA, BB
+            # etc.  we have to read the pseudocode to understand which
+            # reg is which in our instruction. sigh.
+
+            # first turn the svp64 rm into a "by name" dict, recording
+            # which position in the RM EXTRA it goes into
+            svp64_reg_byname = {}
+            for i in range(4):
+                rfield = rm[str(i)]
+                if not rfield or rfield == '0':
+                    continue
+                print ("EXTRA field", i, rfield)
+                rfield = rfield.split(";") # s:RA;d:CR1 etc.
+                for r in rfield:
+                    r = r[2:] # ignore s: and d:
+                    svp64_reg_byname[r] = i # this reg in EXTRA position 0-3
+            print ("EXTRA field index, by regname", svp64_reg_byname)
+
+            # okaaay now we identify the field value (opcode N,N,N) with
+            # the pseudo-code info (opcode RT, RA, RB)
+            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]
+                regtype = get_regtype(regname)
+                extras[extra] = (field, regname, regtype)
+                print ("    ", extra, extras[extra])
+
+            etype = rm['Etype'] # Extra type: EXTRA3/EXTRA2
 
         return res
 
 if __name__ == '__main__':
     isa = SVP64(['slw 3, 1, 4',
                  'extsw 5, 3',
 
         return res
 
 if __name__ == '__main__':
     isa = SVP64(['slw 3, 1, 4',
                  'extsw 5, 3',
-                 'sv.extsw 5, 3'])
+                 'sv.extsw 5, 3',
+                 'sv.setb 5, 3',
+                 'sv.isel 5, 3, 2, 0'
+                ])
     csvs = SVP64RM()
     csvs = SVP64RM()