lots of debugging of predication, found other errors
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 30 Sep 2018 08:15:17 +0000 (09:15 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 30 Sep 2018 08:15:17 +0000 (09:15 +0100)
lots of stuff here:
* changed sv reg and pred entry layout to make them a bit more
  human-readable: put the key and idx on byte-boundaries
* bug in SV REG setting (getting int table instead of fp one, twice)
* bug(s) in SV PRED table setting (zeroing the reg tables, using idx not
  key and more)
* stop lookup of predication if the *REGISTER* entry is inactive
  (but not if it is a scalar, because scalar predication is ok)
  this was the final piece of the puzzle that got predication working
* added a useful macro for creating SV REG and PRED CAM table entries

predication now working including zeroing

riscv/insn_template_sv.cc
riscv/processor.cc
riscv/sv.cc
riscv/sv.h

index 9cd5a41a3187f3d03ea295b40d8e321ad364bec6..c2f4b1a80aa258696e87fcc971e13271b591954c 100644 (file)
@@ -23,6 +23,7 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
                  dest_pred, dest_pred, dest_pred, dest_pred);
   bool zeroing;
 #if defined(USING_REG_RD) || defined(USING_REG_FRD)
+  // use the ORIGINAL, i.e. NON-REDIRECTED, register here
   dest_pred = insn.predicate(s_insn.rd(), floatintmap & REG_RD, zeroing);
 #endif
   // identify which regs have had their CSR entries set as vectorised.
index 7c17432af3873b9691dc47c6af8af3062131c005..a53ab1e859ee610a0214330846ea173b1b0a4387 100644 (file)
@@ -392,7 +392,7 @@ void processor_t::set_csr(int which, reg_t val)
         }
         else
         {
-            r = &state.sv_int_tb[idx];
+            r = &state.sv_fp_tb[idx];
         }
         r->elwidth = c->b.elwidth;
         r->regidx = c->b.regidx;
@@ -422,12 +422,16 @@ void processor_t::set_csr(int which, reg_t val)
       {
           state.sv_pred_csrs[i].u = 0;
       }
-      memset(state.sv_int_tb, 0, sizeof(state.sv_int_tb));
-      memset(state.sv_fp_tb, 0, sizeof(state.sv_fp_tb));
+      memset(state.sv_pred_int_tb, 0, sizeof(state.sv_pred_int_tb));
+      memset(state.sv_pred_fp_tb, 0, sizeof(state.sv_pred_fp_tb));
       for (int i = 0; i < SV_CSR_SZ; i++)
       {
         union sv_pred_csr_entry *c = &state.sv_pred_csrs[i];
-        uint64_t idx = c->b.regidx;
+        uint64_t idx = c->b.regkey;
+        if (c->u == 0)
+        {
+            break;
+        }
         sv_pred_entry *r;
         // XXX damn.  this basically duplicates sv_insn_t::get_predentry.
         if (c->b.type == 1)
@@ -436,12 +440,14 @@ void processor_t::set_csr(int which, reg_t val)
         }
         else
         {
-            r = &state.sv_pred_int_tb[idx];
+            r = &state.sv_pred_fp_tb[idx];
         }
         r->regidx = c->b.regidx;
         r->zero   = c->b.zero;
         r->inv    = c->b.inv;
-        r->active = true;
+        r->active = c->b.active;
+        fprintf(stderr, "setting PREDCFG type:%d zero:%d %d %d\n",
+                        c->b.type, r->zero, (int)idx, (int)r->regidx);
       }
       break;
     }
@@ -683,7 +689,16 @@ reg_t processor_t::get_csr(int which)
     case CSR_SVREGCFG5:
     case CSR_SVREGCFG6:
     case CSR_SVREGCFG7:
-      return 0;
+      return 0;// XXX TODO: return correct entry
+    case CSR_SVPREDCFG0:
+    case CSR_SVPREDCFG1:
+    case CSR_SVPREDCFG2:
+    case CSR_SVPREDCFG3:
+    case CSR_SVPREDCFG4:
+    case CSR_SVPREDCFG5:
+    case CSR_SVPREDCFG6:
+    case CSR_SVPREDCFG7:
+      return 0;// XXX TODO: return correct entry
 #endif
     case CSR_FFLAGS:
       require_fp;
index 79c2c37f00de7a886be0244ac95b91759e963162..1a16730175765780a49f10264e841048db975478 100644 (file)
@@ -135,10 +135,15 @@ uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int &voffs, int &newoffs)
  */
 reg_t sv_insn_t::predicate(uint64_t reg, bool intreg, bool &zeroing)
 {
+  sv_reg_entry *pr = get_regentry(reg, intreg);
+  if (!pr->active)
+  {
+    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;
index 9315dd05c6d8b6b4ab48eb527f5ab2c77e94ba3f..748b9c64383886abceae228fef45d5b53458c107 100644 (file)
@@ -5,15 +5,21 @@
 
 #include "decode.h"
 
+// useful macros for constructing SV reg and predicate CSR CAM entries
+#define SV_REG_CSR(type, regkey, elwidth, regidx, isvec, packed) \
+  (regkey | (elwidth<<5) | (type<<7) | (regidx<<8) | (isvec<<14) | (packed<<15))
+#define SV_PRED_CSR(type, regkey, zero, inv, regidx, active) \
+  (regkey | (zero<<5) | (inv<<6) | (type<<7) | (regidx<<8) | (active<<14))
+
 // this table is for the CSRs (4? for RV32E, 16 for other types)
 // it's a CAM that's used to generate 2 tables (below)
 // just as in RV, writing to entries in this CAM *clears*
 // all entries with a higher index
 union sv_reg_csr_entry {
     struct {
-        unsigned int type   : 1; // 1=INT, 0=FP
         uint64_t     regkey : 5; // 5 bits
         unsigned int elwidth: 2; // 0=8-bit, 1=dflt, 2=dflt/2 3=dflt*2
+        unsigned int type   : 1; // 1=INT, 0=FP
         uint64_t     regidx : 6; // yes 6 bits
         unsigned int isvec  : 1; // vector=1, scalar=0
         unsigned int packed : 1; // Packed SIMD=1
@@ -44,10 +50,10 @@ typedef struct {
 
 union sv_pred_csr_entry {
     struct {
-        unsigned int type  : 1; // 1=INT, 0=FP
         uint64_t     regkey: 5; // 5 bits
         unsigned int zero  : 1; // zeroing=1, skipping=0
         unsigned int inv   : 1; // inversion=1
+        unsigned int type  : 1; // 1=INT, 0=FP
         uint64_t     regidx: 6; // 6 bits
         unsigned int active: 1; // enabled=1, disabled=0
     } b;