From af7dc4bfb13f2f31e68346e5ba120c47cab95414 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 26 Sep 2018 10:54:54 +0100 Subject: [PATCH] actually implement sv register re-mapping 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 | 40 ++++++++++++++++++++++++++++++++++++++-- riscv/sv.h | 14 +++++++------- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/riscv/sv.cc b/riscv/sv.cc index b0b65ee..0ec5ce7 100644 --- a/riscv/sv.cc +++ b/riscv/sv.cc @@ -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 :) } diff --git a/riscv/sv.h b/riscv/sv.h index 8c2bf3a..f42b3d4 100644 --- a/riscv/sv.h +++ b/riscv/sv.h @@ -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; -- 2.30.2