a LOT of debugging and fixing, sv loop actually working
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 Sep 2018 09:19:47 +0000 (10:19 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 29 Sep 2018 09:19:47 +0000 (10:19 +0100)
riscv/encoding.h
riscv/insn_template_sv.cc
riscv/insns/csrrwi.h
riscv/processor.cc
riscv/sv.cc
riscv/sv.h

index 4fd7b365f04fc2f99dd37fc84108d42a3e9188c9..980a792963c742be4d5262b8511f4af46711c67f 100644 (file)
@@ -1262,6 +1262,22 @@ DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_R
 DECLARE_CSR(svvl, CSR_SVVL)
 DECLARE_CSR(svrealvl, CSR_SVREALVL)
 DECLARE_CSR(svmvl, CSR_SVMVL)
+DECLARE_CSR(svregcfg0, CSR_SVREGCFG0)
+DECLARE_CSR(svregcfg1, CSR_SVREGCFG1)
+DECLARE_CSR(svregcfg2, CSR_SVREGCFG2)
+DECLARE_CSR(svregcfg3, CSR_SVREGCFG3)
+DECLARE_CSR(svregcfg4, CSR_SVREGCFG4)
+DECLARE_CSR(svregcfg5, CSR_SVREGCFG5)
+DECLARE_CSR(svregcfg6, CSR_SVREGCFG6)
+DECLARE_CSR(svregcfg7, CSR_SVREGCFG7)
+DECLARE_CSR(svpredcfg0, CSR_SVPREDCFG0)
+DECLARE_CSR(svpredcfg1, CSR_SVPREDCFG1)
+DECLARE_CSR(svpredcfg2, CSR_SVPREDCFG2)
+DECLARE_CSR(svpredcfg3, CSR_SVPREDCFG3)
+DECLARE_CSR(svpredcfg4, CSR_SVPREDCFG4)
+DECLARE_CSR(svpredcfg5, CSR_SVPREDCFG5)
+DECLARE_CSR(svpredcfg6, CSR_SVPREDCFG6)
+DECLARE_CSR(svpredcfg7, CSR_SVPREDCFG7)
 DECLARE_CSR(fflags, CSR_FFLAGS)
 DECLARE_CSR(frm, CSR_FRM)
 DECLARE_CSR(fcsr, CSR_FCSR)
index 4b7a41ab4279970ad2f221656feb2ece070bd9d7..3ff09e8061842ca190d7af2aa6f3034db3fb1d53 100644 (file)
@@ -1,5 +1,8 @@
 // See LICENSE for license details.
 
+#define xstr(s) str(s)
+#define str(s) #s
+
 reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
 {
   int xlen = ISASZ;
@@ -21,38 +24,44 @@ reg_t FN(processor_t* p, insn_t s_insn, reg_t pc)
   // really could do with a macro for-loop here... oh well...
   // integer ops, RD, RS1, RS2, RS3 (use sv_int_tb)
   bool vectorop =
-#ifdef USING_RD
-  insn.check_reg(true, s_insn.rd()) |
+#ifdef USING_REG_RD
+  insn.sv_check_reg(true, s_insn.rd()) |
 #endif
-#ifdef USING_RS1
-  insn.check_reg(true, s_insn.rs1()) |
+#ifdef USING_REG_RS1
+  insn.sv_check_reg(true, s_insn.rs1()) |
 #endif
-#ifdef USING_RS2
-  insn.check_reg(true, s_insn.rs2()) |
+#ifdef USING_REG_RS2
+  insn.sv_check_reg(true, s_insn.rs2()) |
 #endif
-#ifdef USING_RS2
- insn.check_reg(true, s_insn.rs3()) |
+#ifdef USING_REG_RS2
+ insn.sv_check_reg(true, s_insn.rs3()) |
 #endif
   // fp ops, RD, RS1, RS2, RS3 (use sv_fp_tb)
-#ifdef USING_FRD
-  insn.check_reg(false, s_insn.frd()) |
+#ifdef USING_REG_FRD
+  insn.sv_check_reg(false, s_insn.rd()) |
 #endif
-#ifdef USING_FRS1
-  insn.check_reg(false, s_insn.frs1()) |
+#ifdef USING_REG_FRS1
+  insn.sv_check_reg(false, s_insn.rs1()) |
 #endif
-#ifdef USING_FRS2
-  insn.check_reg(false, s_insn.rs2()) |
+#ifdef USING_REG_FRS2
+  insn.sv_check_reg(false, s_insn.rs2()) |
 #endif
-#ifdef USING_FRS2
-  insn.check_reg(false, s_insn.rs3()) |
+#ifdef USING_REG_FRS2
+  insn.sv_check_reg(false, s_insn.rs3()) |
 #endif
   false; // save a few cycles by |ing the checks together.
 
+  if (insn.sv_check_reg(true, 16))
+  {
+    fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld\n",
+            xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2());
+  }
   // if vectorop is set, one of the regs is not a scalar,
   // so we must read the VL CSR and do a loop
   if (vectorop)
   {
-    // TODO: vlen = p->CSR(SIMPLEV_VL); // something like that...
+    vlen = p->get_state()->vl;
+    fprintf(stderr, "vectorop %x vlen %d\n", INSNCODE, vlen);
   }
   for (int voffs=0; voffs < vlen; voffs++)
   {
index 8793d31fd98eaa28015990bae09337d6196c64bb..7b7060060ed0f6257c6d0cd41551003ddec94120 100644 (file)
@@ -1,4 +1,6 @@
+fprintf(stderr, "csrrwi %lx\n", insn.csr());
 int csr = validate_csr(insn.csr(), true);
+fprintf(stderr, "validated %x\n", csr);
 #ifdef SPIKE_SIMPLEV
 reg_t old = 0; // stop compiler bitchin
 if (csr != CSR_SVVL)
index b5ae0993a5201ddb53006fb20230eb3986db426d..7c17432af3873b9691dc47c6af8af3062131c005 100644 (file)
@@ -333,18 +333,20 @@ void processor_t::set_csr(int which, reg_t val)
   reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP
                        | ((ext != NULL) << IRQ_COP);
   reg_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;
+  fprintf(stderr, "set CSR %x %lx\n", which, val);
   switch (which)
   {
 #ifdef SPIKE_SIMPLEV
     case CSR_SVMVL:
       state.mvl = std::min(val, (uint64_t)63); // limited to XLEN width
+      fprintf(stderr, "set MVL %lx\n", state.mvl);
       break;
     case CSR_SVREALVL:
       state.vl = std::min(val, state.mvl); // limited to MVL
       break;
     case CSR_SVVL:
       state.vl = std::min(state.mvl, val);
-      state.XPR.write(val, state.vl);
+      fprintf(stderr, "set VL %lx\n", state.vl);
       break;
     case CSR_SVREGCFG0:
     case CSR_SVREGCFG1:
@@ -357,6 +359,7 @@ void processor_t::set_csr(int which, reg_t val)
     {
       // identify which (pair) of SV config CAM registers are being set
       int tbidx = (which - CSR_SVREGCFG0) * 2;
+      fprintf(stderr, "set REGCFG %d %lx\n", tbidx, val);
       // lower 16 bits go into even, upper into odd...
       state.sv_csrs[tbidx].u = get_field(val, 0xffff);
       state.sv_csrs[tbidx+1].u = get_field(val, 0xffff0000);
@@ -364,6 +367,7 @@ void processor_t::set_csr(int which, reg_t val)
       // when it comes to context-switching, it's clear what needs to be saved
       for (int i = tbidx+2; i < 16; i++)
       {
+          fprintf(stderr, "clr REGCFG %d\n", i);
           state.sv_csrs[i].u = 0;
       }
       // okaaay and now "unpack" the CAM to make it easier to use.  this
@@ -375,8 +379,12 @@ void processor_t::set_csr(int which, reg_t val)
       for (int i = 0; i < SV_CSR_SZ; i++)
       {
         union sv_reg_csr_entry *c = &state.sv_csrs[i];
-        uint64_t idx = c->b.regidx;
+        uint64_t idx = c->b.regkey;
         sv_reg_entry *r;
+        if (c->u == 0)
+        {
+            break;
+        }
         // XXX damn.  this basically duplicates sv_insn_t::get_regentry.
         if (c->b.type == 1)
         {
@@ -391,6 +399,8 @@ void processor_t::set_csr(int which, reg_t val)
         r->isvec = c->b.isvec;
         r->packed = c->b.packed;
         r->active = true;
+        fprintf(stderr, "setting REGCFG type:%d isvec:%d %d %d\n",
+                        c->b.type, r->isvec, (int)idx, (int)r->regidx);
       }
       break;
     }
@@ -665,6 +675,15 @@ reg_t processor_t::get_csr(int which)
       return state.vl;
     case CSR_SVMVL:
       return state.mvl;
+    case CSR_SVREGCFG0:
+    case CSR_SVREGCFG1:
+    case CSR_SVREGCFG2:
+    case CSR_SVREGCFG3:
+    case CSR_SVREGCFG4:
+    case CSR_SVREGCFG5:
+    case CSR_SVREGCFG6:
+    case CSR_SVREGCFG7:
+      return 0;
 #endif
     case CSR_FFLAGS:
       require_fp;
index 43413636cdd32f3d61897a1035a7ad33bb5535f2..ba7f6910421b3fc5d9a26ea27927687407ec91b3 100644 (file)
@@ -44,6 +44,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);
     return true;
   }
   return false;
index 93f3fcfbb78d10168eeb6b1254f0fedc951b50ae..9315dd05c6d8b6b4ab48eb527f5ab2c77e94ba3f 100644 (file)
@@ -11,7 +11,7 @@
 // all entries with a higher index
 union sv_reg_csr_entry {
     struct {
-        unsigned int type   : 1; // 0=INT, 1=FP
+        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
         uint64_t     regidx : 6; // yes 6 bits
@@ -44,7 +44,7 @@ typedef struct {
 
 union sv_pred_csr_entry {
     struct {
-        unsigned int type  : 1; // 0=INT, 1=FP
+        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