diff --git a/README.md b/README.md
index 994f4c0..f872fa4 100644
--- a/README.md
+++ b/README.md
@@ -17,9 +17,9 @@ DBT-RISE-RiscV uses libGIS (https://github.com/vsergeev/libGIS) as well as ELFIO
**Planned features**
-* add platform peripherals to resemble E300 platform
- * PLIC
- * gpio
+* add platform peripherals beyond programmers view to resemble E300 platform
+ * QSPI
+ * PWM
* ...
* and more
diff --git a/dbt-core b/dbt-core
index 29a6988..53d78d9 160000
--- a/dbt-core
+++ b/dbt-core
@@ -1 +1 @@
-Subproject commit 29a69884d2fcfb29f7a5f5a927e93e35f05fdd7e
+Subproject commit 53d78d993a8d3310a8b73fec0b601457b3c0ef75
diff --git a/riscv/gen_input/RV64IBase.core_desc b/riscv/gen_input/RV64IBase.core_desc
index 5508bb9..68ca175 100644
--- a/riscv/gen_input/RV64IBase.core_desc
+++ b/riscv/gen_input/RV64IBase.core_desc
@@ -2,97 +2,114 @@ import "RV32IBase.core_desc"
InsructionSet RV64IBase extends RV32IBase {
instructions{
- LWU {
- encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000011;
- args_disass:"x%rd$d, %imm%(x%rs1$d)";
- val offs[XLEN] <= X[rs1]+imm;
- if(rd!=0) X[rd]<=zext(MEM[offs]{32});
+ LWU { // 80000104: 0000ef03 lwu t5,0(ra)
+ encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011;
+ args_disass:"x%rd$d, %imm%(x%rs1$d)";
+ val offs[XLEN] <= X[rs1]+imm;
+ if(rd!=0) X[rd]<=zext(MEM[offs]{32});
}
LD{
encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000011;
- args_disass:"x%rd$d, %imm%(x%rs1$d)";
- val offs[XLEN] <= X[rs1]+imm;
- if(rd!=0) X[rd]<=sext(MEM[offs]{64});
+ args_disass:"x%rd$d, %imm%(x%rs1$d)";
+ val offs[XLEN] <= X[rs1]+imm;
+ if(rd!=0) X[rd]<=sext(MEM[offs]{64});
}
SD{
- encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0] | b0100011;
- args_disass:"x%rs2$d, %imm%(x%rs1$d)";
- val offs[XLEN] <= X[rs1] + sext(imm, XLEN);
- MEM[offs]{64} <= X[rs2];
+ encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100011;
+ args_disass:"x%rs2$d, %imm%(x%rs1$d)";
+ val offs[XLEN] <= X[rs1] + imm;
+ MEM[offs]{64} <= X[rs2];
}
SLLI {
encoding: b000000 | shamt[5:0] | rs1[4:0] | b001 | rd[4:0] | b0010011;
- args_disass:"x%rd$d, x%rs1$d, %shamt%";
- if(rd != 0) X[rd] <= shll(X[rs1], shamt);
+ args_disass:"x%rd$d, x%rs1$d, %shamt%";
+ if(rd != 0) X[rd] <= shll(X[rs1], shamt);
}
SRLI {
encoding: b000000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011;
- args_disass:"x%rd$d, x%rs1$d, %shamt%";
- if(rd != 0) X[rd] <= shrl(X[rs1], shamt);
+ args_disass:"x%rd$d, x%rs1$d, %shamt%";
+ if(rd != 0) X[rd] <= shrl(X[rs1], shamt);
}
SRAI {
encoding: b010000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011;
- args_disass:"x%rd$d, x%rs1$d, %shamt%";
- if(rd != 0) X[rd] <= shra(X[rs1], shamt);
+ args_disass:"x%rd$d, x%rs1$d, %shamt%";
+ if(rd != 0) X[rd] <= shra(X[rs1], shamt);
}
ADDIW {
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011;
- args_disass:"x%rd$d, x%rs1$d, %imm%";
- if(rd != 0) X[rd] <= sext(X[rs1]{32}, XLEN) + sext(imm, XLEN);
+ args_disass:"x%rd$d, x%rs1$d, %imm%";
+ if(rd != 0){
+ val res[32] <= X[rs1]{32} + imm{32};
+ X[rd] <= sext(res);
+ }
}
SLLIW {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011;
- args_disass:"x%rd$d, x%rs1$d, %shamt%";
- if(rd != 0){
- val sh_val[32] <= shll(X[rs1]{32}, shamt);
- X[rd] <= sext(sh_val, XLEN);
- }
+ args_disass:"x%rd$d, x%rs1$d, %shamt%";
+ if(rd != 0){
+ val sh_val[32] <= shll(X[rs1]{32}, shamt);
+ X[rd] <= sext(sh_val);
+ }
}
SRLIW {
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
- args_disass:"x%rd$d, x%rs1$d, %shamt%";
- if(rd != 0){
- val sh_val[32] <= shrl(X[rs1], shamt);
- X[rd] <= sext(sh_val, XLEN);
- }
+ args_disass:"x%rd$d, x%rs1$d, %shamt%";
+ if(rd != 0){
+ val sh_val[32] <= shrl(X[rs1]{32}, shamt);
+ X[rd] <= sext(sh_val);
+ }
}
SRAIW {
encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
- args_disass:"x%rd$d, x%rs1$d, %shamt%";
- if(rd != 0){
- val sh_val[32] <= shra(X[rs1], shamt);
- X[rd] <= sext(sh_val, XLEN);
- }
+ args_disass:"x%rd$d, x%rs1$d, %shamt%";
+ if(rd != 0){
+ val sh_val[32] <= shra(X[rs1]{32}, shamt);
+ X[rd] <= sext(sh_val);
+ }
}
ADDW {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011;
+ if(rd != 0){
+ val res[32] <= X[rs1]{32} + X[rs2]{32};
+ X[rd] <= sext(res);
+ }
}
SUBW {
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011;
+ if(rd != 0){
+ val res[32] <= X[rs1]{32} - X[rs2]{32};
+ X[rd] <= sext(res);
+ }
}
SLLW {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011;
- args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
- if(rd != 0){
- val sh_val[32] <= shll(X[rs1], X[rs2]&0x1f);
- X[rd] <= sext(sh_val, XLEN);
- }
+ args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
+ if(rd != 0){
+ val mask[32] <= 0x1f;
+ val count[32] <= X[rs2]{32} & mask;
+ val sh_val[32] <= shll(X[rs1]{32}, count);
+ X[rd] <= sext(sh_val);
+ }
}
SRLW {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
- args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
- if(rd != 0){
- val sh_val[32] <= shrl(X[rs1], X[rs2]&0x1f);
- X[rd] <= sext(sh_val, XLEN);
- }
+ args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
+ if(rd != 0){
+ val mask[32] <= 0x1f;
+ val count[32] <= X[rs2]{32} & mask;
+ val sh_val[32] <= shrl(X[rs1]{32}, count);
+ X[rd] <= sext(sh_val);
+ }
}
SRAW {
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
- args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
- if(rd != 0){
- val sh_val[32] <= shra(X[rs1], X[rs2]&0x1f);
- X[rd] <= sext(sh_val, XLEN);
- }
+ args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
+ if(rd != 0){
+ val mask[32] <= 0x1f;
+ val count[32] <= X[rs2]{32} & mask;
+ val sh_val[32] <= shra(X[rs1]{32}, count);
+ X[rd] <= sext(sh_val);
+ }
}
}
}
diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h
index 51cd7c4..15a7ecb 100644
--- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h
+++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h
@@ -308,6 +308,14 @@ public:
mstatus_t mstatus;
+ static const reg_t mstatus_reset_val = 0;
+
+ void write_mstatus(T val, unsigned priv_lvl){
+ auto mask = get_mask(priv_lvl);
+ auto new_val = (mstatus & ~mask) | (val & mask);
+ mstatus=new_val;
+ }
+
T satp;
static constexpr T get_misa() { return (1UL << 30) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; }
@@ -379,14 +387,29 @@ public:
mstatus_t mstatus;
+ static const reg_t mstatus_reset_val = 0xa00000000;
+
+ void write_mstatus(T val, unsigned priv_lvl){
+ T old_val = mstatus;
+ auto mask = get_mask(priv_lvl);
+ auto new_val = (old_val & ~mask) | (val & mask);
+ if((new_val&mstatus.SXL.Mask)==0){
+ new_val |= old_val&mstatus.SXL.Mask;
+ }
+ if((new_val&mstatus.UXL.Mask)==0){
+ new_val |= old_val&mstatus.UXL.Mask;
+ }
+ mstatus=new_val;
+ }
+
T satp;
static constexpr T get_misa() { return (2ULL << 62) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; }
static constexpr T get_mask(unsigned priv_lvl) {
switch (priv_lvl) {
- case PRIV_U: return 0x8000000000000011ULL; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
- case PRIV_S: return 0x80000003000de133ULL; // 0b1...0 0011 0000 0000 0000 1101 1110 0001 0011 0011
+ case PRIV_U: return 0x8000000f00000011ULL; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
+ case PRIV_S: return 0x8000000f000de133ULL; // 0b1...0 0011 0000 0000 0000 1101 1110 0001 0011 0011
default: return 0x8000000f007ff9ddULL; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
}
}
@@ -423,6 +446,8 @@ public:
riscv_hart_msu_vp();
virtual ~riscv_hart_msu_vp() = default;
+ void reset(uint64_t address) override;
+
void load_file(std::string name, int type = -1) override;
virtual phys_addr_t v2p(const iss::addr_t &addr);
@@ -573,66 +598,71 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng
LOG(DEBUG) << "read of " << length << " bytes @addr " << addr;
}
#endif
- switch (addr.space) {
- case traits::MEM: {
- if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) {
- fault_data = addr.val;
- if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val);
- this->reg.trap_state = (1 << 31); // issue trap 0
- return iss::Err;
- }
- try {
- if ((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK)) { // we may cross a page boundary
- vm_info vm = hart_state::decode_vm_info(this->reg.machine_state, state.satp);
- if (vm.levels != 0) { // VM is active
- auto split_addr = (addr.val + length) & ~PGMASK;
- auto len1 = split_addr - addr.val;
- auto res = read(addr, len1, data);
- if (res == iss::Ok)
- res = read(iss::addr_t{addr.type, addr.space, split_addr}, length - len1, data + len1);
- return res;
- }
- }
- phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr);
- auto res = read_mem(paddr, length, data);
- if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
- return res;
- } catch (trap_access &ta) {
- this->reg.trap_state = (1 << 31) | ta.id;
- return iss::Err;
- }
- } break;
- case traits::CSR: {
- if (length != sizeof(reg_t)) return iss::Err;
- return read_csr(addr.val, *reinterpret_cast(data));
- } break;
- case traits::FENCE: {
- if ((addr.val + length) > mem.size()) return iss::Err;
- switch (addr.val) {
- case 2: // SFENCE:VMA lower
- case 3: { // SFENCE:VMA upper
- auto tvm = state.mstatus.TVM;
- if (this->reg.machine_state == PRIV_S & tvm != 0) {
- this->reg.trap_state = (1 << 31) | (2 << 16);
- this->fault_data = this->reg.PC;
+ try {
+ switch (addr.space) {
+ case traits::MEM: {
+ if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) {
+ fault_data = addr.val;
+ if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val);
+ this->reg.trap_state = (1 << 31); // issue trap 0
return iss::Err;
}
- return iss::Ok;
+ try {
+ if ((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK)) { // we may cross a page boundary
+ vm_info vm = hart_state::decode_vm_info(this->reg.machine_state, state.satp);
+ if (vm.levels != 0) { // VM is active
+ auto split_addr = (addr.val + length) & ~PGMASK;
+ auto len1 = split_addr - addr.val;
+ auto res = read(addr, len1, data);
+ if (res == iss::Ok)
+ res = read(iss::addr_t{addr.type, addr.space, split_addr}, length - len1, data + len1);
+ return res;
+ }
+ }
+ phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr);
+ auto res = read_mem(paddr, length, data);
+ if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
+ return res;
+ } catch (trap_access &ta) {
+ this->reg.trap_state = (1 << 31) | ta.id;
+ return iss::Err;
+ }
+ } break;
+ case traits::CSR: {
+ if (length != sizeof(reg_t)) return iss::Err;
+ return read_csr(addr.val, *reinterpret_cast(data));
+ } break;
+ case traits::FENCE: {
+ if ((addr.val + length) > mem.size()) return iss::Err;
+ switch (addr.val) {
+ case 2: // SFENCE:VMA lower
+ case 3: { // SFENCE:VMA upper
+ auto tvm = state.mstatus.TVM;
+ if (this->reg.machine_state == PRIV_S & tvm != 0) {
+ this->reg.trap_state = (1 << 31) | (2 << 16);
+ this->fault_data = this->reg.PC;
+ return iss::Err;
+ }
+ return iss::Ok;
+ }
+ }
+ } break;
+ case traits::RES: {
+ auto it = atomic_reservation.find(addr.val);
+ if (it != atomic_reservation.end() && (*it).second != 0) {
+ memset(data, 0xff, length);
+ atomic_reservation.erase(addr.val);
+ } else
+ memset(data, 0, length);
+ } break;
+ default:
+ return iss::Err; // assert("Not supported");
}
- }
- } break;
- case traits::RES: {
- auto it = atomic_reservation.find(addr.val);
- if (it != atomic_reservation.end() && (*it).second != 0) {
- memset(data, 0xff, length);
- atomic_reservation.erase(addr.val);
- } else
- memset(data, 0, length);
- } break;
- default:
- return iss::Err; // assert("Not supported");
+ return iss::Ok;
+ } catch (trap_access &ta) {
+ this->reg.trap_state = (1 << 31) | ta.id;
+ return iss::Err;
}
- return iss::Ok;
}
template
@@ -810,10 +840,7 @@ template iss::status riscv_hart_msu_vp::read_status(unsign
template iss::status riscv_hart_msu_vp::write_status(unsigned addr, reg_t val) {
auto req_priv_lvl = addr >> 8;
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
- auto mask = hart_state::get_mask(req_priv_lvl);
- auto old_val = state.mstatus;
- auto new_val = (old_val & ~mask) | (val & mask);
- state.mstatus = new_val;
+ state.write_mstatus(val, req_priv_lvl);
check_interrupt();
return iss::Ok;
}
@@ -980,6 +1007,12 @@ inline void riscv_hart_msu_vp::notify_phase(iss::arch_if::exec_phase phase
BASE::notify_phase(phase);
}
+template
+inline void riscv_hart_msu_vp::reset(uint64_t address) {
+ BASE::reset(address);
+ state.mstatus = hart_state::mstatus_reset_val;
+}
+
template void riscv_hart_msu_vp::check_interrupt() {
auto status = state.mstatus;
auto ip = csr[mip];
diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h
index 39bdd5c..5dc4bf4 100644
--- a/riscv/incl/iss/arch/rv32imac.h
+++ b/riscv/incl/iss/arch/rv32imac.h
@@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
-// Created on: Wed Oct 18 11:42:36 CEST 2017
+// Created on: Fri Nov 17 20:34:49 CET 2017
// * rv32imac.h Author:
//
////////////////////////////////////////////////////////////////////////////////
@@ -126,7 +126,7 @@ struct rv32imac: public arch_if {
using addr_t = typename traits::addr_t;
rv32imac();
- ~rv32imac() = default;
+ ~rv32imac();
void reset(uint64_t address=0) override;
diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h
index 18f4ced..2bfbd96 100644
--- a/riscv/incl/iss/arch/rv64ia.h
+++ b/riscv/incl/iss/arch/rv64ia.h
@@ -28,7 +28,7 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
-// Created on: Wed Oct 18 11:42:36 CEST 2017
+// Created on: Fri Nov 17 20:34:49 CET 2017
// * rv64ia.h Author:
//
////////////////////////////////////////////////////////////////////////////////
diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp
index 026e198..fbd5aa8 100644
--- a/riscv/src/internal/vm_rv64ia.cpp
+++ b/riscv/src/internal/vm_rv64ia.cpp
@@ -148,7 +148,8 @@ protected:
}
// some compile time constants
- enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
+ // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
+ enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) };
@@ -217,7 +218,7 @@ private:
const InstructionDesriptor instr_descr[75] = {
/* entries are: valid value, valid mask, function ptr */
/* instruction LWU */
- {32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, &this_class::__lwu},
+ {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu},
/* instruction LD */
{32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld},
/* instruction SD */
@@ -451,7 +452,7 @@ private:
this->gen_sync(iss::PRE_SYNC);
- uint16_t fld_imm_val = 0 | (bit_sub<7,5>(instr)) | (signed_bit_sub<25,7>(instr) << 5);
+ int16_t fld_imm_val = 0 | (bit_sub<7,5>(instr)) | (signed_bit_sub<25,7>(instr) << 5);
uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr));
uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr));
if(this->disass_enabled){
@@ -469,10 +470,7 @@ private:
Value* offs_val = this->builder->CreateAdd(
this->gen_reg_load(fld_rs1_val, 0),
- this->gen_ext(
- this->gen_const(64U, fld_imm_val),
- 64,
- true));
+ this->gen_const(64U, fld_imm_val));
Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0);
this->gen_write_mem(
traits::MEM,
@@ -613,18 +611,16 @@ private:
pc=pc+4;
if(fld_rd_val != 0){
- Value* X_rd_val = this->builder->CreateAdd(
- this->gen_ext(
- this->builder->CreateTrunc(
- this->gen_reg_load(fld_rs1_val, 0),
- this-> get_type(32)
- ),
- 64,
- true),
- this->gen_ext(
- this->gen_const(64U, fld_imm_val),
- 64,
- true));
+ Value* res_val = this->builder->CreateAdd(
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
+ this->gen_const(32U, fld_imm_val));
+ Value* X_rd_val = this->gen_ext(
+ res_val,
+ 64,
+ true);
this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false);
}
this->gen_set_pc(pc, traits::NEXT_PC);
@@ -700,7 +696,10 @@ private:
if(fld_rd_val != 0){
Value* sh_val_val = this->builder->CreateLShr(
- this->gen_reg_load(fld_rs1_val, 0),
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
this->gen_const(32U, fld_shamt_val));
Value* X_rd_val = this->gen_ext(
sh_val_val,
@@ -739,7 +738,10 @@ private:
if(fld_rd_val != 0){
Value* sh_val_val = this->builder->CreateAShr(
- this->gen_reg_load(fld_rs1_val, 0),
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
this->gen_const(32U, fld_shamt_val));
Value* X_rd_val = this->gen_ext(
sh_val_val,
@@ -774,7 +776,22 @@ private:
}
pc=pc+4;
- /* TODO: describe operations for ADDW ! */
+ if(fld_rd_val != 0){
+ Value* res_val = this->builder->CreateAdd(
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs2_val, 0),
+ this-> get_type(32)
+ ));
+ Value* X_rd_val = this->gen_ext(
+ res_val,
+ 64,
+ true);
+ this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false);
+ }
this->gen_set_pc(pc, traits::NEXT_PC);
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
@@ -802,7 +819,22 @@ private:
}
pc=pc+4;
- /* TODO: describe operations for SUBW ! */
+ if(fld_rd_val != 0){
+ Value* res_val = this->builder->CreateSub(
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs2_val, 0),
+ this-> get_type(32)
+ ));
+ Value* X_rd_val = this->gen_ext(
+ res_val,
+ 64,
+ true);
+ this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false);
+ }
this->gen_set_pc(pc, traits::NEXT_PC);
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */
@@ -833,11 +865,19 @@ private:
pc=pc+4;
if(fld_rd_val != 0){
- Value* sh_val_val = this->builder->CreateShl(
- this->gen_reg_load(fld_rs1_val, 0),
- this->builder->CreateAnd(
+ Value* mask_val = this->gen_const(32U, 31);
+ Value* count_val = this->builder->CreateAnd(
+ this->builder->CreateTrunc(
this->gen_reg_load(fld_rs2_val, 0),
- this->gen_const(32U, 31)));
+ this-> get_type(32)
+ ),
+ mask_val);
+ Value* sh_val_val = this->builder->CreateShl(
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
+ count_val);
Value* X_rd_val = this->gen_ext(
sh_val_val,
64,
@@ -874,11 +914,19 @@ private:
pc=pc+4;
if(fld_rd_val != 0){
- Value* sh_val_val = this->builder->CreateLShr(
- this->gen_reg_load(fld_rs1_val, 0),
- this->builder->CreateAnd(
+ Value* mask_val = this->gen_const(32U, 31);
+ Value* count_val = this->builder->CreateAnd(
+ this->builder->CreateTrunc(
this->gen_reg_load(fld_rs2_val, 0),
- this->gen_const(32U, 31)));
+ this-> get_type(32)
+ ),
+ mask_val);
+ Value* sh_val_val = this->builder->CreateLShr(
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
+ count_val);
Value* X_rd_val = this->gen_ext(
sh_val_val,
64,
@@ -915,11 +963,19 @@ private:
pc=pc+4;
if(fld_rd_val != 0){
- Value* sh_val_val = this->builder->CreateAShr(
- this->gen_reg_load(fld_rs1_val, 0),
- this->builder->CreateAnd(
+ Value* mask_val = this->gen_const(32U, 31);
+ Value* count_val = this->builder->CreateAnd(
+ this->builder->CreateTrunc(
this->gen_reg_load(fld_rs2_val, 0),
- this->gen_const(32U, 31)));
+ this-> get_type(32)
+ ),
+ mask_val);
+ Value* sh_val_val = this->builder->CreateAShr(
+ this->builder->CreateTrunc(
+ this->gen_reg_load(fld_rs1_val, 0),
+ this-> get_type(32)
+ ),
+ count_val);
Value* X_rd_val = this->gen_ext(
sh_val_val,
64,
@@ -3384,7 +3440,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
} catch (trap_access &ta) {
throw trap_access(ta.id, pc.val);
}
- if (insn == 0x0000006f) throw simulation_stopped(0);
+ if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
// curr pc on stack
typename vm_impl::processing_pc_entry addr(*this, pc, paddr);
++inst_cnt;
diff --git a/riscv/src/iss/rv32imac.cpp b/riscv/src/iss/rv32imac.cpp
index 677b4f4..7cb43af 100644
--- a/riscv/src/iss/rv32imac.cpp
+++ b/riscv/src/iss/rv32imac.cpp
@@ -52,7 +52,9 @@ extern "C" {
using namespace iss::arch;
-rv32imac::rv32imac() { reg.icount = 0; }
+rv32imac::rv32imac() { reg.icount = 0; reg.machine_state = 0x3;}
+
+rv32imac::~rv32imac(){}
void rv32imac::reset(uint64_t address) {
for (size_t i = 0; i < traits::NUM_REGS; ++i)
diff --git a/riscv/src/iss/rv64ia.cpp b/riscv/src/iss/rv64ia.cpp
index 9b80eb2..7542a04 100644
--- a/riscv/src/iss/rv64ia.cpp
+++ b/riscv/src/iss/rv64ia.cpp
@@ -52,9 +52,9 @@ extern "C" {
using namespace iss::arch;
-rv64ia::rv64ia() { reg.icount = 0; }
+rv64ia::rv64ia() { reg.icount = 0; reg.machine_state = 0x3;}
-rv64ia::~rv64ia() {}
+rv64ia::~rv64ia(){}
void rv64ia::reset(uint64_t address) {
for (size_t i = 0; i < traits::NUM_REGS; ++i)
@@ -62,7 +62,7 @@ void rv64ia::reset(uint64_t address) {
reg.PC = address;
reg.NEXT_PC = reg.PC;
reg.trap_state = 0;
- reg.machine_state = 0x0;
+ reg.machine_state = 0x3;
}
uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast(®); }