aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2012-03-19 17:54:08 -0700
committerAndrew Waterman <waterman@eecs.berkeley.edu>2012-03-19 17:54:08 -0700
commit30e88a7fe9e4626ee2ec4d8f1bd2366c72cf25a2 (patch)
tree862a71acd1600541265d253eb49f43e8a37dfc02
parent672b0eb7de769a72ed7c4f8cd471d433843ef690 (diff)
downloadspike-30e88a7fe9e4626ee2ec4d8f1bd2366c72cf25a2.zip
spike-30e88a7fe9e4626ee2ec4d8f1bd2366c72cf25a2.tar.gz
spike-30e88a7fe9e4626ee2ec4d8f1bd2366c72cf25a2.tar.bz2
abstract regfile write port
-rw-r--r--riscv/decode.h44
1 files changed, 30 insertions, 14 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index eb13b53..d7e91f2 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -137,6 +137,22 @@ union insn_t
};
#include <stdio.h>
+template <class T>
+class write_port_t
+{
+public:
+ write_port_t(T& _t) : t(_t) {}
+ T& operator = (const T& rhs)
+ {
+ return t = rhs;
+ }
+ operator T()
+ {
+ return t;
+ }
+private:
+ T& t;
+};
template <class T, size_t N, bool zero_reg>
class regfile_t
{
@@ -145,15 +161,15 @@ public:
{
memset(data, 0, sizeof(data));
}
- T& operator [] (size_t i)
+ write_port_t<T> write_port(size_t i)
{
- if (zero_reg)
- data[0] = 0;
- return data[i];
+ return write_port_t<T>(data[i]);
}
const T& operator [] (size_t i) const
{
- return const_cast<regfile_t<T,N,zero_reg>&>(*this)[i];
+ if (zero_reg)
+ const_cast<T&>(data[0]) = 0;
+ return data[i];
}
private:
T data[N];
@@ -166,12 +182,12 @@ private:
// helpful macros, etc
#define RS1 XPR[insn.rtype.rs1]
#define RS2 XPR[insn.rtype.rs2]
-#define RD XPR[insn.rtype.rd]
-#define RA XPR[1]
+#define RD XPR.write_port(insn.rtype.rd)
+#define RA XPR.write_port(1)
#define FRS1 FPR[insn.ftype.rs1]
#define FRS2 FPR[insn.ftype.rs2]
#define FRS3 FPR[insn.ftype.rs3]
-#define FRD FPR[insn.ftype.rd]
+#define FRD FPR.write_port(insn.ftype.rd)
#define BIGIMM insn.ltype.bigimm
#define SIMM insn.itype.imm12
#define BIMM ((signed)insn.btype.immlo | (insn.btype.immhi << IMMLO_BITS))
@@ -211,7 +227,7 @@ private:
#define require_rvc if(!(sr & SR_EC)) throw_illegal_instruction
#define CRD_REGNUM ((insn.bits >> 5) & 0x1f)
-#define CRD XPR[CRD_REGNUM]
+#define CRD XPR.write_port(CRD_REGNUM)
#define CRS1 XPR[(insn.bits >> 10) & 0x1f]
#define CRS2 XPR[(insn.bits >> 5) & 0x1f]
#define CIMM6 ((int32_t)((insn.bits >> 10) & 0x3f) << 26 >> 26)
@@ -225,8 +241,8 @@ static const int rvc_rs1_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 7 };
#define rvc_rd_regmap rvc_rs1_regmap
#define rvc_rs2b_regmap rvc_rs1_regmap
static const int rvc_rs2_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 0 };
-#define CRDS XPR[rvc_rd_regmap[(insn.bits >> 13) & 0x7]]
-#define FCRDS FPR[rvc_rd_regmap[(insn.bits >> 13) & 0x7]]
+#define CRDS XPR.write_port(rvc_rd_regmap[(insn.bits >> 13) & 0x7])
+#define FCRDS FPR.write_port(rvc_rd_regmap[(insn.bits >> 13) & 0x7])
#define CRS1S XPR[rvc_rs1_regmap[(insn.bits >> 10) & 0x7]]
#define CRS2S XPR[rvc_rs2_regmap[(insn.bits >> 13) & 0x7]]
#define CRS2BS XPR[rvc_rs2b_regmap[(insn.bits >> 5) & 0x7]]
@@ -237,12 +253,12 @@ static const int rvc_rs2_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 0 };
#define UT_RS1(idx) uts[idx]->XPR[insn.rtype.rs1]
#define UT_RS2(idx) uts[idx]->XPR[insn.rtype.rs2]
-#define UT_RD(idx) uts[idx]->XPR[insn.rtype.rd]
-#define UT_RA(idx) uts[idx]->XPR[1]
+#define UT_RD(idx) uts[idx]->XPR.write_port(insn.rtype.rd)
+#define UT_RA(idx) uts[idx]->XPR.write_port(1)
#define UT_FRS1(idx) uts[idx]->FPR[insn.ftype.rs1]
#define UT_FRS2(idx) uts[idx]->FPR[insn.ftype.rs2]
#define UT_FRS3(idx) uts[idx]->FPR[insn.ftype.rs3]
-#define UT_FRD(idx) uts[idx]->FPR[insn.ftype.rd]
+#define UT_FRD(idx) uts[idx]->FPR.write_port(insn.ftype.rd)
#define UT_RM(idx) ((insn.ftype.rm != 7) ? insn.ftype.rm : \
((uts[idx]->fsr & FSR_RD) >> FSR_RD_SHIFT))