From 17e556e261ddd70705c4fcf4e49838c5b4f6e072 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 29 Oct 2018 06:31:25 +0000 Subject: [PATCH] override and redirect mmu store functions to sv_proc_t --- riscv/sv_insn_redirect.cc | 155 +++++++------------------------------- riscv/sv_insn_redirect.h | 5 +- riscv/sv_mmu.cc | 14 ++-- riscv/sv_mmu.h | 2 + 4 files changed, 44 insertions(+), 132 deletions(-) diff --git a/riscv/sv_insn_redirect.cc b/riscv/sv_insn_redirect.cc index 85ee6d6..3eb7a39 100644 --- a/riscv/sv_insn_redirect.cc +++ b/riscv/sv_insn_redirect.cc @@ -41,23 +41,6 @@ void (sv_proc_t::WRITE_RVC_FRS2S)(sv_float64_t const& value) WRITE_FREG(_insn->rvc_rs2s(), freg(value)); } -//void (sv_proc_t::WRITE_RD)(bool value) -//{ -// WRITE_REG( _insn->rd(), value ? 1 : 0); -//} - -// -//void (sv_proc_t::WRITE_RD)(sv_reg_t value) -//{ -// WRITE_REG( _insn->rd(), value ); -//} - - -//void (sv_proc_t::WRITE_RVC_RS1S)(sv_sreg_t value) -//{ -// WRITE_REG(_insn->rvc_rs1s(), value ); -//} - void (sv_proc_t::WRITE_RVC_RS1S)(sv_reg_t const& value) { WRITE_REG(_insn->rvc_rs1s(), value ); @@ -68,32 +51,13 @@ void (sv_proc_t::WRITE_RVC_RS2S)(sv_reg_t const& value) WRITE_REG(_insn->rvc_rs2s(), value ); } -//void (sv_proc_t::WRITE_RVC_RS2S)(sv_sreg_t value) -//{ -// WRITE_REG(_insn->rvc_rs2s(), value ); -//} - void (sv_proc_t::WRITE_RD)(sv_reg_t const& value) { WRITE_REG( _insn->rd(), value ); // XXX TODO: replace properly } -//void (sv_proc_t::WRITE_RD)(sv_sreg_t value) -//{ -// WRITE_REG( _insn->rd(), value ); // XXX TODO: replace properly -//} - -//void (sv_proc_t::WRITE_REG)(reg_t reg, sv_sreg_t value) -//{ -// //WRITE_REG( reg, value ); // XXX TODO: replace properly -// STATE.XPR.write(reg, value); -//} - -//#define OFFSDIV - void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value) { - //WRITE_REG( reg, value ); // XXX TODO: replace properly reg_t reg = spec.reg; if (spec.offset) { reg += *spec.offset; @@ -105,7 +69,6 @@ void (sv_proc_t::DO_WRITE_FREG)(reg_spec_t const& spec, sv_freg_t const& value) void (sv_proc_t::WRITE_REG)(reg_spec_t const& spec, sv_reg_t const& value) { uint64_t wval = (uint64_t)value; - //WRITE_REG( reg, value ); // XXX TODO: replace properly reg_t reg = spec.reg; int bitwidth = get_bitwidth(_insn->reg_elwidth(reg, true), xlen); unsigned int shift = 0; @@ -244,13 +207,6 @@ sv_reg_t sv_proc_t::uint64_max() return ((UINT64_C(18446744073709551615))); } -/* -sv_reg_t (sv_proc_t::sext_xlen)(uint64_t x) -{ - x = (((sreg_t)(x) << (64-xlen)) >> (64-xlen)); - return sv_uint64_t(x); -} -*/ sv_sreg_t (sv_proc_t::sext_xlen)(sv_sreg_t const& v) { int64_t x = v; @@ -272,12 +228,6 @@ sv_reg_t (sv_proc_t::zext_xlen)(sv_reg_t const& v) return sv_reg_t(x); } -/* -sv_reg_t (sv_proc_t::sext32)(uint_fast32_t v) -{ - return sext32((uint64_t)v); // XXX TODO do properly -} -*/ sv_sreg_t (sv_proc_t::sext32)(sv_reg_t const& v) { uint64_t x = v; @@ -285,13 +235,6 @@ sv_sreg_t (sv_proc_t::sext32)(sv_reg_t const& v) return sv_sreg_t((int64_t)x, v.get_xlen(), v.get_elwidth()); } -//sv_sreg_t (sv_proc_t::sext32)(sv_sreg_t const& v) -//{ -// int64_t x = v; -// x = ((sreg_t)(int32_t)(x)); -// return sv_sreg_t(x); -//} - sv_reg_t (sv_proc_t::zext32)(sv_reg_t const& v) { uint64_t x = v; @@ -299,70 +242,6 @@ sv_reg_t (sv_proc_t::zext32)(sv_reg_t const& v) return sv_reg_t(x); } -/* -sv_reg_t sv_reg_t::make_sv_int64_t (int64_t v) const -{ - return sv_sreg_t(v); -} - -sv_reg_t sv_reg_t::make_sv_uint64_t (uint64_t v) const -{ - return sv_uint64_t(v); -} - - -sv_reg_t::operator sv_sreg_t () -{ - return sv_sreg_t ( as_uint64() ); -} - -sv_reg_t::operator int32_t () -{ - uint64_t x = get_data(); - sv_sreg_t _x = (sv_sreg_t) x; - sv_sreg_t y = sv_sreg_t ( _x ); - return y; -} - - -sv_reg_t::operator uint16_t () -{ - uint64_t x = get_data(); - uint16_t _x = (uint16_t) x; - sv_uint16_t y = sv_uint16_t ( _x ); - return y; -} - - -sv_reg_t::operator uint8_t () // XXX TODO, make_sv_char_t -{ - uint64_t x = get_data(); - uint8_t _x = (uint8_t) x; - sv_uint64_t y = sv_uint64_t ( _x ); - return y; -} - -sv_reg_t::operator char () // XXX TODO, make_sv_char_t -{ - uint64_t x = get_data(); - char _x = (char) x; - sv_sreg_t y = sv_sreg_t ( _x ); - return y; -} - -sv_reg_t::operator uint32_t () // TODO, make_sv_uint32_t - { return make_sv_uint64_t( (sv_sreg_t) (as_uint64()) ); } -sv_reg_t::operator sv_sreg_t () - { return make_sv_int64_t( (sv_sreg_t) (as_uint64()) ); } - -sv_reg_t::operator sv_reg_t () -{ - uint64_t x = get_data(); - sv_uint64_t y = sv_uint64_t ( x ); - return y; -} -*/ - sv_reg_t sv_proc_t::rv_add(sv_reg_t const & lhs, sv_reg_t const & rhs) { uint8_t bitwidth = _insn->src_bitwidth; @@ -455,11 +334,6 @@ sv_reg_t sv_proc_t::rv_sl(sv_reg_t const & lhs, sv_reg_t const & rhs) return lhs << rhs; } -//sv_sreg_t sv_proc_t::rv_sr(sv_sreg_t const & lhs, sv_reg_t const & rhs) -//{ -// return lhs >> rhs; -//} - sv_reg_t sv_proc_t::rv_sr(sv_reg_t const & lhs, sv_reg_t const & rhs) { return lhs >> rhs; @@ -982,3 +856,32 @@ sv_reg_t sv_proc_t::mmu_load(reg_spec_t const& spec, sv_reg_t const& offs, return v; } +void sv_proc_t::mmu_store(reg_spec_t const& spec, sv_reg_t const& offs, + size_t width, reg_t val) +{ + // different "mode" applies, here: addr_mode. + reg_t reg = READ_REG(spec, true, width); + sv_reg_t addr = sv_reg_t((uint64_t)reg + (int64_t)offs); + + // now that the address has been moved on by the modulo-offset, + // get only an elwidth-sized element (if not "default") + width = get_bitwidth(_insn->reg_elwidth(spec.reg, true), width); + fprintf(stderr, "mmu_store wid %ld addr %lx offs %lx stored %lx\n", + width, (uint64_t)reg, (int64_t)offs, (uint64_t)val); + switch (width) + { + case 8: + p->get_mmu()->store_uint8(addr, val); + break; + case 16: + p->get_mmu()->store_uint16(addr, val); + break; + case 32: + p->get_mmu()->store_uint32(addr, val); + break; + case 64: + p->get_mmu()->store_uint64(addr, val); + break; + } +} + diff --git a/riscv/sv_insn_redirect.h b/riscv/sv_insn_redirect.h index a04a828..6314c4c 100644 --- a/riscv/sv_insn_redirect.h +++ b/riscv/sv_insn_redirect.h @@ -246,7 +246,10 @@ public: sv_freg_t fsgnj128(sv_freg_t a, sv_freg_t b, bool n, bool x); sv_reg_t mmu_load(reg_spec_t const& spec, sv_reg_t const& offs, - size_t width, bool ext); + size_t width, bool ext); + + void mmu_store(reg_spec_t const& spec, sv_reg_t const& offs, + size_t width, reg_t val); #include "sv_insn_decl.h" diff --git a/riscv/sv_mmu.cc b/riscv/sv_mmu.cc index 399fa1d..8bded65 100644 --- a/riscv/sv_mmu.cc +++ b/riscv/sv_mmu.cc @@ -21,16 +21,20 @@ sv_load_func(int16, 16, false ) sv_load_func(int32, 32, false ) sv_load_func(int64, 64, false ) -#define sv_store_func(type) \ +#define sv_store_func(type, width) \ +void sv_mmu_t::store_##type(reg_spec_t const& spec, sv_reg_t const& offs, \ + type##_t val) { \ + proc->s.mmu_store(spec, offs, width, val); \ +} \ void sv_mmu_t::store_##type(sv_reg_t const& addr, type##_t val) { \ mmu_t::store_##type(addr, val); \ } // store value to memory at aligned address -sv_store_func(uint8) -sv_store_func(uint16) -sv_store_func(uint32) -sv_store_func(uint64) +sv_store_func(uint8, 8) +sv_store_func(uint16, 16) +sv_store_func(uint32, 32) +sv_store_func(uint64, 64) #if 0 #define sv_amo_func(type) \ diff --git a/riscv/sv_mmu.h b/riscv/sv_mmu.h index 824d166..8c8ce9d 100644 --- a/riscv/sv_mmu.h +++ b/riscv/sv_mmu.h @@ -29,6 +29,8 @@ public: sv_load_func_decl(int64) #define sv_store_func_decl(type) \ + void store_##type(reg_spec_t const& reg, sv_reg_t const& offs, \ + type##_t val); \ void store_##type(sv_reg_t const& addr, type##_t val); // store value to memory at aligned address -- 2.30.2