shuffle to calculate actual bitwidth
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Oct 2018 09:21:51 +0000 (10:21 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 20 Oct 2018 09:21:51 +0000 (10:21 +0100)
riscv/sv_insn_redirect.cc
riscv/sv_reg.h

index 92f93a5c632c98a6cf754d8aed8d9e5af51094c1..6dd6b414fadb13580613d979e6b6fdfaa87316c8 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, xlen, elwidth);
 }
 
 #define GET_REG(name) \
index 71387806dda60dfa324511d6f1154ad68a43ba8d..07d411194ecaea76edcd62bafa9316563e526944 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef SV_REG_H
 #define SV_REG_H
 
+#include <algorithm>
+
 #define sext_bwid(x,wid) (((sreg_t)(x) << (64-wid)) >> (64-wid))
 #define zext_bwid(x,wid) (((reg_t)(x) << (64-wid)) >> (64-wid))
 
@@ -8,13 +10,20 @@ class sv_sreg_t;
 
 class sv_regbase_t {
 public:
-    sv_regbase_t() : elwidth(0) { } // default elwidth
-    sv_regbase_t(uint8_t _elwidth) : elwidth(_elwidth) {}
+    sv_regbase_t() :
+                    xlen(0), elwidth(0) { } // default elwidth
+    sv_regbase_t(int _xlen) :
+                    xlen(_xlen), elwidth(0) { } // default elwidth
+    sv_regbase_t(int _xlen, uint8_t _elwidth) :
+                    xlen(_xlen), elwidth(_elwidth) {}
 
+    int xlen;
     uint8_t elwidth;
 public:
+  int get_xlen() const { return xlen; }
   uint8_t get_width() const { return elwidth; }
-  uint8_t get_width(sv_regbase_t const&r) const {
+  uint8_t get_width(sv_regbase_t const&r) const
+  {
     // 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
@@ -34,13 +43,32 @@ public:
                        0x3  // 8-8: 8
                     };
     return tb[elwidth|(r.elwidth<<2)];
+  }
+  int get_bitwidth() const
+  {
+    switch (elwidth) {
+        case 0: return xlen;
+        case 1: return xlen / 2;
+        case 2: return xlen * 2;
+        default: return 8;
     }
+  }
+  int get_bitwidth(sv_regbase_t const&r) const
+  {
+    int rw = r.get_bitwidth();
+    int lw = get_bitwidth();
+    return std::max(lw, rw);
+  }
 };
 
 class sv_reg_t : public 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)
+    sv_reg_t(uint64_t _reg, uint8_t _elwidth) :
+                sv_regbase_t(_elwidth), reg(_reg)
+                                                {}
+    sv_reg_t(uint64_t _reg, int xlen, uint8_t _elwidth) :
+                sv_regbase_t(xlen, _elwidth), reg(_reg)
                                                 {}
 
     uint64_t reg;