got sv.bc working for pospopcount
[openpower-isa.git] / src / openpower / sv / sv_analysis.py
index ab8fd8c7ec9d117527758f097e9f524534dcaa01..21778ad02d78c4f7ef5b6df93e096f4abbe365ad 100644 (file)
@@ -33,6 +33,29 @@ from openpower.decoder.power_enums import find_wiki_file, get_csv
 from openpower.util import log
 
 
+# Ignore those containing: valid test sprs
+def glob_valid_csvs(root):
+    def check_csv(fname):
+        _, name = os.path.split(fname)
+        if '-' in name:
+            return False
+        if 'valid' in fname:
+            return False
+        if 'test' in fname:
+            return False
+        if fname.endswith('insndb.csv'):
+            return False
+        if fname.endswith('sprs.csv'):
+            return False
+        if fname.endswith('minor_19_valid.csv'):
+            return False
+        if 'RM' in fname:
+            return False
+        return True
+
+    yield from filter(check_csv, glob(root))
+
+
 # Write an array of dictionaries to the CSV file name:
 def write_csv(name, items, headers):
     file_path = find_wiki_file(name)
@@ -142,17 +165,6 @@ def create_key(row):
     else:
         res['imm'] = ''
 
-    res['PU'] = '' # disabled (uses modes, now)
-    return res
-
-    # pack/unpack, start with LDST with immediate for now
-    if (res['imm'] == '1' and res['unit'] == 'LDST' and
-        ((res['in'] == '1' and res['outcnt'] == '1') or # LD-imm
-         (res['in'] == '2' and res['outcnt'] == '0'))): # ST-imm
-        res['PU'] = "1"
-    else:
-        res['PU'] = ''
-
     return res
 
 #
@@ -191,9 +203,6 @@ def keyname(row):
         res.append("CRo")
     elif 'imm' in row and row['imm']:
         res.append("imm")
-    if 'PU' in row and row['PU']:
-        #print("key", row)
-        res.append("PU")
     return '-'.join(res)
 
 
@@ -213,15 +222,16 @@ class Format(enum.Enum):
 
     def declarations(self, values, lens):
         def declaration_binutils(value, width):
-            yield f"/* TODO: implement binutils declaration (value={value!r}, width={width!r}) */"
+            yield "/* TODO: implement binutils declaration " \
+                  "(value=%x, width=%x) */" % (value, width)
 
         def declaration_vhdl(value, width):
-            yield f"    type sv_{value}_rom_array_t is " \
-                f"array(0 to {width}) of sv_decode_rom_t;"
+            yield "    type sv_%s_rom_array_t is " \
+                "array(0 to %d) of sv_decode_rom_t;" % (value, width)
 
         for value in values:
             if value not in lens:
-                todo = [f"TODO {value} (or no SVP64 augmentation)"]
+                todo = ["TODO %s (or no SVP64 augmentation)" % value]
                 todo = self.wrap_comment(todo)
                 yield from map(lambda line: f"    {line}", todo)
             else:
@@ -235,9 +245,9 @@ class Format(enum.Enum):
         def definitions_vhdl():
             for (value, entries) in entries_svp64.items():
                 yield ""
-                yield f"    constant sv_{value}_decode_rom_array :"
-                yield f"             sv_{value}_rom_array_t := ("
-                yield f"        -- {'  '.join(fullcols)}"
+                yield "    constant sv_%s_decode_rom_array :" % value
+                yield "             sv_%s_rom_array_t := (" % value
+                yield "        -- %s" % '  '.join(fullcols)
 
                 for (op, insn, row) in entries:
                     yield f"    {op:>13} => ({', '.join(row)}), -- {insn}"
@@ -258,14 +268,14 @@ class Format(enum.Enum):
         def wrap_comment_binutils(lines):
             lines = tuple(lines)
             if len(lines) == 1:
-                yield f"/* {lines[0]} */"
+                yield "/* %s */" % lines[0]
             else:
                 yield "/*"
-                yield from map(lambda line: f" * {line}", lines)
+                yield from map(lambda line: " * %s" % line, lines)
                 yield " */"
 
         def wrap_comment_vhdl(lines):
-            yield from map(lambda line: f"-- {line}", lines)
+            yield from map(lambda line: "-- %s" % line, lines)
 
         yield from {
             Format.BINUTILS: wrap_comment_binutils,
@@ -287,21 +297,7 @@ def read_csvs():
     pth = find_wiki_file("*.csv")
 
     # Ignore those containing: valid test sprs
-    for fname in glob(pth):
-        #print("sv analysis checking", fname)
-        _, name = os.path.split(fname)
-        if '-' in name:
-            continue
-        if 'valid' in fname:
-            continue
-        if 'test' in fname:
-            continue
-        if fname.endswith('sprs.csv'):
-            continue
-        if fname.endswith('minor_19_valid.csv'):
-            continue
-        if 'RM' in fname:
-            continue
+    for fname in glob_valid_csvs(pth):
         csvname = os.path.split(fname)[1]
         csvname_ = csvname.split(".")[0]
         # csvname is something like: minor_59.csv, fname the whole path
@@ -319,13 +315,21 @@ def read_csvs():
                 continue  # skip pseudo-alias lxxxbr
             if insn_name in ['mcrxr', 'mcrxrx', 'darn']:
                 continue
-            if insn_name in ['bctar', 'bcctr']:
+            if insn_name in ['bctar', 'bcctr']:  # for now. TODO
                 continue
             if 'rfid' in insn_name:
                 continue
-            if insn_name in ['setvl', ]:  # SVP64 opcodes
+            if 'addpcis' in insn_name:  # skip for now
                 continue
 
+            # sv.bc is being classified as 2P-2S-1D by mistake due to SPRs
+            if insn_name.startswith('bc'):
+                # whoops: remove out reg (SPRs CTR etc)
+                row['in1'] = 'NONE'
+                row['in2'] = 'NONE'
+                row['in3'] = 'NONE'
+                row['out'] = 'NONE'
+
             insns[(insn_name, condition)] = row  # accumulate csv data
             insn_to_csv[insn_name] = csvname_  # CSV file name by instruction
             dkey = create_key(row)
@@ -349,7 +353,7 @@ def read_csvs():
     primarykeys.sort()
 
     return (csvs, csvs_svp64, primarykeys, bykey, insn_to_csv, insns,
-           dictkeys, immediates)
+            dictkeys, immediates)
 
 
 def regs_profile(insn, res):
@@ -417,30 +421,18 @@ def extra_classifier(insn_name, value, name, res, regs):
     #     if regs == ['RA', '', '', 'RT', '', '']:
     # is in the order in1  in2  in3 out1 out2 Rc=1
 
-    #********
+    # ********
     # start with LD/ST
 
-    if value == 'LDSTRM-2P-1S1D-PU':              # pack/unpack LD
-        res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
-        res['0'] = dRT    # RT: Rdest_EXTRA2
-        res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
-
-    elif value == 'LDSTRM-2P-1S1D':
+    if value == 'LDSTRM-2P-1S1D':
         res['Etype'] = 'EXTRA3'  # RM EXTRA3 type
         res['0'] = dRT    # RT: Rdest_EXTRA3
         res['1'] = 's:RA'  # RA: Rsrc1_EXTRA3
 
     elif value == 'LDSTRM-2P-1S2D':
-        res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
-        res['0'] = dRT    # RT: Rdest_EXTRA3
-        res['1'] = 'd:RA'  # RA: Rdest2_EXTRA2
-        res['2'] = 's:RA'  # RA: Rsrc1_EXTRA2
-
-    elif value == 'LDSTRM-2P-2S-PU': # pack/unpack ST
-        # stw, std, sth, stb
-        res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
-        res['0'] = sRS    # RS: Rdest1_EXTRA2
-        res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
+        res['Etype'] = 'EXTRA3'  # RM EXTRA2 type
+        res['0'] = dRT          # RT: Rdest_EXTRA3
+        res['1'] = 'd:RA;s:RA'  # RA: Rdest2_EXTRA3
 
     elif value == 'LDSTRM-2P-2S':
         # stw, std, sth, stb
@@ -450,20 +442,18 @@ def extra_classifier(insn_name, value, name, res, regs):
 
     elif value == 'LDSTRM-2P-2S1D':
         if 'st' in insn_name and 'x' not in insn_name:  # stwu/stbu etc
-            res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
-            res['0'] = 'd:RA'  # RA: Rdest1_EXTRA2
-            res['1'] = sRS    # RS: Rdsrc1_EXTRA2
-            res['2'] = 's:RA'  # RA: Rsrc2_EXTRA2
+            res['Etype'] = 'EXTRA3'  # RM EXTRA2 type
+            res['0'] = 'd:RA;s:RA'  # RA: Rdest_EXTRA3 /  Rsrc_EXTRA3
+            res['1'] = sRS    # RS: Rdsrc1_EXTRA3
         elif 'st' in insn_name and 'x' in insn_name:  # stwux
-            res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
-            res['0'] = 'd:RA'  # RA: Rdest1_EXTRA2
-            # RS: Rdest2_EXTRA2, RA: Rsrc1_EXTRA2
-            res['1'] = "%s;%s" % (sRS, 's:RA')
-            res['2'] = 's:RB'  # RB: Rsrc2_EXTRA2
+            res['Etype'] = 'EXTRA3'  # RM EXTRA2 type
+            # RS: Rdest2_EXTRA2, RA: Rsrc1_EXTRA2 / Rdest
+            res['0'] = "%s;s:RA;d:RA" % (sRS)
+            res['1'] = 's:RB'  # RB: Rsrc2_EXTRA2
         elif 'u' in insn_name:  # ldux etc.
             res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
             res['0'] = dRT    # RT: Rdest1_EXTRA2
-            res['1'] = 'd:RA'  # RA: Rdest2_EXTRA2
+            res['1'] = 's:RA;d:RA'  # RA: Rdest2_EXTRA2
             res['2'] = 's:RB'  # RB: Rsrc1_EXTRA2
         else:
             res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
@@ -474,13 +464,13 @@ def extra_classifier(insn_name, value, name, res, regs):
     elif value == 'LDSTRM-2P-3S':
         res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
         if 'cx' in insn_name:
-            res['0'] = "%s;%s" % (sRS, dCR) # RS: Rsrc1_EXTRA2 CR0: dest
+            res['0'] = "%s;%s" % (sRS, dCR)  # RS: Rsrc1_EXTRA2 CR0: dest
         else:
             res['0'] = sRS  # RS: Rsrc1_EXTRA2
         res['1'] = 's:RA'  # RA: Rsrc2_EXTRA2
         res['2'] = 's:RB'  # RA: Rsrc3_EXTRA2
 
-    #**********
+    # **********
     # now begins,arithmetic
 
     elif value == 'RM-2P-1S1D':
@@ -488,6 +478,10 @@ def extra_classifier(insn_name, value, name, res, regs):
         if insn_name == 'mtspr':
             res['0'] = 'd:SPR'  # SPR: Rdest1_EXTRA3
             res['1'] = 's:RS'  # RS: Rsrc1_EXTRA3
+        elif insn_name == 'rlwinm':
+            # weird one, RA is a dest but not in bits 6:10
+            res['0'] = 'd:RA;d:CR0'  # RA: Rdest1_EXTRA3
+            res['1'] = 's:RS'  # RS: Rsrc1_EXTRA3
         elif insn_name == 'mfspr':
             res['0'] = 'd:RS'  # RS: Rdest1_EXTRA3
             res['1'] = 's:SPR'  # SPR: Rsrc1_EXTRA3
@@ -497,6 +491,9 @@ def extra_classifier(insn_name, value, name, res, regs):
         elif 'mfcr' in insn_name or 'mfocrf' in insn_name:
             res['0'] = 'd:RT'  # RT: Rdest1_EXTRA3
             res['1'] = 's:CR'  # CR: Rsrc1_EXTRA3
+        elif regs == ['', '', '', 'RT', 'BI', '']:
+            res['0'] = 'd:RT'  # RT: Rdest1_EXTRA3
+            res['1'] = 's:BI'  # BI: Rsrc1_EXTRA3
         elif insn_name == 'setb':
             res['0'] = 'd:RT'  # RT: Rdest1_EXTRA3
             res['1'] = 's:BFA'  # BFA: Rsrc1_EXTRA3
@@ -528,16 +525,24 @@ def extra_classifier(insn_name, value, name, res, regs):
         elif regs == ['', 'FRB', '', 'FRT', '', 'CR1']:
             res['0'] = 'd:FRT;d:CR1'  # FRT,CR1: Rdest1_EXTRA3
             res['1'] = 's:FRB'  # FRB: Rsrc1_EXTRA3
-        elif insn_name.startswith('bc'):
-            res['0'] = 'd:BI'  # BI: Rdest1_EXTRA3
-            res['1'] = 's:BI'  # BI: Rsrc1_EXTRA3
+        elif regs == ['', 'RB', '', 'FRT', '', 'CR1']:
+            res['0'] = 'd:FRT;d:CR1'  # FRT,CR1: Rdest1_EXTRA3
+            res['1'] = 's:RB'  # RB: Rsrc1_EXTRA3
+        elif regs == ['', 'RB', '', 'FRT', '', '']:
+            res['0'] = 'd:FRT'  # FRT: Rdest1_EXTRA3
+            res['1'] = 's:RB'  # RB: Rsrc1_EXTRA3
+        elif regs == ['', 'FRB', '', 'RT', '', 'CR0']:
+            res['0'] = 'd:RT;d:CR0'  # RT,CR0: Rdest1_EXTRA3
+            res['1'] = 's:FRB'  # FRB: Rsrc1_EXTRA3
         elif insn_name == 'fishmv':
-            # an overwrite ibstruction
+            # an overwrite instruction
             res['0'] = 'd:FRS'  # FRS: Rdest1_EXTRA3
             res['1'] = 's:FRS'  # FRS: Rsrc1_EXTRA3
+        elif insn_name == 'setvl':
+            res['0'] = 'd:RT'  # RT: Rdest1_EXTRA3
+            res['1'] = 's:RA'  # RS: Rsrc1_EXTRA3
         else:
-            res['0'] = 'TODO'
-            print("regs TODO", insn_name, regs)
+            raise NotImplementedError(insn_name)
 
     elif value == 'RM-1P-2S1D':
         res['Etype'] = 'EXTRA3'  # RM EXTRA3 type
@@ -562,6 +567,14 @@ def extra_classifier(insn_name, value, name, res, regs):
             res['0'] = 'd:FRT;d:CR1'  # FRT,CR1: Rdest1_EXTRA3
             res['1'] = 's:FRA'  # FRA: Rsrc1_EXTRA3
             res['2'] = 's:FRB'  # FRB: Rsrc1_EXTRA3
+        elif regs == ['FRA', 'RB', '', 'FRT', '', 'CR1']:
+            res['0'] = 'd:FRT;d:CR1'  # FRT,CR1: Rdest1_EXTRA3
+            res['1'] = 's:FRA'  # FRA: Rsrc1_EXTRA3
+            res['2'] = 's:RB'  # RB: Rsrc1_EXTRA3
+        elif regs == ['RS', 'RB', '', 'RA', '', '']:
+            res['0'] = 'd:RA'  # RA: Rdest1_EXTRA3
+            res['1'] = 's:RS'  # RS: Rsrc1_EXTRA3
+            res['2'] = 's:RB'  # RB: Rsrc1_EXTRA3
         elif name == '2R-1W' or insn_name == 'cmpb':  # cmpb
             if insn_name in ['bpermd', 'cmpb']:
                 res['0'] = 'd:RA'  # RA: Rdest1_EXTRA3
@@ -587,8 +600,12 @@ def extra_classifier(insn_name, value, name, res, regs):
             res['0'] = 'd:RA;d:CR0'  # RA,CR0: Rdest1_EXTRA3
             res['1'] = 's:RA'  # RA: Rsrc1_EXTRA3
             res['2'] = 's:RS'  # RS: Rsrc1_EXTRA3
+        elif regs == ['RA', '', 'RB', 'RT', '', '']:  # maddsubrs
+            res['0'] = 's:RT;d:RT'  # RT: Rdest1_EXTRA2
+            res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
+            res['2'] = 's:RB'  # RT: Rsrc2_EXTRA2
         else:
-            res['0'] = 'TODO'
+            raise NotImplementedError(insn_name)
 
     elif value == 'RM-2P-2S1D':
         res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
@@ -597,21 +614,34 @@ def extra_classifier(insn_name, value, name, res, regs):
             res['1'] = 's:RS'  # RS: Rsrc1_EXTRA2
             res['2'] = 's:CR'  # CR: Rsrc2_EXTRA2
         else:
-            res['0'] = 'TODO'
+            raise NotImplementedError(insn_name)
 
     elif value == 'RM-1P-3S1D':
         res['Etype'] = 'EXTRA2'  # RM EXTRA2 type
-        if regs == ['RA', 'RB', 'RT', 'RT', '', 'CR0']:
+        if regs == ['FRT', 'FRB', 'FRA', 'FRT', '', 'CR1']:  # ffmadds/fdmadds
+            res['0'] = 's:FRT;d:FRT;d:CR1'  # FRT,CR1: Rdest1_EXTRA2
+            res['1'] = 's:FRB'  # FRB: Rsrc1_EXTRA2
+            res['2'] = 's:FRA'  # FRA: Rsrc2_EXTRA2
+        elif regs == ['RA', 'RB', 'RC', 'RT', '', '']:  # madd*
+            res['0'] = 'd:RT'  # RT,CR0: Rdest1_EXTRA2
+            res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
+            res['2'] = 's:RB'  # RT: Rsrc2_EXTRA2
+            res['3'] = 's:RC'  # RT: Rsrc3_EXTRA2
+        elif regs == ['RA', 'RB', 'RC', 'RT', '', 'CR0']:  # pcdec
             res['0'] = 'd:RT;d:CR0'  # RT,CR0: Rdest1_EXTRA2
             res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
             res['2'] = 's:RB'  # RT: Rsrc2_EXTRA2
-            res['3'] = 's:RT'  # RT: Rsrc3_EXTRA2
+            res['3'] = 's:RC'  # RT: Rsrc3_EXTRA2
+        elif regs == ['RA', 'RB', 'RT', 'RT', '', 'CR0']:  # overwrite 3-in
+            res['0'] = 's:RT;d:RT;d:CR0'  # RT,CR0: Rdest1_EXTRA2
+            res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
+            res['2'] = 's:RB'  # RT: Rsrc2_EXTRA2
         elif insn_name == 'isel':
             res['0'] = 'd:RT'  # RT: Rdest1_EXTRA2
             res['1'] = 's:RA'  # RA: Rsrc1_EXTRA2
             res['2'] = 's:RB'  # RT: Rsrc2_EXTRA2
             res['3'] = 's:BC'  # BC: Rsrc3_EXTRA2
-        else:
+        else:  # fmadd*
             res['0'] = 'd:FRT;d:CR1'  # FRT, CR1: Rdest1_EXTRA2
             res['1'] = 's:FRA'  # FRA: Rsrc1_EXTRA2
             res['2'] = 's:FRB'  # FRB: Rsrc2_EXTRA2
@@ -624,6 +654,25 @@ def extra_classifier(insn_name, value, name, res, regs):
         if insn_name == 'fmvis':
             res['0'] = 'd:FRS'  # FRS: Rdest1_EXTRA3
 
+    # HACK! thos should be RM-1P-1S butvthere is a bug with sv.bc
+    elif value == 'RM-2P-1S':
+        res['Etype'] = 'EXTRA3'  # RM EXTRA3 type
+        if insn_name.startswith('bc'):
+            res['0'] = 's:BI'  # BI: Rsrc1_EXTRA3
+
+    elif value == 'RM-1P-1S':
+        pass  # FIXME
+
+    elif value == 'non-SV':
+        return
+
+    else:
+        raise NotImplementedError(insn_name)
+
+    #if insn_name.startswith("rlw"):
+    #    print("regs ", value, insn_name, regs, res)
+
+
 
 def process_csvs(format):
 
@@ -634,15 +683,17 @@ def process_csvs(format):
     print('')
 
     (csvs, csvs_svp64, primarykeys, bykey, insn_to_csv, insns,
-           dictkeys, immediates) = read_csvs()
+     dictkeys, immediates) = read_csvs()
 
     # mapping to old SVPrefix "Forms"
     mapsto = {'3R-1W-CRo': 'RM-1P-3S1D',
+              '3R-1W': 'RM-1P-3S1D',
               '2R-1W-CRio': 'RM-1P-2S1D',
               '2R-1W-CRi': 'RM-1P-3S1D',
               '2R-1W-CRo': 'RM-1P-2S1D',
               '2R': 'non-SV',
               '2R-1W': 'RM-1P-2S1D',
+              '2R-1W-imm': 'RM-1P-2S1D',
               '1R-CRio': 'RM-2P-2S1D',
               '2R-CRio': 'RM-1P-2S1D',
               '2R-CRo': 'RM-1P-2S1D',
@@ -659,20 +710,20 @@ def process_csvs(format):
               '1W-CRi': 'RM-2P-1S1D',
               'CRio': 'RM-2P-1S1D',
               'CR=2R1W': 'RM-1P-2S1D',
-              'CRi': 'non-SV',
+              'CRi': 'RM-2P-1S',  # HACK, bc here, it should be 1P
               'imm': 'non-SV',
               '': 'non-SV',
               'LDST-2R-imm': 'LDSTRM-2P-2S',
-              'LDST-2R-imm-PU': 'LDSTRM-2P-2S-PU',
               'LDST-2R-1W-imm': 'LDSTRM-2P-2S1D',
               'LDST-2R-1W': 'LDSTRM-2P-2S1D',
               'LDST-2R-2W': 'LDSTRM-2P-2S1D',
-              'LDST-1R-1W-imm-PU': 'LDSTRM-2P-1S1D-PU',
               'LDST-1R-1W-imm': 'LDSTRM-2P-1S1D',
               'LDST-1R-2W-imm': 'LDSTRM-2P-1S2D',
               'LDST-3R': 'LDSTRM-2P-3S',
               'LDST-3R-CRo': 'LDSTRM-2P-3S',  # st*x
               'LDST-3R-1W': 'LDSTRM-2P-2S1D',  # st*x
+              'LDST-2R': 'non-SV',  # dcbz -- TODO: any vectorizable?
+              'CRo': 'non-SV',  # mtfsb1 -- TODO: any vectorizable?
               }
     print("# map to old SV Prefix")
     print('')
@@ -728,10 +779,9 @@ def process_csvs(format):
     # create a CSV file, per category, with SV "augmentation" info
     # XXX note: 'out2' not added here, needs to be added to CSV files
     # KEEP TRACK OF THESE https://bugs.libre-soc.org/show_bug.cgi?id=619
-    csvcols = ['insn', 'mode', 'CONDITIONS', 'Ptype', 'Etype',]
+    csvcols = ['insn', 'mode', 'CONDITIONS', 'Ptype', 'Etype', 'SM']
     csvcols += ['0', '1', '2', '3']
     csvcols += ['in1', 'in2', 'in3', 'out', 'CR in', 'CR out']  # temporary
-    csvcols += ['PU'] # pack/unpack
     for key in primarykeys:
         # get the decoded key containing row-analysis, and name/value
         dkey = dictkeys[key]
@@ -760,6 +810,9 @@ def process_csvs(format):
             condition = row[3]
             insn = insns[(insn_name, condition)]
 
+            #if insn_name == 'rlwinm':
+            #    print ("upd rlwinm", insn)
+
             # start constructing svp64 CSV row
             res = OrderedDict()
             res['insn'] = insn_name
@@ -778,29 +831,38 @@ def process_csvs(format):
 
             # set the SVP64 mode to NORMAL, LDST, BRANCH or CR
             crops = ['mfcr', 'mfocrf', 'mtcrf', 'mtocrf',
-                    ]
+                     ]
             mode = 'NORMAL'
             if value.startswith('LDST'):
-                mode = 'LDST'
+                if 'x' in insn_name:  # Indexed detection
+                    mode = 'LDST_IDX'
+                else:
+                    mode = 'LDST_IMM'
             elif insn_name.startswith('bc'):
                 mode = 'BRANCH'
-            elif insn_name.startswith('cr') or insn_name in crops:
+            elif (insn_name.startswith('cmp') or
+                  insn_name.startswith('cr') or
+                  insn_name in crops):
                 mode = 'CROP'
             res['mode'] = mode
 
-            # Pack/Unpack
-            if value.endswith('PU'):
-                pack = '1'
-            else:
-                pack = '0'
-            res['PU'] = pack
-
             # create a register profile list (update res row as well)
             regs = regs_profile(insn, res)
 
             #print("regs", insn_name, regs)
             extra_classifier(insn_name, value, name, res, regs)
 
+            # source-mask is hard to detect, it's part of RM-nn-nn.
+            # to make style easier, create a yes/no decision here
+            # see https://libre-soc.org/openpower/sv/svp64/#extra_remap
+            # MASK_SRC
+            vstripped = value.replace("LDST", "")
+            if vstripped in ['RM-2P-1S1D', 'RM-2P-2S',
+                             'RM-2P-2S1D', 'RM-2P-1S2D', 'RM-2P-3S',
+                             ]:
+                res['SM'] = 'EN'
+            else:
+                res['SM'] = 'NO'
             # add to svp64 csvs
             # for k in ['in1', 'in2', 'in3', 'out', 'CR in', 'CR out']:
             #    del res[k]
@@ -822,8 +884,8 @@ def process_csvs(format):
         if value == '-':
             continue
             from time import sleep
-            print ("WARNING, filename '-' should NOT exist. instrs missing")
-            print ("TODO: fix this (and put in the bugreport number here)")
+            print("WARNING, filename '-' should NOT exist. instrs missing")
+            print("TODO: fix this (and put in the bugreport number here)")
             sleep(2)
         # print out svp64 tables by category
         print("## %s" % value)
@@ -849,24 +911,10 @@ def process_csvs(format):
     pth = find_wiki_file("*.csv")
 
     # Ignore those containing: valid test sprs
-    for fname in glob(pth):
-        #print("post-checking", fname)
-        _, name = os.path.split(fname)
-        if '-' in name:
-            continue
-        if 'valid' in fname:
-            continue
-        if 'test' in fname:
-            continue
-        if fname.endswith('sprs.csv'):
-            continue
-        if fname.endswith('minor_19_valid.csv'):
-            continue
-        if 'RM' in fname:
-            continue
+    for fname in glob_valid_csvs(pth):
         svp64_csv = svt.get_svp64_csv(fname)
 
-    csvcols = ['insn', 'mode', 'Ptype', 'Etype']
+    csvcols = ['insn', 'mode', 'Ptype', 'Etype', 'SM']
     csvcols += ['in1', 'in2', 'in3', 'out', 'out2', 'CR in', 'CR out']
 
     if format is Format.VHDL:
@@ -925,7 +973,8 @@ def output(format, svt, csvcols, insns, csvs_svp64, stream):
     fullcols = csvcols + sv_cols
 
     entries_svp64 = defaultdict(list)
-    for (value, csv) in filter(lambda kv: kv[0] in lens, csvs_svp64_canon.items()):
+    for (value, csv) in filter(lambda kv: kv[0] in lens,
+                               csvs_svp64_canon.items()):
         for entry in csv:
             insn = str(entry['insn'])
             condition = str(entry['CONDITIONS'])