Fixed 64bit integer base instruction set
This commit is contained in:
parent
7512aad118
commit
5d508740fd
|
@ -17,9 +17,9 @@ DBT-RISE-RiscV uses libGIS (https://github.com/vsergeev/libGIS) as well as ELFIO
|
||||||
|
|
||||||
**Planned features**
|
**Planned features**
|
||||||
|
|
||||||
* add platform peripherals to resemble E300 platform
|
* add platform peripherals beyond programmers view to resemble E300 platform
|
||||||
* PLIC
|
* QSPI
|
||||||
* gpio
|
* PWM
|
||||||
* ...
|
* ...
|
||||||
* and more
|
* and more
|
||||||
|
|
||||||
|
|
2
dbt-core
2
dbt-core
|
@ -1 +1 @@
|
||||||
Subproject commit 29a69884d2fcfb29f7a5f5a927e93e35f05fdd7e
|
Subproject commit 53d78d993a8d3310a8b73fec0b601457b3c0ef75
|
|
@ -2,8 +2,8 @@ import "RV32IBase.core_desc"
|
||||||
|
|
||||||
InsructionSet RV64IBase extends RV32IBase {
|
InsructionSet RV64IBase extends RV32IBase {
|
||||||
instructions{
|
instructions{
|
||||||
LWU {
|
LWU { // 80000104: 0000ef03 lwu t5,0(ra)
|
||||||
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000011;
|
encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011;
|
||||||
args_disass:"x%rd$d, %imm%(x%rs1$d)";
|
args_disass:"x%rd$d, %imm%(x%rs1$d)";
|
||||||
val offs[XLEN] <= X[rs1]+imm;
|
val offs[XLEN] <= X[rs1]+imm;
|
||||||
if(rd!=0) X[rd]<=zext(MEM[offs]{32});
|
if(rd!=0) X[rd]<=zext(MEM[offs]{32});
|
||||||
|
@ -15,9 +15,9 @@ InsructionSet RV64IBase extends RV32IBase {
|
||||||
if(rd!=0) X[rd]<=sext(MEM[offs]{64});
|
if(rd!=0) X[rd]<=sext(MEM[offs]{64});
|
||||||
}
|
}
|
||||||
SD{
|
SD{
|
||||||
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0] | b0100011;
|
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)";
|
args_disass:"x%rs2$d, %imm%(x%rs1$d)";
|
||||||
val offs[XLEN] <= X[rs1] + sext(imm, XLEN);
|
val offs[XLEN] <= X[rs1] + imm;
|
||||||
MEM[offs]{64} <= X[rs2];
|
MEM[offs]{64} <= X[rs2];
|
||||||
}
|
}
|
||||||
SLLI {
|
SLLI {
|
||||||
|
@ -38,60 +38,77 @@ InsructionSet RV64IBase extends RV32IBase {
|
||||||
ADDIW {
|
ADDIW {
|
||||||
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011;
|
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, %imm%";
|
args_disass:"x%rd$d, x%rs1$d, %imm%";
|
||||||
if(rd != 0) X[rd] <= sext(X[rs1]{32}, XLEN) + sext(imm, XLEN);
|
if(rd != 0){
|
||||||
|
val res[32] <= X[rs1]{32} + imm{32};
|
||||||
|
X[rd] <= sext(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SLLIW {
|
SLLIW {
|
||||||
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011;
|
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, %shamt%";
|
args_disass:"x%rd$d, x%rs1$d, %shamt%";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
val sh_val[32] <= shll(X[rs1]{32}, shamt);
|
val sh_val[32] <= shll(X[rs1]{32}, shamt);
|
||||||
X[rd] <= sext(sh_val, XLEN);
|
X[rd] <= sext(sh_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SRLIW {
|
SRLIW {
|
||||||
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
|
encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, %shamt%";
|
args_disass:"x%rd$d, x%rs1$d, %shamt%";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
val sh_val[32] <= shrl(X[rs1], shamt);
|
val sh_val[32] <= shrl(X[rs1]{32}, shamt);
|
||||||
X[rd] <= sext(sh_val, XLEN);
|
X[rd] <= sext(sh_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SRAIW {
|
SRAIW {
|
||||||
encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
|
encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, %shamt%";
|
args_disass:"x%rd$d, x%rs1$d, %shamt%";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
val sh_val[32] <= shra(X[rs1], shamt);
|
val sh_val[32] <= shra(X[rs1]{32}, shamt);
|
||||||
X[rd] <= sext(sh_val, XLEN);
|
X[rd] <= sext(sh_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ADDW {
|
ADDW {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011;
|
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 {
|
SUBW {
|
||||||
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011;
|
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 {
|
SLLW {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
val sh_val[32] <= shll(X[rs1], X[rs2]&0x1f);
|
val mask[32] <= 0x1f;
|
||||||
X[rd] <= sext(sh_val, XLEN);
|
val count[32] <= X[rs2]{32} & mask;
|
||||||
|
val sh_val[32] <= shll(X[rs1]{32}, count);
|
||||||
|
X[rd] <= sext(sh_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SRLW {
|
SRLW {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
val sh_val[32] <= shrl(X[rs1], X[rs2]&0x1f);
|
val mask[32] <= 0x1f;
|
||||||
X[rd] <= sext(sh_val, XLEN);
|
val count[32] <= X[rs2]{32} & mask;
|
||||||
|
val sh_val[32] <= shrl(X[rs1]{32}, count);
|
||||||
|
X[rd] <= sext(sh_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SRAW {
|
SRAW {
|
||||||
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
|
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
val sh_val[32] <= shra(X[rs1], X[rs2]&0x1f);
|
val mask[32] <= 0x1f;
|
||||||
X[rd] <= sext(sh_val, XLEN);
|
val count[32] <= X[rs2]{32} & mask;
|
||||||
|
val sh_val[32] <= shra(X[rs1]{32}, count);
|
||||||
|
X[rd] <= sext(sh_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -308,6 +308,14 @@ public:
|
||||||
|
|
||||||
mstatus_t mstatus;
|
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;
|
T satp;
|
||||||
|
|
||||||
static constexpr T get_misa() { return (1UL << 30) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; }
|
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;
|
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;
|
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_misa() { return (2ULL << 62) | ISA_I | ISA_M | ISA_A | ISA_U | ISA_S | ISA_M; }
|
||||||
|
|
||||||
static constexpr T get_mask(unsigned priv_lvl) {
|
static constexpr T get_mask(unsigned priv_lvl) {
|
||||||
switch (priv_lvl) {
|
switch (priv_lvl) {
|
||||||
case PRIV_U: return 0x8000000000000011ULL; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
|
case PRIV_U: return 0x8000000f00000011ULL; // 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_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
|
default: return 0x8000000f007ff9ddULL; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,6 +446,8 @@ public:
|
||||||
riscv_hart_msu_vp();
|
riscv_hart_msu_vp();
|
||||||
virtual ~riscv_hart_msu_vp() = default;
|
virtual ~riscv_hart_msu_vp() = default;
|
||||||
|
|
||||||
|
void reset(uint64_t address) override;
|
||||||
|
|
||||||
void load_file(std::string name, int type = -1) override;
|
void load_file(std::string name, int type = -1) override;
|
||||||
|
|
||||||
virtual phys_addr_t v2p(const iss::addr_t &addr);
|
virtual phys_addr_t v2p(const iss::addr_t &addr);
|
||||||
|
@ -573,6 +598,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
|
||||||
LOG(DEBUG) << "read of " << length << " bytes @addr " << addr;
|
LOG(DEBUG) << "read of " << length << " bytes @addr " << addr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
try {
|
||||||
switch (addr.space) {
|
switch (addr.space) {
|
||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) {
|
if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) {
|
||||||
|
@ -633,6 +659,10 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
|
||||||
return iss::Err; // assert("Not supported");
|
return iss::Err; // assert("Not supported");
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
|
} catch (trap_access &ta) {
|
||||||
|
this->reg.trap_state = (1 << 31) | ta.id;
|
||||||
|
return iss::Err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE>
|
||||||
|
@ -810,10 +840,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_status(unsign
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_status(unsigned addr, reg_t val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_status(unsigned addr, reg_t val) {
|
||||||
auto req_priv_lvl = addr >> 8;
|
auto req_priv_lvl = addr >> 8;
|
||||||
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
|
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
|
||||||
auto mask = hart_state<reg_t>::get_mask(req_priv_lvl);
|
state.write_mstatus(val, req_priv_lvl);
|
||||||
auto old_val = state.mstatus;
|
|
||||||
auto new_val = (old_val & ~mask) | (val & mask);
|
|
||||||
state.mstatus = new_val;
|
|
||||||
check_interrupt();
|
check_interrupt();
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
@ -980,6 +1007,12 @@ inline void riscv_hart_msu_vp<BASE>::notify_phase(iss::arch_if::exec_phase phase
|
||||||
BASE::notify_phase(phase);
|
BASE::notify_phase(phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename BASE>
|
||||||
|
inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) {
|
||||||
|
BASE::reset(address);
|
||||||
|
state.mstatus = hart_state<reg_t>::mstatus_reset_val;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
||||||
auto status = state.mstatus;
|
auto status = state.mstatus;
|
||||||
auto ip = csr[mip];
|
auto ip = csr[mip];
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// 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: <CoreDSL Generator>
|
// * rv32imac.h Author: <CoreDSL Generator>
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -126,7 +126,7 @@ struct rv32imac: public arch_if {
|
||||||
using addr_t = typename traits<rv32imac>::addr_t;
|
using addr_t = typename traits<rv32imac>::addr_t;
|
||||||
|
|
||||||
rv32imac();
|
rv32imac();
|
||||||
~rv32imac() = default;
|
~rv32imac();
|
||||||
|
|
||||||
void reset(uint64_t address=0) override;
|
void reset(uint64_t address=0) override;
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// 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: <CoreDSL Generator>
|
// * rv64ia.h Author: <CoreDSL Generator>
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -148,7 +148,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
// some compile time constants
|
// 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 { 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) };
|
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] = {
|
const InstructionDesriptor instr_descr[75] = {
|
||||||
/* entries are: valid value, valid mask, function ptr */
|
/* entries are: valid value, valid mask, function ptr */
|
||||||
/* instruction LWU */
|
/* instruction LWU */
|
||||||
{32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, &this_class::__lwu},
|
{32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu},
|
||||||
/* instruction LD */
|
/* instruction LD */
|
||||||
{32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld},
|
{32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld},
|
||||||
/* instruction SD */
|
/* instruction SD */
|
||||||
|
@ -451,7 +452,7 @@ private:
|
||||||
|
|
||||||
this->gen_sync(iss::PRE_SYNC);
|
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_rs1_val = 0 | (bit_sub<15,5>(instr));
|
||||||
uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr));
|
uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr));
|
||||||
if(this->disass_enabled){
|
if(this->disass_enabled){
|
||||||
|
@ -469,10 +470,7 @@ private:
|
||||||
|
|
||||||
Value* offs_val = this->builder->CreateAdd(
|
Value* offs_val = this->builder->CreateAdd(
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
this->gen_reg_load(fld_rs1_val, 0),
|
||||||
this->gen_ext(
|
this->gen_const(64U, fld_imm_val));
|
||||||
this->gen_const(64U, fld_imm_val),
|
|
||||||
64,
|
|
||||||
true));
|
|
||||||
Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0);
|
Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0);
|
||||||
this->gen_write_mem(
|
this->gen_write_mem(
|
||||||
traits<ARCH>::MEM,
|
traits<ARCH>::MEM,
|
||||||
|
@ -613,18 +611,16 @@ private:
|
||||||
pc=pc+4;
|
pc=pc+4;
|
||||||
|
|
||||||
if(fld_rd_val != 0){
|
if(fld_rd_val != 0){
|
||||||
Value* X_rd_val = this->builder->CreateAdd(
|
Value* res_val = this->builder->CreateAdd(
|
||||||
this->gen_ext(
|
|
||||||
this->builder->CreateTrunc(
|
this->builder->CreateTrunc(
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
this->gen_reg_load(fld_rs1_val, 0),
|
||||||
this-> get_type(32)
|
this-> get_type(32)
|
||||||
),
|
),
|
||||||
|
this->gen_const(32U, fld_imm_val));
|
||||||
|
Value* X_rd_val = this->gen_ext(
|
||||||
|
res_val,
|
||||||
64,
|
64,
|
||||||
true),
|
true);
|
||||||
this->gen_ext(
|
|
||||||
this->gen_const(64U, fld_imm_val),
|
|
||||||
64,
|
|
||||||
true));
|
|
||||||
this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false);
|
this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false);
|
||||||
}
|
}
|
||||||
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||||
|
@ -700,7 +696,10 @@ private:
|
||||||
|
|
||||||
if(fld_rd_val != 0){
|
if(fld_rd_val != 0){
|
||||||
Value* sh_val_val = this->builder->CreateLShr(
|
Value* sh_val_val = this->builder->CreateLShr(
|
||||||
|
this->builder->CreateTrunc(
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
this->gen_reg_load(fld_rs1_val, 0),
|
||||||
|
this-> get_type(32)
|
||||||
|
),
|
||||||
this->gen_const(32U, fld_shamt_val));
|
this->gen_const(32U, fld_shamt_val));
|
||||||
Value* X_rd_val = this->gen_ext(
|
Value* X_rd_val = this->gen_ext(
|
||||||
sh_val_val,
|
sh_val_val,
|
||||||
|
@ -739,7 +738,10 @@ private:
|
||||||
|
|
||||||
if(fld_rd_val != 0){
|
if(fld_rd_val != 0){
|
||||||
Value* sh_val_val = this->builder->CreateAShr(
|
Value* sh_val_val = this->builder->CreateAShr(
|
||||||
|
this->builder->CreateTrunc(
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
this->gen_reg_load(fld_rs1_val, 0),
|
||||||
|
this-> get_type(32)
|
||||||
|
),
|
||||||
this->gen_const(32U, fld_shamt_val));
|
this->gen_const(32U, fld_shamt_val));
|
||||||
Value* X_rd_val = this->gen_ext(
|
Value* X_rd_val = this->gen_ext(
|
||||||
sh_val_val,
|
sh_val_val,
|
||||||
|
@ -774,7 +776,22 @@ private:
|
||||||
}
|
}
|
||||||
pc=pc+4;
|
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<ARCH>::NEXT_PC);
|
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
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 */
|
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;
|
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<ARCH>::NEXT_PC);
|
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
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 */
|
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;
|
pc=pc+4;
|
||||||
|
|
||||||
if(fld_rd_val != 0){
|
if(fld_rd_val != 0){
|
||||||
Value* sh_val_val = this->builder->CreateShl(
|
Value* mask_val = this->gen_const(32U, 31);
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
Value* count_val = this->builder->CreateAnd(
|
||||||
this->builder->CreateAnd(
|
this->builder->CreateTrunc(
|
||||||
this->gen_reg_load(fld_rs2_val, 0),
|
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(
|
Value* X_rd_val = this->gen_ext(
|
||||||
sh_val_val,
|
sh_val_val,
|
||||||
64,
|
64,
|
||||||
|
@ -874,11 +914,19 @@ private:
|
||||||
pc=pc+4;
|
pc=pc+4;
|
||||||
|
|
||||||
if(fld_rd_val != 0){
|
if(fld_rd_val != 0){
|
||||||
Value* sh_val_val = this->builder->CreateLShr(
|
Value* mask_val = this->gen_const(32U, 31);
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
Value* count_val = this->builder->CreateAnd(
|
||||||
this->builder->CreateAnd(
|
this->builder->CreateTrunc(
|
||||||
this->gen_reg_load(fld_rs2_val, 0),
|
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(
|
Value* X_rd_val = this->gen_ext(
|
||||||
sh_val_val,
|
sh_val_val,
|
||||||
64,
|
64,
|
||||||
|
@ -915,11 +963,19 @@ private:
|
||||||
pc=pc+4;
|
pc=pc+4;
|
||||||
|
|
||||||
if(fld_rd_val != 0){
|
if(fld_rd_val != 0){
|
||||||
Value* sh_val_val = this->builder->CreateAShr(
|
Value* mask_val = this->gen_const(32U, 31);
|
||||||
this->gen_reg_load(fld_rs1_val, 0),
|
Value* count_val = this->builder->CreateAnd(
|
||||||
this->builder->CreateAnd(
|
this->builder->CreateTrunc(
|
||||||
this->gen_reg_load(fld_rs2_val, 0),
|
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(
|
Value* X_rd_val = this->gen_ext(
|
||||||
sh_val_val,
|
sh_val_val,
|
||||||
64,
|
64,
|
||||||
|
@ -3384,7 +3440,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
} catch (trap_access &ta) {
|
} catch (trap_access &ta) {
|
||||||
throw trap_access(ta.id, pc.val);
|
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
|
// curr pc on stack
|
||||||
typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr);
|
typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr);
|
||||||
++inst_cnt;
|
++inst_cnt;
|
||||||
|
|
|
@ -52,7 +52,9 @@ extern "C" {
|
||||||
|
|
||||||
using namespace iss::arch;
|
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) {
|
void rv32imac::reset(uint64_t address) {
|
||||||
for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i)
|
for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i)
|
||||||
|
|
|
@ -52,9 +52,9 @@ extern "C" {
|
||||||
|
|
||||||
using namespace iss::arch;
|
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) {
|
void rv64ia::reset(uint64_t address) {
|
||||||
for (size_t i = 0; i < traits<rv64ia>::NUM_REGS; ++i)
|
for (size_t i = 0; i < traits<rv64ia>::NUM_REGS; ++i)
|
||||||
|
@ -62,7 +62,7 @@ void rv64ia::reset(uint64_t address) {
|
||||||
reg.PC = address;
|
reg.PC = address;
|
||||||
reg.NEXT_PC = reg.PC;
|
reg.NEXT_PC = reg.PC;
|
||||||
reg.trap_state = 0;
|
reg.trap_state = 0;
|
||||||
reg.machine_state = 0x0;
|
reg.machine_state = 0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(®); }
|
uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(®); }
|
||||||
|
|
Loading…
Reference in New Issue