move svp64 reg-decode function to more appropriate location
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 27 Jan 2021 18:16:47 +0000 (18:16 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 28 Jan 2021 15:07:58 +0000 (15:07 +0000)
use it in SVP64RM get_svp64_csv to decode EXTRA bit-field positions

src/soc/decoder/power_svp64.py
src/soc/sv/trans/svp64.py

index df496d242fb1d2cc5025d0382c2398e744223691..15d4f8c792f7d58164406a4686021360afa28f5a 100644 (file)
@@ -5,6 +5,60 @@
 from soc.decoder.power_enums import get_csv, find_wiki_dir
 import os
 
+# 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"
+
+
+def decode_extra(rm, prefix=''):
+    # first turn the svp64 rm into a "by name" dict, recording
+    # 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
+    svp64_srcreg_byname = {}
+    svp64_destreg_byname = {}
+    for i in range(4):
+        print (rm)
+        rfield = rm[prefix+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:
+            if rtype == 'd':
+                svp64_destreg_byname[r] = i # dest reg in EXTRA position 0-3
+            else:
+                svp64_srcreg_byname[r] = i # src 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 == 's':
+                    src_reg_cr = True
+
+    return dest_reg_cr, src_reg_cr, svp64_srcreg_byname, svp64_destreg_byname
+
+
 # gets SVP64 ReMap information
 class SVP64RM:
     def __init__(self):
@@ -39,6 +93,26 @@ class SVP64RM:
                           'SV_Ptype': 'Ptype', 'SV_Etype': 'Etype'}.items():
                 entry[k] = svp64[v]
 
+            # hmm, we need something more useful: a cross-association
+            # of the in1/2/3 and CR in/out with the EXTRA0-3 fields
+            decode = decode_extra(entry, "EXTRA")
+            dest_reg_cr, src_reg_cr, svp64_src, svp64_dest = decode
+            
+            # now examine in1/2/3/out, create sv_in1/2/3/out
+            for fname in ['in1', 'in2', 'in3', 'out']:
+                regfield = entry[fname]
+                extra_index = None
+                if regfield == 'RA_OR_ZERO':
+                    regfield = 'RA'
+                print (asmcode, regfield, fname, svp64_dest, svp64_src)
+                # find the reg in the SVP64 extra map
+                if (fname == 'out' and regfield in svp64_dest):
+                    extra_index = svp64_dest[regfield]
+                if (fname != 'out' and regfield in svp64_src):
+                    extra_index = svp64_src[regfield]
+                # ta-daa, we know in1/2/3/out's bit-offset
+                entry['sv_%s' % fname] = extra_index
+
         return v30b
 
 if __name__ == '__main__':
index 2e54f708580d6bcfd123c57a6403d14e7249c775..746fa563f9f8d2a9ba24d53a2636d054a1e3f352 100644 (file)
@@ -18,27 +18,9 @@ import os, sys
 from collections import OrderedDict
 
 from soc.decoder.pseudo.pagereader import ISA
-from soc.decoder.power_svp64 import SVP64RM
+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,7 +111,6 @@ def decode_ffirst(encoding):
     return decode_bo(encoding)
 
 
-
 # decodes svp64 assembly listings and creates EXT001 svp64 prefixes
 class SVP64:
     def __init__(self, lst):
@@ -189,27 +170,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)