start adding explicit twin-predicated branch identification (rs2)
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 9 Oct 2018 14:51:12 +0000 (15:51 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 9 Oct 2018 14:51:12 +0000 (15:51 +0100)
id_regs.py
riscv/insn_template_sv.cc
riscv/sv.cc
riscv/sv_decode.h

index 4dbf3b5e2c702b67dc97ee3809f9331aaaffd166..e7a434bd1fd49a9971b97007140f2940c53e09af 100644 (file)
@@ -62,7 +62,7 @@ drlookup = { 'rd': 0, 'frd': 0, 'rs1': 1, 'rs2': 2, 'rs3': 3,
              'rvc_frs2': 2, 'rvc_frs2s': 2,
              }
 
-def find_registers(fname, insn, twin_predication, immed_offset):
+def find_registers(fname, insn, twin_predication, immed_offset, is_branch):
     # HACK! macro-skipping of instructions too painful
     for notparallel in ['csr', 'lui', 'c_j', 'wfi', 'auipc',
                         'dret', 'uret', 'mret', 'sret',
@@ -176,11 +176,13 @@ if __name__ == '__main__':
         regsname = os.path.join(insns_dir, regsname)
         twin_predication = False
         immed_offset = False
+        is_branch = False
         with open(regsname, "w") as f:
             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"
+                is_branch = 'STD' # standard branch
             if insn in ['lb', 'lbu', 'lw', 'lwu', 'ld', 'ldu']:
                 twin_predication = True
                 txt += "#define INSN_TYPE_LOAD\n"
@@ -214,5 +216,6 @@ if __name__ == '__main__':
                 txt += "#define INSN_TYPE_FP_BRANCH\n"
             if twin_predication:
                 txt += "\n#define INSN_CATEGORY_TWINPREDICATION\n"
-            txt += find_registers(fname, insn, twin_predication, immed_offset)
+            txt += find_registers(fname, insn, twin_predication,
+                                  immed_offset, is_branch)
             f.write(txt)
index 9edce51c3071ebe7e3ae119ba96796f8e607fb17..d2f3500a1cd3871ea32fe33fb33b2e42b9df31c6 100644 (file)
@@ -3,10 +3,10 @@
 #define xstr(s) str(s)
 #define str(s) #s
 
-#ifdef USING_NOREGS
-    #define set_pc _set_pc
+#ifdef INSN_TYPE_BRANCH
+    #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_pred);
 #else
-    #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs);
+    #define set_pc _set_pc
 #endif
 
 reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
@@ -37,6 +37,10 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
   reg_t src_pred = ~0x0;
   int *src_offs = &(p->get_state()->srcoffs);
   bool zeroingsrc = false;
+#endif
+#ifdef INSN_TYPE_BRANCH
+  reg_t target_pred = ~0x0;
+  bool zeroingtarg = false;
 #endif
   sv_insn_t insn(p, bits, floatintmap, PRED_ARGS, OFFS_ARGS);
   reg_t sp = 0;
@@ -52,6 +56,10 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
 #ifdef INSN_TYPE_C_STACK_ST
     sp = insn._remap(X_SP, true, dest_offs);
 #endif
+#ifdef INSN_TYPE_BRANCH
+    // all branch ops are rs1, rs2.  take target (dest) predicate from rs2.
+    target_pred = insn.predicate(s_insn.rs2(), true, zeroingtarg);
+#endif
 #ifdef INSN_CATEGORY_TWINPREDICATION
 #ifdef INSN_TYPE_C_STACK_LD
     src_pred = insn.predicate(sp, SRC_PREDINT, zeroingsrc);
index a5bae3178d1d934613100908b98e66dd105339b3..edb6f8ba47dbfd16ab89ab766501793f2dde7040 100644 (file)
@@ -204,7 +204,8 @@ uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set)
     return val;
 }
 
-void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs)
+void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
+                      uint64_t predicate)
 {
     if (vlen == 1 or not at_least_one_reg_vectorised)
     {
index d72444f227cf3c746689259f78341305aa86db5b..92ed7956a9ffd5fe98071a7f5176621f7fbb01a5 100644 (file)
@@ -58,7 +58,8 @@ public:
   uint64_t _rvc_rs2s() { return _remap(insn_t::rvc_rs2s(), fimap & REG_RVC_RS2S,
                                        offs_rs2); }
 
-  void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs);
+  void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
+             uint64_t predicate);
 
   // used for predicated branches. sets bit N if val=true; clears bit N if false
   uint64_t rd_bitset(uint64_t bit, bool val);