Fixed handling of compressed ISA
This commit is contained in:
parent
9970303fa4
commit
b0dcb3b60e
2
dbt-core
2
dbt-core
@ -1 +1 @@
|
||||
Subproject commit 55b281a010a7cedc7ba23c3856a551a9ee314eb4
|
||||
Subproject commit 29a69884d2fcfb29f7a5f5a927e93e35f05fdd7e
|
@ -97,14 +97,14 @@ public:
|
||||
void notify_phase(iss::arch_if::exec_phase phase);
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
#ifndef WITH_SCV
|
||||
std::stringstream s;
|
||||
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
|
||||
<< std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]";
|
||||
CLOG(INFO, disass) << "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<instr<<"\t"<<s.str();
|
||||
#else
|
||||
if (logging::INFO <= logging::Log<logging::Output2FILE<logging::disass>>::reporting_level() && logging::Output2FILE<logging::disass>::stream()){
|
||||
std::stringstream s;
|
||||
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
|
||||
<< std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]";
|
||||
scc::Log<logging::Output2FILE<logging::disass>>().get(logging::INFO, "disass")
|
||||
<< "0x"<<std::setw(16)<<std::setfill('0')<<std::hex<<pc<<"\t\t"<<std::setw(40)<<std::setfill(' ')<<std::left<<instr<<s.str();
|
||||
}
|
||||
owner->disass_output(pc,instr);
|
||||
#endif
|
||||
};
|
||||
|
||||
iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) {
|
||||
@ -221,7 +221,7 @@ void core_complex::start_of_simulation() {
|
||||
quantum_keeper.reset();
|
||||
if (elf_file.value.size() > 0) cpu->load_file(elf_file.value);
|
||||
#ifdef WITH_SCV
|
||||
if (stream_handle == NULL) {
|
||||
if (m_db!=nullptr && stream_handle == nullptr) {
|
||||
string basename(this->name());
|
||||
stream_handle = new scv_tr_stream((basename + ".instr").c_str(), "TRANSACTOR", m_db);
|
||||
instr_tr_handle = new scv_tr_generator<>("execute", *stream_handle);
|
||||
@ -232,6 +232,7 @@ void core_complex::start_of_simulation() {
|
||||
|
||||
void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
|
||||
#ifdef WITH_SCV
|
||||
if (m_db==nullptr) return;
|
||||
if(tr_handle.is_active()) tr_handle.end_transaction();
|
||||
tr_handle = instr_tr_handle->begin_transaction();
|
||||
tr_handle.record_attribute("PC", pc);
|
||||
@ -270,7 +271,7 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data,
|
||||
gp.set_streaming_width(4);
|
||||
auto delay{quantum_keeper.get_local_time()};
|
||||
#ifdef WITH_SCV
|
||||
if(tr_handle.is_valid()){
|
||||
if(m_db!=nullptr && tr_handle.is_valid()){
|
||||
if(is_fetch && tr_handle.is_active()) tr_handle.end_transaction();
|
||||
auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this);
|
||||
gp.set_extension(preExt);
|
||||
|
@ -12,42 +12,37 @@ InsructionSet RV32CI {
|
||||
PC[XLEN](is_pc)
|
||||
}
|
||||
instructions{
|
||||
C.ADDI4SPN { //(RES, nzuimm=0)
|
||||
encoding: b000 | nzuimm[5:4] | nzuimm[9:6] | nzuimm[2:2] | nzuimm[3:3] | rd[2:0] | b00;
|
||||
args_disass: "x%rd$d, 0x%nzuimm$05x";
|
||||
if(nzuimm == 0)
|
||||
raise(0, 2);
|
||||
C.ADDI4SPN { //(RES, imm=0)
|
||||
encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00;
|
||||
args_disass: "x%rd$d, 0x%imm$05x";
|
||||
if(imm == 0) raise(0, 2);
|
||||
val rd_idx[5] <= rd+8;
|
||||
val x2_idx[5] <= 2;
|
||||
X[rd_idx] <= X[x2_idx] + nzuimm;
|
||||
X[rd_idx] <= X[x2_idx] + imm;
|
||||
}
|
||||
C.LW { // (RV32)
|
||||
encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00;
|
||||
args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x";
|
||||
val rs1_idx[5] <= rs1+8;
|
||||
val adr[XLEN] <= X[rs1_idx]+uimm;
|
||||
val rd_idx[5] <= rd+8;
|
||||
X[rd_idx] <= MEM[adr]{32};
|
||||
val offs[XLEN] <= X[rs1_idx]+uimm;
|
||||
X[rd_idx] <= MEM[offs]{32};
|
||||
}
|
||||
C.SW {//(RV32)
|
||||
encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00;
|
||||
args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x";
|
||||
val rs1_idx[5] <= rs1+8;
|
||||
val adr[XLEN] <= X[rs1_idx]+uimm;
|
||||
val rs2_idx[5] <= rs2+8;
|
||||
MEM[adr]{32} <= X[rs2_idx];
|
||||
}
|
||||
C.NOP {//(RV32)
|
||||
encoding: b000 | b0 | b00000 | b00000 | b01; //TODO
|
||||
args_disass: "";
|
||||
val offs[XLEN] <= X[rs1_idx]+uimm;
|
||||
MEM[offs]{32} <= X[rs2_idx];
|
||||
}
|
||||
C.ADDI {//(RV32)
|
||||
encoding:b000 | nzimm[5:5]s | rs1[4:0] | nzimm[4:0]s | b01;
|
||||
args_disass: "x%rs1$d, 0x%nzimm$05x";
|
||||
if(nzimm == 0)
|
||||
raise(0, 2);
|
||||
X[rs1] <= X[rs1] + nzimm;
|
||||
|
||||
encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01;
|
||||
args_disass: "x%rs1$d, 0x%imm$05x";
|
||||
X[rs1] <= X[rs1] + imm;
|
||||
}
|
||||
C.NOP {
|
||||
encoding:b000 | b0 | b00000 | b00000 | b01;
|
||||
}
|
||||
// C.JAL will be overwritten by C.ADDIW for RV64/128
|
||||
C.JAL(no_cont) {//(RV32)
|
||||
@ -60,35 +55,32 @@ InsructionSet RV32CI {
|
||||
C.LI {//(RV32)
|
||||
encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01;
|
||||
args_disass: "x%rd$d, 0x%imm$05x";
|
||||
if(rd == 0) raise(0, 2);
|
||||
if(rd == 0) raise(0, 2); //TODO: should it be handled as trap?
|
||||
X[rd] <= imm;
|
||||
}
|
||||
// order matters here as C.ADDI16SP overwrites C.LUI vor rd==2
|
||||
C.LUI {//(RV32)
|
||||
encoding:b011 | nzimm[17:17]s | rd[4:0] | nzimm[16:12]s | b01;
|
||||
args_disass: "x%rd$d, 0x%nzimm$05x";
|
||||
if(rd == 0) raise(0, 2);
|
||||
if(rd == 2) raise(0, 2);
|
||||
if(nzimm == 0) raise(0, 2);
|
||||
X[rd] <= nzimm;
|
||||
encoding:b011 | imm[17:17]s | rd[4:0] | imm[16:12]s | b01;
|
||||
args_disass: "x%rd$d, 0x%imm$05x";
|
||||
if(rd == 0) raise(0, 2); //TODO: should it be handled as trap?
|
||||
if(imm == 0) raise(0, 2); //TODO: should it be handled as trap?
|
||||
X[rd] <= imm;
|
||||
}
|
||||
C.ADDI16SP {//(RV32)
|
||||
encoding:b011 | nzimm[9:9]s | b00010 | nzimm[4:4]s |nzimm[6:6]s | nzimm[8:7]s | nzimm[5:5]s | b01;
|
||||
args_disass: "0x%nzimm$05x";
|
||||
encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01;
|
||||
args_disass: "0x%imm$05x";
|
||||
val x2_idx[5] <= 2;
|
||||
X[x2_idx] <= X[x2_idx]s + nzimm;
|
||||
X[x2_idx] <= X[x2_idx]s + imm;
|
||||
}
|
||||
C.SRLI {//(RV32 nse)
|
||||
encoding:b100 | shamt[5:5] | b00 | rs1[2:0] | shamt[4:0] | b01;
|
||||
encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01;
|
||||
args_disass: "x(8+%rs1$d), %shamt$d";
|
||||
if(shamt > 31) raise(0, 2);
|
||||
val rs1_idx[5] <= rs1+8;
|
||||
X[rs1_idx] <= shrl(X[rs1_idx], shamt);
|
||||
}
|
||||
C.SRAI {//(RV32)
|
||||
encoding:b100 | shamt[5:5] | b01 | rs1[2:0] | shamt[4:0] | b01;
|
||||
encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01;
|
||||
args_disass: "x(8+%rs1$d), %shamt$d";
|
||||
if(shamt > 31) raise(0, 2);
|
||||
val rs1_idx[5] <= rs1+8;
|
||||
X[rs1_idx] <= shra(X[rs1_idx], shamt);
|
||||
}
|
||||
@ -132,27 +124,23 @@ InsructionSet RV32CI {
|
||||
PC<=PC+imm;
|
||||
}
|
||||
C.BEQZ(no_cont) {//(RV32)
|
||||
encoding:b110 | imm[8:8]s | imm[4:3]s | rs1d[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01;
|
||||
args_disass: "x(8+%rs1d$d), 0x%imm$05x";
|
||||
val rs1[5] <= rs1d+8;
|
||||
PC<=choose(X[rs1]==0, PC+imm, PC+2);
|
||||
encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01;
|
||||
args_disass: "x(8+%rs1$d), 0x%imm$05x";
|
||||
val rs1_idx[5] <= rs1+8;
|
||||
PC<=choose(X[rs1_idx]==0, PC+imm, PC+2);
|
||||
}
|
||||
C.BNEZ(no_cont) {//(RV32)
|
||||
encoding:b111 | imm[8:8] | imm[4:3] | rs1d[2:0] | imm[7:6] | imm[2:1] | imm[5:5] | b01;
|
||||
args_disass: "x(8+%rs1d$d),, 0x%imm$05x";
|
||||
val rs1[5] <= rs1d+8;
|
||||
PC<=choose(X[rs1]!=0, PC+imm, PC+2);
|
||||
encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01;
|
||||
args_disass: "x(8+%rs1$d), 0x%imm$05x";
|
||||
val rs1_idx[5] <= rs1+8;
|
||||
PC<=choose(X[rs1_idx]!=0, PC+imm, PC+2);
|
||||
}
|
||||
C.SLLI {//(RV32)
|
||||
encoding:b000 | shamt[5:5] | rs1[4:0] | shamt[4:0] | b10;
|
||||
encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10;
|
||||
args_disass: "x%rs1$d, %shamt$d";
|
||||
if(rs1 == 0) raise(0, 2);
|
||||
if(shamt > 31) raise(0, 2);
|
||||
X[rs1] <= shll(X[rs1], shamt);
|
||||
}
|
||||
C.LQSP {//(RV128)
|
||||
encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:4] | uimm[9:6] | b10;
|
||||
}
|
||||
C.LWSP {//
|
||||
encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10;
|
||||
args_disass: "x%rd$d, sp, 0x%uimm$05x";
|
||||
@ -160,7 +148,7 @@ InsructionSet RV32CI {
|
||||
val offs[XLEN] <= X[x2_idx] + uimm;
|
||||
X[rd] <= MEM[offs]{32};
|
||||
}
|
||||
// order matters as C.JR is a special case of C.JR
|
||||
// order matters as C.JR is a special case of C.MV
|
||||
C.MV {//(RV32)
|
||||
encoding:b100 | b0 | rd[4:0] | rs2[4:0] | b10;
|
||||
args_disass: "x%rd$d, x%rs2$d";
|
||||
@ -171,23 +159,23 @@ InsructionSet RV32CI {
|
||||
args_disass: "x%rs1$d";
|
||||
PC <= X[rs1];
|
||||
}
|
||||
C.EBREAK(no_cont) {//(RV32)
|
||||
encoding:b100 | b1 | b00000 | b00000 | b10;
|
||||
raise(0, 3);
|
||||
}
|
||||
// order matters as C.JALR is a special case of C.ADD
|
||||
// order matters as C.EBREAK is a special case of C.JALR which is a special case of C.ADD
|
||||
C.ADD {//(RV32)
|
||||
encoding:b100 | b1 | rd[4:0] | rs2[4:0] | b10;
|
||||
args_disass: "x%rd$d, x%rs2$d";
|
||||
X[rd] <= X[rd] + X[rs2];
|
||||
X[rd] <= X[rd] + X[rs2];
|
||||
}
|
||||
C.JALR(no_cont) {//(RV32)
|
||||
encoding:b100 | b1 | rs1[4:0] | b00000 | b10;
|
||||
args_disass: "x%rs1$d";
|
||||
val rd[5] <= 1;
|
||||
X[rd] <= PC+2;
|
||||
val r_idx[5] <= 1;
|
||||
X[r_idx] <= PC+2;
|
||||
PC<=X[rs1];
|
||||
}
|
||||
C.EBREAK(no_cont) {//(RV32)
|
||||
encoding:b100 | b1 | b00000 | b00000 | b10;
|
||||
raise(0, 3);
|
||||
}
|
||||
C.SWSP {//
|
||||
encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10;
|
||||
args_disass: "x2+0x%uimm$05x, x%rs2$d";
|
||||
@ -195,6 +183,10 @@ InsructionSet RV32CI {
|
||||
val offs[XLEN] <= X[x2_idx] + uimm;
|
||||
MEM[offs]{32} <= X[rs2];
|
||||
}
|
||||
DII {
|
||||
encoding:b000 | b0 | b00000 | b00000 | b00;
|
||||
raise(0, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,6 +435,8 @@ public:
|
||||
virtual uint64_t leave_trap(uint64_t flags) override;
|
||||
void wait_until(uint64_t flags) override;
|
||||
|
||||
void notify_phase(iss::arch_if::exec_phase phase);
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
std::stringstream s;
|
||||
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
|
||||
@ -468,6 +470,7 @@ protected:
|
||||
|
||||
private:
|
||||
iss::status read_cycle(unsigned addr, reg_t &val);
|
||||
iss::status read_time(unsigned addr, reg_t &val);
|
||||
iss::status read_status(unsigned addr, reg_t &val);
|
||||
iss::status write_status(unsigned addr, reg_t val);
|
||||
iss::status read_ie(unsigned addr, reg_t &val);
|
||||
@ -489,6 +492,10 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
|
||||
for (unsigned addr = mcycle; addr <= hpmcounter31; ++addr) csr_wr_cb[addr] = nullptr;
|
||||
for (unsigned addr = mcycleh; addr <= hpmcounter31h; ++addr) csr_wr_cb[addr] = nullptr;
|
||||
// special handling
|
||||
csr_rd_cb[time] = &riscv_hart_msu_vp<BASE>::read_time;
|
||||
csr_wr_cb[time] = nullptr;
|
||||
csr_rd_cb[timeh] = &riscv_hart_msu_vp<BASE>::read_time;
|
||||
csr_wr_cb[timeh] = nullptr;
|
||||
csr_rd_cb[mcycle] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
csr_rd_cb[mcycleh] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
csr_rd_cb[minstret] = &riscv_hart_msu_vp<BASE>::read_cycle;
|
||||
@ -781,6 +788,17 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t &val) {
|
||||
uint64_t time_val=this->reg.icount>>12;
|
||||
if (addr == time) {
|
||||
val = static_cast<reg_t>(time_val);
|
||||
} else if (addr == timeh) {
|
||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
||||
val = static_cast<reg_t>(time_val >> 32);
|
||||
}
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_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);
|
||||
@ -862,8 +880,9 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length
|
||||
if ((paddr.val + length) > mem.size()) return iss::Err;
|
||||
switch (paddr.val) {
|
||||
case 0x0200BFF8: { // CLINT base, mtime reg
|
||||
uint64_t mtime = this->reg.icount >> 12 /*12*/;
|
||||
std::copy((uint8_t *)&mtime, ((uint8_t *)&mtime) + length, data);
|
||||
if(sizeof(reg_t)<length) return iss::Err;
|
||||
reg_t time_val=this->csr[time];
|
||||
std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data);
|
||||
} break;
|
||||
case 0x10008000: {
|
||||
const mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
@ -954,6 +973,11 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template<typename BASE>
|
||||
inline void riscv_hart_msu_vp<BASE>::notify_phase(iss::arch_if::exec_phase phase) {
|
||||
BASE::notify_phase(phase);
|
||||
}
|
||||
|
||||
template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
||||
auto status = state.mstatus;
|
||||
auto ip = csr[mip];
|
||||
|
@ -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) };
|
||||
|
||||
@ -281,7 +282,7 @@ vm_impl<ARCH>::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<ARCH>::processing_pc_entry addr(*this, pc, paddr);
|
||||
++inst_cnt;
|
||||
|
@ -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) };
|
||||
|
||||
@ -364,10 +365,10 @@ private:
|
||||
{16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw},
|
||||
/* instruction C.SW */
|
||||
{16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw},
|
||||
/* instruction C.NOP */
|
||||
{16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop},
|
||||
/* instruction C.ADDI */
|
||||
{16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi},
|
||||
/* instruction C.NOP */
|
||||
{16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop},
|
||||
/* instruction C.JAL */
|
||||
{16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal},
|
||||
/* instruction C.LI */
|
||||
@ -377,9 +378,9 @@ private:
|
||||
/* instruction C.ADDI16SP */
|
||||
{16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp},
|
||||
/* instruction C.SRLI */
|
||||
{16, 0b1000000000000001, 0b1110110000000011, &this_class::__c_srli},
|
||||
{16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli},
|
||||
/* instruction C.SRAI */
|
||||
{16, 0b1000010000000001, 0b1110110000000011, &this_class::__c_srai},
|
||||
{16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai},
|
||||
/* instruction C.ANDI */
|
||||
{16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi},
|
||||
/* instruction C.SUB */
|
||||
@ -397,23 +398,23 @@ private:
|
||||
/* instruction C.BNEZ */
|
||||
{16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez},
|
||||
/* instruction C.SLLI */
|
||||
{16, 0b0000000000000010, 0b1110000000000011, &this_class::__c_slli},
|
||||
/* instruction C.LQSP */
|
||||
{16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_lqsp},
|
||||
{16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli},
|
||||
/* instruction C.LWSP */
|
||||
{16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp},
|
||||
/* instruction C.MV */
|
||||
{16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv},
|
||||
/* instruction C.JR */
|
||||
{16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr},
|
||||
/* instruction C.EBREAK */
|
||||
{16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak},
|
||||
/* instruction C.ADD */
|
||||
{16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add},
|
||||
/* instruction C.JALR */
|
||||
{16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr},
|
||||
/* instruction C.EBREAK */
|
||||
{16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak},
|
||||
/* instruction C.SWSP */
|
||||
{16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp},
|
||||
/* instruction DII */
|
||||
{16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii},
|
||||
};
|
||||
// instruction LUI
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
@ -3353,11 +3354,11 @@ private:
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr));
|
||||
uint16_t fld_nzuimm_val = 0 | (bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4);
|
||||
uint16_t fld_imm_val = 0 | (bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4);
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.ADDI4SPN x%1$d, 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_nzuimm_val;
|
||||
ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_imm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
@ -3367,14 +3368,14 @@ private:
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
if(fld_nzuimm_val == 0){
|
||||
if(fld_imm_val == 0){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
uint8_t rd_idx_val = (fld_rd_val + 8);
|
||||
uint8_t x2_idx_val = 2;
|
||||
Value* X_rd_idx_val = this->builder->CreateAdd(
|
||||
this->gen_reg_load(x2_idx_val, 0),
|
||||
this->gen_const(32U, fld_nzuimm_val));
|
||||
this->gen_const(32U, fld_imm_val));
|
||||
this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false);
|
||||
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
@ -3406,11 +3407,11 @@ private:
|
||||
pc=pc+2;
|
||||
|
||||
uint8_t rs1_idx_val = (fld_rs1_val + 8);
|
||||
Value* adr_val = this->builder->CreateAdd(
|
||||
uint8_t rd_idx_val = (fld_rd_val + 8);
|
||||
Value* offs_val = this->builder->CreateAdd(
|
||||
this->gen_reg_load(rs1_idx_val, 0),
|
||||
this->gen_const(32U, fld_uimm_val));
|
||||
uint8_t rd_idx_val = (fld_rd_val + 8);
|
||||
Value* X_rd_idx_val = this->gen_read_mem(traits<ARCH>::MEM, adr_val, 32/8);
|
||||
Value* X_rd_idx_val = this->gen_read_mem(traits<ARCH>::MEM, offs_val, 32/8);
|
||||
this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false);
|
||||
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
@ -3442,15 +3443,47 @@ private:
|
||||
pc=pc+2;
|
||||
|
||||
uint8_t rs1_idx_val = (fld_rs1_val + 8);
|
||||
Value* adr_val = this->builder->CreateAdd(
|
||||
uint8_t rs2_idx_val = (fld_rs2_val + 8);
|
||||
Value* offs_val = this->builder->CreateAdd(
|
||||
this->gen_reg_load(rs1_idx_val, 0),
|
||||
this->gen_const(32U, fld_uimm_val));
|
||||
uint8_t rs2_idx_val = (fld_rs2_val + 8);
|
||||
Value* MEM_adr_val = this->gen_reg_load(rs2_idx_val, 0);
|
||||
Value* MEM_offs_val = this->gen_reg_load(rs2_idx_val, 0);
|
||||
this->gen_write_mem(
|
||||
traits<ARCH>::MEM,
|
||||
adr_val,
|
||||
this->builder->CreateZExtOrTrunc(MEM_adr_val,this->get_type(32)));
|
||||
offs_val,
|
||||
this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32)));
|
||||
this->gen_set_pc(pc, traits<ARCH>::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 */
|
||||
this->gen_trap_check(bb);
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
// instruction C.ADDI
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.ADDI");
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5);
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.ADDI x%1$d, 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr(ins_fmter.str()),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
Value* X_rs1_val = this->builder->CreateAdd(
|
||||
this->gen_reg_load(fld_rs1_val, 0),
|
||||
this->gen_const(32U, fld_imm_val));
|
||||
this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false);
|
||||
this->gen_set_pc(pc, traits<ARCH>::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 */
|
||||
@ -3467,12 +3500,10 @@ private:
|
||||
;
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.NOP ");
|
||||
ins_fmter ;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr(ins_fmter.str()),
|
||||
this->builder->CreateGlobalStringPtr("C.NOP"),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
@ -3486,41 +3517,6 @@ private:
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
// instruction C.ADDI
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.ADDI");
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
int8_t fld_nzimm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5);
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.ADDI x%1$d, 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_nzimm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr(ins_fmter.str()),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
if(fld_nzimm_val == 0){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
Value* X_rs1_val = this->builder->CreateAdd(
|
||||
this->gen_reg_load(fld_rs1_val, 0),
|
||||
this->gen_const(32U, fld_nzimm_val));
|
||||
this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false);
|
||||
this->gen_set_pc(pc, traits<ARCH>::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 */
|
||||
this->gen_trap_check(bb);
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
// instruction C.JAL
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.JAL");
|
||||
@ -3594,12 +3590,12 @@ private:
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
int32_t fld_nzimm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17);
|
||||
int32_t fld_imm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17);
|
||||
uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.LUI x%1$d, 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_nzimm_val;
|
||||
ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
@ -3612,13 +3608,10 @@ private:
|
||||
if(fld_rd_val == 0){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
if(fld_rd_val == 2){
|
||||
if(fld_imm_val == 0){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
if(fld_nzimm_val == 0){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
Value* X_rd_val = this->gen_const(32U, fld_nzimm_val);
|
||||
Value* X_rd_val = this->gen_const(32U, fld_imm_val);
|
||||
this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false);
|
||||
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
@ -3633,11 +3626,11 @@ private:
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
int16_t fld_nzimm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9);
|
||||
int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9);
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.ADDI16SP 0x%1$05x");
|
||||
ins_fmter % (int64_t)fld_nzimm_val;
|
||||
ins_fmter % (int64_t)fld_imm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
@ -3652,7 +3645,7 @@ private:
|
||||
this->gen_ext(
|
||||
this->gen_reg_load(x2_idx_val, 0),
|
||||
32, true),
|
||||
this->gen_const(32U, fld_nzimm_val));
|
||||
this->gen_const(32U, fld_imm_val));
|
||||
this->builder->CreateStore(X_x2_idx_val, get_reg_ptr(x2_idx_val), false);
|
||||
this->gen_set_pc(pc, traits<ARCH>::NEXT_PC);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
@ -3667,7 +3660,7 @@ private:
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5);
|
||||
uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr));
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
@ -3682,9 +3675,6 @@ private:
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
if(fld_shamt_val > 31){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
uint8_t rs1_idx_val = (fld_rs1_val + 8);
|
||||
Value* X_rs1_idx_val = this->builder->CreateLShr(
|
||||
this->gen_reg_load(rs1_idx_val, 0),
|
||||
@ -3703,7 +3693,7 @@ private:
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5);
|
||||
uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr));
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
@ -3718,9 +3708,6 @@ private:
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
if(fld_shamt_val > 31){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
uint8_t rs1_idx_val = (fld_rs1_val + 8);
|
||||
Value* X_rs1_idx_val = this->builder->CreateAShr(
|
||||
this->gen_reg_load(rs1_idx_val, 0),
|
||||
@ -3938,11 +3925,11 @@ private:
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8);
|
||||
uint8_t fld_rs1d_val = 0 | (bit_sub<7,3>(instr));
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.BEQZ x(8+%1$d), 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rs1d_val % (int64_t)fld_imm_val;
|
||||
ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
@ -3952,11 +3939,11 @@ private:
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
uint8_t rs1_val = (fld_rs1d_val + 8);
|
||||
uint8_t rs1_idx_val = (fld_rs1_val + 8);
|
||||
Value* PC_val = this->gen_choose(
|
||||
this->builder->CreateICmp(
|
||||
ICmpInst::ICMP_EQ,
|
||||
this->gen_reg_load(rs1_val, 0),
|
||||
this->gen_reg_load(rs1_idx_val, 0),
|
||||
this->gen_const(32U, 0)),
|
||||
this->builder->CreateAdd(
|
||||
this->gen_reg_load(traits<ARCH>::PC, 0),
|
||||
@ -3977,12 +3964,12 @@ private:
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
uint16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8);
|
||||
uint8_t fld_rs1d_val = 0 | (bit_sub<7,3>(instr));
|
||||
int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8);
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
boost::format ins_fmter("C.BNEZ x(8+%1$d),, 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rs1d_val % (uint64_t)fld_imm_val;
|
||||
boost::format ins_fmter("C.BNEZ x(8+%1$d), 0x%2$05x");
|
||||
ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val;
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
@ -3992,11 +3979,11 @@ private:
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
uint8_t rs1_val = (fld_rs1d_val + 8);
|
||||
uint8_t rs1_idx_val = (fld_rs1_val + 8);
|
||||
Value* PC_val = this->gen_choose(
|
||||
this->builder->CreateICmp(
|
||||
ICmpInst::ICMP_NE,
|
||||
this->gen_reg_load(rs1_val, 0),
|
||||
this->gen_reg_load(rs1_idx_val, 0),
|
||||
this->gen_const(32U, 0)),
|
||||
this->builder->CreateAdd(
|
||||
this->gen_reg_load(traits<ARCH>::PC, 0),
|
||||
@ -4017,7 +4004,7 @@ private:
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5);
|
||||
uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr));
|
||||
uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
@ -4035,9 +4022,6 @@ private:
|
||||
if(fld_rs1_val == 0){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
if(fld_shamt_val > 31){
|
||||
this->gen_raise_trap(0, 2);
|
||||
}
|
||||
Value* X_rs1_val = this->builder->CreateShl(
|
||||
this->gen_reg_load(fld_rs1_val, 0),
|
||||
this->gen_const(32U, fld_shamt_val));
|
||||
@ -4049,33 +4033,6 @@ private:
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
// instruction C.LQSP
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_lqsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.LQSP");
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
uint16_t fld_uimm_val = 0 | (bit_sub<2,4>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 5);
|
||||
uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr));
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr("C.LQSP"),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
/* TODO: describe operations for C.LQSP ! */
|
||||
this->gen_set_pc(pc, traits<ARCH>::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 */
|
||||
this->gen_trap_check(bb);
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
// instruction C.LWSP
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.LWSP");
|
||||
@ -4167,30 +4124,6 @@ private:
|
||||
return std::make_tuple(iss::vm::BRANCH, nullptr);
|
||||
}
|
||||
|
||||
// instruction C.EBREAK
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.EBREAK");
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
;
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr("C.EBREAK"),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
this->gen_raise_trap(0, 3);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
this->gen_trap_check(this->leave_blk);
|
||||
return std::make_tuple(iss::vm::BRANCH, nullptr);
|
||||
}
|
||||
|
||||
// instruction C.ADD
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.ADD");
|
||||
@ -4243,11 +4176,11 @@ private:
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
uint8_t rd_val = 1;
|
||||
Value* X_rd_val = this->builder->CreateAdd(
|
||||
uint8_t r_idx_val = 1;
|
||||
Value* X_r_idx_val = this->builder->CreateAdd(
|
||||
this->gen_reg_load(traits<ARCH>::PC, 0),
|
||||
this->gen_const(32U, 2));
|
||||
this->builder->CreateStore(X_rd_val, get_reg_ptr(rd_val), false);
|
||||
this->builder->CreateStore(X_r_idx_val, get_reg_ptr(r_idx_val), false);
|
||||
Value* PC_val = this->gen_reg_load(fld_rs1_val, 0);
|
||||
this->builder->CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
@ -4255,6 +4188,30 @@ private:
|
||||
return std::make_tuple(iss::vm::BRANCH, nullptr);
|
||||
}
|
||||
|
||||
// instruction C.EBREAK
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.EBREAK");
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
;
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr("C.EBREAK"),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
this->gen_raise_trap(0, 3);
|
||||
this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */
|
||||
this->gen_trap_check(this->leave_blk);
|
||||
return std::make_tuple(iss::vm::BRANCH, nullptr);
|
||||
}
|
||||
|
||||
// instruction C.SWSP
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("C.SWSP");
|
||||
@ -4292,6 +4249,32 @@ private:
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
// instruction DII
|
||||
std::tuple<vm::continuation_e, llvm::BasicBlock*> __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){
|
||||
bb->setName("DII");
|
||||
|
||||
this->gen_sync(iss::PRE_SYNC);
|
||||
|
||||
;
|
||||
if(this->disass_enabled){
|
||||
/* generate console output when executing the command */
|
||||
std::vector<llvm::Value*> args {
|
||||
this->core_ptr,
|
||||
this->gen_const(64, pc.val),
|
||||
this->builder->CreateGlobalStringPtr("DII"),
|
||||
};
|
||||
this->builder->CreateCall(this->mod->getFunction("print_disass"), args);
|
||||
}
|
||||
pc=pc+2;
|
||||
|
||||
this->gen_raise_trap(0, 2);
|
||||
this->gen_set_pc(pc, traits<ARCH>::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 */
|
||||
this->gen_trap_check(bb);
|
||||
return std::make_tuple(vm::CONT, bb);
|
||||
}
|
||||
|
||||
/* end generated code */
|
||||
/****************************************************************************
|
||||
* end opcode definitions
|
||||
@ -4358,7 +4341,7 @@ vm_impl<ARCH>::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<ARCH>::processing_pc_entry addr(*this, pc, paddr);
|
||||
++inst_cnt;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit fbd3247649d3b12d0e752c92a5d856572641445c
|
||||
Subproject commit ba65d9f172246d6735a40fd6259ec13467e43419
|
Loading…
Reference in New Issue
Block a user