actually implement sv register re-mapping
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 26 Sep 2018 09:54:54 +0000 (10:54 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 26 Sep 2018 09:54:54 +0000 (10:54 +0100)
the algorithm here checks the (required) table (int or fp), checks if
the entry is "active", does a redirect, then checks if the entry is
scalar or vector.  if vector, the loop-offset (passed by value) is
added

riscv/sv.cc
riscv/sv.h

index b0b65ee45001a461c14025de78b2e2c8a2a3d694..0ec5ce73406e2d6d105c38e725c6626c936e8804 100644 (file)
@@ -29,8 +29,44 @@ bool sv_check_reg(bool intreg, uint64_t reg)
   return false;
 }
 
-uint64_t sv_insn_t::remap(uint64_t reg, bool isint)
+uint64_t sv_insn_t::remap(uint64_t reg, bool intreg)
 {
-    return reg;
+  // okaay so first determine which map to use.  intreg is passed
+  // in (ultimately) from the 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];
+  }
+  // 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
+  }
+
+  // next we go through the lookup table.  *THIS* is why the
+  // sv_reg_entry table is 32 entries (5-bit) *NOT* 6 bits
+  // the *KEY* (reg) is 5-bit, the *VALUE* (actual target reg) is 6-bit
+  // XXX TODO: must actually double NXPR and NXFR in processor.h to cope!!
+  reg = r->regidx;
+
+  // now we determine if this is a scalar/vector: if it's scalar
+  // we return the re-mapped register...
+  if (!r->isvec) // scalar
+  {
+    return reg; // ... remapped at this point...
+  }
+
+  // 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.
+  return reg + this->voffs; // wheww :)
 }
 
index 8c2bf3a4216fd6b1c0d483bda3b29bae12370203..f42b3d420778bcab076b7e3359038c5a393548cc 100644 (file)
@@ -11,9 +11,9 @@
 // all entries with a higher index
 typedef struct {
     unsigned int type   : 1; // 0=INT, 1=FP
-    unsigned int regkey : 5; // 5 bits
+    uint64_t     regkey : 5; // 5 bits
     unsigned int elwidth: 2; // 0=8-bit, 1=dflt, 2=dflt/2 3=dflt*2
-    unsigned int regidx : 6; // yes 6 bits
+    uint64_t     regidx : 6; // yes 6 bits
     unsigned int isvec  : 1; // vector=1, scalar=0
     unsigned int packed : 1; // Packed SIMD=1
 } sv_reg_csr_entry;
@@ -30,7 +30,7 @@ extern sv_reg_csr_entry sv_csrs[SV_CSR_SZ];
 // in SV however the instruction is STILL ONLY 5 BITS.
 typedef struct {
     unsigned int elwidth: 2; // 0=8-bit, 1=dflt, 2=dflt/2 3=dflt*2
-    unsigned int regidx : 6; // yes 6 bits.
+    uint64_t     regidx : 6; // yes 6 bits.
     unsigned int isvec  : 1; // vector=1, scalar=0
     unsigned int packed : 1; // Packed SIMD=1
     unsigned int active : 1; // enabled=1, disabled=0
@@ -43,20 +43,20 @@ extern sv_reg_entry sv_fp_tb[NFPR];
 
 typedef struct {
     unsigned int type  : 1; // 0=INT, 1=FP
-    unsigned int regkey: 5; // 5 bits: 
+    uint64_t     regkey: 5; // 5 bits
     unsigned int zero  : 1; // zeroing=1, skipping=0
     unsigned int inv   : 1; // inversion=1
-    unsigned int regidx: 6; // 6 bits
+    uint64_t     regidx: 6; // 6 bits
     unsigned int active: 1; // enabled=1, disabled=0
 } sv_pred_csr_entry;
 
 extern sv_pred_csr_entry sv_pred_csrs[SV_CSR_SZ];
 
 typedef struct {
-    unsigned int regkey: 5; // 5 bits: 
+    uint64_t     regkey: 5; // 5 bits
     unsigned int zero  : 1; // zeroing=1, skipping=0
     unsigned int inv   : 1; // inversion=1
-    unsigned int regidx: 6; // 6 bits
+    uint64_t     regidx: 6; // 6 bits
     unsigned int active: 1; // enabled=1, disabled=0
 } sv_pred_entry;