Fix SVP64 translator to yield the unaltered instruction
[soc.git] / src / soc / sv / trans / svp64.py
index 0cb14a78d900d99cb8a864de80af77dd7f17d32e..a2427fd686004a926789ddf285496700c887fe6c 100644 (file)
@@ -18,27 +18,9 @@ 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
+from soc.decoder.power_svp64 import SVP64RM, get_regtype, decode_extra
 
 
-# identifies register by type
-def is_CR_3bit(regname):
-    return regname in ['BF', 'BFA']
-
-def is_CR_5bit(regname):
-    return regname in ['BA', 'BB', 'BC', 'BI', 'BT']
-
-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"
-
 # decode GPR into sv extra
 def  get_extra_gpr(etype, regmode, field):
     if regmode == 'scalar':
@@ -129,31 +111,18 @@ def decode_ffirst(encoding):
     return decode_bo(encoding)
 
 
-# gets SVP64 ReMap information
-class SVP64RM:
-    def __init__(self):
-        self.instrs = {}
-        pth = find_wiki_dir()
-        for fname in os.listdir(pth):
-            if fname.startswith("RM") or fname.startswith("LDSTRM"):
-                for entry in get_csv(fname):
-                    self.instrs[entry['insn']] = entry
-
-
 # decodes svp64 assembly listings and creates EXT001 svp64 prefixes
-class SVP64:
+class SVP64Asm:
     def __init__(self, lst):
         self.lst = lst
         self.trans = self.translate(lst)
 
     def __iter__(self):
-        for insn in self.trans:
-            yield insn
+        yield from self.trans
 
     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
             ls = insn.split(' ')
@@ -165,7 +134,7 @@ class SVP64:
 
             # identify if is a svp64 mnemonic
             if not opcode.startswith('sv.'):
-                res.append(insn) # unaltered
+                yield insn  # unaltered
                 continue
             opcode = opcode[3:] # strip leading "sv."
 
@@ -199,27 +168,11 @@ class SVP64:
             # which position in the RM EXTRA it goes into
             # also: record if the src or dest was a CR, for sanity-checking
             # (elwidth overrides on CRs are banned)
-            dest_reg_cr, src_reg_cr = False, False
+            decode = decode_extra(rm)
+            dest_reg_cr, src_reg_cr, svp64_src, svp64_dest = decode
             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:
-                    rtype = r[0]
-                    # TODO: ignoring s/d makes it impossible to do
-                    # LD/ST-with-update.
-                    r = r[2:] # ignore s: and d:
-                    svp64_reg_byname[r] = i # this reg in EXTRA position 0-3
-                    # check the regtype (if CR, record that)
-                    regtype = get_regtype(r)
-                    if regtype in ['CR_3bit', 'CR_5bit']:
-                        if rtype == 'd':
-                            dest_reg_cr = True
-                        if rtype == 'd':
-                            src_reg_cr = True
+            svp64_reg_byname.update(svp64_src)
+            svp64_reg_byname.update(svp64_dest)
 
             print ("EXTRA field index, by regname", svp64_reg_byname)
 
@@ -585,10 +538,21 @@ class SVP64:
                 print ("    smask  16-17:", bin(smask))
             print ()
 
-        return res
+            # first construct the prefix: EXT001, bits 7/9=1, in MSB0 order
+            svp64_prefix = 0x1 << (31-5) # EXT001
+            svp64_prefix |= 0x1 << (31-7) # SVP64 marker 1
+            svp64_prefix |= 0x1 << (31-9) # SVP64 marker 2
+            rmfields = [6, 8] + list(range(10,32)) # SVP64 24-bit RM
+            for i, x in enumerate(rmfields):
+                svp64_prefix |= ((svp64_rm>>i)&0b1) << (31-x)
+
+            # fiinally yield the svp64 prefix and the thingy.  v3.0b opcode
+            yield ".long 0x%x" % svp64_prefix
+            yield "%s %s" % (v30b_op, ", ".join(v30b_newfields))
+            print ("new v3.0B fields", v30b_op, v30b_newfields)
 
 if __name__ == '__main__':
-    isa = SVP64(['slw 3, 1, 4',
+    isa = SVP64Asm(['slw 3, 1, 4',
                  'extsw 5, 3',
                  'sv.extsw 5, 3',
                  'sv.cmpi 5, 1, 3, 2',
@@ -601,4 +565,5 @@ if __name__ == '__main__':
                  'sv.extsw./satu/sz/dz/sm=r3/m=r3 5, 31',
                  'sv.extsw./pr=eq 5.v, 31',
                 ])
+    print ("list", list(isa))
     csvs = SVP64RM()