override setpc macro so that sv can redirect it in branch
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 7 Oct 2018 14:06:39 +0000 (15:06 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 7 Oct 2018 14:06:39 +0000 (15:06 +0100)
this is slightly complicated.  setpc is a global macro, intended for
use in the templates.  however for SV it needs to be conditional,
so needs to redirect to a function in sv_insn_t.

that in turn needs quite a few extra parameters: the current loop
element offset, the argument to set_pc just in case actually it is
detected that this really is to be a branch not a predication scenario
and so on.

have not tried out vectorisation yet, at least straight non-vectorised
branch operations (unit tests) pass.

riscv/decode.h
riscv/insn_template.cc
riscv/insn_template_sv.cc
riscv/sv.cc
riscv/sv_decode.h

index f9e3b6f649fec534693b25b48cdf20d201dcd085..f7a8f10d39d1005503dc3d049984d70229521a18 100644 (file)
@@ -201,11 +201,15 @@ private:
 #define sext_xlen(x) (((sreg_t)(x) << (64-xlen)) >> (64-xlen))
 #define zext_xlen(x) (((reg_t)(x) << (64-xlen)) >> (64-xlen))
 
-#define set_pc(x) \
+#define _set_pc(x) \
   do { p->check_pc_alignment(x); \
        npc = sext_xlen(x); \
      } while(0)
 
+#ifndef SPIKE_SIMPLEV
+    #define set_pc _set_pc
+#endif
+
 #define set_pc_and_serialize(x) \
   do { reg_t __npc = (x) & p->pc_alignment_mask(); \
        npc = PC_SERIALIZE_AFTER; \
index ebfc02af4eca1fa242a63bf2f20c77d18bf5bad8..3e23731c1cd095ace0c82307390363efd713a24e 100644 (file)
 
 #define INSN NAME
 #define INCLUDEFILE "insns/NAME.h"
+#define SVINCLUDEFILE "insns/sv_NAME.h"
 #define INSNCODE OPCODE
-#include "sv_decode.h"
 #include "insns/regs_NAME.h"
+#include "sv_decode.h"
 #define FN rv32_NAME
 #define ISASZ 32
 #include "insn_template_sv.cc"
index 9869707f2bfcfd8f531e49bfcc8f2c17ebfa237f..9edce51c3071ebe7e3ae119ba96796f8e607fb17 100644 (file)
@@ -3,6 +3,12 @@
 #define xstr(s) str(s)
 #define str(s) #s
 
+#ifdef USING_NOREGS
+    #define set_pc _set_pc
+#else
+    #define set_pc(x) insn.setpc(xlen, vlen, npc, x, *dest_offs);
+#endif
+
 reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
 {
   int xlen = ISASZ;
index 6979e44701a93b578f945fd7d204399bab9850ad..a5bae3178d1d934613100908b98e66dd105339b3 100644 (file)
@@ -45,6 +45,7 @@ bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg)
   if (r->active && r->isvec)
   {
     fprintf(stderr, "checkreg: %ld active\n", reg);
+    at_least_one_reg_vectorised = true;
     return true;
   }
   return false;
@@ -202,3 +203,14 @@ uint64_t sv_insn_t::rd_bitset(uint64_t bit, bool set)
     WRITE_REG(reg, val);
     return val;
 }
+
+void sv_insn_t::setpc(int xlen, int vlen, reg_t &npc, reg_t addr, uint64_t offs)
+{
+    if (vlen == 1 or not at_least_one_reg_vectorised)
+    {
+        _set_pc(addr);
+        return;
+    }
+    rd_bitset(offs, true);
+}
+
index 54ede0311e9262640995f96960b76ff0a9959e51..d72444f227cf3c746689259f78341305aa86db5b 100644 (file)
@@ -24,7 +24,8 @@ public:
             uint64_t &p_rd, uint64_t &p_rs1, uint64_t &p_rs2, uint64_t &p_rs3,
             uint64_t *p_im,
             int *o_rd, int *o_rs1, int *o_rs2, int *o_rs3, int *o_imm) :
-            insn_t(bits), p(pr), vloop_continue(false), fimap(f),
+            insn_t(bits), p(pr), vloop_continue(false),
+            at_least_one_reg_vectorised(false), fimap(f),
             offs_rd(o_rd), offs_rs1(o_rs1), offs_rs2(o_rs2), offs_rs3(o_rs3),
             offs_imm(o_imm),
             prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3) {}
@@ -57,6 +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);
+
   // used for predicated branches. sets bit N if val=true; clears bit N if false
   uint64_t rd_bitset(uint64_t bit, bool val);
 
@@ -84,6 +87,7 @@ public:
 
 private:
   bool vloop_continue;
+  bool at_least_one_reg_vectorised;
   unsigned int fimap;
   int *offs_rd;
   int *offs_rs1;