big reorganisation to support twin-predication
[riscv-isa-sim.git] / id_regs.py
index 734f02930f7f2d420de0e35c0fa827710510e340..49f68b0ac94ed91c2e47c0eecc53cf8aad83625f 100644 (file)
@@ -54,7 +54,15 @@ allints = intpatterns + cintpatterns[2:]
 
 skip = '#define USING_NOREGS\n' \
        '#define REGS_PATTERN 0x0\n'
-def find_registers(fname):
+
+# this matches the order of the 4 predication arguments to
+drlookup = { 'rd': 0, 'frd': 0, 'rs1': 1, 'rs2': 2, 'rs3': 3,
+             'rvc_rs1': 1, 'rvc_rs1s': 1,
+             'rvc_rs2': 2, 'rvc_rs2s': 2,
+             'rvc_frs2': 2, 'rvc_frs2s': 2,
+             }
+
+def find_registers(fname, twin_predication):
     # HACK! macro-skipping of instructions too painful
     for notparallel in ['csr', 'lui', 'c_j', 'wfi', 'auipc',
                         'dret', 'uret', 'mret', 'sret',
@@ -62,9 +70,11 @@ def find_registers(fname):
         if notparallel in fname:
             return skip
     res = []
+    regs = []
     isintfloat = 0x0 + floatmask << len(allints)
     with open(fname) as f:
         f = f.read()
+        dest_reg = None
         for pattern in patterns:
             x = f.find(pattern)
             if x == -1:
@@ -88,16 +98,50 @@ def find_registers(fname):
             p = pattern
             if p.startswith('WRITE_'):
                 p = p[6:]
+                dest_reg = p
             if pattern in allints:
                 idx = allints.index(pattern)
                 isintfloat += 1 << idx
             if pattern in allfloats:
                 idx = allfloats.index(pattern)
                 isintfloat &= ~(1 << (idx+len(allints)))
+            regs.append(p)
             res.append('#define USING_REG_%s' % p)
+        if dest_reg:
+            dr = dest_reg
+            fdest = False
+            if dest_reg.startswith('RVC_F'):
+                fdest = True
+                dr = 'RVC_' + dest_reg[5:]
+            if dest_reg == 'FRD':
+                fdest = True
+                dr = 'RD'
+            dridx = drlookup[dest_reg.lower()]
+            res.append('#define DEST_REG %s' % dr.lower())
+            res.append('#define _DEST_REG _%s' % dr.lower())
+            res.append('#define DEST_PREDINT %d' % (0 if fdest else 1))
     if not res:
         return skip
     res.append('#define REGS_PATTERN 0x%x' % isintfloat)
+
+    predargs = ['dest_pred'] * 4
+    if twin_predication:
+        found = None
+        for search in ['rs1', 'rs2', 'rs3', 'rvc_rs1', 'rvc_rs1s',
+                       'rvc_rs2', 'rvc_rs2s',
+                       'frs1', 'frs2', 'frs3',
+                       'rvc_frs2', 'rvc_frs2s']:
+            if search.upper() in regs:
+                found = search
+        if found:
+            predargs[drlookup[found]] = 'src_pred'
+            fsrc = 'f' in found
+            found = found.replace('f', '')
+            res.append('#define SRC_PREDINT %d' % (0 if fsrc else 1))
+            res.append('#define SRC_REG %s' % found)
+
+    res.append('#define PRED_ARGS %s' % ','.join(predargs))
+
     return '\n'.join(res)
 
 if __name__ == '__main__':
@@ -107,8 +151,7 @@ if __name__ == '__main__':
         regsname = os.path.join(insns_dir, regsname)
         twin_predication = False
         with open(regsname, "w") as f:
-            txt = find_registers(fname)
-            txt += "\n#define INSN_%s\n" % insn.upper()
+            txt = "\n#define INSN_%s\n" % insn.upper()
             # help identify type of register
             if insn in ['beq', 'bne', 'blt', 'bltu', 'bge', 'bgeu']:
                 txt += "#define INSN_TYPE_BRANCH\n"
@@ -141,4 +184,5 @@ if __name__ == '__main__':
                 txt += "#define INSN_TYPE_FP_BRANCH\n"
             if twin_predication:
                 txt += "\n#define INSN_CATEGORY_TWINPREDICATION\n"
+            txt += find_registers(fname, twin_predication)
             f.write(txt)