From 873e4257f2dc247108e6db76cf0c78069d362ecd Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Fri, 15 Dec 2017 14:13:22 +0100 Subject: [PATCH] Restructured DBT function to encapsulate the compilation process This should enable the implementation of multi-threading of the compilation process --- .project | 1 + README.md | 2 +- dbt-core | 2 +- riscv.sc/src/sysc/core_complex.cpp | 16 +- riscv/incl/iss/arch/riscv_hart_msu_vp.h | 128 +- riscv/incl/iss/arch/rv32imac.h | 31 +- riscv/incl/iss/arch/rv64ia.h | 31 +- .../incl/iss/debugger/riscv_target_adapter.h | 14 +- riscv/src/CMakeLists.txt | 3 +- riscv/src/internal/vm_riscv.in.cpp | 68 +- riscv/src/internal/vm_rv32imac.cpp | 1001 ++--- riscv/src/internal/vm_rv64ia.cpp | 3335 ++++++++--------- riscv/src/iss/rv32imac.cpp | 2 +- riscv/src/iss/rv64ia.cpp | 2 +- riscv/src/main.cpp | 22 +- sc-components | 2 +- simple-system.json | 4 +- 17 files changed, 2317 insertions(+), 2347 deletions(-) diff --git a/.project b/.project index 43247d2..3e68573 100644 --- a/.project +++ b/.project @@ -7,6 +7,7 @@ org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, diff --git a/README.md b/README.md index 13e150e..3dea4c9 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Am instruction set simulator based on DBT-RISE implementing the RISC-V ISA **DBT-RISE-RISCV README** This is work in progress, so use at your own risk. Goal is to implement an open-source ISS which can easily embedded e.g. into SystemC Virtual Prototypes. It used code generation to allow easy extension and adaptation of the used instruction. -The RISC-V ISS reaches about 20MIPS at an Intel Core i7-2600K. +The RISC-V ISS reaches about 30MIPS running on Intel Core i7-2600K. The implementation is based on LLVM 4.0. Eclipse CDT 4.7 (Oxygen) is recommended as IDE. diff --git a/dbt-core b/dbt-core index cf96794..4bfcd8a 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit cf9679475121f85a6333970f80bb6a40a8b4a0a5 +Subproject commit 4bfcd8a10e81d610d46b329841ae3ba7cbc0627a diff --git a/riscv.sc/src/sysc/core_complex.cpp b/riscv.sc/src/sysc/core_complex.cpp index a3f48c8..808d43b 100644 --- a/riscv.sc/src/sysc/core_complex.cpp +++ b/riscv.sc/src/sysc/core_complex.cpp @@ -94,7 +94,9 @@ public: base_type::hart_state& get_state() { return this->state; } - void notify_phase(iss::arch_if::exec_phase phase); + void notify_phase(exec_phase) override; + + iss::sync_type needed_sync() const override { return iss::PRE_SYNC; } void disass_output(uint64_t pc, const std::string instr) override { if (logging::INFO <= logging::Log>::reporting_level() && logging::Output2FILE::stream()){ @@ -108,15 +110,15 @@ public: }; iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) { - if (addr.type & iss::DEBUG) + if (addr.access && iss::access_type::DEBUG) return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; else { - return owner->read_mem(addr.val, length, data,addr.type && iss::FETCH) ? iss::Ok : iss::Err; + return owner->read_mem(addr.val, length, data,addr.access && iss::access_type::FETCH) ? iss::Ok : iss::Err; } } iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) { - if (addr.type & iss::DEBUG) + if (addr.access && iss::access_type::DEBUG) return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; else{ auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; @@ -187,9 +189,9 @@ int cmd_sysc(int argc, char* argv[], iss::debugger::out_func of, iss::debugger:: } -void core_wrapper::notify_phase(exec_phase phase) { - core_type::notify_phase(phase); - if (phase == ISTART) owner->sync(); +void core_wrapper::notify_phase(exec_phase p) { + if(p == ISTART) + owner->sync(); } core_complex::core_complex(sc_core::sc_module_name name) diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h index 06c7f8b..2e41781 100644 --- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h +++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h @@ -222,6 +222,7 @@ struct vm_info { int idxbits; int ptesize; uint64_t ptbase; + bool is_active() { return levels;} }; class trap_load_access_fault : public trap_access { @@ -450,7 +451,7 @@ public: void load_file(std::string name, int type = -1) override; - virtual phys_addr_t v2p(const iss::addr_t &addr); + virtual phys_addr_t virt2phys(const iss::addr_t &addr) override; iss::status read(const iss::addr_t &addr, unsigned length, uint8_t *const data) override; iss::status write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) override; @@ -460,8 +461,6 @@ 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') @@ -486,6 +485,8 @@ protected: mem_type mem; csr_type csr; hart_state state; + vm_info vm[2]; + void update_vm_info(); unsigned to_host_wr_cnt = 0; std::stringstream uart_buf; std::unordered_map ptw; @@ -571,7 +572,7 @@ template void riscv_hart_msu_vp::load_file(std::string nam const auto seg_data = pseg->get_data(); if (fsize > 0) { auto res = this->write( - typed_addr_t(iss::DEBUG_WRITE, traits::MEM, pseg->get_physical_address()), + phys_addr_t(iss::access_type::DEBUG_WRITE, traits::MEM, pseg->get_physical_address()), fsize, reinterpret_cast(seg_data)); if (res != iss::Ok) LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex @@ -586,13 +587,15 @@ template void riscv_hart_msu_vp::load_file(std::string nam } return; } + throw std::runtime_error("memory load file is not a valid elf file"); } + throw std::runtime_error("memory load file not found"); } template iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned length, uint8_t *const data) { #ifndef NDEBUG - if (addr.type & iss::DEBUG) { + if (addr.access && iss::access_type::DEBUG) { LOG(DEBUG) << "debug read of " << length << " bytes @addr " << addr; } else { LOG(DEBUG) << "read of " << length << " bytes @addr " << addr; @@ -601,9 +604,9 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng try { switch (addr.space) { case traits::MEM: { - if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) { + if ((addr.access == iss::access_type::FETCH || addr.access == iss::access_type::DEBUG_FETCH) && (addr.val & 0x1) == 1) { fault_data = addr.val; - if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val); + if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val); this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } @@ -615,12 +618,11 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng 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); + res = read(iss::addr_t{addr.access, 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); + auto res = read_mem( BASE::v2p(addr), 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) { @@ -668,7 +670,7 @@ iss::status riscv_hart_msu_vp::read(const iss::addr_t &addr, unsigned leng template iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) { #ifndef NDEBUG - const char *prefix = addr.type & iss::DEBUG ? "debug " : ""; + const char *prefix = (addr.access && iss::access_type::DEBUG)? "debug " : ""; switch (length) { case 8: LOG(DEBUG) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t *)&data[0] << std::dec @@ -693,9 +695,9 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len try { switch (addr.space) { case traits::MEM: { - if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) { + if ((addr.access && iss::access_type::FETCH) && (addr.val & 0x1) == 1) { fault_data = addr.val; - if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val); + if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val); this->reg.trap_state = (1 << 31); // issue trap 0 return iss::Err; } @@ -707,12 +709,11 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len auto len1 = split_addr - addr.val; auto res = write(addr, len1, data); if (res == iss::Ok) - res = write(iss::addr_t{addr.type, addr.space, split_addr}, length - len1, data + len1); + res = write(iss::addr_t{addr.access, 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 = write_mem(paddr, length, data); + auto res = write_mem(BASE::v2p(addr), length, data); if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) return res; } catch (trap_access &ta) { @@ -720,7 +721,7 @@ iss::status riscv_hart_msu_vp::write(const iss::addr_t &addr, unsigned len return iss::Err; } - phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); + phys_addr_t paddr = BASE::v2p(addr); if ((paddr.val + length) > mem.size()) return iss::Err; switch (paddr.val) { case 0x10013000: // UART0 base, TXFIFO reg @@ -842,6 +843,7 @@ template iss::status riscv_hart_msu_vp::write_status(unsig if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); state.write_mstatus(val, req_priv_lvl); check_interrupt(); + update_vm_info(); return iss::Ok; } @@ -901,6 +903,7 @@ template iss::status riscv_hart_msu_vp::write_satp(unsigne return iss::Err; } state.satp = val; + update_vm_info(); return iss::Ok; } @@ -909,8 +912,9 @@ iss::status riscv_hart_msu_vp::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 - if(sizeof(reg_t)csr[time]; + if(sizeof(reg_t)read_csr(time, time_val); std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data); } break; case 0x10008000: { @@ -960,7 +964,7 @@ iss::status riscv_hart_msu_vp::write_mem(phys_addr_t paddr, unsigned lengt mem_type::page_type &p = mem(paddr.val / mem.page_size); std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask)); // tohost handling in case of riscv-test - if ((paddr.type & iss::DEBUG) == 0) { + if (paddr.access && iss::access_type::FUNC) { auto tohost_upper = (traits::XLEN == 32 && paddr.val == (tohost + 4)) || (traits::XLEN == 64 && paddr.val == tohost); auto tohost_lower = @@ -1003,15 +1007,23 @@ iss::status riscv_hart_msu_vp::write_mem(phys_addr_t paddr, unsigned lengt return iss::Ok; } -template -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; + update_vm_info(); +} + +template +inline void riscv_hart_msu_vp::update_vm_info() { + vm[1] = hart_state::decode_vm_info(this->reg.machine_state, state.satp); + BASE::addr_mode[3]=BASE::addr_mode[2]=vm[1].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL; + if(state.mstatus.MPRV) + vm[0] = hart_state::decode_vm_info(state.mstatus.MPP, state.satp); + else + vm[0] = vm[1]; + BASE::addr_mode[1]=BASE::addr_mode[0]=vm[0].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL; + ptw.clear(); } template void riscv_hart_msu_vp::check_interrupt() { @@ -1042,37 +1054,12 @@ template void riscv_hart_msu_vp::check_interrupt() { } template -typename riscv_hart_msu_vp::phys_addr_t riscv_hart_msu_vp::v2p(const iss::addr_t &addr) { - const uint64_t tmp = reg_t(1) << (traits::XLEN - 1); - const uint64_t msk = tmp | (tmp - 1); - - if (addr.space != traits::MEM) { // non-memory access - phys_addr_t ret(addr); - ret.val &= msk; - return ret; - } - - const auto type = (access_type)(addr.getAccessType() & ~iss::DEBUG); - uint32_t mode = type != iss::FETCH && state.mstatus.MPRV ? // MPRV - mode = state.mstatus.MPP: - this->reg.machine_state; - - const vm_info vm = hart_state::decode_vm_info(mode, state.satp); - - if (vm.levels == 0) { - phys_addr_t ret(addr); - ret.val &= msk; - return ret; - } - - const bool s_mode = mode == PRIV_S; - const bool sum = state.mstatus.SUM; - const bool mxr = state.mstatus.MXR; - +typename riscv_hart_msu_vp::phys_addr_t riscv_hart_msu_vp::virt2phys(const iss::addr_t &addr) { + const auto type = addr.access & iss::access_type::FUNC; auto it = ptw.find(addr.val >> PGSHIFT); if (it != ptw.end()) { const reg_t pte = it->second; - const reg_t ad = PTE_A | ((type == iss::WRITE) * PTE_D); + const reg_t ad = PTE_A | (type == iss::access_type::WRITE) * PTE_D; #ifdef RISCV_ENABLE_DIRTY // set accessed and possibly dirty bits. *(uint32_t *)ppte |= ad; @@ -1080,11 +1067,21 @@ typename riscv_hart_msu_vp::phys_addr_t riscv_hart_msu_vp::v2p(const #else // take exception if access or possibly dirty bit is not set. if ((pte & ad) == ad) - return {addr.getAccessType(), addr.space, (pte & (~PGMASK)) | (addr.val & PGMASK)}; + return {addr.access, addr.space, (pte & (~PGMASK)) | (addr.val & PGMASK)}; else - ptw.erase(it); + ptw.erase(it); // throw an exception #endif } else { + uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV + state.mstatus.MPP: + this->reg.machine_state; + + const vm_info& vm = this->vm[static_cast(type)/2]; + + const bool s_mode = mode == PRIV_S; + const bool sum = state.mstatus.SUM; + const bool mxr = state.mstatus.MXR; + // verify bits xlen-1:va_bits-1 are all equal const int va_bits = PGSHIFT + vm.levels * vm.idxbits; const reg_t mask = (reg_t(1) << (traits::XLEN > -(va_bits - 1))) - 1; @@ -1099,25 +1096,24 @@ typename riscv_hart_msu_vp::phys_addr_t riscv_hart_msu_vp::v2p(const // check that physical address of PTE is legal reg_t pte = 0; const uint8_t res = - this->read(phys_addr_t(addr.getAccessType(), traits::MEM, base + idx * vm.ptesize), vm.ptesize, - (uint8_t *)&pte); + this->read(phys_addr_t{addr.access, traits::MEM, base + idx * vm.ptesize}, vm.ptesize, (uint8_t *)&pte); if (res != 0) throw trap_load_access_fault(addr.val); const reg_t ppn = pte >> PTE_PPN_SHIFT; if (PTE_TABLE(pte)) { // next level of page table base = ppn << PGSHIFT; - } else if ((pte & PTE_U) ? s_mode && (type == iss::FETCH || !sum) : !s_mode) { + } else if ((pte & PTE_U) ? s_mode && (type == iss::access_type::FETCH || !sum) : !s_mode) { break; } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) { break; - } else if (type == iss::FETCH ? !(pte & PTE_X) - : type == iss::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X)) + } else if (type == iss::access_type::FETCH ? !(pte & PTE_X) + : type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X)) : !((pte & PTE_R) && (pte & PTE_W))) { break; } else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) { break; } else { - const reg_t ad = PTE_A | ((type == iss::WRITE) * PTE_D); + const reg_t ad = PTE_A | ((type == iss::access_type::WRITE) * PTE_D); #ifdef RISCV_ENABLE_DIRTY // set accessed and possibly dirty bits. *(uint32_t *)ppte |= ad; @@ -1130,18 +1126,18 @@ typename riscv_hart_msu_vp::phys_addr_t riscv_hart_msu_vp::v2p(const const reg_t value = (ppn | (vpn & ((reg_t(1) << ptshift) - 1))) << PGSHIFT; const reg_t offset = addr.val & PGMASK; ptw[vpn] = value | (pte & 0xff); - return {addr.getAccessType(), addr.space, value | offset}; + return {addr.access, addr.space, value | offset}; } } } switch (type) { - case FETCH: + case access_type::FETCH: this->fault_data = addr.val; throw trap_instruction_page_fault(addr.val); - case READ: + case access_type::READ: this->fault_data = addr.val; throw trap_load_page_fault(addr.val); - case WRITE: + case access_type::WRITE: this->fault_data = addr.val; throw trap_store_page_fault(addr.val); default: @@ -1217,6 +1213,7 @@ template uint64_t riscv_hart_msu_vp::enter_trap(uint64_t f CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause])<<"' ("<reg.NEXT_PC; } @@ -1253,6 +1250,7 @@ template uint64_t riscv_hart_msu_vp::leave_trap(uint64_t f // sets the pc to the value stored in the x epc register. this->reg.NEXT_PC = csr[uepc | inst_priv << 8]; CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " << lvl[this->reg.machine_state]; + update_vm_info(); return this->reg.NEXT_PC; } diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index 78ea62f..7fbfb49 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: Sun Nov 19 14:05:47 CET 2017 +// Created on: Fri Dec 15 14:41:57 CET 2017 // * rv32imac.h Author: // //////////////////////////////////////////////////////////////////////////////// @@ -98,9 +98,9 @@ struct traits { using code_word_t = uint32_t; //TODO: check removal - using virt_addr_t = iss::typed_addr_t; + using virt_addr_t = iss::typed_addr_t; - using phys_addr_t = iss::typed_addr_t; + using phys_addr_t = iss::typed_addr_t; constexpr static unsigned reg_bit_width(unsigned r) { const uint32_t RV32IMAC_reg_size[] = {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}; @@ -112,6 +112,8 @@ struct traits { return RV32IMAC_reg_byte_offset[r]; } + static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); + enum sreg_flag_e {FLAGS}; enum mem_type_e {MEM,CSR,FENCE,RES}; @@ -140,19 +142,20 @@ struct rv32imac: public arch_if { /// deprecated void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; - void notify_phase(exec_phase phase){ - if(phase==ISTART){ - ++reg.icount; - reg.PC=reg.NEXT_PC; - reg.trap_state=reg.pending_trap; - } - } - uint64_t get_icount() { return reg.icount;} - virtual phys_addr_t v2p(const iss::addr_t& pc); + inline phys_addr_t v2p(const iss::addr_t& addr){ + if(addr.space != traits::MEM || + addr.type == iss::address_type::PHYSICAL || + addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL){ + return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); + } else + return virt2phys(addr); + } - virtual iss::sync_type needed_sync() const { return iss::PRE_SYNC; } + virtual phys_addr_t virt2phys(const iss::addr_t& addr); + + virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } protected: struct RV32IMAC_regs { @@ -193,6 +196,8 @@ protected: uint32_t trap_state, pending_trap, machine_state; uint64_t icount; } reg; + + address_type addr_mode[4]; }; } diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h index b0b2d09..6f91112 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: Sun Nov 19 14:05:47 CET 2017 +// Created on: Fri Dec 15 14:41:58 CET 2017 // * rv64ia.h Author: // //////////////////////////////////////////////////////////////////////////////// @@ -98,9 +98,9 @@ struct traits { using code_word_t = uint64_t; //TODO: check removal - using virt_addr_t = iss::typed_addr_t; + using virt_addr_t = iss::typed_addr_t; - using phys_addr_t = iss::typed_addr_t; + using phys_addr_t = iss::typed_addr_t; constexpr static unsigned reg_bit_width(unsigned r) { const uint32_t RV64IA_reg_size[] = {64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,64}; @@ -112,6 +112,8 @@ struct traits { return RV64IA_reg_byte_offset[r]; } + static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); + enum sreg_flag_e {FLAGS}; enum mem_type_e {MEM,CSR,FENCE,RES}; @@ -140,19 +142,20 @@ struct rv64ia: public arch_if { /// deprecated void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; - void notify_phase(exec_phase phase){ - if(phase==ISTART){ - ++reg.icount; - reg.PC=reg.NEXT_PC; - reg.trap_state=reg.pending_trap; - } - } - uint64_t get_icount() { return reg.icount;} - virtual phys_addr_t v2p(const iss::addr_t& pc); + inline phys_addr_t v2p(const iss::addr_t& addr){ + if(addr.space != traits::MEM || + addr.type == iss::address_type::PHYSICAL || + addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL){ + return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); + } else + return virt2phys(addr); + } - virtual iss::sync_type needed_sync() const { return iss::PRE_SYNC; } + virtual phys_addr_t virt2phys(const iss::addr_t& addr); + + virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } protected: struct RV64IA_regs { @@ -193,6 +196,8 @@ protected: uint32_t trap_state, pending_trap, machine_state; uint64_t icount; } reg; + + address_type addr_mode[4]; }; } diff --git a/riscv/incl/iss/debugger/riscv_target_adapter.h b/riscv/incl/iss/debugger/riscv_target_adapter.h index 84eeeb9..8d5f27f 100644 --- a/riscv/incl/iss/debugger/riscv_target_adapter.h +++ b/riscv/incl/iss/debugger/riscv_target_adapter.h @@ -211,7 +211,7 @@ status riscv_target_adapter::read_single_register(unsigned int reg_no, std std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin()); std::fill(avail.begin(), avail.end(), 0xff); } else { - typed_addr_t a(iss::DEBUG_READ, traits::CSR, reg_no - 65); + typed_addr_t a(iss::access_type::DEBUG_READ, traits::CSR, reg_no - 65); data.resize(sizeof(typename traits::reg_t)); avail.resize(sizeof(typename traits::reg_t)); std::fill(avail.begin(), avail.end(), 0xff); @@ -228,20 +228,20 @@ status riscv_target_adapter::write_single_register(unsigned int reg_no, co auto offset = traits::reg_byte_offset(reg_no); std::copy(data.begin(), data.begin() + reg_width, reg_base + offset); } else { - typed_addr_t a(iss::DEBUG_WRITE, traits::CSR, reg_no - 65); + typed_addr_t a(iss::access_type::DEBUG_WRITE, traits::CSR, reg_no - 65); core->write(a, data.size(), data.data()); } return Ok; } template status riscv_target_adapter::read_mem(uint64_t addr, std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); + auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr}); auto f = [&]() -> status { return core->read(a, data.size(), data.data()); }; return srv->execute_syncronized(f); } template status riscv_target_adapter::write_mem(uint64_t addr, const std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); + auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr}); return srv->execute_syncronized(&arch_if::write, core, a, data.size(), data.data()); } @@ -292,8 +292,8 @@ template status riscv_target_adapter::packetsize_query(std } template status riscv_target_adapter::add_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - auto eaddr = map_addr({iss::CODE, iss::PHYSICAL, addr + length}); + auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr}); + auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length}); target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex << saddr.val << std::dec; @@ -302,7 +302,7 @@ template status riscv_target_adapter::add_break(int type, } template status riscv_target_adapter::remove_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); + auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr}); unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val); if (handle) { LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val diff --git a/riscv/src/CMakeLists.txt b/riscv/src/CMakeLists.txt index d7a38c3..ccdc31f 100644 --- a/riscv/src/CMakeLists.txt +++ b/riscv/src/CMakeLists.txt @@ -16,7 +16,8 @@ set(APP_SOURCES main.cpp) set(LIBRARY_NAME risc-v) # Define the library -add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES}) +#add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES}) +add_library(${LIBRARY_NAME} ${LIB_SOURCES}) SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive) set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. diff --git a/riscv/src/internal/vm_riscv.in.cpp b/riscv/src/internal/vm_riscv.in.cpp index 5482395..6598bd5 100644 --- a/riscv/src/internal/vm_riscv.in.cpp +++ b/riscv/src/internal/vm_riscv.in.cpp @@ -62,7 +62,7 @@ public: vm_impl(); - vm_impl(ARCH &core, bool dump = false); + vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } @@ -102,13 +102,13 @@ protected: inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { - return this->builder->CreateLoad(get_reg_ptr(i), false); + return this->builder.CreateLoad(get_reg_ptr(i), false); } inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { - llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), + llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), this->get_type(traits::XLEN)); - this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true); + this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } // some compile time constants @@ -186,30 +186,11 @@ private: ****************************************************************************/ std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, llvm::BasicBlock *bb) { - bb->setName("illegal_instruction"); - -// this->gen_sync(iss::PRE_SYNC); -// if(this->disass_enabled){ -// /* generate console output when executing the command */ -// boost::format ins_fmter("DB x%1$d"); -// ins_fmter % (uint64_t)instr; -// std::vector 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 + ((instr & 3) == 3 ? 4 : 2); -// this->gen_raise_trap(0, 2); // illegal instruction trap -// 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); - // this->gen_sync(iss::PRE_SYNC); - this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), true), + this->gen_sync(iss::PRE_SYNC); + this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), true), get_reg_ptr(traits::PC), true); - this->builder->CreateStore( - this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), true), + this->builder.CreateStore( + this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits::ICOUNT), true), this->gen_const(64U, 1)), get_reg_ptr(traits::ICOUNT), true); if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); @@ -229,8 +210,8 @@ template void debug_fn(CODE_WORD insn) { template vm_impl::vm_impl() { this(new ARCH()); } template -vm_impl::vm_impl(ARCH &core, bool dump) -: vm::vm_base(core, dump) { +vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) +: vm::vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -239,7 +220,6 @@ vm_impl::vm_impl(ARCH &core, bool dump) auto quantrant = instr.value & 0x3; expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op); } - this->sync_exec = static_cast(this->sync_exec | core.needed_sync()); } template @@ -278,44 +258,44 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, } template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { - this->builder->SetInsertPoint(leave_blk); - this->builder->CreateRet(this->builder->CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); + this->builder.SetInsertPoint(leave_blk); + this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); - this->builder->CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); } template void vm_impl::gen_leave_trap(unsigned lvl) { std::vector args{ this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), }; - this->builder->CreateCall(this->mod->getFunction("leave_trap"), args); + this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); } template void vm_impl::gen_wait(unsigned type) { std::vector args{ this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), }; - this->builder->CreateCall(this->mod->getFunction("wait"), args); + this->builder.CreateCall(this->mod->getFunction("wait"), args); } template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { - this->builder->SetInsertPoint(trap_blk); - auto *trap_state_val = this->builder->CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); + this->builder.SetInsertPoint(trap_blk); + auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); std::vector args{this->core_ptr, this->adj_to64(trap_state_val), - this->adj_to64(this->builder->CreateLoad(get_reg_ptr(traits::PC), false))}; - this->builder->CreateCall(this->mod->getFunction("enter_trap"), args); - auto *trap_addr_val = this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), false); - this->builder->CreateRet(trap_addr_val); + this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; + this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); + auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateRet(trap_addr_val); } template inline void vm_impl::gen_trap_check(llvm::BasicBlock *bb) { - auto *v = this->builder->CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); - this->gen_cond_branch(this->builder->CreateICmp( + auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, v, llvm::ConstantInt::get(getContext(), llvm::APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index 2408e39..7014917 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -62,7 +62,7 @@ public: vm_impl(); - vm_impl(ARCH &core, bool dump = false); + vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } @@ -102,13 +102,13 @@ protected: inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { - return this->builder->CreateLoad(get_reg_ptr(i), false); + return this->builder.CreateLoad(get_reg_ptr(i), false); } inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { - llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), + llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), this->get_type(traits::XLEN)); - this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true); + this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } // some compile time constants @@ -395,15 +395,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ 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->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 */ @@ -427,17 +427,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -461,22 +461,22 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)); - 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); } - Value* PC_val = this->builder->CreateAdd( + Value* PC_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -498,25 +498,25 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)); - 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); } - Value* ret_val = this->builder->CreateAdd( + Value* ret_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - Value* PC_val = this->builder->CreateAnd( + Value* PC_val = this->builder.CreateAnd( ret_val, - this->builder->CreateNot(this->gen_const(32U, 1))); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateNot(this->gen_const(32U, 1))); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -538,25 +538,25 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -578,25 +578,25 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_NE, this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -618,14 +618,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -633,14 +633,14 @@ private: this->gen_ext( this->gen_reg_load(fld_rs2_val, 0), 32, true)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -662,14 +662,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SGE, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -677,14 +677,14 @@ private: this->gen_ext( this->gen_reg_load(fld_rs2_val, 0), 32, true)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -706,25 +706,25 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -746,25 +746,25 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_UGE, this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 4)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -786,13 +786,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ @@ -800,7 +800,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 8/8), 32, 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -825,13 +825,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ @@ -839,7 +839,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 16/8), 32, 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -864,13 +864,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ @@ -878,7 +878,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -903,13 +903,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ @@ -917,7 +917,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 8/8), 32, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -942,13 +942,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); if(fld_rd_val != 0){ @@ -956,7 +956,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 16/8), 32, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -981,20 +981,20 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(8))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(8))); 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 */ @@ -1018,20 +1018,20 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(16))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(16))); 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 */ @@ -1055,20 +1055,20 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -1092,17 +1092,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1127,15 +1127,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -1146,7 +1146,7 @@ private: this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1171,16 +1171,16 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; int32_t full_imm_val = fld_imm_val; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -1191,7 +1191,7 @@ private: this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1216,17 +1216,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateXor( + Value* X_rd_val = this->builder.CreateXor( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1251,17 +1251,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateOr( + Value* X_rd_val = this->builder.CreateOr( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1286,17 +1286,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAnd( + Value* X_rd_val = this->builder.CreateAnd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_imm_val)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1321,17 +1321,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateShl( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + if(fld_shamt_val > 31){ + this->gen_raise_trap(0, 0); + } else { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateShl( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(32U, fld_shamt_val)); + 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 */ @@ -1356,17 +1360,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateLShr( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + if(fld_shamt_val > 31){ + this->gen_raise_trap(0, 0); + } else { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateLShr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(32U, fld_shamt_val)); + 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 */ @@ -1391,17 +1399,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAShr( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + if(fld_shamt_val > 31){ + this->gen_raise_trap(0, 0); + } else { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAShr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(32U, fld_shamt_val)); + 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 */ @@ -1426,17 +1438,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1461,17 +1473,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateSub( + Value* X_rd_val = this->builder.CreateSub( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1496,19 +1508,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateShl( + Value* X_rd_val = this->builder.CreateShl( this->gen_reg_load(fld_rs1_val, 0), - this->builder->CreateAnd( + this->builder.CreateAnd( this->gen_reg_load(fld_rs2_val, 0), 31)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1533,15 +1545,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -1552,7 +1564,7 @@ private: this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1577,15 +1589,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -1598,7 +1610,7 @@ private: this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1623,17 +1635,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateXor( + Value* X_rd_val = this->builder.CreateXor( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1658,19 +1670,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateLShr( + Value* X_rd_val = this->builder.CreateLShr( this->gen_reg_load(fld_rs1_val, 0), - this->builder->CreateAnd( + this->builder.CreateAnd( this->gen_reg_load(fld_rs2_val, 0), 31)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1695,19 +1707,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAShr( + Value* X_rd_val = this->builder.CreateAShr( this->gen_reg_load(fld_rs1_val, 0), - this->builder->CreateAnd( + this->builder.CreateAnd( this->gen_reg_load(fld_rs2_val, 0), 31)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1732,17 +1744,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateOr( + Value* X_rd_val = this->builder.CreateOr( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1767,17 +1779,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAnd( + Value* X_rd_val = this->builder.CreateAnd( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -1801,21 +1813,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("FENCE"), + this->builder.CreateGlobalStringPtr("FENCE"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* FENCE_fence_val = this->builder->CreateOr( - this->builder->CreateShl( + Value* FENCE_fence_val = this->builder.CreateOr( + this->builder.CreateShl( this->gen_const(32U, fld_pred_val), this->gen_const(32U, 4)), this->gen_const(32U, fld_succ_val)); this->gen_write_mem( traits::FENCE, (uint64_t)0, - this->builder->CreateZExtOrTrunc(FENCE_fence_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(FENCE_fence_val,this->get_type(32))); 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 */ @@ -1837,9 +1849,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("FENCE_I"), + this->builder.CreateGlobalStringPtr("FENCE_I"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -1847,7 +1859,7 @@ private: this->gen_write_mem( traits::FENCE, (uint64_t)1, - this->builder->CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); @@ -1866,9 +1878,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("ECALL"), + this->builder.CreateGlobalStringPtr("ECALL"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -1890,9 +1902,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("EBREAK"), + this->builder.CreateGlobalStringPtr("EBREAK"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -1914,9 +1926,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("URET"), + this->builder.CreateGlobalStringPtr("URET"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -1938,9 +1950,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("SRET"), + this->builder.CreateGlobalStringPtr("SRET"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -1962,9 +1974,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("MRET"), + this->builder.CreateGlobalStringPtr("MRET"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -1986,9 +1998,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("WFI"), + this->builder.CreateGlobalStringPtr("WFI"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2013,9 +2025,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("SFENCE.VMA"), + this->builder.CreateGlobalStringPtr("SFENCE.VMA"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2023,12 +2035,12 @@ private: this->gen_write_mem( traits::FENCE, (uint64_t)2, - this->builder->CreateZExtOrTrunc(FENCE_fencevmal_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(FENCE_fencevmal_val,this->get_type(32))); Value* FENCE_fencevmau_val = this->gen_const(32U, fld_rs2_val); this->gen_write_mem( traits::FENCE, (uint64_t)3, - this->builder->CreateZExtOrTrunc(FENCE_fencevmau_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(FENCE_fencevmau_val,this->get_type(32))); 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 */ @@ -2052,9 +2064,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2065,15 +2077,15 @@ private: this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); Value* X_rd_val = csr_val_val; - 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); } else { Value* CSR_csr_val = rs_val_val; this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2098,9 +2110,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2108,16 +2120,16 @@ private: Value* xrs1_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = xrd_val; - 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); } if(fld_rs1_val != 0){ - Value* CSR_csr_val = this->builder->CreateOr( + Value* CSR_csr_val = this->builder.CreateOr( xrd_val, xrs1_val); this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2142,9 +2154,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2152,16 +2164,16 @@ private: Value* xrs1_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = xrd_val; - 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); } if(fld_rs1_val != 0){ - Value* CSR_csr_val = this->builder->CreateAnd( + Value* CSR_csr_val = this->builder.CreateAnd( xrd_val, - this->builder->CreateNot(xrs1_val)); + this->builder.CreateNot(xrs1_val)); this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2186,15 +2198,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); - 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); } Value* CSR_csr_val = this->gen_ext( this->gen_const(32U, fld_zimm_val), @@ -2203,7 +2215,7 @@ private: this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); 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 */ @@ -2227,15 +2239,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* res_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); if(fld_zimm_val != 0){ - Value* CSR_csr_val = this->builder->CreateOr( + Value* CSR_csr_val = this->builder.CreateOr( res_val, this->gen_ext( this->gen_const(32U, fld_zimm_val), @@ -2244,11 +2256,11 @@ private: this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); } if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2273,28 +2285,28 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* res_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } if(fld_zimm_val != 0){ - Value* CSR_csr_val = this->builder->CreateAnd( + Value* CSR_csr_val = this->builder.CreateAnd( res_val, - this->builder->CreateNot(this->gen_ext( + this->builder.CreateNot(this->gen_ext( this->gen_const(32U, fld_zimm_val), 32, false))); this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2319,14 +2331,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* res_val = this->builder->CreateMul( + Value* res_val = this->builder.CreateMul( this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), 64, @@ -2339,7 +2351,7 @@ private: res_val, 32, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2364,14 +2376,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* res_val = this->builder->CreateMul( + Value* res_val = this->builder.CreateMul( this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), 64, @@ -2381,12 +2393,12 @@ private: 64, true)); Value* X_rd_val = this->gen_ext( - this->builder->CreateLShr( + this->builder.CreateLShr( res_val, 32), 32, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2411,14 +2423,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* res_val = this->builder->CreateMul( + Value* res_val = this->builder.CreateMul( this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), 64, @@ -2428,12 +2440,12 @@ private: 64, false)); Value* X_rd_val = this->gen_ext( - this->builder->CreateLShr( + this->builder.CreateLShr( res_val, 32), 32, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2458,14 +2470,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* res_val = this->builder->CreateMul( + Value* res_val = this->builder.CreateMul( this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), 64, @@ -2475,12 +2487,12 @@ private: 64, false)); Value* X_rd_val = this->gen_ext( - this->builder->CreateLShr( + this->builder.CreateLShr( res_val, 32), 32, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2505,9 +2517,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2515,16 +2527,16 @@ private: llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { - Value* X_rd_val = this->builder->CreateSDiv( + Value* X_rd_val = this->builder.CreateSDiv( this->gen_ext( this->gen_reg_load(fld_rs1_val, 1), 32, @@ -2533,17 +2545,17 @@ private: this->gen_reg_load(fld_rs2_val, 1), 32, 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->builder->CreateBr(bbnext); - this->builder->SetInsertPoint(bb_else); + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); { - Value* X_rd_val = this->builder->CreateNeg(this->gen_const(32U, 1)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + Value* X_rd_val = this->builder.CreateNeg(this->gen_const(32U, 1)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } - this->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2568,9 +2580,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2578,16 +2590,16 @@ private: llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { - Value* X_rd_val = this->builder->CreateUDiv( + Value* X_rd_val = this->builder.CreateUDiv( this->gen_ext( this->gen_reg_load(fld_rs1_val, 1), 32, @@ -2596,17 +2608,17 @@ private: this->gen_reg_load(fld_rs2_val, 1), 32, false)); - 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->builder->CreateBr(bbnext); - this->builder->SetInsertPoint(bb_else); + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); { - Value* X_rd_val = this->builder->CreateNeg(this->gen_const(32U, 1)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + Value* X_rd_val = this->builder.CreateNeg(this->gen_const(32U, 1)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); } - this->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2631,9 +2643,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2641,16 +2653,16 @@ private: llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { - Value* X_rd_val = this->builder->CreateSRem( + Value* X_rd_val = this->builder.CreateSRem( this->gen_ext( this->gen_reg_load(fld_rs1_val, 1), 32, @@ -2659,17 +2671,17 @@ private: this->gen_reg_load(fld_rs2_val, 1), 32, 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->builder->CreateBr(bbnext); - this->builder->SetInsertPoint(bb_else); + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); { Value* X_rd_val = this->gen_reg_load(fld_rs1_val, 1); - 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->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2694,9 +2706,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2704,16 +2716,16 @@ private: llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, this->gen_reg_load(fld_rs2_val, 0), this->gen_const(32U, 0)), bb_then, bb_else); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { - Value* X_rd_val = this->builder->CreateURem( + Value* X_rd_val = this->builder.CreateURem( this->gen_ext( this->gen_reg_load(fld_rs1_val, 1), 32, @@ -2722,17 +2734,17 @@ private: this->gen_reg_load(fld_rs2_val, 1), 32, false)); - 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->builder->CreateBr(bbnext); - this->builder->SetInsertPoint(bb_else); + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); { Value* X_rd_val = this->gen_reg_load(fld_rs1_val, 1); - 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->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2758,9 +2770,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2770,15 +2782,15 @@ private: this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, 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); Value* RES_offs_val = this->gen_ext( - this->builder->CreateNeg(this->gen_const(8U, 1)), + this->builder.CreateNeg(this->gen_const(8U, 1)), 32, true); this->gen_write_mem( traits::RES, offs_val, - this->builder->CreateZExtOrTrunc(RES_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(RES_offs_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2805,9 +2817,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2815,34 +2827,34 @@ private: Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, res1_val, this->gen_const(32U, 0)), bb_then, bbnext); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 1); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); } - this->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_NE, res1_val, this->gen_const(32U, 0)), this->gen_const(32U, 0), this->gen_const(32U, 1), 32); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2869,9 +2881,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2881,13 +2893,13 @@ private: this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, 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); } Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -2913,9 +2925,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2926,16 +2938,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateAdd( + Value* res2_val = this->builder.CreateAdd( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -2961,9 +2973,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2974,16 +2986,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateXor( + Value* res2_val = this->builder.CreateXor( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3009,9 +3021,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3022,16 +3034,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateAnd( + Value* res2_val = this->builder.CreateAnd( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3057,9 +3069,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3070,16 +3082,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateOr( + Value* res2_val = this->builder.CreateOr( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3105,9 +3117,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3118,10 +3130,10 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SGT, this->gen_ext( res1_val, @@ -3136,7 +3148,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3162,9 +3174,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3175,10 +3187,10 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( res1_val, @@ -3193,7 +3205,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3219,9 +3231,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3232,10 +3244,10 @@ private: false); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_UGT, res1_val, this->gen_reg_load(fld_rs2_val, 0)), @@ -3246,7 +3258,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3272,9 +3284,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3285,10 +3297,10 @@ private: false); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( res1_val, @@ -3303,7 +3315,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3326,9 +3338,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; @@ -3337,10 +3349,10 @@ private: } uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t x2_idx_val = 2; - Value* X_rd_idx_val = this->builder->CreateAdd( + Value* X_rd_idx_val = this->builder.CreateAdd( this->gen_reg_load(x2_idx_val, 0), this->gen_const(32U, fld_imm_val)); - this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); + this->builder.CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_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 */ @@ -3364,19 +3376,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); uint8_t rd_idx_val = (fld_rd_val + 8); - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_uimm_val)); Value* X_rd_idx_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); + this->builder.CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_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 */ @@ -3400,22 +3412,22 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_uimm_val)); Value* MEM_offs_val = this->gen_reg_load(rs2_idx_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3438,16 +3450,16 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; - Value* X_rs1_val = this->builder->CreateAdd( + 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->builder.CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_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 */ @@ -3467,9 +3479,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("C.NOP"), + this->builder.CreateGlobalStringPtr("C.NOP"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; @@ -3495,21 +3507,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rd_val = 1; - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(rd_val), false); - Value* PC_val = this->builder->CreateAdd( + this->builder.CreateStore(X_rd_val, get_reg_ptr(rd_val), false); + Value* PC_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -3530,9 +3542,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; @@ -3540,7 +3552,7 @@ private: this->gen_raise_trap(0, 2); } 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->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 */ @@ -3563,9 +3575,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; @@ -3576,7 +3588,7 @@ private: this->gen_raise_trap(0, 2); } 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->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 */ @@ -3598,19 +3610,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t x2_idx_val = 2; - Value* X_x2_idx_val = this->builder->CreateAdd( + Value* X_x2_idx_val = this->builder.CreateAdd( this->gen_ext( this->gen_reg_load(x2_idx_val, 0), 32, true), this->gen_const(32U, fld_imm_val)); - this->builder->CreateStore(X_x2_idx_val, get_reg_ptr(x2_idx_val), false); + this->builder.CreateStore(X_x2_idx_val, get_reg_ptr(x2_idx_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 */ @@ -3633,17 +3645,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* X_rs1_idx_val = this->builder->CreateLShr( + Value* X_rs1_idx_val = this->builder.CreateLShr( this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_shamt_val)); - this->builder->CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_val), false); + this->builder.CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_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 */ @@ -3666,17 +3678,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* X_rs1_idx_val = this->builder->CreateAShr( + Value* X_rs1_idx_val = this->builder.CreateAShr( this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_shamt_val)); - this->builder->CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_val), false); + this->builder.CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_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 */ @@ -3699,17 +3711,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* X_rs1_idx_val = this->builder->CreateAnd( + Value* X_rs1_idx_val = this->builder.CreateAnd( this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, fld_imm_val)); - this->builder->CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_val), false); + this->builder.CreateStore(X_rs1_idx_val, get_reg_ptr(rs1_idx_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 */ @@ -3732,18 +3744,18 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); - Value* X_rd_idx_val = this->builder->CreateSub( + Value* X_rd_idx_val = this->builder.CreateSub( this->gen_reg_load(rd_idx_val, 0), this->gen_reg_load(rs2_idx_val, 0)); - this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); + this->builder.CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_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 */ @@ -3766,18 +3778,18 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); - Value* X_rd_idx_val = this->builder->CreateXor( + Value* X_rd_idx_val = this->builder.CreateXor( this->gen_reg_load(rd_idx_val, 0), this->gen_reg_load(rs2_idx_val, 0)); - this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); + this->builder.CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_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 */ @@ -3800,18 +3812,18 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); - Value* X_rd_idx_val = this->builder->CreateOr( + Value* X_rd_idx_val = this->builder.CreateOr( this->gen_reg_load(rd_idx_val, 0), this->gen_reg_load(rs2_idx_val, 0)); - this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); + this->builder.CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_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 */ @@ -3834,18 +3846,18 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rd_idx_val = (fld_rd_val + 8); uint8_t rs2_idx_val = (fld_rs2_val + 8); - Value* X_rd_idx_val = this->builder->CreateAnd( + Value* X_rd_idx_val = this->builder.CreateAnd( this->gen_reg_load(rd_idx_val, 0), this->gen_reg_load(rs2_idx_val, 0)); - this->builder->CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_val), false); + this->builder.CreateStore(X_rd_idx_val, get_reg_ptr(rd_idx_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 */ @@ -3867,16 +3879,16 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; - Value* PC_val = this->builder->CreateAdd( + Value* PC_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -3897,26 +3909,26 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, 0)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -3937,26 +3949,26 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t rs1_idx_val = (fld_rs1_val + 8); Value* PC_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_NE, this->gen_reg_load(rs1_idx_val, 0), this->gen_const(32U, 0)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, fld_imm_val)), - this->builder->CreateAdd( + this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)), 32); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -3977,19 +3989,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; if(fld_rs1_val == 0){ this->gen_raise_trap(0, 2); } - Value* X_rs1_val = this->builder->CreateShl( + Value* X_rs1_val = this->builder.CreateShl( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(32U, fld_shamt_val)); - this->builder->CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); + this->builder.CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_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 */ @@ -4012,18 +4024,18 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t x2_idx_val = 2; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(x2_idx_val, 0), this->gen_const(32U, fld_uimm_val)); Value* X_rd_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - 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::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 */ @@ -4046,14 +4058,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; Value* X_rd_val = this->gen_reg_load(fld_rs2_val, 0); - 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::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 */ @@ -4075,14 +4087,14 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; Value* PC_val = this->gen_reg_load(fld_rs1_val, 0); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -4103,16 +4115,16 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(fld_rd_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::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 */ @@ -4134,19 +4146,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t r_idx_val = 1; - Value* X_r_idx_val = this->builder->CreateAdd( + Value* X_r_idx_val = this->builder.CreateAdd( this->gen_reg_load(traits::PC, 0), this->gen_const(32U, 2)); - this->builder->CreateStore(X_r_idx_val, get_reg_ptr(r_idx_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::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); 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); @@ -4164,9 +4176,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("C.EBREAK"), + this->builder.CreateGlobalStringPtr("C.EBREAK"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; @@ -4191,21 +4203,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; uint8_t x2_idx_val = 2; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(x2_idx_val, 0), this->gen_const(32U, fld_uimm_val)); Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -4225,9 +4237,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("DII"), + this->builder.CreateGlobalStringPtr("DII"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+2; @@ -4245,11 +4257,11 @@ private: ****************************************************************************/ std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, llvm::BasicBlock *bb) { - // this->gen_sync(iss::PRE_SYNC); - this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), true), + this->gen_sync(iss::PRE_SYNC); + this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), true), get_reg_ptr(traits::PC), true); - this->builder->CreateStore( - this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), true), + this->builder.CreateStore( + this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits::ICOUNT), true), this->gen_const(64U, 1)), get_reg_ptr(traits::ICOUNT), true); if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); @@ -4269,8 +4281,8 @@ template void debug_fn(CODE_WORD insn) { template vm_impl::vm_impl() { this(new ARCH()); } template -vm_impl::vm_impl(ARCH &core, bool dump) -: vm::vm_base(core, dump) { +vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) +: vm::vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -4279,7 +4291,6 @@ vm_impl::vm_impl(ARCH &core, bool dump) auto quantrant = instr.value & 0x3; expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op); } - this->sync_exec = static_cast(this->sync_exec | core.needed_sync()); } template @@ -4287,8 +4298,8 @@ std::tuple vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, llvm::BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 code_word_t insn = 0; - iss::addr_t paddr; const typename traits::addr_t upper_bits = ~traits::PGMASK; + phys_addr_t paddr(pc); try { uint8_t *const data = (uint8_t *)&insn; paddr = this->core.v2p(pc); @@ -4318,44 +4329,44 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, } template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { - this->builder->SetInsertPoint(leave_blk); - this->builder->CreateRet(this->builder->CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); + this->builder.SetInsertPoint(leave_blk); + this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); - this->builder->CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); } template void vm_impl::gen_leave_trap(unsigned lvl) { std::vector args{ this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), }; - this->builder->CreateCall(this->mod->getFunction("leave_trap"), args); + this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); } template void vm_impl::gen_wait(unsigned type) { std::vector args{ this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), }; - this->builder->CreateCall(this->mod->getFunction("wait"), args); + this->builder.CreateCall(this->mod->getFunction("wait"), args); } template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { - this->builder->SetInsertPoint(trap_blk); - auto *trap_state_val = this->builder->CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); + this->builder.SetInsertPoint(trap_blk); + auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); std::vector args{this->core_ptr, this->adj_to64(trap_state_val), - this->adj_to64(this->builder->CreateLoad(get_reg_ptr(traits::PC), false))}; - this->builder->CreateCall(this->mod->getFunction("enter_trap"), args); - auto *trap_addr_val = this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), false); - this->builder->CreateRet(trap_addr_val); + this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; + this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); + auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateRet(trap_addr_val); } template inline void vm_impl::gen_trap_check(llvm::BasicBlock *bb) { - auto *v = this->builder->CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); - this->gen_cond_branch(this->builder->CreateICmp( + auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, v, llvm::ConstantInt::get(getContext(), llvm::APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index a609ff7..8af1940 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -62,7 +62,7 @@ public: vm_impl(); - vm_impl(ARCH &core, bool dump = false); + vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } @@ -74,13 +74,15 @@ public: } protected: + using vm::vm_base::get_reg_ptr; + template inline llvm::ConstantInt *size(T type) { return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); } inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) const { - return this->gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); + return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, @@ -98,53 +100,15 @@ protected: void gen_trap_check(llvm::BasicBlock *bb); - inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { - llvm::Value *next_pc_v = this->builder->CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), - this->get_type(traits::XLEN)); - this->builder->CreateStore(next_pc_v, get_reg_ptr(reg_num), true); - } - - inline llvm::Value *get_reg_ptr(unsigned i) { - void *ptr = this->core.get_regs_base_ptr() + traits::reg_byte_offset(i); - llvm::PointerType *ptrType = nullptr; - switch (traits::reg_bit_width(i) >> 3) { - case 8: - ptrType = llvm::Type::getInt64PtrTy(this->mod->getContext()); - break; - case 4: - ptrType = llvm::Type::getInt32PtrTy(this->mod->getContext()); - break; - case 2: - ptrType = llvm::Type::getInt16PtrTy(this->mod->getContext()); - break; - case 1: - ptrType = llvm::Type::getInt8PtrTy(this->mod->getContext()); - break; - default: - throw std::runtime_error("unsupported access with"); - break; - } - return llvm::ConstantExpr::getIntToPtr( - llvm::ConstantInt::get(this->mod->getContext(), - llvm::APInt(8 /*bits*/ * sizeof(uint8_t *), reinterpret_cast(ptr))), - ptrType); - } inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { - // if(level){ - return this->builder->CreateLoad(get_reg_ptr(i), false); - // } else { - // if(!this->loaded_regs[i]) - // this->loaded_regs[i]=this->builder->CreateLoad(get_reg_ptr(i), - // false); - // return this->loaded_regs[i]; - // } + return this->builder.CreateLoad(get_reg_ptr(i), false); } - inline void gen_set_pc(virt_addr_t pc) { - llvm::Value *pc_l = this->builder->CreateSExt(this->gen_const(traits::caddr_bit_width, (unsigned)pc), - this->get_type(traits::caddr_bit_width)); - super::gen_set_reg(traits::PC, pc_l); + inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { + llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), + this->get_type(traits::XLEN)); + this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } // some compile time constants @@ -223,6 +187,12 @@ private: {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld}, /* instruction SD */ {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd}, + /* instruction SLLI */ + {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli}, + /* instruction SRLI */ + {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli}, + /* instruction SRAI */ + {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai}, /* instruction ADDIW */ {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw}, /* instruction SLLIW */ @@ -289,12 +259,6 @@ private: {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori}, /* instruction ANDI */ {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, - /* instruction SLLI */ - {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli}, - /* instruction SRLI */ - {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli}, - /* instruction SRAI */ - {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai}, /* instruction ADD */ {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, /* instruction SUB */ @@ -406,13 +370,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(64U, fld_imm_val)); if(fld_rd_val != 0){ @@ -420,7 +384,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, false); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -445,13 +409,13 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(64U, fld_imm_val)); if(fld_rd_val != 0){ @@ -459,7 +423,7 @@ private: this->gen_read_mem(traits::MEM, offs_val, 64/8), 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -484,1370 +448,20 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* offs_val = this->builder->CreateAdd( + Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), 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, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction ADDIW - std::tuple __addiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDIW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("ADDIW x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - 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->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); - 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 SLLIW - std::tuple __slliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLIW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SLLIW x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* sh_val_val = this->builder->CreateShl( - 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, - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SRLIW - std::tuple __srliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLIW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SRLIW x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* sh_val_val = this->builder->CreateLShr( - 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, - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SRAIW - std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAIW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SRAIW x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* sh_val_val = this->builder->CreateAShr( - 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, - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction ADDW - std::tuple __addw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - 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){ - /* generate console output when executing the command */ - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("ADDW"), - }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); - } - pc=pc+4; - - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SUBW - std::tuple __subw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SUBW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - 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){ - /* generate console output when executing the command */ - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("SUBW"), - }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); - } - pc=pc+4; - - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SLLW - std::tuple __sllw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("SLLW x%1$d, x%2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - 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-> 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, - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SRLW - std::tuple __srlw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("SRLW x%1$d, x%2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - 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-> 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, - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SRAW - std::tuple __sraw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("SRAW x%1$d, x%2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - 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-> 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, - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction LUI - std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LUI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - int32_t fld_imm_val = 0 | (signed_bit_sub<12,20>(instr) << 12); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LUI x%1$d, 0x%2$05x"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_const(64U, fld_imm_val); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction AUIPC - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AUIPC"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - int32_t fld_imm_val = 0 | (signed_bit_sub<12,20>(instr) << 12); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AUIPC x%1%, 0x%2$08x"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction JAL - std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("JAL"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - int32_t fld_imm_val = 0 | (bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (signed_bit_sub<31,1>(instr) << 20); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("JAL x%1$d, 0x%2$x"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - Value* PC_val = this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 JALR - std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("JALR"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("JALR x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* new_pc_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - Value* align_val = this->builder->CreateAnd( - new_pc_val, - this->gen_const(64U, 2)); - llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( - ICmpInst::ICMP_NE, - align_val, - this->gen_const(64U, 0)), - bb_then, - bb_else); - this->builder->SetInsertPoint(bb_then); - { - this->gen_raise_trap(0, 0); - } - this->builder->CreateBr(bbnext); - this->builder->SetInsertPoint(bb_else); - { - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 1), - this->gen_const(64U, 4)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - Value* PC_val = this->builder->CreateAnd( - new_pc_val, - this->builder->CreateNot(this->gen_const(64U, 1))); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - } - this->builder->CreateBr(bbnext); - bb=bbnext; - this->builder->SetInsertPoint(bb); - 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 BEQ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BEQ"); - - this->gen_sync(iss::PRE_SYNC); - - int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("BEQ x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* PC_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_reg_load(fld_rs1_val, 0), - this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)), - 64); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 BNE - std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BNE"); - - this->gen_sync(iss::PRE_SYNC); - - int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("BNE x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* PC_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs1_val, 0), - this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)), - 64); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 BLT - std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BLT"); - - this->gen_sync(iss::PRE_SYNC); - - int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("BLT x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* PC_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 64, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, true)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)), - 64); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 BGE - std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BGE"); - - this->gen_sync(iss::PRE_SYNC); - - int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("BGE x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* PC_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_SGE, - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 64, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, true)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)), - 64); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 BLTU - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BLTU"); - - this->gen_sync(iss::PRE_SYNC); - - int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("BLTU x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* PC_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val, 0), - this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)), - 64); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 BGEU - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BGEU"); - - this->gen_sync(iss::PRE_SYNC); - - int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("BGEU x%1$d, x%2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; - std::vector 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+4; - - Value* PC_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_UGE, - this->gen_reg_load(fld_rs1_val, 0), - this->gen_reg_load(fld_rs2_val, 0)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, fld_imm_val)), - this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)), - 64); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - 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 LB - std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LB"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LB x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction LH - std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LH"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LH x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction LW - std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LW"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LW x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction LBU - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LBU"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LBU x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 64, - false); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction LHU - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LHU"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LHU x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 64, - false); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SB - std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SB"); - - this->gen_sync(iss::PRE_SYNC); - - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("SB x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - 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, - offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(8))); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SH - std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SH"); - - this->gen_sync(iss::PRE_SYNC); - - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("SH x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - 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, - offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(16))); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SW - std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SW"); - - this->gen_sync(iss::PRE_SYNC); - - 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){ - /* generate console output when executing the command */ - boost::format ins_fmter("SW x%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; - std::vector 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+4; - - Value* offs_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - 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, - offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction ADDI - std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("ADDI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SLTI - std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SLTI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 64, true), - this->gen_ext( - this->gen_const(64U, fld_imm_val), - 64, true)), - this->gen_const(64U, 1), - this->gen_const(64U, 0), - 64); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SLTIU - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTIU"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SLTIU x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - int64_t full_imm_val = fld_imm_val; - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 64, false), - this->gen_ext( - full_imm_val, - 64, false)), - this->gen_const(64U, 1), - this->gen_const(64U, 0), - 64); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction XORI - std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("XORI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("XORI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateXor( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction ORI - std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ORI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("ORI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateOr( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - 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 */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction ANDI - std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ANDI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("ANDI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAnd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_imm_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -1871,17 +485,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateShl( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + if(fld_shamt_val > 31){ + this->gen_raise_trap(0, 0); + } else { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateShl( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_shamt_val)); + 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 */ @@ -1906,17 +524,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateLShr( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + if(fld_shamt_val > 31){ + this->gen_raise_trap(0, 0); + } else { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateLShr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_shamt_val)); + 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 */ @@ -1941,17 +563,1371 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + if(fld_shamt_val > 31){ + this->gen_raise_trap(0, 0); + } else { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAShr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_shamt_val)); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction ADDIW + std::tuple __addiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("ADDIW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("ADDIW x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAShr( + 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); + 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 SLLIW + std::tuple __slliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SLLIW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SLLIW x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* sh_val_val = this->builder.CreateShl( + 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, + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SRLIW + std::tuple __srliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SRLIW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SRLIW x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* sh_val_val = this->builder.CreateLShr( + 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, + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SRAIW + std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SRAIW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SRAIW x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* sh_val_val = this->builder.CreateAShr( + 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, + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction ADDW + std::tuple __addw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("ADDW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + 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){ + /* generate console output when executing the command */ + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr("ADDW"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SUBW + std::tuple __subw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SUBW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + 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){ + /* generate console output when executing the command */ + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr("SUBW"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SLLW + std::tuple __sllw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SLLW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("SLLW x%1$d, x%2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + 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-> 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, + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SRLW + std::tuple __srlw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SRLW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("SRLW x%1$d, x%2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + 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-> 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, + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SRAW + std::tuple __sraw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SRAW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("SRAW x%1$d, x%2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + 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-> 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, + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction LUI + std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LUI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + int32_t fld_imm_val = 0 | (signed_bit_sub<12,20>(instr) << 12); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LUI x%1$d, 0x%2$05x"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_const(64U, fld_imm_val); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AUIPC + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + int32_t fld_imm_val = 0 | (signed_bit_sub<12,20>(instr) << 12); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AUIPC x%1%, 0x%2$08x"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction JAL + std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + int32_t fld_imm_val = 0 | (bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (signed_bit_sub<31,1>(instr) << 20); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("JAL x%1$d, 0x%2$x"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 JALR + std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("JALR"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("JALR x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* new_pc_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + Value* align_val = this->builder.CreateAnd( + new_pc_val, + this->gen_const(64U, 2)); + llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( + ICmpInst::ICMP_NE, + align_val, + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + this->gen_raise_trap(0, 0); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 1), + this->gen_const(64U, 4)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* PC_val = this->builder.CreateAnd( + new_pc_val, + this->builder.CreateNot(this->gen_const(64U, 1))); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + 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 BEQ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("BEQ"); + + this->gen_sync(iss::PRE_SYNC); + + int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("BEQ x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + this->gen_reg_load(fld_rs2_val, 0)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 BNE + std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("BNE"); + + this->gen_sync(iss::PRE_SYNC); + + int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("BNE x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 BLT + std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("BLT"); + + this->gen_sync(iss::PRE_SYNC); + + int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("BLT x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 BGE + std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("BGE"); + + this->gen_sync(iss::PRE_SYNC); + + int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("BGE x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SGE, + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 BLTU + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("BLTU"); + + this->gen_sync(iss::PRE_SYNC); + + int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("BLTU x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 BGEU + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("BGEU"); + + this->gen_sync(iss::PRE_SYNC); + + int16_t fld_imm_val = 0 | (bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (signed_bit_sub<31,1>(instr) << 12); + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("BGEU x%1$d, x%2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val; + std::vector 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+4; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGE, + this->gen_reg_load(fld_rs1_val, 0), + this->gen_reg_load(fld_rs2_val, 0)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + this->gen_reg_load(traits::PC, 0), + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + 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 LB + std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LB"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LB x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction LH + std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LH"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LH x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction LW + std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LW"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LW x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction LBU + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LBU"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LBU x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 64, + false); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction LHU + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LHU"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LHU x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 64, + false); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SB + std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SB"); + + this->gen_sync(iss::PRE_SYNC); + + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("SB x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + 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, + offs_val, + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(8))); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SH + std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SH"); + + this->gen_sync(iss::PRE_SYNC); + + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("SH x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + 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, + offs_val, + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(16))); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SW + std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SW"); + + this->gen_sync(iss::PRE_SYNC); + + 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){ + /* generate console output when executing the command */ + boost::format ins_fmter("SW x%1$d, %2%(x%3$d)"); + ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + std::vector 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+4; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + 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, + offs_val, + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction ADDI + std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("ADDI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("ADDI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SLTI + std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SLTI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SLTI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 64, true), + this->gen_ext( + this->gen_const(64U, fld_imm_val), + 64, true)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SLTIU + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SLTIU"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SLTIU x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + int64_t full_imm_val = fld_imm_val; + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 64, false), + this->gen_ext( + full_imm_val, + 64, false)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction XORI + std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("XORI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("XORI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateXor( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction ORI + std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("ORI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("ORI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateOr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + 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 */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction ANDI + std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("ANDI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + int16_t fld_imm_val = 0 | (signed_bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("ANDI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAnd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_imm_val)); + 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 */ @@ -1976,17 +1952,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( + Value* X_rd_val = this->builder.CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2011,17 +1987,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateSub( + Value* X_rd_val = this->builder.CreateSub( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2046,19 +2022,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateShl( + Value* X_rd_val = this->builder.CreateShl( this->gen_reg_load(fld_rs1_val, 0), - this->builder->CreateAnd( + this->builder.CreateAnd( this->gen_reg_load(fld_rs2_val, 0), 63)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2083,15 +2059,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -2102,7 +2078,7 @@ private: this->gen_const(64U, 1), this->gen_const(64U, 0), 64); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2127,15 +2103,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( this->gen_reg_load(fld_rs1_val, 0), @@ -2148,7 +2124,7 @@ private: this->gen_const(64U, 1), this->gen_const(64U, 0), 64); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2173,17 +2149,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateXor( + Value* X_rd_val = this->builder.CreateXor( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2208,19 +2184,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateLShr( + Value* X_rd_val = this->builder.CreateLShr( this->gen_reg_load(fld_rs1_val, 0), - this->builder->CreateAnd( + this->builder.CreateAnd( this->gen_reg_load(fld_rs2_val, 0), 63)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2245,19 +2221,19 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAShr( + Value* X_rd_val = this->builder.CreateAShr( this->gen_reg_load(fld_rs1_val, 0), - this->builder->CreateAnd( + this->builder.CreateAnd( this->gen_reg_load(fld_rs2_val, 0), 63)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2282,17 +2258,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateOr( + Value* X_rd_val = this->builder.CreateOr( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2317,17 +2293,17 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAnd( + Value* X_rd_val = this->builder.CreateAnd( this->gen_reg_load(fld_rs1_val, 0), this->gen_reg_load(fld_rs2_val, 0)); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2351,21 +2327,21 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("FENCE"), + this->builder.CreateGlobalStringPtr("FENCE"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; - Value* FENCE_fence_val = this->builder->CreateOr( - this->builder->CreateShl( + Value* FENCE_fence_val = this->builder.CreateOr( + this->builder.CreateShl( this->gen_const(64U, fld_pred_val), this->gen_const(64U, 4)), this->gen_const(64U, fld_succ_val)); this->gen_write_mem( traits::FENCE, (uint64_t)0, - this->builder->CreateZExtOrTrunc(FENCE_fence_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(FENCE_fence_val,this->get_type(64))); 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 */ @@ -2387,9 +2363,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("FENCE_I"), + this->builder.CreateGlobalStringPtr("FENCE_I"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2397,7 +2373,7 @@ private: this->gen_write_mem( traits::FENCE, (uint64_t)1, - this->builder->CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); @@ -2416,9 +2392,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("ECALL"), + this->builder.CreateGlobalStringPtr("ECALL"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2440,9 +2416,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("EBREAK"), + this->builder.CreateGlobalStringPtr("EBREAK"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2464,9 +2440,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("URET"), + this->builder.CreateGlobalStringPtr("URET"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2488,9 +2464,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("SRET"), + this->builder.CreateGlobalStringPtr("SRET"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2512,9 +2488,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("MRET"), + this->builder.CreateGlobalStringPtr("MRET"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2536,9 +2512,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("WFI"), + this->builder.CreateGlobalStringPtr("WFI"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2563,9 +2539,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr("SFENCE.VMA"), + this->builder.CreateGlobalStringPtr("SFENCE.VMA"), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2573,12 +2549,12 @@ private: this->gen_write_mem( traits::FENCE, (uint64_t)2, - this->builder->CreateZExtOrTrunc(FENCE_fencevmal_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(FENCE_fencevmal_val,this->get_type(64))); Value* FENCE_fencevmau_val = this->gen_const(64U, fld_rs2_val); this->gen_write_mem( traits::FENCE, (uint64_t)3, - this->builder->CreateZExtOrTrunc(FENCE_fencevmau_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(FENCE_fencevmau_val,this->get_type(64))); 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 */ @@ -2602,9 +2578,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2615,15 +2591,15 @@ private: this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); Value* X_rd_val = csr_val_val; - 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); } else { Value* CSR_csr_val = rs_val_val; this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2648,9 +2624,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2658,16 +2634,16 @@ private: Value* xrs1_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = xrd_val; - 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); } if(fld_rs1_val != 0){ - Value* CSR_csr_val = this->builder->CreateOr( + Value* CSR_csr_val = this->builder.CreateOr( xrd_val, xrs1_val); this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2692,9 +2668,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2702,16 +2678,16 @@ private: Value* xrs1_val = this->gen_reg_load(fld_rs1_val, 0); if(fld_rd_val != 0){ Value* X_rd_val = xrd_val; - 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); } if(fld_rs1_val != 0){ - Value* CSR_csr_val = this->builder->CreateAnd( + Value* CSR_csr_val = this->builder.CreateAnd( xrd_val, - this->builder->CreateNot(xrs1_val)); + this->builder.CreateNot(xrs1_val)); this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2736,15 +2712,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; if(fld_rd_val != 0){ Value* X_rd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); - 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); } Value* CSR_csr_val = this->gen_ext( this->gen_const(64U, fld_zimm_val), @@ -2753,7 +2729,7 @@ private: this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); 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 */ @@ -2777,15 +2753,15 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* res_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); if(fld_zimm_val != 0){ - Value* CSR_csr_val = this->builder->CreateOr( + Value* CSR_csr_val = this->builder.CreateOr( res_val, this->gen_ext( this->gen_const(64U, fld_zimm_val), @@ -2794,11 +2770,11 @@ private: this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); } if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2823,28 +2799,28 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; Value* res_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } if(fld_zimm_val != 0){ - Value* CSR_csr_val = this->builder->CreateAnd( + Value* CSR_csr_val = this->builder.CreateAnd( res_val, - this->builder->CreateNot(this->gen_ext( + this->builder.CreateNot(this->gen_ext( this->gen_const(64U, fld_zimm_val), 64, false))); this->gen_write_mem( traits::CSR, fld_csr_val, - this->builder->CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(CSR_csr_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2870,9 +2846,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2882,15 +2858,15 @@ private: this->gen_read_mem(traits::MEM, offs_val, 64/8), 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); Value* RES_offs_val = this->gen_ext( - this->builder->CreateNeg(this->gen_const(8U, 1)), + this->builder.CreateNeg(this->gen_const(8U, 1)), 64, true); this->gen_write_mem( traits::RES, offs_val, - this->builder->CreateZExtOrTrunc(RES_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(RES_offs_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -2917,9 +2893,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2928,35 +2904,35 @@ private: llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, res_val, this->gen_const(64U, 0)), bb_then, bb_else); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 1); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64)));if(fld_rd_val != 0){ + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64)));if(fld_rd_val != 0){ Value* X_rd_val = this->gen_const(64U, 0); - 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->builder->CreateBr(bbnext); - this->builder->SetInsertPoint(bb_else); + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); { if(fld_rd_val != 0){ Value* X_rd_val = this->gen_const(64U, 1); - 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->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); 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 */ @@ -2982,9 +2958,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -2994,13 +2970,13 @@ private: this->gen_read_mem(traits::MEM, offs_val, 64/8), 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); } Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3026,9 +3002,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3039,16 +3015,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } - Value* res2_val = this->builder->CreateAdd( + Value* res2_val = this->builder.CreateAdd( res_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3074,9 +3050,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3087,16 +3063,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } - Value* res2_val = this->builder->CreateXor( + Value* res2_val = this->builder.CreateXor( res_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3122,9 +3098,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3135,16 +3111,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } - Value* res2_val = this->builder->CreateAnd( + Value* res2_val = this->builder.CreateAnd( res_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3170,9 +3146,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3183,16 +3159,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } - Value* res2_val = this->builder->CreateOr( + Value* res2_val = this->builder.CreateOr( res_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3218,9 +3194,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3231,10 +3207,10 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SGT, this->gen_ext( res_val, @@ -3249,7 +3225,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3275,9 +3251,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3288,10 +3264,10 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( res_val, @@ -3306,7 +3282,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3332,9 +3308,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3345,10 +3321,10 @@ private: false); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_UGT, res_val, this->gen_reg_load(fld_rs2_val, 0)), @@ -3359,7 +3335,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3385,9 +3361,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3398,10 +3374,10 @@ private: false); if(fld_rd_val != 0){ Value* X_rd_val = res_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, res_val, this->gen_reg_load(fld_rs2_val, 0)), @@ -3412,7 +3388,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(64))); 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 */ @@ -3437,9 +3413,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3449,15 +3425,15 @@ private: this->gen_read_mem(traits::MEM, offs_val, 32/8), 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); Value* RES_offs_val = this->gen_ext( - this->builder->CreateNeg(this->gen_const(8U, 1)), + this->builder.CreateNeg(this->gen_const(8U, 1)), 32, true); this->gen_write_mem( traits::RES, offs_val, - this->builder->CreateZExtOrTrunc(RES_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(RES_offs_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -3484,9 +3460,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3494,34 +3470,34 @@ private: Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - // this->builder->SetInsertPoint(bb); - this->gen_cond_branch(this->builder->CreateICmp( + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, res1_val, this->gen_const(32U, 0)), bb_then, bbnext); - this->builder->SetInsertPoint(bb_then); + this->builder.SetInsertPoint(bb_then); { Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 1); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); } - this->builder->CreateBr(bbnext); + this->builder.CreateBr(bbnext); bb=bbnext; - this->builder->SetInsertPoint(bb); + this->builder.SetInsertPoint(bb); if(fld_rd_val != 0){ Value* X_rd_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_NE, res1_val, this->gen_const(64U, 0)), this->gen_const(64U, 0), this->gen_const(64U, 1), 64); - 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::NEXT_PC); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ @@ -3548,9 +3524,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3560,13 +3536,13 @@ private: this->gen_read_mem(traits::MEM, offs_val, 32/8), 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); } Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3592,9 +3568,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3605,16 +3581,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateAdd( + Value* res2_val = this->builder.CreateAdd( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3640,9 +3616,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3653,16 +3629,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateXor( + Value* res2_val = this->builder.CreateXor( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3688,9 +3664,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3701,16 +3677,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateAnd( + Value* res2_val = this->builder.CreateAnd( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3736,9 +3712,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3749,16 +3725,16 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } - Value* res2_val = this->builder->CreateOr( + Value* res2_val = this->builder.CreateOr( res1_val, this->gen_reg_load(fld_rs2_val, 0)); Value* MEM_offs_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3784,9 +3760,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3797,10 +3773,10 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SGT, this->gen_ext( res1_val, @@ -3815,7 +3791,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3841,9 +3817,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3854,10 +3830,10 @@ private: true); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( res1_val, @@ -3872,7 +3848,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3898,9 +3874,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3911,10 +3887,10 @@ private: false); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_UGT, res1_val, this->gen_reg_load(fld_rs2_val, 0)), @@ -3925,7 +3901,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3951,9 +3927,9 @@ private: std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(ins_fmter.str()), }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } pc=pc+4; @@ -3964,10 +3940,10 @@ private: false); if(fld_rd_val != 0){ Value* X_rd_val = res1_val; - 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); } Value* res2_val = this->gen_choose( - this->builder->CreateICmp( + this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( res1_val, @@ -3982,7 +3958,7 @@ private: this->gen_write_mem( traits::MEM, offs_val, - this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->builder.CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); 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 */ @@ -3996,24 +3972,16 @@ private: ****************************************************************************/ std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, llvm::BasicBlock *bb) { - bb->setName("illegal_instruction"); - this->gen_sync(iss::PRE_SYNC); - if(this->disass_enabled){ - /* generate console output when executing the command */ - /* generate console output when executing the command */ - boost::format ins_fmter("DB 0x%1$x"); - ins_fmter % (uint64_t)instr; - std::vector 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); - } + this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), true), + get_reg_ptr(traits::PC), true); + this->builder.CreateStore( + this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits::ICOUNT), true), + this->gen_const(64U, 1)), + get_reg_ptr(traits::ICOUNT), true); + if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); pc = pc + ((instr & 3) == 3 ? 4 : 2); - - this->gen_raise_trap(0, 2); + this->gen_raise_trap(0, 2); // illegal instruction trap 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); @@ -4028,8 +3996,8 @@ template void debug_fn(CODE_WORD insn) { template vm_impl::vm_impl() { this(new ARCH()); } template -vm_impl::vm_impl(ARCH &core, bool dump) -: vm::vm_base(core, dump) { +vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) +: vm::vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -4038,7 +4006,6 @@ vm_impl::vm_impl(ARCH &core, bool dump) auto quantrant = instr.value & 0x3; expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op); } - this->sync_exec = static_cast(this->sync_exec | core.needed_sync()); } template @@ -4046,7 +4013,7 @@ std::tuple vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, llvm::BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 code_word_t insn = 0; - iss::addr_t paddr; + iss::addr_t paddr(pc); const typename traits::addr_t upper_bits = ~traits::PGMASK; try { uint8_t *const data = (uint8_t *)&insn; @@ -4077,44 +4044,44 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, } template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { - this->builder->SetInsertPoint(leave_blk); - this->builder->CreateRet(this->builder->CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); + this->builder.SetInsertPoint(leave_blk); + this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); - this->builder->CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); } template void vm_impl::gen_leave_trap(unsigned lvl) { std::vector args{ this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), }; - this->builder->CreateCall(this->mod->getFunction("leave_trap"), args); + this->builder.CreateCall(this->mod->getFunction("leave_trap"), args); auto *PC_val = this->gen_read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN / 8); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); } template void vm_impl::gen_wait(unsigned type) { std::vector args{ this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), }; - this->builder->CreateCall(this->mod->getFunction("wait"), args); + this->builder.CreateCall(this->mod->getFunction("wait"), args); } template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { - this->builder->SetInsertPoint(trap_blk); - auto *trap_state_val = this->builder->CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); + this->builder.SetInsertPoint(trap_blk); + auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); std::vector args{this->core_ptr, this->adj_to64(trap_state_val), - this->adj_to64(this->builder->CreateLoad(get_reg_ptr(traits::PC), false))}; - this->builder->CreateCall(this->mod->getFunction("enter_trap"), args); - auto *trap_addr_val = this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), false); - this->builder->CreateRet(trap_addr_val); + this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; + this->builder.CreateCall(this->mod->getFunction("enter_trap"), args); + auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateRet(trap_addr_val); } template inline void vm_impl::gen_trap_check(llvm::BasicBlock *bb) { - auto *v = this->builder->CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); - this->gen_cond_branch(this->builder->CreateICmp( + auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits::TRAP_STATE), true); + this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, v, llvm::ConstantInt::get(getContext(), llvm::APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); diff --git a/riscv/src/iss/rv32imac.cpp b/riscv/src/iss/rv32imac.cpp index 7cb43af..aa6330b 100644 --- a/riscv/src/iss/rv32imac.cpp +++ b/riscv/src/iss/rv32imac.cpp @@ -67,6 +67,6 @@ void rv32imac::reset(uint64_t address) { uint8_t *rv32imac::get_regs_base_ptr() { return reinterpret_cast(®); } -rv32imac::phys_addr_t rv32imac::v2p(const iss::addr_t &pc) { +rv32imac::phys_addr_t rv32imac::virt2phys(const iss::addr_t &pc) { return phys_addr_t(pc); // change logical address to physical address } diff --git a/riscv/src/iss/rv64ia.cpp b/riscv/src/iss/rv64ia.cpp index 7542a04..b6534e4 100644 --- a/riscv/src/iss/rv64ia.cpp +++ b/riscv/src/iss/rv64ia.cpp @@ -67,6 +67,6 @@ void rv64ia::reset(uint64_t address) { uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast(®); } -rv64ia::phys_addr_t rv64ia::v2p(const iss::addr_t &pc) { +rv64ia::phys_addr_t rv64ia::virt2phys(const iss::addr_t &pc) { return phys_addr_t(pc); // change logical address to physical address } diff --git a/riscv/src/main.cpp b/riscv/src/main.cpp index 05331da..4affd45 100644 --- a/riscv/src/main.cpp +++ b/riscv/src/main.cpp @@ -54,7 +54,7 @@ int main(int argc, char *argv[]) { // clang-format off desc.add_options() ("help,h", "Print help message") - ("loglevel,l", po::value()->implicit_value(2), "Sets logging verbosity") + ("verbose,v", po::value()->implicit_value(0), "Sets logging verbosity") ("logfile,f", po::value(), "Sets default log file.") ("disass,d", po::value()->implicit_value(""), "Enables disassembly") ("elf", po::value>(), "ELF file(s) to load") @@ -62,10 +62,8 @@ int main(int argc, char *argv[]) { ("input,i", po::value(), "the elf file to load (instead of hex files)") ("dump-ir", "dump the intermediate representation") ("cycles,c", po::value()->default_value(-1), "number of cycles to run") - ("systemc,s", "Run as SystemC simulation") ("time", po::value(), "SystemC simulation time in ms") ("reset,r", po::value(), "reset address") - ("trace", po::value(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") ("mem,m", po::value(), "the memory input file") ("isa", po::value()->default_value("rv32imac"), "isa to use for simulation"); // clang-format on @@ -86,8 +84,8 @@ int main(int argc, char *argv[]) { } std::vector args = collect_unrecognized(parsed.options, po::include_positional); - if (clim.count("loglevel")) { - auto l = logging::as_log_level(clim["loglevel"].as()); + if (clim.count("verbose")) { + auto l = logging::as_log_level(clim["verbose"].as()); LOGGER(DEFAULT)::reporting_level() = l; LOGGER(connection)::reporting_level() = l; } @@ -104,18 +102,20 @@ int main(int argc, char *argv[]) { bool dump = clim.count("dump-ir"); // instantiate the simulator std::unique_ptr vm{nullptr}; - if (clim["isa"].as().substr(0, 4)=="rv64") { + std::string isa_opt(clim["isa"].as()); + if (isa_opt.substr(0, 4)=="rv64") { iss::arch::rv64ia* cpu = new iss::arch::riscv_hart_msu_vp(); - vm = iss::create(cpu, clim["gdb-port"].as(), dump); - } else if (clim["isa"].as().substr(0, 4)=="rv32") { + vm = iss::create(cpu, clim["gdb-port"].as()); + } else if (isa_opt.substr(0, 4)=="rv32") { iss::arch::rv32imac* cpu = new iss::arch::riscv_hart_msu_vp(); - vm = iss::create(cpu, clim["gdb-port"].as(), dump); + vm = iss::create(cpu, clim["gdb-port"].as()); } else { LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as() << std::endl; return 127; } if (clim.count("elf")) - for (std::string input : clim["elf"].as>()) vm->get_arch()->load_file(input); + for (std::string input : clim["elf"].as>()) + vm->get_arch()->load_file(input); if (clim.count("mem")) vm->get_arch()->load_file(clim["mem"].as(), iss::arch::traits::MEM); for (std::string input : args) vm->get_arch()->load_file(input);// treat remaining arguments as elf files @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) { } int64_t cycles = -1; cycles = clim["cycles"].as(); - return vm->start(cycles); + return vm->start(cycles, dump); } catch (std::exception &e) { LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" << std::endl; diff --git a/sc-components b/sc-components index 02cb175..0122e4d 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit 02cb1756166adb7074f6e5dfa106ca5ab04176c6 +Subproject commit 0122e4d3123eff995aa90a08b8fda3e5b94827d9 diff --git a/simple-system.json b/simple-system.json index a2bd7ac..01855f0 100644 --- a/simple-system.json +++ b/simple-system.json @@ -1,13 +1,13 @@ { "i_simple_system":{ "i_uart0":{ - "write_to_ws": false + "write_to_ws": true }, "i_uart1":{ "write_to_ws": false }, "i_gpio0":{ - "write_to_ws": false + "write_to_ws": true } } }