aboutsummaryrefslogtreecommitdiff
path: root/riscv/decode.h
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2014-12-04 23:10:33 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2014-12-04 23:32:54 -0800
commitd643e43dca834fcb2e40504f65d5043d9f2b018b (patch)
tree289f2043af8249f74f408ad804b843c27289d25d /riscv/decode.h
parentcec752d09191e96a51f5c21ed8d51e1218f804ff (diff)
downloadspike-d643e43dca834fcb2e40504f65d5043d9f2b018b.zip
spike-d643e43dca834fcb2e40504f65d5043d9f2b018b.tar.gz
spike-d643e43dca834fcb2e40504f65d5043d9f2b018b.tar.bz2
Support 2/4/6/8-byte instructions
Most of the complexity is in instruction address translation, since instructions may span page boundaries.
Diffstat (limited to 'riscv/decode.h')
-rw-r--r--riscv/decode.h40
1 files changed, 21 insertions, 19 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 543080d..b325c59 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -44,26 +44,29 @@ const int NFPR = 32;
#define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT)
#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
+typedef uint64_t insn_bits_t;
class insn_t
{
public:
- uint32_t bits() { return b; }
- int32_t i_imm() { return int32_t(b) >> 20; }
- int32_t s_imm() { return x(7, 5) + (xs(25, 7) << 5); }
- int32_t sb_imm() { return (x(8, 4) << 1) + (x(25,6) << 5) + (x(7,1) << 11) + (imm_sign() << 12); }
- int32_t u_imm() { return int32_t(b) >> 12 << 12; }
- int32_t uj_imm() { return (x(21, 10) << 1) + (x(20, 1) << 11) + (x(12, 8) << 12) + (imm_sign() << 20); }
- uint32_t rd() { return x(7, 5); }
- uint32_t rs1() { return x(15, 5); }
- uint32_t rs2() { return x(20, 5); }
- uint32_t rs3() { return x(27, 5); }
- uint32_t rm() { return x(12, 3); }
- uint32_t csr() { return x(20, 12); }
+ insn_t() = default;
+ insn_t(insn_bits_t bits) : b(bits) {}
+ insn_bits_t bits() { return b; }
+ int64_t i_imm() { return int64_t(b) >> 20; }
+ int64_t s_imm() { return x(7, 5) + (xs(25, 7) << 5); }
+ int64_t sb_imm() { return (x(8, 4) << 1) + (x(25,6) << 5) + (x(7,1) << 11) + (imm_sign() << 12); }
+ int64_t u_imm() { return int64_t(b) >> 12 << 12; }
+ int64_t uj_imm() { return (x(21, 10) << 1) + (x(20, 1) << 11) + (x(12, 8) << 12) + (imm_sign() << 20); }
+ uint64_t rd() { return x(7, 5); }
+ uint64_t rs1() { return x(15, 5); }
+ uint64_t rs2() { return x(20, 5); }
+ uint64_t rs3() { return x(27, 5); }
+ uint64_t rm() { return x(12, 3); }
+ uint64_t csr() { return x(20, 12); }
private:
- uint32_t b;
- uint32_t x(int lo, int len) { return b << (32-lo-len) >> (32-len); }
- uint32_t xs(int lo, int len) { return int32_t(b) << (32-lo-len) >> (32-len); }
- uint32_t imm_sign() { return xs(31, 1); }
+ insn_bits_t b;
+ uint64_t x(int lo, int len) { return (b >> lo) & ((insn_bits_t(1) << len)-1); }
+ uint64_t xs(int lo, int len) { return int64_t(b) << (64-lo-len) >> (64-len); }
+ uint64_t imm_sign() { return xs(63, 1); }
};
template <class T, size_t N, bool zero_reg>
@@ -76,9 +79,8 @@ public:
}
void write(size_t i, T value)
{
- data[i] = value;
- if (zero_reg)
- data[0] = 0;
+ if (!zero_reg || i != 0)
+ data[i] = value;
}
const T& operator [] (size_t i) const
{