};
#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
{
{
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];
// 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))
#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)
#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]]
#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))