split out sv_reg_t elwidth into separate base class
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 19 Oct 2018 23:56:34 +0000 (00:56 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 19 Oct 2018 23:56:34 +0000 (00:56 +0100)
riscv/sv_insn_redirect.cc
riscv/sv_reg.h

index a5ba035d3b9957ebd62840241934779e32460b5b..6dbf7e0e8981b2d257b1a39d65000e5dc8cd776f 100644 (file)
@@ -104,7 +104,7 @@ sv_reg_t sv_proc_t::get_intreg(reg_t reg)
 {
     uint8_t elwidth = _insn->reg_elwidth(reg, true);
     uint64_t data = _insn->p->get_state()->XPR[reg];
-    return sv_reg_t(data /*, elwidth*/);
+    return sv_reg_t(data , elwidth);
 }
 
 #define GET_REG(name) \
index 4e9689e577b57eeb7a58b421a4c05c833f9fd499..6375a1adef78b64c6294631895174a5b5710428c 100644 (file)
@@ -3,34 +3,61 @@
 
 class sv_sreg_t;
 
-class sv_reg_t {
+class sv_regbase_t {
 public:
-    sv_reg_t(uint64_t _reg) : reg(_reg) , elwidth(0) { } // default elwidth
-    sv_reg_t(uint64_t _reg, uint8_t _elwidth) : reg(_reg), elwidth(_elwidth) {}
+    sv_regbase_t() : elwidth(0) { } // default elwidth
+    sv_regbase_t(uint8_t _elwidth) : elwidth(_elwidth) {}
 
-    uint64_t reg;
     uint8_t elwidth;
 public:
-  uint64_t get_data() { return reg; }
-  uint8_t get_width() { return elwidth; }
+  uint8_t get_width() const { return elwidth; }
+  uint8_t get_width(sv_regbase_t const&r) {
+    // bitfield 0b00=default, 0b01=default/2, 0b10=default*2, 0b11=8-bit
+    uint8_t tb[16] = { 0x0, // default-default: default
+                       0x0, // default-default/2: default
+                       0x2, // default-default*2: default*2
+                       0x0, // default-8: default
+                       0x0, // default/2-default: default
+                       0x1, // default/2-default/2: default/2
+                       0x2, // default/2-default*2: default*2
+                       0x1, // default/2-8: default*2
+                       0x2, // default*2-default: default*2
+                       0x2, // default*2-default/2: default*2
+                       0x2, // default*2-default*2: default*2
+                       0x2, // default*2-8: default*2
+                       0x0, // 8-default: default
+                       0x1, // 8-default/2: default/2
+                       0x2, // 8-default*2: default*2
+                       0x3  // 8-8: 8
+    };
+    return tb[elwidth|(r.elwidth<<2)];
+    }
+};
+
+class sv_reg_t : sv_regbase_t {
+public:
+    sv_reg_t(uint64_t _reg) : sv_regbase_t(), reg(_reg) { } // default elwidth
+    sv_reg_t(uint64_t _reg, uint8_t _elwidth) : sv_regbase_t(_elwidth), reg(_reg)
+                                                {}
 
-  operator uint64_t() const & { return reg; }
-  operator sv_sreg_t() const &;
+    uint64_t reg;
+public:
+
+  operator uint64_t() const& { return reg; }
+  operator sv_sreg_t() const&;
 };
 
-class sv_sreg_t {
+class sv_sreg_t : sv_regbase_t {
 public:
-    sv_sreg_t(int64_t _reg) : reg(_reg) , elwidth(0) {} // default elwidth
-    sv_sreg_t(int64_t _reg, uint8_t _elwidth) : reg(_reg), elwidth(_elwidth) {}
+    sv_sreg_t(int64_t _reg) : sv_regbase_t(), reg(_reg) {} // default elwidth
+    sv_sreg_t(int64_t _reg, uint8_t _elwidth) : sv_regbase_t(_elwidth),
+                                                reg(_reg) {}
 
     int64_t reg;
-    uint8_t elwidth;
 public:
-  int64_t get_data() { return reg; }
-  uint8_t get_width() { return elwidth; }
 
   operator int64_t() const& { return reg; }
-  operator sv_reg_t() const& { return sv_reg_t((uint64_t)reg, elwidth); }
+  operator sv_reg_t() const& { return sv_reg_t((uint64_t)reg, get_width()); }
 };
 
 inline sv_reg_t::operator sv_sreg_t() const &