reorganise twin-predication
[riscv-isa-sim.git] / riscv / sv.cc
index 4acc9d2b90b7fae2d0026d3e4d15e2719567a294..9cc46507e524b5dfafd3d917762841426bd8dd0e 100644 (file)
@@ -1,30 +1,50 @@
 #include "sv.h"
 #include "sv_decode.h"
 
-sv_reg_csr_entry sv_csrs[SV_CSR_SZ];
-sv_reg_entry sv_int_tb[NXPR];
-sv_reg_entry sv_fp_tb[NFPR];
-sv_pred_csr_entry sv_pred_csrs[SV_CSR_SZ];
-sv_pred_entry sv_pred_int_tb[NXPR];
-sv_pred_entry sv_pred_fp_tb[NFPR];
+sv_pred_entry* sv_insn_t::get_predentry(uint64_t reg, bool intreg)
+{
+  // okaay so first determine which map to use.  intreg is passed
+  // in (ultimately) from id_regs.py's examination of the use of
+  // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
+  // in from sv_insn_t::fimap...
+  sv_pred_entry *r;
+  if (intreg)
+  {
+    return &p->get_state()->sv_pred_int_tb[reg];
+  }
+  else
+  {
+    return &p->get_state()->sv_pred_fp_tb[reg];
+  }
+}
 
-bool sv_check_reg(bool intreg, uint64_t reg)
+sv_reg_entry* sv_insn_t::get_regentry(uint64_t reg, bool intreg)
 {
+  // okaay so first determine which map to use.  intreg is passed
+  // in (ultimately) from id_regs.py's examination of the use of
+  // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
+  // in from sv_insn_t::fimap...
   sv_reg_entry *r;
   if (intreg)
   {
-    r = &sv_int_tb[reg];
+    return &p->get_state()->sv_int_tb[reg];
   }
   else
   {
-    r = &sv_fp_tb[reg];
+    return &p->get_state()->sv_fp_tb[reg];
   }
+}
+
+bool sv_insn_t::sv_check_reg(bool intreg, uint64_t reg)
+{
+  sv_reg_entry *r = get_regentry(reg, intreg);
   if (r->elwidth != 0)
   {
     // XXX raise exception
   }
   if (r->active && r->isvec)
   {
+    fprintf(stderr, "checkreg: %ld active\n", reg);
     return true;
   }
   return false;
@@ -52,21 +72,15 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int &voffs)
   // in (ultimately) from id_regs.py's examination of the use of
   // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
   // in from sv_insn_t::fimap...
-  sv_reg_entry *r;
-  if (intreg)
-  {
-    r = &sv_int_tb[reg];
-  }
-  else
-  {
-    r = &sv_fp_tb[reg];
-  }
+  sv_reg_entry *r = get_regentry(reg, intreg);
+
   // next we check if this entry is active.  if not, the register
   // is not being "redirected", so just return the actual reg.
   if (!r->active)
   {
     return reg; // not active: return as-is
   }
+  vloop_continue = true;
 
   // next we go through the lookup table.  *THIS* is why the
   // sv_reg_entry table is 32 entries (5-bit) *NOT* 6 bits
@@ -78,18 +92,15 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int &voffs)
   // we return the re-mapped register...
   if (!r->isvec) // scalar
   {
-    return reg; // ... remapped at this point...
+    return reg; 
   }
+  vloop_continue = true;
 
   // aaand now, as it's a "vector", FINALLY we can add on the loop-offset
   // which was passed in to the sv_insn_t constructor (by reference)
   // and, at last, we have "parallelism" a la contiguous registers.
   reg += voffs; // wheww :)
 
-  // however... before returning, we increment the loop-offset for
-  // this particular register, so that on the next loop the next
-  // contiguous register will be used.
-  voffs += 1;
   return reg;
 }
 
@@ -118,21 +129,17 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int &voffs)
  * down to the number of bits in the predication i.e. the bitwidth of integer
  * registers (i.e. XLEN bits).
  */
-reg_t sv_insn_t::predicate(processor_t *p, uint64_t reg,
-                           bool intreg, bool &zeroing)
+reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing)
 {
-  sv_pred_entry *r;
-  if (intreg)
-  {
-    r = &sv_pred_int_tb[reg];
-  }
-  else
+  sv_reg_entry *pr = get_regentry(reg, intreg);
+  if (!pr->active)
   {
-    r = &sv_pred_fp_tb[reg];
+    return ~0x0; // *REGISTER* not active: return all-1s (unconditional "on")
   }
+  sv_pred_entry *r = get_predentry(reg, intreg);
   if (!r->active)
   {
-    return ~0x0; // not active: return all-1s (unconditional "on")
+    return ~0x0; // *PREDICATION* not active: return all-1s (unconditional "on")
   }
   zeroing = r->zero;
   reg = r->regidx;
@@ -143,3 +150,20 @@ reg_t sv_insn_t::predicate(processor_t *p, uint64_t reg,
   }
   return predicate;
 }
+
+uint64_t sv_insn_t::predicated(uint64_t reg, int offs, uint64_t pred)
+{
+    if (pred & (1<<offs))
+    {
+        return reg;
+    }
+    fprintf(stderr, "predication %ld %d %lx\n", reg, offs, pred);
+    return 0;
+}
+
+bool sv_insn_t::stop_vloop(void)
+{
+    return (p->get_state()->vl == 0) || !vloop_continue;
+}
+
+