diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2014-12-04 23:10:33 -0800 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2014-12-04 23:32:54 -0800 |
commit | d643e43dca834fcb2e40504f65d5043d9f2b018b (patch) | |
tree | 289f2043af8249f74f408ad804b843c27289d25d /riscv/decode.h | |
parent | cec752d09191e96a51f5c21ed8d51e1218f804ff (diff) | |
download | spike-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.h | 40 |
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 { |