get predicated-vectorised branch working
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 9 Oct 2018 18:33:53 +0000 (19:33 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 9 Oct 2018 18:33:53 +0000 (19:33 +0100)
riscv/insn_template_sv.cc
riscv/sv.cc
riscv/sv_decode.h

index 7a67f6c1b3721678c5729831fe4450544c9dcccd..f5796462222169df321dfa52bb5d0739d88c6c35 100644 (file)
 #define xstr(s) str(s)
 #define str(s) #s
 
+#include "sv.h"
+
 #ifdef INSN_TYPE_BRANCH
-    #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_pred);
+    #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs, target_reg);
 #else
     #define set_pc _set_pc
 #endif
@@ -99,6 +101,11 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
   bool zeroingtarg = false;
 #endif
   sv_insn_t insn(p, bits, floatintmap, PRED_ARGS, OFFS_ARGS);
+#ifdef INSN_TYPE_BRANCH
+  sv_pred_entry *r = insn.get_predentry(s_insn.rs2(), true);
+  reg_t _target_reg = 0;
+  reg_t *target_reg = NULL;
+#endif
   reg_t sp = 0;
   if (vlen > 0)
   {
@@ -114,7 +121,14 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
 #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);
+    if (r->active)
+    {
+      _target_reg = r->regidx;
+      target_reg = &_target_reg;
+      insn.predicate(s_insn.rs2(), true, zeroingtarg);
+      fprintf(stderr, "branch pred reg %ld pred %lx\n",
+                       _target_reg, target_pred);
+    }
 #endif
 #ifdef INSN_CATEGORY_TWINPREDICATION
 #ifdef INSN_TYPE_C_STACK_LD
@@ -246,6 +260,7 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
   if (insn.get_if_one_reg_vectorised() &&
       (insn.get_saved_branch_rd() & mask) == (target_pred & mask))
   {
+    fprintf(stderr, "vector branch ACTIVE\n");
     _set_pc(insn.get_saved_branch_addr());
   }
 #endif
index c06bdd5575751829352c396664c74778e8f24fa9..ba4fd53a0bcfa2fc80ca84d84d34d6ec31a6ea0b 100644 (file)
@@ -191,9 +191,8 @@ uint64_t sv_insn_t::_rvc_spoffs_imm(uint64_t elwidth, uint64_t offs)
 }
 
 // for use in predicated branches. sets bit N if val=true; clears bit N if false
-uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set)
+uint64_t sv_insn_t::rd_bitset(reg_t reg, uint64_t bit, bool set)
 {
-    reg_t reg = rd();
     uint64_t val = READ_REG(reg);
     if (set) {
         val |= (1<<bit);
@@ -205,7 +204,7 @@ uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set)
 }
 
 void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
-                      uint64_t predicate)
+                      reg_t *target_reg)
 {
     save_branch_addr = addr;
     if (not at_least_one_reg_vectorised)
@@ -213,6 +212,20 @@ void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
         _set_pc(addr);
         return;
     }
-    save_branch_rd = rd_bitset(offs, true);
+    if (target_reg != NULL) {
+        fprintf(stderr, "setpc pre rd %ld v %lx pred %lx\n",
+                        *target_reg, READ_REG(*target_reg), prs1);
+    }
+    if ((1<<offs) & prs1)
+    {
+        if (target_reg) {
+            save_branch_rd = rd_bitset(*target_reg, offs, true);
+        } else {
+            save_branch_rd |= (1<<offs);
+        }
+    }
+    fprintf(stderr, "setpc %lx offs %ld predicate %lx rs1 %ld rs2 %ld\n",
+            save_branch_rd, offs, prs1,
+            READ_REG(rs1()), READ_REG(rs2()));
 }
 
index 42ea2e3334e3d6b5c5ca26548216ef65b72b7d7d..98252e78df3dae6d081ae7f80277987ffc0cb60c 100644 (file)
@@ -60,10 +60,10 @@ public:
                                        offs_rs2); }
 
   void setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs,
-             uint64_t predicate);
+             reg_t *target_reg);
 
   // used for predicated branches. sets bit N if val=true; clears bit N if false
-  uint64_t rd_bitset(uint64_t bit, bool val);
+  uint64_t rd_bitset(reg_t reg, uint64_t bit, bool val);
 
   bool sv_check_reg(bool intreg, uint64_t reg);
   sv_reg_entry* get_regentry(uint64_t reg, bool isint);