diff --git a/riscv/gen_input/.gitignore b/riscv/gen_input/.gitignore new file mode 100644 index 0000000..b34c537 --- /dev/null +++ b/riscv/gen_input/.gitignore @@ -0,0 +1 @@ +/src-gen/ diff --git a/riscv/gen_input/RV32C.core_desc b/riscv/gen_input/RV32C.core_desc index 77ca0af..59bc051 100644 --- a/riscv/gen_input/RV32C.core_desc +++ b/riscv/gen_input/RV32C.core_desc @@ -130,13 +130,13 @@ InsructionSet RV32CI { args_disass: "0x%imm$05x"; PC<=PC+imm; } - C.BEQZ(no_cont) {//(RV32) + C.BEQZ(no_cont,cond) {//(RV32) encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01; args_disass: "x(8+%rs1$d), 0x%imm$05x"; val rs1_idx[5] <= rs1+8; PC<=choose(X[rs1_idx]==0, PC+imm, PC+2); } - C.BNEZ(no_cont) {//(RV32) + C.BNEZ(no_cont,cond) {//(RV32) encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01; args_disass: "x(8+%rs1$d), 0x%imm$05x"; val rs1_idx[5] <= rs1+8; diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32IBase.core_desc index 8943009..bbf4a79 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32IBase.core_desc @@ -47,32 +47,32 @@ InsructionSet RV32IBase { PC<=new_pc & ~0x1; } } - BEQ(no_cont){ + BEQ(no_cont,cond){ encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:1]s | imm[11:11]s | b1100011; args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; PC<=choose(X[rs1]==X[rs2], PC+imm, PC+4); } - BNE(no_cont){ + BNE(no_cont,cond){ encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:1]s | imm[11:11]s | b1100011; args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; PC<=choose(X[rs1]!=X[rs2], PC+imm, PC+4); } - BLT(no_cont){ + BLT(no_cont,cond){ encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b100 | imm[4:1]s | imm[11:11]s | b1100011; args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; PC<=choose(X[rs1]s=X[rs2]s, PC+imm, PC+4); } - BLTU(no_cont) { + BLTU(no_cont,cond) { encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b110 | imm[4:1]s | imm[11:11]s | b1100011; args_disass:"x%rs1$d, x%rs2$d, 0x%imm$x"; PC<=choose(X[rs1]=X[rs2], PC+imm, PC+4); diff --git a/riscv/gen_input/templates/CORENAME_cyles.txt.gtl b/riscv/gen_input/templates/CORENAME_cyles.txt.gtl new file mode 100644 index 0000000..4f5eac7 --- /dev/null +++ b/riscv/gen_input/templates/CORENAME_cyles.txt.gtl @@ -0,0 +1,8 @@ +{ + '${coreDef.name}' : [<%instructions.each{instr -> %> + { + 'name' : '${instr.name}', + 'delay' : ${generator.hasAttribute(instr.instruction, com.minres.coredsl.coreDsl.InstrAttribute.COND)?[1,1]:1 + },<%}%> + ] +} \ No newline at end of file diff --git a/riscv/gen_input/templates/incl-CORENAME.h.gtl b/riscv/gen_input/templates/incl-CORENAME.h.gtl new file mode 100644 index 0000000..9af6850 --- /dev/null +++ b/riscv/gen_input/templates/incl-CORENAME.h.gtl @@ -0,0 +1,164 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//////////////////////////////////////////////////////////////////////////////// +<% +import com.minres.coredsl.coreDsl.Register +import com.minres.coredsl.coreDsl.RegisterFile +def getTypeSize(size){ + if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8 +} +%> +#ifndef _${coreDef.name.toUpperCase()}_H_ +#define _${coreDef.name.toUpperCase()}_H_ + +#include +#include +#include +#include + +namespace iss { +namespace arch { + +struct ${coreDef.name.toLowerCase()}; + +template<> +struct traits<${coreDef.name.toLowerCase()}> { + + enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}}; + + enum reg_e {<% + allRegs.each { reg -> + if( reg instanceof RegisterFile) { + (reg.range.right..reg.range.left).each{%> + ${reg.name}${it},<% + } + } else if(reg instanceof Register){ %> + ${reg.name},<% + } + }%> + NUM_REGS, + NEXT_${pc.name}=NUM_REGS, + TRAP_STATE, + PENDING_TRAP, + MACHINE_STATE, + ICOUNT + }; + + using reg_t = uint${regDataWidth}_t; + + using addr_t = uint${addrDataWidth}_t; + + using code_word_t = uint${addrDataWidth}_t; //TODO: check removal + + using virt_addr_t = iss::typed_addr_t; + + using phys_addr_t = iss::typed_addr_t; + + constexpr static unsigned reg_bit_width(unsigned r) { + constexpr std::array ${coreDef.name}_reg_size{{${regSizes.join(",")}}}; + return ${coreDef.name}_reg_size[r]; + } + + constexpr static unsigned reg_byte_offset(unsigned r) { + constexpr std::array ${coreDef.name}_reg_byte_offset{{${regOffsets.join(",")}}}; + return ${coreDef.name}_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 {${allSpaces.collect{s -> s.name}.join(', ')}}; + +}; + +struct ${coreDef.name.toLowerCase()}: public arch_if { + + using virt_addr_t = typename traits<${coreDef.name.toLowerCase()}>::virt_addr_t; + using phys_addr_t = typename traits<${coreDef.name.toLowerCase()}>::phys_addr_t; + using reg_t = typename traits<${coreDef.name.toLowerCase()}>::reg_t; + using addr_t = typename traits<${coreDef.name.toLowerCase()}>::addr_t; + + ${coreDef.name.toLowerCase()}(); + ~${coreDef.name.toLowerCase()}(); + + void reset(uint64_t address=0) override; + + uint8_t* get_regs_base_ptr() override; + /// deprecated + void get_reg(short idx, std::vector& value) override {} + void set_reg(short idx, const std::vector& value) override {} + /// deprecated + bool get_flag(int flag) override {return false;} + void set_flag(int, bool value) override {}; + /// deprecated + void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; + + uint64_t get_icount() { return reg.icount;} + + inline phys_addr_t v2p(const iss::addr_t& addr){ + if(addr.space != traits<${coreDef.name.toLowerCase()}>::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<${coreDef.name.toLowerCase()}>::addr_mask); + } else + return virt2phys(addr); + } + + virtual phys_addr_t virt2phys(const iss::addr_t& addr); + + virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } + +protected: + struct ${coreDef.name}_regs {<% + allRegs.each { reg -> + if( reg instanceof RegisterFile) { + (reg.range.right..reg.range.left).each{%> + uint${generator.getSize(reg)}_t ${reg.name}${it} = 0;<% + } + } else if(reg instanceof Register){ %> + uint${generator.getSize(reg)}_t ${reg.name} = 0;<% + } + }%> + uint${generator.getSize(pc)}_t NEXT_${pc.name} = 0; + uint32_t trap_state = 0, pending_trap = 0, machine_state = 0; + uint64_t icount = 0; + } reg; + + std::array addr_mode; + + uint64_t cycles = 0; + +}; + +} +} +#endif /* _${coreDef.name.toUpperCase()}_H_ */ diff --git a/riscv/gen_input/templates/src-CORENAME.cpp.gtl b/riscv/gen_input/templates/src-CORENAME.cpp.gtl new file mode 100644 index 0000000..836bab0 --- /dev/null +++ b/riscv/gen_input/templates/src-CORENAME.cpp.gtl @@ -0,0 +1,73 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//////////////////////////////////////////////////////////////////////////////// + +#include "util/ities.h" +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +#include +#ifdef __cplusplus +} +#endif +#include +#include +#include + +using namespace iss::arch; + +${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { + reg.icount=0; +} + +${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}(){ +} + +void ${coreDef.name.toLowerCase()}::reset(uint64_t address) { + for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0)); + reg.PC=address; + reg.NEXT_PC=reg.PC; + reg.trap_state=0; + reg.machine_state=0x0; +} + +uint8_t* ${coreDef.name.toLowerCase()}::get_regs_base_ptr(){ + return reinterpret_cast(®); +} + +${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::v2p(const iss::addr_t& pc) { + return phys_addr_t(pc); //change logical address to physical address +} diff --git a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl new file mode 100644 index 0000000..b4f91f7 --- /dev/null +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -0,0 +1,323 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Contributors: +// eyck@minres.com - initial API and implementation +// +// +//////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace iss { +namespace ${coreDef.name.toLowerCase()} { +using namespace iss::arch; +using namespace llvm; +using namespace iss::debugger; + +template class vm_impl : public vm::vm_base { +public: + using super = typename vm::vm_base; + using virt_addr_t = typename super::virt_addr_t; + using phys_addr_t = typename super::phys_addr_t; + using code_word_t = typename super::code_word_t; + using addr_t = typename super::addr_t; + + vm_impl(); + + vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0); + + void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } + + target_adapter_if *accquire_target_adapter(server_if *srv) { + debugger_if::dbg_enabled = true; + if (vm::vm_base::tgt_adapter == nullptr) + vm::vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); + return vm::vm_base::tgt_adapter; + } + +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 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 &, + llvm::BasicBlock *) override; + + void gen_leave_behavior(llvm::BasicBlock *leave_blk) override; + + void gen_raise_trap(uint16_t trap_id, uint16_t cause); + + void gen_leave_trap(unsigned lvl); + + void gen_wait(unsigned type); + + void gen_trap_behavior(llvm::BasicBlock *) override; + + void gen_trap_check(llvm::BasicBlock *bb); + + + inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { + 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), + this->get_type(traits::XLEN)); + this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); + } + + // some compile time constants + // enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 }; + enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 }; + enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 }; + enum { LUT_SIZE = 1 << util::bit_count(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) }; + + using this_class = vm_impl; + using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, + code_word_t instr, + llvm::BasicBlock *bb); + std::array lut; + + std::array lut_00, lut_01, lut_10; + std::array lut_11; + + std::array qlut; + + std::array lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; + + void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[], + compile_func f) { + if (pos < 0) { + lut[idx] = f; + } else { + auto bitmask = 1UL << pos; + if ((mask & bitmask) == 0) { + expand_bit_mask(pos - 1, mask, value, valid, idx, lut, f); + } else { + if ((valid & bitmask) == 0) { + expand_bit_mask(pos - 1, mask, value, valid, (idx << 1), lut, f); + expand_bit_mask(pos - 1, mask, value, valid, (idx << 1) + 1, lut, f); + } else { + auto new_val = idx << 1; + if ((value & bitmask) != 0) new_val++; + expand_bit_mask(pos - 1, mask, value, valid, new_val, lut, f); + } + } + } + } + + inline uint32_t extract_fields(uint32_t val) { return extract_fields(29, val >> 2, lutmasks[val & 0x3], 0); } + + uint32_t extract_fields(int pos, uint32_t val, uint32_t mask, uint32_t lut_val) { + if (pos >= 0) { + auto bitmask = 1UL << pos; + if ((mask & bitmask) == 0) { + lut_val = extract_fields(pos - 1, val, mask, lut_val); + } else { + auto new_val = lut_val << 1; + if ((val & bitmask) != 0) new_val++; + lut_val = extract_fields(pos - 1, val, mask, new_val); + } + } + return lut_val; + } + +private: + /**************************************************************************** + * start opcode definitions + ****************************************************************************/ + struct InstructionDesriptor { + size_t length; + uint32_t value; + uint32_t mask; + compile_func op; + }; + + const std::array instr_descr = {{ + /* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %> + /* instruction ${instr.instruction.name} */ + {${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%> + }}; + + /* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %> + /* instruction ${idx}: ${instr.name} */ + std::tuple __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){<%instr.code.eachLine{%> + ${it}<%}%> + } + <%}%> + /**************************************************************************** + * end opcode definitions + ****************************************************************************/ + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, + llvm::BasicBlock *bb) { + this->gen_sync(iss::PRE_SYNC, instr_descr.size()); + 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); + pc = pc + ((instr & 3) == 3 ? 4 : 2); + this->gen_raise_trap(0, 2); // illegal instruction trap + this->gen_sync(iss::POST_SYNC, instr_descr.size()); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); + } +}; + +template void debug_fn(CODE_WORD insn) { + volatile CODE_WORD x = insn; + insn = 2 * x; +} + +template vm_impl::vm_impl() { this(new ARCH()); } + +template +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(); + qlut[3] = lut_11.data(); + for (auto instr : instr_descr) { + auto quantrant = instr.value & 0x3; + expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op); + } +} + +template +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; + 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); + if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary + auto res = this->core.read(paddr, 2, data); + if (res != iss::Ok) throw trap_access(1, pc.val); + if ((insn & 0x3) == 0x3) { // this is a 32bit instruction + res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); + } + } else { + auto res = this->core.read(paddr, 4, data); + if (res != iss::Ok) throw trap_access(1, pc.val); + } + } catch (trap_access &ta) { + throw trap_access(ta.id, pc.val); + } + if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' + // curr pc on stack + typename vm_impl::processing_pc_entry addr(*this, pc, paddr); + ++inst_cnt; + auto lut_val = extract_fields(insn); + auto f = qlut[insn & 0x3][lut_val]; + if (f == nullptr) { + f = &this_class::illegal_intruction; + } + return (this->*f)(pc, insn, this_block); +} + +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)); +} + +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); +} + +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); + 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); +} + +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); +} + +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); + 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); +} + +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( + ICmpInst::ICMP_EQ, v, + llvm::ConstantInt::get(getContext(), llvm::APInt(v->getType()->getIntegerBitWidth(), 0))), + bb, this->trap_blk, 1); +} + +} // namespace ${coreDef.name.toLowerCase()} + +template <> +std::unique_ptr create(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) { + std::unique_ptr<${coreDef.name.toLowerCase()}::vm_impl> ret = + std::make_unique<${coreDef.name.toLowerCase()}::vm_impl>(*core, dump); + if (port != 0) debugger::server::run_server(ret.get(), port); + return ret; +} + +} // namespace iss diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index 8d55e4d..0814d96 100644 --- a/riscv/incl/iss/arch/rv32imac.h +++ b/riscv/incl/iss/arch/rv32imac.h @@ -28,9 +28,6 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Tue Feb 06 17:18:49 UTC 2018 -// * rv32imac.h Author: -// //////////////////////////////////////////////////////////////////////////////// #ifndef _RV32IMAC_H_ @@ -49,7 +46,7 @@ struct rv32imac; template<> struct traits { - enum constants {XLEN=32,XLEN2=64,XLEN_BIT_MASK=31,PCLEN=32,fence=0,fencei=1,fencevmal=2,fencevmau=3,MISA_VAL=1075056897,PGSIZE=4096,PGMASK=4095}; + enum constants {XLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095}; enum reg_e { X0, @@ -117,7 +114,7 @@ struct traits { enum sreg_flag_e {FLAGS}; - enum mem_type_e {MEM,CSR,FENCE,RES}; + enum mem_type_e {MEM, CSR, FENCE, RES}; }; diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h index fdb77b5..3566e49 100644 --- a/riscv/incl/iss/arch/rv64ia.h +++ b/riscv/incl/iss/arch/rv64ia.h @@ -28,9 +28,6 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Tue Feb 06 17:18:50 UTC 2018 -// * rv64ia.h Author: -// //////////////////////////////////////////////////////////////////////////////// #ifndef _RV64IA_H_ @@ -49,7 +46,7 @@ struct rv64ia; template<> struct traits { - enum constants {XLEN=64,XLEN2=128,XLEN_BIT_MASK=63,PCLEN=64,fence=0,fencei=1,fencevmal=2,fencevmau=3,MISA_VAL=2147746049,PGSIZE=4096,PGMASK=4095}; + enum constants {XLEN=64, XLEN2=128, XLEN_BIT_MASK=63, PCLEN=64, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=2147746049, PGSIZE=4096, PGMASK=4095}; enum reg_e { X0, @@ -117,7 +114,7 @@ struct traits { enum sreg_flag_e {FLAGS}; - enum mem_type_e {MEM,CSR,FENCE,RES}; + enum mem_type_e {MEM, CSR, FENCE, RES}; }; diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index 4e9de68..850e394 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -179,9 +179,8 @@ private: compile_func op; }; - /* start generated code */ const std::array instr_descr = {{ - /* entries are: valid value, valid mask, function ptr */ + /* entries are: size, valid value, valid mask, function ptr */ /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ @@ -381,4076 +380,4077 @@ private: /* instruction DII */ {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, }}; - //0: instruction LUI + + /* instruction definitions */ + /* instruction 0: LUI */ std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LUI"); - - this->gen_sync(iss::PRE_SYNC, 0); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 0); - 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); + bb->setName("LUI"); + + this->gen_sync(iss::PRE_SYNC, 0); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 0); + 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); } - //1: instruction AUIPC + /* instruction 1: AUIPC */ std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AUIPC"); - - this->gen_sync(iss::PRE_SYNC, 1); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 1); - 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); + bb->setName("AUIPC"); + + this->gen_sync(iss::PRE_SYNC, 1); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 1); + 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); } - //2: instruction JAL + /* instruction 2: JAL */ std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("JAL"); - - this->gen_sync(iss::PRE_SYNC, 2); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - Value* PC_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 2); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("JAL"); + + this->gen_sync(iss::PRE_SYNC, 2); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* PC_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 2); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //3: instruction JALR + /* instruction 3: JALR */ std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("JALR"); - - this->gen_sync(iss::PRE_SYNC, 3); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - 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( - ret_val, - 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, 3); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("JALR"); + + this->gen_sync(iss::PRE_SYNC, 3); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + 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( + ret_val, + 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, 3); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //4: instruction BEQ + /* instruction 4: BEQ */ std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BEQ"); - - this->gen_sync(iss::PRE_SYNC, 4); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 4); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BEQ"); + + this->gen_sync(iss::PRE_SYNC, 4); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 4); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //5: instruction BNE + /* instruction 5: BNE */ std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BNE"); - - this->gen_sync(iss::PRE_SYNC, 5); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 5); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BNE"); + + this->gen_sync(iss::PRE_SYNC, 5); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 5); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //6: instruction BLT + /* instruction 6: BLT */ std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BLT"); - - this->gen_sync(iss::PRE_SYNC, 6); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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), - 32, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, true)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 6); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BLT"); + + this->gen_sync(iss::PRE_SYNC, 6); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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), + 32, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, true)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 6); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //7: instruction BGE + /* instruction 7: BGE */ std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BGE"); - - this->gen_sync(iss::PRE_SYNC, 7); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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), - 32, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, true)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 7); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BGE"); + + this->gen_sync(iss::PRE_SYNC, 7); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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), + 32, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, true)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 7); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //8: instruction BLTU + /* instruction 8: BLTU */ std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BLTU"); - - this->gen_sync(iss::PRE_SYNC, 8); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 8); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BLTU"); + + this->gen_sync(iss::PRE_SYNC, 8); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 8); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //9: instruction BGEU + /* instruction 9: BGEU */ std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BGEU"); - - this->gen_sync(iss::PRE_SYNC, 9); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 9); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BGEU"); + + this->gen_sync(iss::PRE_SYNC, 9); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 9); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //10: instruction LB + /* instruction 10: LB */ std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LB"); - - this->gen_sync(iss::PRE_SYNC, 10); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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){ - Value* X_rd_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 10); - 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); + bb->setName("LB"); + + this->gen_sync(iss::PRE_SYNC, 10); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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){ + Value* X_rd_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 10); + 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); } - //11: instruction LH + /* instruction 11: LH */ std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LH"); - - this->gen_sync(iss::PRE_SYNC, 11); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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){ - Value* X_rd_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 11); - 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); + bb->setName("LH"); + + this->gen_sync(iss::PRE_SYNC, 11); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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){ + Value* X_rd_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 11); + 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); } - //12: instruction LW + /* instruction 12: LW */ std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LW"); - - this->gen_sync(iss::PRE_SYNC, 12); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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){ - Value* X_rd_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 12); - 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); + bb->setName("LW"); + + this->gen_sync(iss::PRE_SYNC, 12); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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){ + Value* X_rd_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 12); + 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); } - //13: instruction LBU + /* instruction 13: LBU */ std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LBU"); - - this->gen_sync(iss::PRE_SYNC, 13); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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){ - Value* X_rd_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 13); - 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); + bb->setName("LBU"); + + this->gen_sync(iss::PRE_SYNC, 13); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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){ + Value* X_rd_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 13); + 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); } - //14: instruction LHU + /* instruction 14: LHU */ std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LHU"); - - this->gen_sync(iss::PRE_SYNC, 14); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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){ - Value* X_rd_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 14); - 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); + bb->setName("LHU"); + + this->gen_sync(iss::PRE_SYNC, 14); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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){ + Value* X_rd_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 14); + 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); } - //15: instruction SB + /* instruction 15: SB */ std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SB"); - - this->gen_sync(iss::PRE_SYNC, 15); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 15); - 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); + bb->setName("SB"); + + this->gen_sync(iss::PRE_SYNC, 15); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 15); + 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); } - //16: instruction SH + /* instruction 16: SH */ std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SH"); - - this->gen_sync(iss::PRE_SYNC, 16); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 16); - 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); + bb->setName("SH"); + + this->gen_sync(iss::PRE_SYNC, 16); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 16); + 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); } - //17: instruction SW + /* instruction 17: SW */ std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SW"); - - this->gen_sync(iss::PRE_SYNC, 17); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 17); - 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); + bb->setName("SW"); + + this->gen_sync(iss::PRE_SYNC, 17); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 17); + 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); } - //18: instruction ADDI + /* instruction 18: ADDI */ std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDI"); - - this->gen_sync(iss::PRE_SYNC, 18); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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(32U, 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, 18); - 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); + bb->setName("ADDI"); + + this->gen_sync(iss::PRE_SYNC, 18); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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(32U, 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, 18); + 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); } - //19: instruction SLTI + /* instruction 19: SLTI */ std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTI"); - - this->gen_sync(iss::PRE_SYNC, 19); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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), - 32, true), - this->gen_ext( - this->gen_const(32U, fld_imm_val), - 32, true)), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 19); - 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); + bb->setName("SLTI"); + + this->gen_sync(iss::PRE_SYNC, 19); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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), + 32, true), + this->gen_ext( + this->gen_const(32U, fld_imm_val), + 32, true)), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 19); + 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); } - //20: instruction SLTIU + /* instruction 20: SLTIU */ std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTIU"); - - this->gen_sync(iss::PRE_SYNC, 20); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - ICmpInst::ICMP_ULT, - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 32, false), - this->gen_ext( - full_imm_val, - 32, false)), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 20); - 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); + bb->setName("SLTIU"); + + this->gen_sync(iss::PRE_SYNC, 20); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + ICmpInst::ICMP_ULT, + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 32, false), + this->gen_ext( + full_imm_val, + 32, false)), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 20); + 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); } - //21: instruction XORI + /* instruction 21: XORI */ std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("XORI"); - - this->gen_sync(iss::PRE_SYNC, 21); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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(32U, 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, 21); - 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); + bb->setName("XORI"); + + this->gen_sync(iss::PRE_SYNC, 21); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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(32U, 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, 21); + 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); } - //22: instruction ORI + /* instruction 22: ORI */ std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ORI"); - - this->gen_sync(iss::PRE_SYNC, 22); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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(32U, 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, 22); - 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); + bb->setName("ORI"); + + this->gen_sync(iss::PRE_SYNC, 22); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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(32U, 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, 22); + 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); } - //23: instruction ANDI + /* instruction 23: ANDI */ std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ANDI"); - - this->gen_sync(iss::PRE_SYNC, 23); - - 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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(32U, 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, 23); - 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); + bb->setName("ANDI"); + + this->gen_sync(iss::PRE_SYNC, 23); + + 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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(32U, 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, 23); + 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); } - //24: instruction SLLI + /* instruction 24: SLLI */ std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(iss::PRE_SYNC, 24); - - 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("SLLI 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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.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, 24); - 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); + bb->setName("SLLI"); + + this->gen_sync(iss::PRE_SYNC, 24); + + 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("SLLI 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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.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, 24); + 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); } - //25: instruction SRLI + /* instruction 25: SRLI */ std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(iss::PRE_SYNC, 25); - - 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("SRLI 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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.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, 25); - 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); + bb->setName("SRLI"); + + this->gen_sync(iss::PRE_SYNC, 25); + + 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("SRLI 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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.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, 25); + 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); } - //26: instruction SRAI + /* instruction 26: SRAI */ std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(iss::PRE_SYNC, 26); - - 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("SRAI 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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(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, 26); - 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); + bb->setName("SRAI"); + + this->gen_sync(iss::PRE_SYNC, 26); + + 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("SRAI 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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(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, 26); + 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); } - //27: instruction ADD + /* instruction 27: ADD */ std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADD"); - - this->gen_sync(iss::PRE_SYNC, 27); - - 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("ADD 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 27); - 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); + bb->setName("ADD"); + + this->gen_sync(iss::PRE_SYNC, 27); + + 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("ADD 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 27); + 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); } - //28: instruction SUB + /* instruction 28: SUB */ std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SUB"); - - this->gen_sync(iss::PRE_SYNC, 28); - - 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("SUB 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 28); - 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); + bb->setName("SUB"); + + this->gen_sync(iss::PRE_SYNC, 28); + + 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("SUB 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 28); + 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); } - //29: instruction SLL + /* instruction 29: SLL */ std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLL"); - - this->gen_sync(iss::PRE_SYNC, 29); - - 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("SLL 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val, 0), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 29); - 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); + bb->setName("SLL"); + + this->gen_sync(iss::PRE_SYNC, 29); + + 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("SLL 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateShl( + this->gen_reg_load(fld_rs1_val, 0), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 29); + 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); } - //30: instruction SLT + /* instruction 30: SLT */ std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLT"); - - this->gen_sync(iss::PRE_SYNC, 30); - - 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("SLT 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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), - 32, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, true)), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 30); - 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); + bb->setName("SLT"); + + this->gen_sync(iss::PRE_SYNC, 30); + + 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("SLT 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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), + 32, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, true)), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 30); + 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); } - //31: instruction SLTU + /* instruction 31: SLTU */ std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTU"); - - this->gen_sync(iss::PRE_SYNC, 31); - - 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("SLTU 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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), - 32, - false), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, - false)), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 31); - 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); + bb->setName("SLTU"); + + this->gen_sync(iss::PRE_SYNC, 31); + + 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("SLTU 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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), + 32, + false), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, + false)), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 31); + 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); } - //32: instruction XOR + /* instruction 32: XOR */ std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("XOR"); - - this->gen_sync(iss::PRE_SYNC, 32); - - 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("XOR 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 32); - 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); + bb->setName("XOR"); + + this->gen_sync(iss::PRE_SYNC, 32); + + 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("XOR 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 32); + 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); } - //33: instruction SRL + /* instruction 33: SRL */ std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRL"); - - this->gen_sync(iss::PRE_SYNC, 33); - - 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("SRL 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val, 0), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 33); - 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); + bb->setName("SRL"); + + this->gen_sync(iss::PRE_SYNC, 33); + + 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("SRL 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateLShr( + this->gen_reg_load(fld_rs1_val, 0), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 33); + 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); } - //34: instruction SRA + /* instruction 34: SRA */ std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRA"); - - this->gen_sync(iss::PRE_SYNC, 34); - - 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("SRA 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val, 0), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 34); - 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); + bb->setName("SRA"); + + this->gen_sync(iss::PRE_SYNC, 34); + + 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("SRA 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAShr( + this->gen_reg_load(fld_rs1_val, 0), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 34); + 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); } - //35: instruction OR + /* instruction 35: OR */ std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("OR"); - - this->gen_sync(iss::PRE_SYNC, 35); - - 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("OR 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 35); - 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); + bb->setName("OR"); + + this->gen_sync(iss::PRE_SYNC, 35); + + 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("OR 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 35); + 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); } - //36: instruction AND + /* instruction 36: AND */ std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AND"); - - this->gen_sync(iss::PRE_SYNC, 36); - - 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("AND 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 36); - 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); + bb->setName("AND"); + + this->gen_sync(iss::PRE_SYNC, 36); + + 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("AND 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 36); + 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); } - //37: instruction FENCE + /* instruction 37: FENCE */ std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("FENCE"); - - this->gen_sync(iss::PRE_SYNC, 37); - - 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_succ_val = 0 | (bit_sub<20,4>(instr)); - uint8_t fld_pred_val = 0 | (bit_sub<24,4>(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("FENCE"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 37); - 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); + bb->setName("FENCE"); + + this->gen_sync(iss::PRE_SYNC, 37); + + 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_succ_val = 0 | (bit_sub<20,4>(instr)); + uint8_t fld_pred_val = 0 | (bit_sub<24,4>(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("FENCE"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 37); + 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); } - //38: instruction FENCE_I + /* instruction 38: FENCE_I */ std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("FENCE_I"); - - this->gen_sync(iss::PRE_SYNC, 38); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_imm_val = 0 | (bit_sub<20,12>(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("FENCE_I"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* FENCE_fencei_val = this->gen_const(32U, fld_imm_val); - this->gen_write_mem( - traits::FENCE, - (uint64_t)1, - this->builder.CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 38); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::FLUSH, nullptr); + bb->setName("FENCE_I"); + + this->gen_sync(iss::PRE_SYNC, 38); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_imm_val = 0 | (bit_sub<20,12>(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("FENCE_I"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* FENCE_fencei_val = this->gen_const(32U, fld_imm_val); + this->gen_write_mem( + traits::FENCE, + (uint64_t)1, + this->builder.CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 38); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::FLUSH, nullptr); } - //39: instruction ECALL + /* instruction 39: ECALL */ std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ECALL"); - - this->gen_sync(iss::PRE_SYNC, 39); - - ; - 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("ECALL"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - this->gen_raise_trap(0, 11); - this->gen_sync(iss::POST_SYNC, 39); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("ECALL"); + + this->gen_sync(iss::PRE_SYNC, 39); + + ; + 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("ECALL"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + this->gen_raise_trap(0, 11); + this->gen_sync(iss::POST_SYNC, 39); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //40: instruction EBREAK + /* instruction 40: EBREAK */ std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("EBREAK"); - - this->gen_sync(iss::PRE_SYNC, 40); - - ; - 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("EBREAK"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 40); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("EBREAK"); + + this->gen_sync(iss::PRE_SYNC, 40); + + ; + 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("EBREAK"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + this->gen_raise_trap(0, 3); + this->gen_sync(iss::POST_SYNC, 40); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //41: instruction URET + /* instruction 41: URET */ std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("URET"); - - this->gen_sync(iss::PRE_SYNC, 41); - - ; - 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("URET"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - this->gen_leave_trap(0); - this->gen_sync(iss::POST_SYNC, 41); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("URET"); + + this->gen_sync(iss::PRE_SYNC, 41); + + ; + 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("URET"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + this->gen_leave_trap(0); + this->gen_sync(iss::POST_SYNC, 41); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //42: instruction SRET + /* instruction 42: SRET */ std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRET"); - - this->gen_sync(iss::PRE_SYNC, 42); - - ; - 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("SRET"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - this->gen_leave_trap(1); - this->gen_sync(iss::POST_SYNC, 42); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("SRET"); + + this->gen_sync(iss::PRE_SYNC, 42); + + ; + 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("SRET"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + this->gen_leave_trap(1); + this->gen_sync(iss::POST_SYNC, 42); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //43: instruction MRET + /* instruction 43: MRET */ std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("MRET"); - - this->gen_sync(iss::PRE_SYNC, 43); - - ; - 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("MRET"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - this->gen_leave_trap(3); - this->gen_sync(iss::POST_SYNC, 43); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("MRET"); + + this->gen_sync(iss::PRE_SYNC, 43); + + ; + 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("MRET"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + this->gen_leave_trap(3); + this->gen_sync(iss::POST_SYNC, 43); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //44: instruction WFI + /* instruction 44: WFI */ std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("WFI"); - - this->gen_sync(iss::PRE_SYNC, 44); - - ; - 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("WFI"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - this->gen_wait(1); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 44); - 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); + bb->setName("WFI"); + + this->gen_sync(iss::PRE_SYNC, 44); + + ; + 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("WFI"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + this->gen_wait(1); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 44); + 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); } - //45: instruction SFENCE.VMA + /* instruction 45: SFENCE.VMA */ std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SFENCE.VMA"); - - this->gen_sync(iss::PRE_SYNC, 45); - - 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("SFENCE.VMA"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* FENCE_fencevmal_val = this->gen_const(32U, fld_rs1_val); - this->gen_write_mem( - traits::FENCE, - (uint64_t)2, - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 45); - 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); + bb->setName("SFENCE.VMA"); + + this->gen_sync(iss::PRE_SYNC, 45); + + 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("SFENCE.VMA"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* FENCE_fencevmal_val = this->gen_const(32U, fld_rs1_val); + this->gen_write_mem( + traits::FENCE, + (uint64_t)2, + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 45); + 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); } - //46: instruction CSRRW + /* instruction 46: CSRRW */ std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRW"); - - this->gen_sync(iss::PRE_SYNC, 46); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRW x%1$d, %2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* rs_val_val = this->gen_reg_load(fld_rs1_val, 0); - if(fld_rd_val != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); - 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))); - Value* X_rd_val = csr_val_val; - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 46); - 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); + bb->setName("CSRRW"); + + this->gen_sync(iss::PRE_SYNC, 46); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRW x%1$d, %2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* rs_val_val = this->gen_reg_load(fld_rs1_val, 0); + if(fld_rd_val != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); + 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))); + Value* X_rd_val = csr_val_val; + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 46); + 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); } - //47: instruction CSRRS + /* instruction 47: CSRRS */ std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRS"); - - this->gen_sync(iss::PRE_SYNC, 47); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRS x%1$d, %2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); - 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); - } - if(fld_rs1_val != 0){ - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 47); - 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); + bb->setName("CSRRS"); + + this->gen_sync(iss::PRE_SYNC, 47); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRS x%1$d, %2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); + 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); + } + if(fld_rs1_val != 0){ + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 47); + 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); } - //48: instruction CSRRC + /* instruction 48: CSRRC */ std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRC"); - - this->gen_sync(iss::PRE_SYNC, 48); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRC x%1$d, %2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); - 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); - } - if(fld_rs1_val != 0){ - Value* CSR_csr_val = this->builder.CreateAnd( - xrd_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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 48); - 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); + bb->setName("CSRRC"); + + this->gen_sync(iss::PRE_SYNC, 48); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRC x%1$d, %2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 32/8); + 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); + } + if(fld_rs1_val != 0){ + Value* CSR_csr_val = this->builder.CreateAnd( + xrd_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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 48); + 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); } - //49: instruction CSRRWI + /* instruction 49: CSRRWI */ std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRWI"); - - this->gen_sync(iss::PRE_SYNC, 49); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRWI x%1$d, %2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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); - } - Value* CSR_csr_val = 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 49); - 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); + bb->setName("CSRRWI"); + + this->gen_sync(iss::PRE_SYNC, 49); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRWI x%1$d, %2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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); + } + Value* CSR_csr_val = 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 49); + 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); } - //50: instruction CSRRSI + /* instruction 50: CSRRSI */ std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRSI"); - - this->gen_sync(iss::PRE_SYNC, 50); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRSI x%1$d, %2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - res_val, - 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))); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 50); - 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); + bb->setName("CSRRSI"); + + this->gen_sync(iss::PRE_SYNC, 50); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRSI x%1$d, %2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + res_val, + 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))); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 50); + 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); } - //51: instruction CSRRCI + /* instruction 51: CSRRCI */ std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRCI"); - - this->gen_sync(iss::PRE_SYNC, 51); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRCI x%1$d, %2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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); - } - if(fld_zimm_val != 0){ - Value* CSR_csr_val = this->builder.CreateAnd( - res_val, - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 51); - 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); + bb->setName("CSRRCI"); + + this->gen_sync(iss::PRE_SYNC, 51); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRCI x%1$d, %2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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); + } + if(fld_zimm_val != 0){ + Value* CSR_csr_val = this->builder.CreateAnd( + res_val, + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 51); + 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); } - //52: instruction MUL + /* instruction 52: MUL */ std::tuple __mul(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("MUL"); - - this->gen_sync(iss::PRE_SYNC, 52); - - 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("MUL 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 64, - false), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, - false)); - Value* X_rd_val = this->gen_ext( - res_val, - 32, - 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, 52); - 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); + bb->setName("MUL"); + + this->gen_sync(iss::PRE_SYNC, 52); + + 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("MUL 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 64, + false), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, + false)); + Value* X_rd_val = this->gen_ext( + res_val, + 32, + 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, 52); + 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); } - //53: instruction MULH + /* instruction 53: MULH */ std::tuple __mulh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("MULH"); - - this->gen_sync(iss::PRE_SYNC, 53); - - 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("MULH 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* res_val = this->builder.CreateMul( - 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)); - Value* X_rd_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - 32), - 32, - 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, 53); - 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); + bb->setName("MULH"); + + this->gen_sync(iss::PRE_SYNC, 53); + + 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("MULH 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* res_val = this->builder.CreateMul( + 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)); + Value* X_rd_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + 32), + 32, + 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, 53); + 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); } - //54: instruction MULHSU + /* instruction 54: MULHSU */ std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("MULHSU"); - - this->gen_sync(iss::PRE_SYNC, 54); - - 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("MULHSU 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* res_val = this->builder.CreateMul( - 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, - false)); - Value* X_rd_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - 32), - 32, - 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, 54); - 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); + bb->setName("MULHSU"); + + this->gen_sync(iss::PRE_SYNC, 54); + + 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("MULHSU 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* res_val = this->builder.CreateMul( + 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, + false)); + Value* X_rd_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + 32), + 32, + 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, 54); + 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); } - //55: instruction MULHU + /* instruction 55: MULHU */ std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("MULHU"); - - this->gen_sync(iss::PRE_SYNC, 55); - - 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("MULHU 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 0), - 64, - false), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, - false)); - Value* X_rd_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - 32), - 32, - 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, 55); - 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); + bb->setName("MULHU"); + + this->gen_sync(iss::PRE_SYNC, 55); + + 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("MULHU 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 0), + 64, + false), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, + false)); + Value* X_rd_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + 32), + 32, + 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, 55); + 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); } - //56: instruction DIV + /* instruction 56: DIV */ std::tuple __div(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("DIV"); - - this->gen_sync(iss::PRE_SYNC, 56); - - 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("DIV 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - 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, - this->gen_reg_load(fld_rs2_val, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* X_rd_val = this->builder.CreateSDiv( - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 1), - 32, - true), - this->gen_ext( - 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.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); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 56); - 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); + bb->setName("DIV"); + + this->gen_sync(iss::PRE_SYNC, 56); + + 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("DIV 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + 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, + this->gen_reg_load(fld_rs2_val, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* X_rd_val = this->builder.CreateSDiv( + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 1), + 32, + true), + this->gen_ext( + 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.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); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 56); + 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); } - //57: instruction DIVU + /* instruction 57: DIVU */ std::tuple __divu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("DIVU"); - - this->gen_sync(iss::PRE_SYNC, 57); - - 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("DIVU 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - 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, - this->gen_reg_load(fld_rs2_val, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* X_rd_val = this->builder.CreateUDiv( - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 1), - 32, - false), - this->gen_ext( - 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.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); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 57); - 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); + bb->setName("DIVU"); + + this->gen_sync(iss::PRE_SYNC, 57); + + 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("DIVU 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + 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, + this->gen_reg_load(fld_rs2_val, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* X_rd_val = this->builder.CreateUDiv( + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 1), + 32, + false), + this->gen_ext( + 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.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); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 57); + 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); } - //58: instruction REM + /* instruction 58: REM */ std::tuple __rem(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("REM"); - - this->gen_sync(iss::PRE_SYNC, 58); - - 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("REM 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - 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, - this->gen_reg_load(fld_rs2_val, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* X_rd_val = this->builder.CreateSRem( - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 1), - 32, - true), - this->gen_ext( - 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.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.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 58); - 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); + bb->setName("REM"); + + this->gen_sync(iss::PRE_SYNC, 58); + + 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("REM 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + 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, + this->gen_reg_load(fld_rs2_val, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* X_rd_val = this->builder.CreateSRem( + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 1), + 32, + true), + this->gen_ext( + 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.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.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 58); + 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); } - //59: instruction REMU + /* instruction 59: REMU */ std::tuple __remu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("REMU"); - - this->gen_sync(iss::PRE_SYNC, 59); - - 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("REMU 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - 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, - this->gen_reg_load(fld_rs2_val, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* X_rd_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(fld_rs1_val, 1), - 32, - false), - this->gen_ext( - 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.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.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 59); - 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); + bb->setName("REMU"); + + this->gen_sync(iss::PRE_SYNC, 59); + + 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("REMU 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + 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, + this->gen_reg_load(fld_rs2_val, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* X_rd_val = this->builder.CreateURem( + this->gen_ext( + this->gen_reg_load(fld_rs1_val, 1), + 32, + false), + this->gen_ext( + 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.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.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 59); + 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); } - //60: instruction LR.W + /* instruction 60: LR.W */ std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LR.W"); - - this->gen_sync(iss::PRE_SYNC, 60); - - 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_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LR.W x%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* X_rd_val = this->gen_ext( - 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); - Value* RES_offs_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 60); - 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); + bb->setName("LR.W"); + + this->gen_sync(iss::PRE_SYNC, 60); + + 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_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LR.W x%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* X_rd_val = this->gen_ext( + 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); + Value* RES_offs_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 60); + 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); } - //61: instruction SC.W + /* instruction 61: SC.W */ std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SC.W"); - - this->gen_sync(iss::PRE_SYNC, 61); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SC.W 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - 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( - ICmpInst::ICMP_NE, - res1_val, - this->gen_const(32U, 0)), - bb_then, - bbnext); - 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.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_choose( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 61); - 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); + bb->setName("SC.W"); + + this->gen_sync(iss::PRE_SYNC, 61); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SC.W 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + 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( + ICmpInst::ICMP_NE, + res1_val, + this->gen_const(32U, 0)), + bb_then, + bbnext); + 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.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_choose( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 61); + 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); } - //62: instruction AMOSWAP.W + /* instruction 62: AMOSWAP.W */ std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOSWAP.W"); - - this->gen_sync(iss::PRE_SYNC, 62); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOSWAP.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - 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); - } - 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, 62); - 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); + bb->setName("AMOSWAP.W"); + + this->gen_sync(iss::PRE_SYNC, 62); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOSWAP.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + 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); + } + 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, 62); + 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); } - //63: instruction AMOADD.W + /* instruction 63: AMOADD.W */ std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOADD.W"); - - this->gen_sync(iss::PRE_SYNC, 63); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOADD.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 63); - 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); + bb->setName("AMOADD.W"); + + this->gen_sync(iss::PRE_SYNC, 63); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOADD.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 63); + 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); } - //64: instruction AMOXOR.W + /* instruction 64: AMOXOR.W */ std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOXOR.W"); - - this->gen_sync(iss::PRE_SYNC, 64); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOXOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 64); - 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); + bb->setName("AMOXOR.W"); + + this->gen_sync(iss::PRE_SYNC, 64); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOXOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 64); + 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); } - //65: instruction AMOAND.W + /* instruction 65: AMOAND.W */ std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOAND.W"); - - this->gen_sync(iss::PRE_SYNC, 65); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOAND.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 65); - 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); + bb->setName("AMOAND.W"); + + this->gen_sync(iss::PRE_SYNC, 65); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOAND.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 65); + 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); } - //66: instruction AMOOR.W + /* instruction 66: AMOOR.W */ std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOOR.W"); - - this->gen_sync(iss::PRE_SYNC, 66); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 66); - 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); + bb->setName("AMOOR.W"); + + this->gen_sync(iss::PRE_SYNC, 66); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 66); + 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); } - //67: instruction AMOMIN.W + /* instruction 67: AMOMIN.W */ std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMIN.W"); - - this->gen_sync(iss::PRE_SYNC, 67); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMIN.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SGT, - this->gen_ext( - res1_val, - 32, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, true)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 32); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 67); - 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); + bb->setName("AMOMIN.W"); + + this->gen_sync(iss::PRE_SYNC, 67); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMIN.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SGT, + this->gen_ext( + res1_val, + 32, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, true)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 32); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 67); + 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); } - //68: instruction AMOMAX.W + /* instruction 68: AMOMAX.W */ std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMAX.W"); - - this->gen_sync(iss::PRE_SYNC, 68); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMAX.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - res1_val, - 32, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, true)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 32); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 68); - 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); + bb->setName("AMOMAX.W"); + + this->gen_sync(iss::PRE_SYNC, 68); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAX.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + res1_val, + 32, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, true)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 32); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 68); + 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); } - //69: instruction AMOMINU.W + /* instruction 69: AMOMINU.W */ std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMINU.W"); - - this->gen_sync(iss::PRE_SYNC, 69); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMINU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res1_val, - this->gen_reg_load(fld_rs2_val, 0)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 32); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 69); - 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); + bb->setName("AMOMINU.W"); + + this->gen_sync(iss::PRE_SYNC, 69); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMINU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res1_val, + this->gen_reg_load(fld_rs2_val, 0)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 32); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 69); + 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); } - //70: instruction AMOMAXU.W + /* instruction 70: AMOMAXU.W */ std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMAXU.W"); - - this->gen_sync(iss::PRE_SYNC, 70); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMAXU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_ext( - res1_val, - 32, false), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 32, false)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 32); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 70); - 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); + bb->setName("AMOMAXU.W"); + + this->gen_sync(iss::PRE_SYNC, 70); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAXU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + res1_val, + 32, false), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 32, false)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 32); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 70); + 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); } - //71: instruction C.ADDI4SPN + /* instruction 71: C.ADDI4SPN */ std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.ADDI4SPN"); - - this->gen_sync(iss::PRE_SYNC, 71); - - uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); - uint16_t fld_imm_val = 0 | (bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.ADDI4SPN x%1$d, 0x%2$05x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(fld_imm_val == 0){ - this->gen_raise_trap(0, 2); - } - uint8_t rd_idx_val = (fld_rd_val + 8); - uint8_t x2_idx_val = 2; - Value* X_rd_idx_val = this->builder.CreateAdd( - this->gen_reg_load(x2_idx_val, 0), - this->gen_const(32U, fld_imm_val)); - 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, 71); - 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); + bb->setName("C.ADDI4SPN"); + + this->gen_sync(iss::PRE_SYNC, 71); + + uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); + uint16_t fld_imm_val = 0 | (bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.ADDI4SPN x%1$d, 0x%2$05x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(fld_imm_val == 0){ + this->gen_raise_trap(0, 2); + } + uint8_t rd_idx_val = (fld_rd_val + 8); + uint8_t x2_idx_val = 2; + Value* X_rd_idx_val = this->builder.CreateAdd( + this->gen_reg_load(x2_idx_val, 0), + this->gen_const(32U, fld_imm_val)); + 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, 71); + 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); } - //72: instruction C.LW + /* instruction 72: C.LW */ std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.LW"); - - this->gen_sync(iss::PRE_SYNC, 72); - - uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); - uint8_t fld_uimm_val = 0 | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.LW x(8+%1$d), x(8+%2$d), 0x%3$05x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_uimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 72); - 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); + bb->setName("C.LW"); + + this->gen_sync(iss::PRE_SYNC, 72); + + uint8_t fld_rd_val = 0 | (bit_sub<2,3>(instr)); + uint8_t fld_uimm_val = 0 | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.LW x(8+%1$d), x(8+%2$d), 0x%3$05x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_uimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 72); + 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); } - //73: instruction C.SW + /* instruction 73: C.SW */ std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.SW"); - - this->gen_sync(iss::PRE_SYNC, 73); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); - uint8_t fld_uimm_val = 0 | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.SW x(8+%1$d), x(8+%2$d), 0x%3$05x"); - ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 73); - 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); + bb->setName("C.SW"); + + this->gen_sync(iss::PRE_SYNC, 73); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); + uint8_t fld_uimm_val = 0 | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.SW x(8+%1$d), x(8+%2$d), 0x%3$05x"); + ins_fmter % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 73); + 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); } - //74: instruction C.ADDI + /* instruction 74: C.ADDI */ std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.ADDI"); - - this->gen_sync(iss::PRE_SYNC, 74); - - int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); - uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.ADDI x%1$d, 0x%2$05x"); - ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; - std::vector 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* X_rs1_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 74); - 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); + bb->setName("C.ADDI"); + + this->gen_sync(iss::PRE_SYNC, 74); + + int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); + uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.ADDI x%1$d, 0x%2$05x"); + ins_fmter % (uint64_t)fld_rs1_val % (int64_t)fld_imm_val; + std::vector 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* X_rs1_val = this->builder.CreateAdd( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(32U, fld_imm_val)); + this->builder.CreateStore(X_rs1_val, get_reg_ptr(fld_rs1_val), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 74); + 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); } - //75: instruction C.NOP + /* instruction 75: C.NOP */ std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.NOP"); - - this->gen_sync(iss::PRE_SYNC, 75); - - ; - 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("C.NOP"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - /* TODO: describe operations for C.NOP ! */ - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 75); - 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); + bb->setName("C.NOP"); + + this->gen_sync(iss::PRE_SYNC, 75); + + ; + 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("C.NOP"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + /* TODO: describe operations for C.NOP ! */ + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 75); + 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); } - //76: instruction C.JAL + /* instruction 76: C.JAL */ std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.JAL"); - - this->gen_sync(iss::PRE_SYNC, 76); - - int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 11); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.JAL 0x%1$05x"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t rd_val = 1; - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)); - this->builder.CreateStore(X_rd_val, get_reg_ptr(rd_val), false); - Value* PC_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 76); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.JAL"); + + this->gen_sync(iss::PRE_SYNC, 76); + + int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 11); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.JAL 0x%1$05x"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t rd_val = 1; + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(rd_val), false); + Value* PC_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 76); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //77: instruction C.LI + /* instruction 77: C.LI */ std::tuple __c_li(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.LI"); - - this->gen_sync(iss::PRE_SYNC, 77); - - int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.LI 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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(fld_rd_val == 0){ - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 77); - 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); + bb->setName("C.LI"); + + this->gen_sync(iss::PRE_SYNC, 77); + + int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.LI 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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(fld_rd_val == 0){ + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 77); + 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); } - //78: instruction C.LUI + /* instruction 78: C.LUI */ std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.LUI"); - - this->gen_sync(iss::PRE_SYNC, 78); - - int32_t fld_imm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17); - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.LUI x%1$d, 0x%2$05x"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(fld_rd_val == 0){ - this->gen_raise_trap(0, 2); - } - if(fld_imm_val == 0){ - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 78); - 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); + bb->setName("C.LUI"); + + this->gen_sync(iss::PRE_SYNC, 78); + + int32_t fld_imm_val = 0 | (bit_sub<2,5>(instr) << 12) | (signed_bit_sub<12,1>(instr) << 17); + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.LUI x%1$d, 0x%2$05x"); + ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(fld_rd_val == 0){ + this->gen_raise_trap(0, 2); + } + if(fld_imm_val == 0){ + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 78); + 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); } - //79: instruction C.ADDI16SP + /* instruction 79: C.ADDI16SP */ std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.ADDI16SP"); - - this->gen_sync(iss::PRE_SYNC, 79); - - int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.ADDI16SP 0x%1$05x"); - ins_fmter % (int64_t)fld_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t x2_idx_val = 2; - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 79); - 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); + bb->setName("C.ADDI16SP"); + + this->gen_sync(iss::PRE_SYNC, 79); + + int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 9); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.ADDI16SP 0x%1$05x"); + ins_fmter % (int64_t)fld_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t x2_idx_val = 2; + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 79); + 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); } - //80: instruction C.SRLI + /* instruction 80: C.SRLI */ std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.SRLI"); - - this->gen_sync(iss::PRE_SYNC, 80); - - uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.SRLI x(8+%1$d), %2$d"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* X_rs1_idx_val = this->builder.CreateLShr( - this->gen_reg_load(rs1_idx_val, 0), - this->gen_const(32U, fld_shamt_val)); - 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, 80); - 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); + bb->setName("C.SRLI"); + + this->gen_sync(iss::PRE_SYNC, 80); + + uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.SRLI x(8+%1$d), %2$d"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = (fld_rs1_val + 8); + Value* X_rs1_idx_val = this->builder.CreateLShr( + this->gen_reg_load(rs1_idx_val, 0), + this->gen_const(32U, fld_shamt_val)); + 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, 80); + 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); } - //81: instruction C.SRAI + /* instruction 81: C.SRAI */ std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.SRAI"); - - this->gen_sync(iss::PRE_SYNC, 81); - - uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.SRAI x(8+%1$d), %2$d"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* X_rs1_idx_val = this->builder.CreateAShr( - this->gen_reg_load(rs1_idx_val, 0), - this->gen_const(32U, fld_shamt_val)); - 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, 81); - 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); + bb->setName("C.SRAI"); + + this->gen_sync(iss::PRE_SYNC, 81); + + uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.SRAI x(8+%1$d), %2$d"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = (fld_rs1_val + 8); + Value* X_rs1_idx_val = this->builder.CreateAShr( + this->gen_reg_load(rs1_idx_val, 0), + this->gen_const(32U, fld_shamt_val)); + 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, 81); + 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); } - //82: instruction C.ANDI + /* instruction 82: C.ANDI */ std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.ANDI"); - - this->gen_sync(iss::PRE_SYNC, 82); - - int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.ANDI x(8+%1$d), 0x%2$05x"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t rs1_idx_val = (fld_rs1_val + 8); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 82); - 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); + bb->setName("C.ANDI"); + + this->gen_sync(iss::PRE_SYNC, 82); + + int8_t fld_imm_val = 0 | (bit_sub<2,5>(instr)) | (signed_bit_sub<12,1>(instr) << 5); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.ANDI x(8+%1$d), 0x%2$05x"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = (fld_rs1_val + 8); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 82); + 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); } - //83: instruction C.SUB + /* instruction 83: C.SUB */ std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.SUB"); - - this->gen_sync(iss::PRE_SYNC, 83); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); - uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.SUB x(8+%1$d), x(8+%2$d)"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 83); - 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); + bb->setName("C.SUB"); + + this->gen_sync(iss::PRE_SYNC, 83); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); + uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.SUB x(8+%1$d), x(8+%2$d)"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 83); + 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); } - //84: instruction C.XOR + /* instruction 84: C.XOR */ std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.XOR"); - - this->gen_sync(iss::PRE_SYNC, 84); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); - uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.XOR x(8+%1$d), x(8+%2$d)"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 84); - 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); + bb->setName("C.XOR"); + + this->gen_sync(iss::PRE_SYNC, 84); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); + uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.XOR x(8+%1$d), x(8+%2$d)"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 84); + 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); } - //85: instruction C.OR + /* instruction 85: C.OR */ std::tuple __c_or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.OR"); - - this->gen_sync(iss::PRE_SYNC, 85); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); - uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.OR x(8+%1$d), x(8+%2$d)"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 85); - 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); + bb->setName("C.OR"); + + this->gen_sync(iss::PRE_SYNC, 85); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); + uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.OR x(8+%1$d), x(8+%2$d)"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 85); + 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); } - //86: instruction C.AND + /* instruction 86: C.AND */ std::tuple __c_and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.AND"); - - this->gen_sync(iss::PRE_SYNC, 86); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); - uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.AND x(8+%1$d), x(8+%2$d)"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 86); - 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); + bb->setName("C.AND"); + + this->gen_sync(iss::PRE_SYNC, 86); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,3>(instr)); + uint8_t fld_rd_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.AND x(8+%1$d), x(8+%2$d)"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 86); + 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); } - //87: instruction C.J + /* instruction 87: C.J */ std::tuple __c_j(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.J"); - - this->gen_sync(iss::PRE_SYNC, 87); - - int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 11); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.J 0x%1$05x"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* PC_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 87); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.J"); + + this->gen_sync(iss::PRE_SYNC, 87); + + int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,3>(instr) << 1) | (bit_sub<6,1>(instr) << 7) | (bit_sub<7,1>(instr) << 6) | (bit_sub<8,1>(instr) << 10) | (bit_sub<9,2>(instr) << 8) | (bit_sub<11,1>(instr) << 4) | (signed_bit_sub<12,1>(instr) << 11); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.J 0x%1$05x"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* PC_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 87); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //88: instruction C.BEQZ + /* instruction 88: C.BEQZ */ std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.BEQZ"); - - this->gen_sync(iss::PRE_SYNC, 88); - - int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.BEQZ x(8+%1$d), 0x%2$05x"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* PC_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_reg_load(rs1_idx_val, 0), - this->gen_const(32U, 0)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 88); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.BEQZ"); + + this->gen_sync(iss::PRE_SYNC, 88); + + int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.BEQZ x(8+%1$d), 0x%2$05x"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = (fld_rs1_val + 8); + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1_idx_val, 0), + this->gen_const(32U, 0)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 88); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //89: instruction C.BNEZ + /* instruction 89: C.BNEZ */ std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.BNEZ"); - - this->gen_sync(iss::PRE_SYNC, 89); - - int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); - uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.BNEZ x(8+%1$d), 0x%2$05x"); - ins_fmter % (uint64_t)fld_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t rs1_idx_val = (fld_rs1_val + 8); - Value* PC_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_NE, - this->gen_reg_load(rs1_idx_val, 0), - this->gen_const(32U, 0)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 89); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.BNEZ"); + + this->gen_sync(iss::PRE_SYNC, 89); + + int16_t fld_imm_val = 0 | (bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (signed_bit_sub<12,1>(instr) << 8); + uint8_t fld_rs1_val = 0 | (bit_sub<7,3>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.BNEZ x(8+%1$d), 0x%2$05x"); + ins_fmter % (uint64_t)fld_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = (fld_rs1_val + 8); + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->gen_reg_load(rs1_idx_val, 0), + this->gen_const(32U, 0)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 89); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //90: instruction C.SLLI + /* instruction 90: C.SLLI */ std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.SLLI"); - - this->gen_sync(iss::PRE_SYNC, 90); - - uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.SLLI x%1$d, %2$d"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(fld_rs1_val == 0){ - this->gen_raise_trap(0, 2); - } - Value* X_rs1_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(32U, fld_shamt_val)); - 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, 90); - 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); + bb->setName("C.SLLI"); + + this->gen_sync(iss::PRE_SYNC, 90); + + uint8_t fld_shamt_val = 0 | (bit_sub<2,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.SLLI x%1$d, %2$d"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(fld_rs1_val == 0){ + this->gen_raise_trap(0, 2); + } + Value* X_rs1_val = this->builder.CreateShl( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(32U, fld_shamt_val)); + 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, 90); + 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); } - //91: instruction C.LWSP + /* instruction 91: C.LWSP */ std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.LWSP"); - - this->gen_sync(iss::PRE_SYNC, 91); - - uint8_t fld_uimm_val = 0 | (bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5); - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.LWSP x%1$d, sp, 0x%2$05x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t x2_idx_val = 2; - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 91); - 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); + bb->setName("C.LWSP"); + + this->gen_sync(iss::PRE_SYNC, 91); + + uint8_t fld_uimm_val = 0 | (bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5); + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.LWSP x%1$d, sp, 0x%2$05x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t x2_idx_val = 2; + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 91); + 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); } - //92: instruction C.MV + /* instruction 92: C.MV */ std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.MV"); - - this->gen_sync(iss::PRE_SYNC, 92); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.MV x%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 92); - 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); + bb->setName("C.MV"); + + this->gen_sync(iss::PRE_SYNC, 92); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.MV x%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 92); + 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); } - //93: instruction C.JR + /* instruction 93: C.JR */ std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.JR"); - - this->gen_sync(iss::PRE_SYNC, 93); - - uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.JR x%1$d"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - 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->gen_sync(iss::POST_SYNC, 93); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.JR"); + + this->gen_sync(iss::PRE_SYNC, 93); + + uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.JR x%1$d"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + 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->gen_sync(iss::POST_SYNC, 93); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //94: instruction C.ADD + /* instruction 94: C.ADD */ std::tuple __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.ADD"); - - this->gen_sync(iss::PRE_SYNC, 94); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.ADD x%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 94); - 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); + bb->setName("C.ADD"); + + this->gen_sync(iss::PRE_SYNC, 94); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.ADD x%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 94); + 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); } - //95: instruction C.JALR + /* instruction 95: C.JALR */ std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.JALR"); - - this->gen_sync(iss::PRE_SYNC, 95); - - uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.JALR x%1$d"); - ins_fmter % (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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t r_idx_val = 1; - Value* X_r_idx_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)); - 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->gen_sync(iss::POST_SYNC, 95); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.JALR"); + + this->gen_sync(iss::PRE_SYNC, 95); + + uint8_t fld_rs1_val = 0 | (bit_sub<7,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.JALR x%1$d"); + ins_fmter % (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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t r_idx_val = 1; + Value* X_r_idx_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)); + 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->gen_sync(iss::POST_SYNC, 95); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //96: instruction C.EBREAK + /* instruction 96: C.EBREAK */ std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.EBREAK"); - - this->gen_sync(iss::PRE_SYNC, 96); - - ; - 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("C.EBREAK"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 96); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("C.EBREAK"); + + this->gen_sync(iss::PRE_SYNC, 96); + + ; + 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("C.EBREAK"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + this->gen_raise_trap(0, 3); + this->gen_sync(iss::POST_SYNC, 96); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //97: instruction C.SWSP + /* instruction 97: C.SWSP */ std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("C.SWSP"); - - this->gen_sync(iss::PRE_SYNC, 97); - - uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); - uint8_t fld_uimm_val = 0 | (bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("C.SWSP x2+0x%1$05x, x%2$d"); - ins_fmter % (uint64_t)fld_uimm_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); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - uint8_t x2_idx_val = 2; - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 97); - 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); + bb->setName("C.SWSP"); + + this->gen_sync(iss::PRE_SYNC, 97); + + uint8_t fld_rs2_val = 0 | (bit_sub<2,5>(instr)); + uint8_t fld_uimm_val = 0 | (bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("C.SWSP x2+0x%1$05x, x%2$d"); + ins_fmter % (uint64_t)fld_uimm_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); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + uint8_t x2_idx_val = 2; + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 97); + 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); } - //98: instruction DII + /* instruction 98: DII */ std::tuple __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("DII"); - - this->gen_sync(iss::PRE_SYNC, 98); - - ; - 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("DII"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - this->gen_raise_trap(0, 2); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 98); - 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); + bb->setName("DII"); + + this->gen_sync(iss::PRE_SYNC, 98); + + ; + 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("DII"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + this->gen_raise_trap(0, 2); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 98); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); } -/* end generated code */ /**************************************************************************** * end opcode definitions ****************************************************************************/ diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index cc357cc..6186d58 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -179,9 +179,8 @@ private: compile_func op; }; - /* start generated code */ const std::array instr_descr = {{ - /* entries are: valid value, valid mask, function ptr */ + /* entries are: size, valid value, valid mask, function ptr */ /* instruction LWU */ {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, /* instruction LD */ @@ -355,3791 +354,3792 @@ private: /* instruction AMOMAXU.W */ {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, }}; - //0: instruction LWU + + /* instruction definitions */ + /* instruction 0: LWU */ std::tuple __lwu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LWU"); - - this->gen_sync(iss::PRE_SYNC, 0); - - 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("LWU 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, - 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, 0); - 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); + bb->setName("LWU"); + + this->gen_sync(iss::PRE_SYNC, 0); + + 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("LWU 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, + 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, 0); + 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); } - //1: instruction LD + /* instruction 1: LD */ std::tuple __ld(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LD"); - - this->gen_sync(iss::PRE_SYNC, 1); - - 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("LD 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 64/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, 1); - 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); + bb->setName("LD"); + + this->gen_sync(iss::PRE_SYNC, 1); + + 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("LD 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 64/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, 1); + 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); } - //2: instruction SD + /* instruction 2: SD */ std::tuple __sd(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SD"); - - this->gen_sync(iss::PRE_SYNC, 2); - - 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("SD 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 2); - 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); + bb->setName("SD"); + + this->gen_sync(iss::PRE_SYNC, 2); + + 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("SD 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 2); + 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); } - //3: instruction SLLI + /* instruction 3: SLLI */ std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(iss::PRE_SYNC, 3); - - 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("SLLI 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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.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, 3); - 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); + bb->setName("SLLI"); + + this->gen_sync(iss::PRE_SYNC, 3); + + 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("SLLI 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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.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, 3); + 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); } - //4: instruction SRLI + /* instruction 4: SRLI */ std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(iss::PRE_SYNC, 4); - - 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("SRLI 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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.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, 4); - 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); + bb->setName("SRLI"); + + this->gen_sync(iss::PRE_SYNC, 4); + + 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("SRLI 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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.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, 4); + 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); } - //5: instruction SRAI + /* instruction 5: SRAI */ std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(iss::PRE_SYNC, 5); - - 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("SRAI 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 5); - 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); + bb->setName("SRAI"); + + this->gen_sync(iss::PRE_SYNC, 5); + + 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("SRAI 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 5); + 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); } - //6: instruction ADDIW + /* instruction 6: ADDIW */ std::tuple __addiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDIW"); - - this->gen_sync(iss::PRE_SYNC, 6); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 6); - 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); + bb->setName("ADDIW"); + + this->gen_sync(iss::PRE_SYNC, 6); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 6); + 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); } - //7: instruction SLLIW + /* instruction 7: SLLIW */ std::tuple __slliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLIW"); - - this->gen_sync(iss::PRE_SYNC, 7); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 7); - 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); + bb->setName("SLLIW"); + + this->gen_sync(iss::PRE_SYNC, 7); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 7); + 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); } - //8: instruction SRLIW + /* instruction 8: SRLIW */ std::tuple __srliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLIW"); - - this->gen_sync(iss::PRE_SYNC, 8); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 8); - 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); + bb->setName("SRLIW"); + + this->gen_sync(iss::PRE_SYNC, 8); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 8); + 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); } - //9: instruction SRAIW + /* instruction 9: SRAIW */ std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAIW"); - - this->gen_sync(iss::PRE_SYNC, 9); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 9); - 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); + bb->setName("SRAIW"); + + this->gen_sync(iss::PRE_SYNC, 9); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 9); + 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); } - //10: instruction ADDW + /* instruction 10: ADDW */ std::tuple __addw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDW"); - - this->gen_sync(iss::PRE_SYNC, 10); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 10); - 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); + bb->setName("ADDW"); + + this->gen_sync(iss::PRE_SYNC, 10); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 10); + 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); } - //11: instruction SUBW + /* instruction 11: SUBW */ std::tuple __subw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SUBW"); - - this->gen_sync(iss::PRE_SYNC, 11); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 11); - 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); + bb->setName("SUBW"); + + this->gen_sync(iss::PRE_SYNC, 11); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 11); + 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); } - //12: instruction SLLW + /* instruction 12: SLLW */ std::tuple __sllw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLW"); - - this->gen_sync(iss::PRE_SYNC, 12); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 12); - 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); + bb->setName("SLLW"); + + this->gen_sync(iss::PRE_SYNC, 12); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 12); + 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); } - //13: instruction SRLW + /* instruction 13: SRLW */ std::tuple __srlw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLW"); - - this->gen_sync(iss::PRE_SYNC, 13); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 13); - 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); + bb->setName("SRLW"); + + this->gen_sync(iss::PRE_SYNC, 13); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 13); + 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); } - //14: instruction SRAW + /* instruction 14: SRAW */ std::tuple __sraw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAW"); - - this->gen_sync(iss::PRE_SYNC, 14); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 14); - 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); + bb->setName("SRAW"); + + this->gen_sync(iss::PRE_SYNC, 14); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 14); + 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); } - //15: instruction LUI + /* instruction 15: LUI */ std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LUI"); - - this->gen_sync(iss::PRE_SYNC, 15); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 15); - 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); + bb->setName("LUI"); + + this->gen_sync(iss::PRE_SYNC, 15); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 15); + 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); } - //16: instruction AUIPC + /* instruction 16: AUIPC */ std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AUIPC"); - - this->gen_sync(iss::PRE_SYNC, 16); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_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, 16); - 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); + bb->setName("AUIPC"); + + this->gen_sync(iss::PRE_SYNC, 16); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_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, 16); + 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); } - //17: instruction JAL + /* instruction 17: JAL */ std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("JAL"); - - this->gen_sync(iss::PRE_SYNC, 17); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)); - this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - Value* PC_val = this->builder.CreateAdd( - cur_pc_val, - 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, 17); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("JAL"); + + this->gen_sync(iss::PRE_SYNC, 17); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* PC_val = this->builder.CreateAdd( + cur_pc_val, + 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, 17); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //18: instruction JALR + /* instruction 18: JALR */ std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("JALR"); - - this->gen_sync(iss::PRE_SYNC, 18); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - 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, 18); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("JALR"); + + this->gen_sync(iss::PRE_SYNC, 18); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + 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, 18); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //19: instruction BEQ + /* instruction 19: BEQ */ std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BEQ"); - - this->gen_sync(iss::PRE_SYNC, 19); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - this->gen_const(64U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 19); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BEQ"); + + this->gen_sync(iss::PRE_SYNC, 19); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 19); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //20: instruction BNE + /* instruction 20: BNE */ std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BNE"); - - this->gen_sync(iss::PRE_SYNC, 20); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - this->gen_const(64U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 20); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BNE"); + + this->gen_sync(iss::PRE_SYNC, 20); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 20); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //21: instruction BLT + /* instruction 21: BLT */ std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BLT"); - - this->gen_sync(iss::PRE_SYNC, 21); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - this->gen_const(64U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 21); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BLT"); + + this->gen_sync(iss::PRE_SYNC, 21); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 21); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //22: instruction BGE + /* instruction 22: BGE */ std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BGE"); - - this->gen_sync(iss::PRE_SYNC, 22); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - this->gen_const(64U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 22); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BGE"); + + this->gen_sync(iss::PRE_SYNC, 22); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 22); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //23: instruction BLTU + /* instruction 23: BLTU */ std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BLTU"); - - this->gen_sync(iss::PRE_SYNC, 23); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - this->gen_const(64U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 23); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BLTU"); + + this->gen_sync(iss::PRE_SYNC, 23); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 23); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //24: instruction BGEU + /* instruction 24: BGEU */ std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("BGEU"); - - this->gen_sync(iss::PRE_SYNC, 24); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - cur_pc_val, - this->gen_const(64U, fld_imm_val)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->gen_sync(iss::POST_SYNC, 24); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("BGEU"); + + this->gen_sync(iss::PRE_SYNC, 24); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + cur_pc_val, + this->gen_const(64U, fld_imm_val)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->gen_sync(iss::POST_SYNC, 24); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //25: instruction LB + /* instruction 25: LB */ std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LB"); - - this->gen_sync(iss::PRE_SYNC, 25); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 25); - 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); + bb->setName("LB"); + + this->gen_sync(iss::PRE_SYNC, 25); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 25); + 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); } - //26: instruction LH + /* instruction 26: LH */ std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LH"); - - this->gen_sync(iss::PRE_SYNC, 26); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 26); - 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); + bb->setName("LH"); + + this->gen_sync(iss::PRE_SYNC, 26); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 26); + 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); } - //27: instruction LW + /* instruction 27: LW */ std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LW"); - - this->gen_sync(iss::PRE_SYNC, 27); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 27); - 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); + bb->setName("LW"); + + this->gen_sync(iss::PRE_SYNC, 27); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 27); + 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); } - //28: instruction LBU + /* instruction 28: LBU */ std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LBU"); - - this->gen_sync(iss::PRE_SYNC, 28); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 28); - 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); + bb->setName("LBU"); + + this->gen_sync(iss::PRE_SYNC, 28); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 28); + 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); } - //29: instruction LHU + /* instruction 29: LHU */ std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LHU"); - - this->gen_sync(iss::PRE_SYNC, 29); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 29); - 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); + bb->setName("LHU"); + + this->gen_sync(iss::PRE_SYNC, 29); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 29); + 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); } - //30: instruction SB + /* instruction 30: SB */ std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SB"); - - this->gen_sync(iss::PRE_SYNC, 30); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 30); - 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); + bb->setName("SB"); + + this->gen_sync(iss::PRE_SYNC, 30); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 30); + 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); } - //31: instruction SH + /* instruction 31: SH */ std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SH"); - - this->gen_sync(iss::PRE_SYNC, 31); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 31); - 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); + bb->setName("SH"); + + this->gen_sync(iss::PRE_SYNC, 31); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 31); + 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); } - //32: instruction SW + /* instruction 32: SW */ std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SW"); - - this->gen_sync(iss::PRE_SYNC, 32); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 32); - 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); + bb->setName("SW"); + + this->gen_sync(iss::PRE_SYNC, 32); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 32); + 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); } - //33: instruction ADDI + /* instruction 33: ADDI */ std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADDI"); - - this->gen_sync(iss::PRE_SYNC, 33); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 33); - 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); + bb->setName("ADDI"); + + this->gen_sync(iss::PRE_SYNC, 33); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 33); + 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); } - //34: instruction SLTI + /* instruction 34: SLTI */ std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTI"); - - this->gen_sync(iss::PRE_SYNC, 34); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 34); - 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); + bb->setName("SLTI"); + + this->gen_sync(iss::PRE_SYNC, 34); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 34); + 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); } - //35: instruction SLTIU + /* instruction 35: SLTIU */ std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTIU"); - - this->gen_sync(iss::PRE_SYNC, 35); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 35); - 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); + bb->setName("SLTIU"); + + this->gen_sync(iss::PRE_SYNC, 35); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 35); + 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); } - //36: instruction XORI + /* instruction 36: XORI */ std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("XORI"); - - this->gen_sync(iss::PRE_SYNC, 36); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 36); - 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); + bb->setName("XORI"); + + this->gen_sync(iss::PRE_SYNC, 36); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 36); + 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); } - //37: instruction ORI + /* instruction 37: ORI */ std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ORI"); - - this->gen_sync(iss::PRE_SYNC, 37); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 37); - 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); + bb->setName("ORI"); + + this->gen_sync(iss::PRE_SYNC, 37); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 37); + 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); } - //38: instruction ANDI + /* instruction 38: ANDI */ std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ANDI"); - - this->gen_sync(iss::PRE_SYNC, 38); - - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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, 38); - 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); + bb->setName("ANDI"); + + this->gen_sync(iss::PRE_SYNC, 38); + + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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, 38); + 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); } - //39: instruction ADD + /* instruction 39: ADD */ std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ADD"); - - this->gen_sync(iss::PRE_SYNC, 39); - - 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("ADD 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 39); - 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); + bb->setName("ADD"); + + this->gen_sync(iss::PRE_SYNC, 39); + + 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("ADD 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 39); + 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); } - //40: instruction SUB + /* instruction 40: SUB */ std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SUB"); - - this->gen_sync(iss::PRE_SYNC, 40); - - 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("SUB 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 40); - 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); + bb->setName("SUB"); + + this->gen_sync(iss::PRE_SYNC, 40); + + 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("SUB 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 40); + 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); } - //41: instruction SLL + /* instruction 41: SLL */ std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLL"); - - this->gen_sync(iss::PRE_SYNC, 41); - - 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("SLL 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val, 0), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 41); - 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); + bb->setName("SLL"); + + this->gen_sync(iss::PRE_SYNC, 41); + + 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("SLL 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateShl( + this->gen_reg_load(fld_rs1_val, 0), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 41); + 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); } - //42: instruction SLT + /* instruction 42: SLT */ std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLT"); - - this->gen_sync(iss::PRE_SYNC, 42); - - 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("SLT 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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_reg_load(fld_rs2_val, 0), - 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, 42); - 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); + bb->setName("SLT"); + + this->gen_sync(iss::PRE_SYNC, 42); + + 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("SLT 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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_reg_load(fld_rs2_val, 0), + 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, 42); + 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); } - //43: instruction SLTU + /* instruction 43: SLTU */ std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLTU"); - - this->gen_sync(iss::PRE_SYNC, 43); - - 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("SLTU 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - 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( - this->gen_reg_load(fld_rs2_val, 0), - 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, 43); - 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); + bb->setName("SLTU"); + + this->gen_sync(iss::PRE_SYNC, 43); + + 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("SLTU 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + 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( + this->gen_reg_load(fld_rs2_val, 0), + 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, 43); + 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); } - //44: instruction XOR + /* instruction 44: XOR */ std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("XOR"); - - this->gen_sync(iss::PRE_SYNC, 44); - - 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("XOR 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 44); - 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); + bb->setName("XOR"); + + this->gen_sync(iss::PRE_SYNC, 44); + + 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("XOR 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 44); + 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); } - //45: instruction SRL + /* instruction 45: SRL */ std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRL"); - - this->gen_sync(iss::PRE_SYNC, 45); - - 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("SRL 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val, 0), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 45); - 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); + bb->setName("SRL"); + + this->gen_sync(iss::PRE_SYNC, 45); + + 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("SRL 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateLShr( + this->gen_reg_load(fld_rs1_val, 0), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 45); + 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); } - //46: instruction SRA + /* instruction 46: SRA */ std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRA"); - - this->gen_sync(iss::PRE_SYNC, 46); - - 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("SRA 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val, 0), - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 46); - 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); + bb->setName("SRA"); + + this->gen_sync(iss::PRE_SYNC, 46); + + 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("SRA 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder.CreateAShr( + this->gen_reg_load(fld_rs1_val, 0), + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 46); + 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); } - //47: instruction OR + /* instruction 47: OR */ std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("OR"); - - this->gen_sync(iss::PRE_SYNC, 47); - - 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("OR 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 47); - 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); + bb->setName("OR"); + + this->gen_sync(iss::PRE_SYNC, 47); + + 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("OR 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 47); + 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); } - //48: instruction AND + /* instruction 48: AND */ std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AND"); - - this->gen_sync(iss::PRE_SYNC, 48); - - 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("AND 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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_reg_load(fld_rs2_val, 0)); - 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, 48); - 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); + bb->setName("AND"); + + this->gen_sync(iss::PRE_SYNC, 48); + + 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("AND 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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_reg_load(fld_rs2_val, 0)); + 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, 48); + 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); } - //49: instruction FENCE + /* instruction 49: FENCE */ std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("FENCE"); - - this->gen_sync(iss::PRE_SYNC, 49); - - 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_succ_val = 0 | (bit_sub<20,4>(instr)); - uint8_t fld_pred_val = 0 | (bit_sub<24,4>(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("FENCE"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 49); - 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); + bb->setName("FENCE"); + + this->gen_sync(iss::PRE_SYNC, 49); + + 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_succ_val = 0 | (bit_sub<20,4>(instr)); + uint8_t fld_pred_val = 0 | (bit_sub<24,4>(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("FENCE"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 49); + 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); } - //50: instruction FENCE_I + /* instruction 50: FENCE_I */ std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("FENCE_I"); - - this->gen_sync(iss::PRE_SYNC, 50); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_imm_val = 0 | (bit_sub<20,12>(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("FENCE_I"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* FENCE_fencei_val = this->gen_const(64U, fld_imm_val); - this->gen_write_mem( - traits::FENCE, - (uint64_t)1, - this->builder.CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 50); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::FLUSH, nullptr); + bb->setName("FENCE_I"); + + this->gen_sync(iss::PRE_SYNC, 50); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_imm_val = 0 | (bit_sub<20,12>(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("FENCE_I"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* FENCE_fencei_val = this->gen_const(64U, fld_imm_val); + this->gen_write_mem( + traits::FENCE, + (uint64_t)1, + this->builder.CreateZExtOrTrunc(FENCE_fencei_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 50); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::FLUSH, nullptr); } - //51: instruction ECALL + /* instruction 51: ECALL */ std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("ECALL"); - - this->gen_sync(iss::PRE_SYNC, 51); - - ; - 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("ECALL"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - this->gen_raise_trap(0, 11); - this->gen_sync(iss::POST_SYNC, 51); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("ECALL"); + + this->gen_sync(iss::PRE_SYNC, 51); + + ; + 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("ECALL"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + this->gen_raise_trap(0, 11); + this->gen_sync(iss::POST_SYNC, 51); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //52: instruction EBREAK + /* instruction 52: EBREAK */ std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("EBREAK"); - - this->gen_sync(iss::PRE_SYNC, 52); - - ; - 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("EBREAK"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 52); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("EBREAK"); + + this->gen_sync(iss::PRE_SYNC, 52); + + ; + 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("EBREAK"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + this->gen_raise_trap(0, 3); + this->gen_sync(iss::POST_SYNC, 52); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //53: instruction URET + /* instruction 53: URET */ std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("URET"); - - this->gen_sync(iss::PRE_SYNC, 53); - - ; - 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("URET"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - this->gen_leave_trap(0); - this->gen_sync(iss::POST_SYNC, 53); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("URET"); + + this->gen_sync(iss::PRE_SYNC, 53); + + ; + 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("URET"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + this->gen_leave_trap(0); + this->gen_sync(iss::POST_SYNC, 53); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //54: instruction SRET + /* instruction 54: SRET */ std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRET"); - - this->gen_sync(iss::PRE_SYNC, 54); - - ; - 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("SRET"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - this->gen_leave_trap(1); - this->gen_sync(iss::POST_SYNC, 54); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("SRET"); + + this->gen_sync(iss::PRE_SYNC, 54); + + ; + 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("SRET"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + this->gen_leave_trap(1); + this->gen_sync(iss::POST_SYNC, 54); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //55: instruction MRET + /* instruction 55: MRET */ std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("MRET"); - - this->gen_sync(iss::PRE_SYNC, 55); - - ; - 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("MRET"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - this->gen_leave_trap(3); - this->gen_sync(iss::POST_SYNC, 55); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + bb->setName("MRET"); + + this->gen_sync(iss::PRE_SYNC, 55); + + ; + 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("MRET"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + this->gen_leave_trap(3); + this->gen_sync(iss::POST_SYNC, 55); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(iss::vm::BRANCH, nullptr); } - //56: instruction WFI + /* instruction 56: WFI */ std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("WFI"); - - this->gen_sync(iss::PRE_SYNC, 56); - - ; - 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("WFI"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - this->gen_wait(1); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 56); - 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); + bb->setName("WFI"); + + this->gen_sync(iss::PRE_SYNC, 56); + + ; + 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("WFI"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + this->gen_wait(1); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 56); + 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); } - //57: instruction SFENCE.VMA + /* instruction 57: SFENCE.VMA */ std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SFENCE.VMA"); - - this->gen_sync(iss::PRE_SYNC, 57); - - 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("SFENCE.VMA"), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* FENCE_fencevmal_val = this->gen_const(64U, fld_rs1_val); - this->gen_write_mem( - traits::FENCE, - (uint64_t)2, - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 57); - 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); + bb->setName("SFENCE.VMA"); + + this->gen_sync(iss::PRE_SYNC, 57); + + 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("SFENCE.VMA"), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* FENCE_fencevmal_val = this->gen_const(64U, fld_rs1_val); + this->gen_write_mem( + traits::FENCE, + (uint64_t)2, + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 57); + 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); } - //58: instruction CSRRW + /* instruction 58: CSRRW */ std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRW"); - - this->gen_sync(iss::PRE_SYNC, 58); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRW x%1$d, %2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* rs_val_val = this->gen_reg_load(fld_rs1_val, 0); - if(fld_rd_val != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); - 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))); - Value* X_rd_val = csr_val_val; - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 58); - 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); + bb->setName("CSRRW"); + + this->gen_sync(iss::PRE_SYNC, 58); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRW x%1$d, %2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* rs_val_val = this->gen_reg_load(fld_rs1_val, 0); + if(fld_rd_val != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); + 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))); + Value* X_rd_val = csr_val_val; + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 58); + 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); } - //59: instruction CSRRS + /* instruction 59: CSRRS */ std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRS"); - - this->gen_sync(iss::PRE_SYNC, 59); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRS x%1$d, %2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); - 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); - } - if(fld_rs1_val != 0){ - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 59); - 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); + bb->setName("CSRRS"); + + this->gen_sync(iss::PRE_SYNC, 59); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRS x%1$d, %2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); + 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); + } + if(fld_rs1_val != 0){ + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 59); + 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); } - //60: instruction CSRRC + /* instruction 60: CSRRC */ std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRC"); - - this->gen_sync(iss::PRE_SYNC, 60); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRC x%1$d, %2$d, x%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); - 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); - } - if(fld_rs1_val != 0){ - Value* CSR_csr_val = this->builder.CreateAnd( - xrd_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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 60); - 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); + bb->setName("CSRRC"); + + this->gen_sync(iss::PRE_SYNC, 60); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRC x%1$d, %2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* xrd_val = this->gen_read_mem(traits::CSR, fld_csr_val, 64/8); + 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); + } + if(fld_rs1_val != 0){ + Value* CSR_csr_val = this->builder.CreateAnd( + xrd_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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 60); + 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); } - //61: instruction CSRRWI + /* instruction 61: CSRRWI */ std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRWI"); - - this->gen_sync(iss::PRE_SYNC, 61); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRWI x%1$d, %2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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); - } - Value* CSR_csr_val = 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 61); - 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); + bb->setName("CSRRWI"); + + this->gen_sync(iss::PRE_SYNC, 61); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRWI x%1$d, %2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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); + } + Value* CSR_csr_val = 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 61); + 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); } - //62: instruction CSRRSI + /* instruction 62: CSRRSI */ std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRSI"); - - this->gen_sync(iss::PRE_SYNC, 62); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRSI x%1$d, %2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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( - res_val, - 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))); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 62); - 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); + bb->setName("CSRRSI"); + + this->gen_sync(iss::PRE_SYNC, 62); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRSI x%1$d, %2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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( + res_val, + 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))); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 62); + 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); } - //63: instruction CSRRCI + /* instruction 63: CSRRCI */ std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("CSRRCI"); - - this->gen_sync(iss::PRE_SYNC, 63); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); - uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("CSRRCI x%1$d, %2$d, 0x%3$x"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - 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); - } - if(fld_zimm_val != 0){ - Value* CSR_csr_val = this->builder.CreateAnd( - res_val, - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 63); - 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); + bb->setName("CSRRCI"); + + this->gen_sync(iss::PRE_SYNC, 63); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_zimm_val = 0 | (bit_sub<15,5>(instr)); + uint16_t fld_csr_val = 0 | (bit_sub<20,12>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("CSRRCI x%1$d, %2$d, 0x%3$x"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_csr_val % (uint64_t)fld_zimm_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + 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); + } + if(fld_zimm_val != 0){ + Value* CSR_csr_val = this->builder.CreateAnd( + res_val, + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 63); + 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); } - //64: instruction LR.D + /* instruction 64: LR.D */ std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LR.D"); - - this->gen_sync(iss::PRE_SYNC, 64); - - 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_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LR.D x%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* X_rd_val = this->gen_ext( - 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); - Value* RES_offs_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 64); - 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); + bb->setName("LR.D"); + + this->gen_sync(iss::PRE_SYNC, 64); + + 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_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LR.D x%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* X_rd_val = this->gen_ext( + 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); + Value* RES_offs_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 64); + 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); } - //65: instruction SC.D + /* instruction 65: SC.D */ std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SC.D"); - - this->gen_sync(iss::PRE_SYNC, 65); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SC.D 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/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); - 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, - res_val, - this->gen_const(64U, 0)), - bb_then, - bb_else); - 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){ - Value* X_rd_val = this->gen_const(64U, 0); - this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - } - 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.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 65); - 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); + bb->setName("SC.D"); + + this->gen_sync(iss::PRE_SYNC, 65); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SC.D 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/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); + 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, + res_val, + this->gen_const(64U, 0)), + bb_then, + bb_else); + 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){ + Value* X_rd_val = this->gen_const(64U, 0); + this->builder.CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + } + 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.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 65); + 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); } - //66: instruction AMOSWAP.D + /* instruction 66: AMOSWAP.D */ std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOSWAP.D"); - - this->gen_sync(iss::PRE_SYNC, 66); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOSWAP.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_ext( - 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); - } - 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, 66); - 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); + bb->setName("AMOSWAP.D"); + + this->gen_sync(iss::PRE_SYNC, 66); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOSWAP.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + 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); + } + 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, 66); + 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); } - //67: instruction AMOADD.D + /* instruction 67: AMOADD.D */ std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOADD.D"); - - this->gen_sync(iss::PRE_SYNC, 67); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOADD.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 67); - 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); + bb->setName("AMOADD.D"); + + this->gen_sync(iss::PRE_SYNC, 67); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOADD.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 67); + 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); } - //68: instruction AMOXOR.D + /* instruction 68: AMOXOR.D */ std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOXOR.D"); - - this->gen_sync(iss::PRE_SYNC, 68); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOXOR.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 68); - 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); + bb->setName("AMOXOR.D"); + + this->gen_sync(iss::PRE_SYNC, 68); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOXOR.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 68); + 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); } - //69: instruction AMOAND.D + /* instruction 69: AMOAND.D */ std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOAND.D"); - - this->gen_sync(iss::PRE_SYNC, 69); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOAND.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 69); - 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); + bb->setName("AMOAND.D"); + + this->gen_sync(iss::PRE_SYNC, 69); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOAND.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 69); + 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); } - //70: instruction AMOOR.D + /* instruction 70: AMOOR.D */ std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOOR.D"); - - this->gen_sync(iss::PRE_SYNC, 70); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOOR.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 70); - 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); + bb->setName("AMOOR.D"); + + this->gen_sync(iss::PRE_SYNC, 70); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOOR.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 70); + 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); } - //71: instruction AMOMIN.D + /* instruction 71: AMOMIN.D */ std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMIN.D"); - - this->gen_sync(iss::PRE_SYNC, 71); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMIN.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SGT, - this->gen_ext( - res_val, - 64, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, true)), - this->gen_reg_load(fld_rs2_val, 0), - res_val, - 64); - Value* MEM_offs_val = res_val; - 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, 71); - 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); + bb->setName("AMOMIN.D"); + + this->gen_sync(iss::PRE_SYNC, 71); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMIN.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SGT, + this->gen_ext( + res_val, + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->gen_reg_load(fld_rs2_val, 0), + res_val, + 64); + Value* MEM_offs_val = res_val; + 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, 71); + 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); } - //72: instruction AMOMAX.D + /* instruction 72: AMOMAX.D */ std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMAX.D"); - - this->gen_sync(iss::PRE_SYNC, 72); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMAX.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - res_val, - 64, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, true)), - this->gen_reg_load(fld_rs2_val, 0), - res_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 72); - 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); + bb->setName("AMOMAX.D"); + + this->gen_sync(iss::PRE_SYNC, 72); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAX.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + res_val, + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->gen_reg_load(fld_rs2_val, 0), + res_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 72); + 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); } - //73: instruction AMOMINU.D + /* instruction 73: AMOMINU.D */ std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMINU.D"); - - this->gen_sync(iss::PRE_SYNC, 73); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMINU.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res_val, - this->gen_reg_load(fld_rs2_val, 0)), - this->gen_reg_load(fld_rs2_val, 0), - res_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 73); - 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); + bb->setName("AMOMINU.D"); + + this->gen_sync(iss::PRE_SYNC, 73); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMINU.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res_val, + this->gen_reg_load(fld_rs2_val, 0)), + this->gen_reg_load(fld_rs2_val, 0), + res_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 73); + 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); } - //74: instruction AMOMAXU.D + /* instruction 74: AMOMAXU.D */ std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMAXU.D"); - - this->gen_sync(iss::PRE_SYNC, 74); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMAXU.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); - 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - res_val, - this->gen_reg_load(fld_rs2_val, 0)), - this->gen_reg_load(fld_rs2_val, 0), - res_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 74); - 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); + bb->setName("AMOMAXU.D"); + + this->gen_sync(iss::PRE_SYNC, 74); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAXU.D x%1$d, x%2$d, x%3$d (aqu=%a,rel=%rl)"); + 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + res_val, + this->gen_reg_load(fld_rs2_val, 0)), + this->gen_reg_load(fld_rs2_val, 0), + res_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 74); + 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); } - //75: instruction LR.W + /* instruction 75: LR.W */ std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("LR.W"); - - this->gen_sync(iss::PRE_SYNC, 75); - - 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_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("LR.W x%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(fld_rd_val != 0){ - Value* offs_val = this->gen_reg_load(fld_rs1_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); - Value* RES_offs_val = this->gen_ext( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 75); - 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); + bb->setName("LR.W"); + + this->gen_sync(iss::PRE_SYNC, 75); + + 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_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LR.W x%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(fld_rs1_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); + Value* RES_offs_val = this->gen_ext( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 75); + 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); } - //76: instruction SC.W + /* instruction 76: SC.W */ std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SC.W"); - - this->gen_sync(iss::PRE_SYNC, 76); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SC.W 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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - 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( - ICmpInst::ICMP_NE, - res1_val, - this->gen_const(32U, 0)), - bb_then, - bbnext); - 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.CreateBr(bbnext); - bb=bbnext; - this->builder.SetInsertPoint(bb); - if(fld_rd_val != 0){ - Value* X_rd_val = this->gen_choose( - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 76); - 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); + bb->setName("SC.W"); + + this->gen_sync(iss::PRE_SYNC, 76); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SC.W 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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + 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( + ICmpInst::ICMP_NE, + res1_val, + this->gen_const(32U, 0)), + bb_then, + bbnext); + 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.CreateBr(bbnext); + bb=bbnext; + this->builder.SetInsertPoint(bb); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_choose( + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 76); + 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); } - //77: instruction AMOSWAP.W + /* instruction 77: AMOSWAP.W */ std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOSWAP.W"); - - this->gen_sync(iss::PRE_SYNC, 77); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOSWAP.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - 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); - } - 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, 77); - 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); + bb->setName("AMOSWAP.W"); + + this->gen_sync(iss::PRE_SYNC, 77); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOSWAP.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + 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); + } + 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, 77); + 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); } - //78: instruction AMOADD.W + /* instruction 78: AMOADD.W */ std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOADD.W"); - - this->gen_sync(iss::PRE_SYNC, 78); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOADD.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 78); - 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); + bb->setName("AMOADD.W"); + + this->gen_sync(iss::PRE_SYNC, 78); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOADD.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 78); + 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); } - //79: instruction AMOXOR.W + /* instruction 79: AMOXOR.W */ std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOXOR.W"); - - this->gen_sync(iss::PRE_SYNC, 79); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOXOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 79); - 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); + bb->setName("AMOXOR.W"); + + this->gen_sync(iss::PRE_SYNC, 79); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOXOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 79); + 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); } - //80: instruction AMOAND.W + /* instruction 80: AMOAND.W */ std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOAND.W"); - - this->gen_sync(iss::PRE_SYNC, 80); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOAND.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 80); - 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); + bb->setName("AMOAND.W"); + + this->gen_sync(iss::PRE_SYNC, 80); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOAND.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 80); + 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); } - //81: instruction AMOOR.W + /* instruction 81: AMOOR.W */ std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOOR.W"); - - this->gen_sync(iss::PRE_SYNC, 81); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 81); - 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); + bb->setName("AMOOR.W"); + + this->gen_sync(iss::PRE_SYNC, 81); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 81); + 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); } - //82: instruction AMOMIN.W + /* instruction 82: AMOMIN.W */ std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMIN.W"); - - this->gen_sync(iss::PRE_SYNC, 82); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMIN.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SGT, - this->gen_ext( - res1_val, - 64, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, true)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 82); - 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); + bb->setName("AMOMIN.W"); + + this->gen_sync(iss::PRE_SYNC, 82); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMIN.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SGT, + this->gen_ext( + res1_val, + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 82); + 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); } - //83: instruction AMOMAX.W + /* instruction 83: AMOMAX.W */ std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMAX.W"); - - this->gen_sync(iss::PRE_SYNC, 83); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMAX.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - res1_val, - 64, true), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, true)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 83); - 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); + bb->setName("AMOMAX.W"); + + this->gen_sync(iss::PRE_SYNC, 83); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAX.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + res1_val, + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 83); + 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); } - //84: instruction AMOMINU.W + /* instruction 84: AMOMINU.W */ std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMINU.W"); - - this->gen_sync(iss::PRE_SYNC, 84); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMINU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res1_val, - this->gen_reg_load(fld_rs2_val, 0)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 84); - 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); + bb->setName("AMOMINU.W"); + + this->gen_sync(iss::PRE_SYNC, 84); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMINU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res1_val, + this->gen_reg_load(fld_rs2_val, 0)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 84); + 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); } - //85: instruction AMOMAXU.W + /* instruction 85: AMOMAXU.W */ std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("AMOMAXU.W"); - - this->gen_sync(iss::PRE_SYNC, 85); - - 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)); - uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); - uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("AMOMAXU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - 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); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_ext( - res1_val, - 64, false), - this->gen_ext( - this->gen_reg_load(fld_rs2_val, 0), - 64, false)), - this->gen_reg_load(fld_rs2_val, 0), - res1_val, - 64); - 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->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 85); - 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); + bb->setName("AMOMAXU.W"); + + this->gen_sync(iss::PRE_SYNC, 85); + + 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)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAXU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_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); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + 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); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + res1_val, + 64, false), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, false)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + 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->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC, 85); + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); } -/* end generated code */ /**************************************************************************** * end opcode definitions ****************************************************************************/