From a576fdf8e556505caeee779d9518cc0807c887ed Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 19 Nov 2018 10:45:50 +0100 Subject: [PATCH 1/7] Cleanup of templates --- riscv/gen_input/RV32IBase.core_desc | 14 +-- riscv/gen_input/minres_rv.core_desc | 2 - riscv/gen_input/templates/incl-CORENAME.h.gtl | 102 ++++++++--------- .../gen_input/templates/src-CORENAME.cpp.gtl | 81 +++++++------- .../templates/vm-vm_CORENAME.cpp.gtl | 104 +++++++++--------- riscv/gen_input/templates/vm_riscv.in.cpp | 35 ++++-- 6 files changed, 173 insertions(+), 165 deletions(-) diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32IBase.core_desc index c768d8f..123e1d1 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32IBase.core_desc @@ -1,8 +1,6 @@ InsructionSet RV32IBase { constants { XLEN, - PCLEN, - XLEN_BIT_MASK:=0x1f, fence:=0, fencei:=1, fencevmal:=2, @@ -16,7 +14,7 @@ InsructionSet RV32IBase { registers { [31:0] X[XLEN], PC[XLEN](is_pc), - alias ZERO[XLEN] is X[0] + alias ZERO[XLEN] is X[0] } instructions { @@ -197,7 +195,7 @@ InsructionSet RV32IBase { SLL { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; - if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&XLEN_BIT_MASK); + if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&(XLEN-1)); } SLT { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; @@ -217,12 +215,12 @@ InsructionSet RV32IBase { SRL { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; - if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&XLEN_BIT_MASK); + if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&(XLEN-1)); } SRA { encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; - if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&XLEN_BIT_MASK); + if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&(XLEN-1)); } OR { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; @@ -279,8 +277,8 @@ InsructionSet RV32IBase { val csr_val[XLEN] <= CSR[csr]; CSR[csr] <= rs_val; // make sure Xrd is updated once CSR write succeeds - X[rd] <= csr_val; - } else { + X[rd] <= csr_val; + } else { CSR[csr] <= rs_val; } } diff --git a/riscv/gen_input/minres_rv.core_desc b/riscv/gen_input/minres_rv.core_desc index c0cb5f2..ca9301d 100644 --- a/riscv/gen_input/minres_rv.core_desc +++ b/riscv/gen_input/minres_rv.core_desc @@ -9,7 +9,6 @@ import "RV64IBase.core_desc" import "RV64A.core_desc" Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { - template:"vm_riscv.in.cpp"; constants { XLEN:=32; PCLEN:=32; @@ -36,7 +35,6 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32 Core RV64IA provides RV64IBase, RV64A, RV32A { - template:"vm_riscv.in.cpp"; constants { XLEN:=64; PCLEN:=64; diff --git a/riscv/gen_input/templates/incl-CORENAME.h.gtl b/riscv/gen_input/templates/incl-CORENAME.h.gtl index 7c6aad2..95052f8 100644 --- a/riscv/gen_input/templates/incl-CORENAME.h.gtl +++ b/riscv/gen_input/templates/incl-CORENAME.h.gtl @@ -1,34 +1,35 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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 @@ -39,18 +40,17 @@ def getTypeSize(size){ #ifndef _${coreDef.name.toUpperCase()}_H_ #define _${coreDef.name.toUpperCase()}_H_ +#include +#include #include #include -#include -#include namespace iss { namespace arch { struct ${coreDef.name.toLowerCase()}; -template<> -struct traits<${coreDef.name.toLowerCase()}> { +template <> struct traits<${coreDef.name.toLowerCase()}> { constexpr static char const* const core_type = "${coreDef.name}"; @@ -87,21 +87,21 @@ struct traits<${coreDef.name.toLowerCase()}> { 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]; - } + static constexpr std::array ${coreDef.name}_reg_size{ + {${regSizes.join(",")}}}; - 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 constexpr unsigned reg_bit_width(unsigned r) { return ${coreDef.name}_reg_size[r]; } + + static constexpr std::array ${coreDef.name}_reg_byte_offset{ + {${regOffsets.join(",")}}}; + + constexpr static unsigned reg_byte_offset(unsigned r) { 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 sreg_flag_e { FLAGS }; - enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}}; + enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} }; }; struct ${coreDef.name.toLowerCase()}: public arch_if { @@ -126,12 +126,13 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { /// deprecated void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; - uint64_t get_icount() { return reg.icount;} + inline uint64_t get_icount() { return reg.icount; } + + inline bool should_stop() { return interrupt_sim; } 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){ + 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); @@ -141,8 +142,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if { virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - inline - uint32_t get_last_branch(){return reg.last_branch;} + inline uint32_t get_last_branch() { return reg.last_branch; } protected: struct ${coreDef.name}_regs {<% diff --git a/riscv/gen_input/templates/src-CORENAME.cpp.gtl b/riscv/gen_input/templates/src-CORENAME.cpp.gtl index cafe82c..58d0342 100644 --- a/riscv/gen_input/templates/src-CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/src-CORENAME.cpp.gtl @@ -1,34 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 2017,2018 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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 @@ -43,30 +43,33 @@ extern "C" { #ifdef __cplusplus } #endif -#include #include #include +#include using namespace iss::arch; +constexpr std::array iss::arch::traits::${coreDef.name}_reg_size; +constexpr std::array iss::arch::traits::${coreDef.name}_reg_byte_offset; + ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { - reg.icount=0; + reg.icount = 0; + reg.machine_state = 0x3; } -${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}(){ +${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; } 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)); + 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; + reg.machine_state=0x3; } -uint8_t* ${coreDef.name.toLowerCase()}::get_regs_base_ptr(){ - return reinterpret_cast(®); -} +uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { return reinterpret_cast(®); } ${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(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 index b84bae6..b56fad8 100644 --- a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -1,38 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 -// -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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 #include @@ -44,12 +40,12 @@ #include -#include #include +#include namespace iss { namespace vm { -namespace fp_impl{ +namespace fp_impl { void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -73,7 +69,7 @@ public: void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } - target_adapter_if *accquire_target_adapter(server_if *srv) { + target_adapter_if *accquire_target_adapter(server_if *srv) override { 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()); @@ -87,7 +83,7 @@ protected: return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); } - void setup_module(llvm::Module* m) override { + void setup_module(llvm::Module *m) override { super::setup_module(m); vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } @@ -117,7 +113,7 @@ protected: 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->get_type(traits::XLEN)); this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } @@ -136,9 +132,9 @@ protected: std::array lut_00, lut_01, lut_10; std::array lut_11; - std::array qlut; + std::array qlut; - std::array lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; + 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) { @@ -248,7 +244,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); try { - uint8_t *const data = (uint8_t *)&insn; + auto *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); @@ -282,7 +278,8 @@ template void vm_impl::gen_leave_behavior(llvm::BasicBlock template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { @@ -292,7 +289,8 @@ template void vm_impl::gen_leave_trap(unsigned 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); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_wait(unsigned type) { @@ -305,11 +303,10 @@ template void vm_impl::gen_wait(unsigned type) { template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - 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.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); + 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); @@ -327,10 +324,9 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl 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; + auto ret = new ${coreDef.name.toLowerCase()}::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); } } // namespace iss diff --git a/riscv/gen_input/templates/vm_riscv.in.cpp b/riscv/gen_input/templates/vm_riscv.in.cpp index d86bf14..46a9529 100644 --- a/riscv/gen_input/templates/vm_riscv.in.cpp +++ b/riscv/gen_input/templates/vm_riscv.in.cpp @@ -44,6 +44,12 @@ #include namespace iss { +namespace vm { +namespace fp_impl { +void add_fp_functions_2_module(llvm::Module *, unsigned); +} +} + namespace CORE_DEF_NAME { using namespace iss::arch; using namespace llvm; @@ -63,7 +69,7 @@ public: void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } - target_adapter_if *accquire_target_adapter(server_if *srv) { + target_adapter_if *accquire_target_adapter(server_if *srv) override { 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()); @@ -77,8 +83,12 @@ protected: 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 { + void setup_module(llvm::Module *m) override { + super::setup_module(m); + vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + } + + inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } @@ -225,7 +235,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); try { - uint8_t *const data = (uint8_t *)&insn; + auto *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); @@ -242,7 +252,6 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, } 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]; @@ -260,6 +269,8 @@ template void vm_impl::gen_leave_behavior(llvm::BasicBlock template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { @@ -269,6 +280,8 @@ template void vm_impl::gen_leave_trap(unsigned 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); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_wait(unsigned type) { @@ -281,6 +294,8 @@ template void vm_impl::gen_wait(unsigned type) { template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); 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); @@ -298,12 +313,10 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl } // namespace CORE_DEF_NAME -template <> -std::unique_ptr create(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { - std::unique_ptr> ret = - std::make_unique>(*core, dump); - if (port != 0) debugger::server::run_server(ret.get(), port); - return ret; +template <> std::unique_ptr create(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { + auto ret = new CORE_DEF_NAME::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); } } // namespace iss From 58a446e6bcc3421e1a8e3a5d5445e83bfa01388e Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 19 Nov 2018 20:39:11 +0100 Subject: [PATCH 2/7] Refoctored to to move SystemC wrapper into riscv library --- CMakeLists.txt | 1 - platform/CMakeLists.txt | 1 - platform/src/CMakeLists.txt | 1 - riscv.sc/CMakeLists.txt | 93 ------------------- {riscv.sc => riscv}/incl/sysc/core_complex.h | 0 riscv/src/CMakeLists.txt | 16 ++++ .../src => riscv/src/sysc}/core_complex.cpp | 0 7 files changed, 16 insertions(+), 96 deletions(-) delete mode 100644 riscv.sc/CMakeLists.txt rename {riscv.sc => riscv}/incl/sysc/core_complex.h (100%) rename {riscv.sc/src => riscv/src/sysc}/core_complex.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a80cb5..29243a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,7 +112,6 @@ add_subdirectory(sc-components) add_subdirectory(softfloat) GET_DIRECTORY_PROPERTY(SOFTFLOAT_INCLUDE_DIRS DIRECTORY softfloat DEFINITION SOFTFLOAT_INCLUDE_DIRS) add_subdirectory(riscv) -add_subdirectory(riscv.sc) add_subdirectory(platform) message(STATUS "Build Type: ${CMAKE_BUILD_TYPE}") diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 43054c9..a96449f 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -25,7 +25,6 @@ endif() add_dependent_subproject(dbt-core) add_dependent_subproject(sc-components) add_dependent_subproject(riscv) -add_dependent_subproject(riscv.sc) include_directories( ${PROJECT_SOURCE_DIR}/../external/elfio diff --git a/platform/src/CMakeLists.txt b/platform/src/CMakeLists.txt index b5b9a04..381aa6c 100644 --- a/platform/src/CMakeLists.txt +++ b/platform/src/CMakeLists.txt @@ -61,7 +61,6 @@ add_executable(${APPLICATION_NAME} ${APP_SOURCES}) target_include_directories(${APPLICATION_NAME} SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS}) # Links the target exe against the libraries target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME}) -target_link_libraries(${APPLICATION_NAME} riscv.sc) target_link_libraries(${APPLICATION_NAME} riscv) target_link_libraries(${APPLICATION_NAME} dbt-core) target_link_libraries(${APPLICATION_NAME} softfloat) diff --git a/riscv.sc/CMakeLists.txt b/riscv.sc/CMakeLists.txt deleted file mode 100644 index 73afb67..0000000 --- a/riscv.sc/CMakeLists.txt +++ /dev/null @@ -1,93 +0,0 @@ -cmake_minimum_required(VERSION 3.3) -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) # main (top) cmake dir - -# CMake useful variables -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") - -# Set the name of your project here -project("riscv.sc") - -include(Common) - -# check that we have averything we need -if(!SystemC_FOUND) - message( FATAL_ERROR "SystemC library not found." ) -endif() - -if(!CCI_FOUND) - message( FATAL_ERROR "SystemC CCI library not found." ) -endif() - -add_definitions(-DWITH_SYSTEMC) -include_directories(${SystemC_INCLUDE_DIRS}) -link_directories(${SystemC_LIBRARY_DIRS}) - -include_directories(${CCI_INCLUDE_DIRS}) -link_directories(${CCI_LIBRARY_DIRS}) - -if(SCV_FOUND) - add_definitions(-DWITH_SCV) - include_directories(${SCV_INCLUDE_DIRS}) - link_directories(${SCV_LIBRARY_DIRS}) -endif() - -# This sets the include directory for the reference project. This is the -I flag in gcc. -include_directories( - ${PROJECT_SOURCE_DIR}/incl - ${LLVM_INCLUDE_DIRS} -) - -add_dependent_subproject(dbt-core) -add_dependent_subproject(sc-components) -add_dependent_subproject(riscv) - -include_directories( - ${PROJECT_SOURCE_DIR}/incl - ${PROJECT_SOURCE_DIR}/../riscv/incl - ${PROJECT_SOURCE_DIR}/../external/elfio - ${PROJECT_SOURCE_DIR}/../external/libGIS - ${Boost_INCLUDE_DIRS} -) - - -# Mac needed variables (adapt for your needs - http://www.cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH) -set(CMAKE_MACOSX_RPATH ON) -set(CMAKE_SKIP_BUILD_RPATH FALSE) -set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) -set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -## the following setting needs to be consistent with the library -#add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS) - -# library files -FILE(GLOB RiscVSCHeaders *.h */*.h) - -set(LIB_HEADERS ${RiscVSCHeaders} ) -set(LIB_SOURCES src/core_complex.cpp ) - -# Define two variables in order not to repeat ourselves. -set(LIBRARY_NAME riscv.sc) - -# Define the library -add_library(${LIBRARY_NAME} ${LIB_SOURCES}) - -set_target_properties(${LIBRARY_NAME} PROPERTIES - VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. - FRAMEWORK FALSE - PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers -) - -# -# SYSTEM PACKAGING (RPM, TGZ, ...) -# _____________________________________________________________________________ - -#include(CPackConfig) - -# -# CMAKE PACKAGING (for other CMake projects to use this one easily) -# _____________________________________________________________________________ - -#include(PackageConfigurator) \ No newline at end of file diff --git a/riscv.sc/incl/sysc/core_complex.h b/riscv/incl/sysc/core_complex.h similarity index 100% rename from riscv.sc/incl/sysc/core_complex.h rename to riscv/incl/sysc/core_complex.h diff --git a/riscv/src/CMakeLists.txt b/riscv/src/CMakeLists.txt index c10d28f..b16dbc1 100644 --- a/riscv/src/CMakeLists.txt +++ b/riscv/src/CMakeLists.txt @@ -12,6 +12,10 @@ set(LIB_SOURCES plugin/instruction_count.cpp plugin/cycle_estimate.cpp) +if(SystemC_FOUND) + set(LIB_SOURCES ${LIB_SOURCES} sysc/core_complex.cpp) +endif() + set(APP_HEADERS ) set(APP_SOURCES main.cpp) @@ -28,6 +32,18 @@ set_target_properties(${LIBRARY_NAME} PROPERTIES PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers ) +if(SystemC_FOUND) + add_definitions(-DWITH_SYSTEMC) + include_directories(${SystemC_INCLUDE_DIRS}) + + include_directories(${CCI_INCLUDE_DIRS}) + + if(SCV_FOUND) + add_definitions(-DWITH_SCV) + include_directories(${SCV_INCLUDE_DIRS}) + endif() +endif() + # This is a make target, so you can do a "make riscv-sc" set(APPLICATION_NAME riscv-sim) diff --git a/riscv.sc/src/core_complex.cpp b/riscv/src/sysc/core_complex.cpp similarity index 100% rename from riscv.sc/src/core_complex.cpp rename to riscv/src/sysc/core_complex.cpp From df03e90181776897b0f7f8de21bf85a54f05243d Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Thu, 22 Nov 2018 20:28:36 +0100 Subject: [PATCH 3/7] Adapted to vm_base refactoring (move into llvm package) --- dbt-core | 2 +- platform/src/sc_main.cpp | 2 +- .../templates/vm-vm_CORENAME.cpp.gtl | 2 +- riscv/gen_input/templates/vm_riscv.in.cpp | 2 +- riscv/src/internal/fp_functions.cpp | 2 +- riscv/src/internal/vm_rv32gc.cpp | 1505 +++++++++-------- riscv/src/internal/vm_rv32imac.cpp | 423 ++--- riscv/src/internal/vm_rv64ia.cpp | 749 ++++---- riscv/src/main.cpp | 2 +- 9 files changed, 1346 insertions(+), 1343 deletions(-) diff --git a/dbt-core b/dbt-core index d73fee6..0b499d2 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit d73fee68dd164c016721ae76d1538136513e6b37 +Subproject commit 0b499d216a2835015b889180ca5108b2daaed9b9 diff --git a/platform/src/sc_main.cpp b/platform/src/sc_main.cpp index d9d60e3..27c058a 100644 --- a/platform/src/sc_main.cpp +++ b/platform/src/sc_main.cpp @@ -32,7 +32,6 @@ #include "CLIParser.h" #include -#include #include #include @@ -45,6 +44,7 @@ #include #include +#include #include #include diff --git a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl index b56fad8..c6f8d37 100644 --- a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/riscv/gen_input/templates/vm_riscv.in.cpp b/riscv/gen_input/templates/vm_riscv.in.cpp index 46a9529..cead0af 100644 --- a/riscv/gen_input/templates/vm_riscv.in.cpp +++ b/riscv/gen_input/templates/vm_riscv.in.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/riscv/src/internal/fp_functions.cpp b/riscv/src/internal/fp_functions.cpp index 34c1bac..4c53f6f 100644 --- a/riscv/src/internal/fp_functions.cpp +++ b/riscv/src/internal/fp_functions.cpp @@ -33,7 +33,7 @@ //////////////////////////////////////////////////////////////////////////////// #include -#include +#include extern "C" { #include diff --git a/riscv/src/internal/vm_rv32gc.cpp b/riscv/src/internal/vm_rv32gc.cpp index bd78915..e6d195d 100644 --- a/riscv/src/internal/vm_rv32gc.cpp +++ b/riscv/src/internal/vm_rv32gc.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -58,10 +58,11 @@ namespace rv32gc { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; +using namespace iss::vm::llvm; -template class vm_impl : public vm::vm_base { +template class vm_impl : public vm_base { public: - using super = typename vm::vm_base; + using super = typename iss::vm::llvm::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; @@ -75,31 +76,31 @@ public: 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; + if (vm_base::tgt_adapter == nullptr) + vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); + return vm_base::tgt_adapter; } protected: - using vm::vm_base::get_reg_ptr; + using vm_base::get_reg_ptr; - template inline llvm::ConstantInt *size(T type) { - return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); + template inline ConstantInt *size(T type) { + return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); } - void setup_module(llvm::Module* m) override { + void setup_module(Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } - inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { + inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } - std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, - llvm::BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, + BasicBlock *) override; - void gen_leave_behavior(llvm::BasicBlock *leave_blk) override; + void gen_leave_behavior(BasicBlock *leave_blk) override; void gen_raise_trap(uint16_t trap_id, uint16_t cause); @@ -107,16 +108,16 @@ protected: void gen_wait(unsigned type); - void gen_trap_behavior(llvm::BasicBlock *) override; + void gen_trap_behavior(BasicBlock *) override; - void gen_trap_check(llvm::BasicBlock *bb); + void gen_trap_check(BasicBlock *bb); - inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { + inline 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), + 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); } @@ -128,9 +129,9 @@ protected: 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, + using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, code_word_t instr, - llvm::BasicBlock *bb); + BasicBlock *bb); std::array lut; std::array lut_00, lut_01, lut_10; @@ -512,7 +513,7 @@ private: /* instruction definitions */ /* instruction 0: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LUI"); this->gen_sync(iss::PRE_SYNC, 0); @@ -523,7 +524,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -540,13 +541,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 1: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AUIPC"); this->gen_sync(iss::PRE_SYNC, 1); @@ -557,7 +558,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -578,13 +579,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 2: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JAL"); this->gen_sync(iss::PRE_SYNC, 2); @@ -595,7 +596,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -622,11 +623,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 2); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 3: JALR */ - std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); this->gen_sync(iss::PRE_SYNC, 3); @@ -638,7 +639,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -658,9 +659,9 @@ private: new_pc_val, this->gen_const(32U, 0x1)); { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -693,11 +694,11 @@ private: this->builder.SetInsertPoint(bb); this->gen_sync(iss::POST_SYNC, 3); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 4: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); this->gen_sync(iss::PRE_SYNC, 4); @@ -709,7 +710,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -739,11 +740,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 4); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 5: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); this->gen_sync(iss::PRE_SYNC, 5); @@ -755,7 +756,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -785,11 +786,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 5); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 6: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); this->gen_sync(iss::PRE_SYNC, 6); @@ -801,7 +802,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -835,11 +836,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 6); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 7: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); this->gen_sync(iss::PRE_SYNC, 7); @@ -851,7 +852,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -885,11 +886,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 7); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 8: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); this->gen_sync(iss::PRE_SYNC, 8); @@ -901,7 +902,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -931,11 +932,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 8); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 9: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); this->gen_sync(iss::PRE_SYNC, 9); @@ -947,7 +948,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -977,11 +978,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 9); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 10: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); this->gen_sync(iss::PRE_SYNC, 10); @@ -993,7 +994,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1018,13 +1019,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 11: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); this->gen_sync(iss::PRE_SYNC, 11); @@ -1036,7 +1037,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1061,13 +1062,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 12: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); this->gen_sync(iss::PRE_SYNC, 12); @@ -1079,7 +1080,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1104,13 +1105,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 13: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); this->gen_sync(iss::PRE_SYNC, 13); @@ -1122,7 +1123,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1147,13 +1148,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 14: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); this->gen_sync(iss::PRE_SYNC, 14); @@ -1165,7 +1166,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1190,13 +1191,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 15: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); this->gen_sync(iss::PRE_SYNC, 15); @@ -1208,7 +1209,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1231,13 +1232,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 16: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); this->gen_sync(iss::PRE_SYNC, 16); @@ -1249,7 +1250,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1272,13 +1273,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 17: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); this->gen_sync(iss::PRE_SYNC, 17); @@ -1290,7 +1291,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1313,13 +1314,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 18: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); this->gen_sync(iss::PRE_SYNC, 18); @@ -1331,7 +1332,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1352,13 +1353,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 19: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); this->gen_sync(iss::PRE_SYNC, 19); @@ -1370,7 +1371,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1396,13 +1397,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 20: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); this->gen_sync(iss::PRE_SYNC, 20); @@ -1414,7 +1415,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1439,13 +1440,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 21: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); this->gen_sync(iss::PRE_SYNC, 21); @@ -1457,7 +1458,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1476,13 +1477,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 22: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); this->gen_sync(iss::PRE_SYNC, 22); @@ -1494,7 +1495,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1513,13 +1514,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 23: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); this->gen_sync(iss::PRE_SYNC, 23); @@ -1531,7 +1532,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1550,13 +1551,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 24: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); this->gen_sync(iss::PRE_SYNC, 24); @@ -1568,7 +1569,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1591,13 +1592,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 25: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); this->gen_sync(iss::PRE_SYNC, 25); @@ -1609,7 +1610,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1632,13 +1633,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 26: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); this->gen_sync(iss::PRE_SYNC, 26); @@ -1650,7 +1651,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1673,13 +1674,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 27: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); this->gen_sync(iss::PRE_SYNC, 27); @@ -1691,7 +1692,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1710,13 +1711,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 28: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); this->gen_sync(iss::PRE_SYNC, 28); @@ -1728,7 +1729,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1747,13 +1748,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 29: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); this->gen_sync(iss::PRE_SYNC, 29); @@ -1765,7 +1766,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1786,13 +1787,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 30: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); this->gen_sync(iss::PRE_SYNC, 30); @@ -1804,7 +1805,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1832,13 +1833,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 31: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); this->gen_sync(iss::PRE_SYNC, 31); @@ -1850,7 +1851,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1880,13 +1881,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 32: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); this->gen_sync(iss::PRE_SYNC, 32); @@ -1898,7 +1899,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1917,13 +1918,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 33: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); this->gen_sync(iss::PRE_SYNC, 33); @@ -1935,7 +1936,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1956,13 +1957,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 34: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); this->gen_sync(iss::PRE_SYNC, 34); @@ -1974,7 +1975,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1995,13 +1996,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 35: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); this->gen_sync(iss::PRE_SYNC, 35); @@ -2013,7 +2014,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2032,13 +2033,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 36: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); this->gen_sync(iss::PRE_SYNC, 36); @@ -2050,7 +2051,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2069,13 +2070,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 37: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); this->gen_sync(iss::PRE_SYNC, 37); @@ -2086,7 +2087,7 @@ private: uint8_t fld_pred_val = ((bit_sub<24,4>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("FENCE"), @@ -2108,13 +2109,13 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 38: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); this->gen_sync(iss::PRE_SYNC, 38); @@ -2124,7 +2125,7 @@ private: uint16_t fld_imm_val = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("FENCE_I"), @@ -2144,18 +2145,18 @@ private: 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); + return std::make_tuple(FLUSH, nullptr); } /* instruction 39: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("ECALL"), @@ -2169,18 +2170,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 40: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("EBREAK"), @@ -2194,18 +2195,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 41: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("URET"), @@ -2219,18 +2220,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 42: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("SRET"), @@ -2244,18 +2245,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 43: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("MRET"), @@ -2269,18 +2270,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 44: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("WFI"), @@ -2294,13 +2295,13 @@ private: 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 45: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); this->gen_sync(iss::PRE_SYNC, 45); @@ -2309,7 +2310,7 @@ private: uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("SFENCE.VMA"), @@ -2332,13 +2333,13 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 46: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); this->gen_sync(iss::PRE_SYNC, 46); @@ -2350,7 +2351,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2380,13 +2381,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 47: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); this->gen_sync(iss::PRE_SYNC, 47); @@ -2398,7 +2399,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2426,13 +2427,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 48: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); this->gen_sync(iss::PRE_SYNC, 48); @@ -2444,7 +2445,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2472,13 +2473,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 49: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); this->gen_sync(iss::PRE_SYNC, 49); @@ -2490,7 +2491,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2515,13 +2516,13 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 50: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); this->gen_sync(iss::PRE_SYNC, 50); @@ -2533,7 +2534,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2563,13 +2564,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 51: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); this->gen_sync(iss::PRE_SYNC, 51); @@ -2581,7 +2582,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2611,13 +2612,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 52: MUL */ - std::tuple __mul(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MUL"); this->gen_sync(iss::PRE_SYNC, 52); @@ -2629,7 +2630,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2658,13 +2659,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 53: MULH */ - std::tuple __mulh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULH"); this->gen_sync(iss::PRE_SYNC, 53); @@ -2676,7 +2677,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2707,13 +2708,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 54: MULHSU */ - std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHSU"); this->gen_sync(iss::PRE_SYNC, 54); @@ -2725,7 +2726,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2756,13 +2757,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 55: MULHU */ - std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHU"); this->gen_sync(iss::PRE_SYNC, 55); @@ -2774,7 +2775,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2805,13 +2806,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 56: DIV */ - std::tuple __div(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIV"); this->gen_sync(iss::PRE_SYNC, 56); @@ -2823,7 +2824,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2836,9 +2837,9 @@ private: 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -2851,9 +2852,9 @@ private: uint32_t M1_val = - 1; uint32_t MMIN_val = - 1 << 32 - 1; { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, @@ -2868,9 +2869,9 @@ private: this->builder.SetInsertPoint(bb_then); { { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, @@ -2934,13 +2935,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 57: DIVU */ - std::tuple __divu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVU"); this->gen_sync(iss::PRE_SYNC, 57); @@ -2952,7 +2953,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2965,9 +2966,9 @@ private: 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3001,13 +3002,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 58: REM */ - std::tuple __rem(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REM"); this->gen_sync(iss::PRE_SYNC, 58); @@ -3019,7 +3020,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3032,9 +3033,9 @@ private: 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3047,9 +3048,9 @@ private: uint32_t M1_val = - 1; uint32_t MMIN_val = - 1 << 32 - 1; { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, @@ -3064,9 +3065,9 @@ private: this->builder.SetInsertPoint(bb_then); { { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, @@ -3134,13 +3135,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 59: REMU */ - std::tuple __remu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMU"); this->gen_sync(iss::PRE_SYNC, 59); @@ -3152,7 +3153,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3165,9 +3166,9 @@ private: 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3201,13 +3202,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 60: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); this->gen_sync(iss::PRE_SYNC, 60); @@ -3220,7 +3221,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3249,13 +3250,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 61: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); this->gen_sync(iss::PRE_SYNC, 61); @@ -3269,7 +3270,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3283,8 +3284,8 @@ private: Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3317,13 +3318,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 62: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); this->gen_sync(iss::PRE_SYNC, 62); @@ -3337,7 +3338,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3363,13 +3364,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 63: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); this->gen_sync(iss::PRE_SYNC, 63); @@ -3383,7 +3384,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3413,13 +3414,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 64: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); this->gen_sync(iss::PRE_SYNC, 64); @@ -3433,7 +3434,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3463,13 +3464,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 65: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); this->gen_sync(iss::PRE_SYNC, 65); @@ -3483,7 +3484,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3513,13 +3514,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 66: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); this->gen_sync(iss::PRE_SYNC, 66); @@ -3533,7 +3534,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3563,13 +3564,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 67: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); this->gen_sync(iss::PRE_SYNC, 67); @@ -3583,7 +3584,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3622,13 +3623,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 68: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); this->gen_sync(iss::PRE_SYNC, 68); @@ -3642,7 +3643,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3681,13 +3682,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 69: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); this->gen_sync(iss::PRE_SYNC, 69); @@ -3701,7 +3702,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3736,13 +3737,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 70: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); this->gen_sync(iss::PRE_SYNC, 70); @@ -3756,7 +3757,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3791,13 +3792,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 71: C.ADDI4SPN */ - std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI4SPN"); this->gen_sync(iss::PRE_SYNC, 71); @@ -3808,7 +3809,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3828,13 +3829,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 72: C.LW */ - std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LW"); this->gen_sync(iss::PRE_SYNC, 72); @@ -3846,7 +3847,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3864,13 +3865,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 73: C.SW */ - std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SW"); this->gen_sync(iss::PRE_SYNC, 73); @@ -3882,7 +3883,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3903,13 +3904,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 74: C.ADDI */ - std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI"); this->gen_sync(iss::PRE_SYNC, 74); @@ -3920,7 +3921,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3939,20 +3940,20 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rs1_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 75: C.NOP */ - std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("C.NOP"), @@ -3966,13 +3967,13 @@ private: /* 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 76: C.JAL */ - std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JAL"); this->gen_sync(iss::PRE_SYNC, 76); @@ -3982,7 +3983,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4007,11 +4008,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 76); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 77: C.LI */ - std::tuple __c_li(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LI"); this->gen_sync(iss::PRE_SYNC, 77); @@ -4022,7 +4023,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4040,13 +4041,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 78: C.LUI */ - std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LUI"); this->gen_sync(iss::PRE_SYNC, 78); @@ -4057,7 +4058,7 @@ private: /* 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 % (uint64_t)fld_imm_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4078,13 +4079,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 79: C.ADDI16SP */ - std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI16SP"); this->gen_sync(iss::PRE_SYNC, 79); @@ -4094,7 +4095,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4113,13 +4114,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 80: C.SRLI */ - std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SRLI"); this->gen_sync(iss::PRE_SYNC, 80); @@ -4130,7 +4131,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4148,13 +4149,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 81: C.SRAI */ - std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SRAI"); this->gen_sync(iss::PRE_SYNC, 81); @@ -4165,7 +4166,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4183,13 +4184,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 82: C.ANDI */ - std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ANDI"); this->gen_sync(iss::PRE_SYNC, 82); @@ -4200,7 +4201,7 @@ private: /* 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 % (uint64_t)fld_imm_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4218,13 +4219,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 83: C.SUB */ - std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SUB"); this->gen_sync(iss::PRE_SYNC, 83); @@ -4235,7 +4236,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4253,13 +4254,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 84: C.XOR */ - std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.XOR"); this->gen_sync(iss::PRE_SYNC, 84); @@ -4270,7 +4271,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4288,13 +4289,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 85: C.OR */ - std::tuple __c_or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.OR"); this->gen_sync(iss::PRE_SYNC, 85); @@ -4305,7 +4306,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4323,13 +4324,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 86: C.AND */ - std::tuple __c_and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.AND"); this->gen_sync(iss::PRE_SYNC, 86); @@ -4340,7 +4341,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4358,13 +4359,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 87: C.J */ - std::tuple __c_j(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.J"); this->gen_sync(iss::PRE_SYNC, 87); @@ -4374,7 +4375,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4395,11 +4396,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 87); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 88: C.BEQZ */ - std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.BEQZ"); this->gen_sync(iss::PRE_SYNC, 88); @@ -4410,7 +4411,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4440,11 +4441,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 88); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 89: C.BNEZ */ - std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.BNEZ"); this->gen_sync(iss::PRE_SYNC, 89); @@ -4455,7 +4456,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4485,11 +4486,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 89); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 90: C.SLLI */ - std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SLLI"); this->gen_sync(iss::PRE_SYNC, 90); @@ -4500,7 +4501,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4520,13 +4521,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rs1_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 91: C.LWSP */ - std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LWSP"); this->gen_sync(iss::PRE_SYNC, 91); @@ -4537,7 +4538,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4555,13 +4556,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 92: C.MV */ - std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.MV"); this->gen_sync(iss::PRE_SYNC, 92); @@ -4572,7 +4573,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4587,13 +4588,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 93: C.JR */ - std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JR"); this->gen_sync(iss::PRE_SYNC, 93); @@ -4603,7 +4604,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4619,11 +4620,11 @@ private: this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 93); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 94: C.ADD */ - std::tuple __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADD"); this->gen_sync(iss::PRE_SYNC, 94); @@ -4634,7 +4635,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4651,13 +4652,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 95: C.JALR */ - std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JALR"); this->gen_sync(iss::PRE_SYNC, 95); @@ -4667,7 +4668,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4687,18 +4688,18 @@ private: this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 95); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 96: C.EBREAK */ - std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("C.EBREAK"), @@ -4712,11 +4713,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 97: C.SWSP */ - std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SWSP"); this->gen_sync(iss::PRE_SYNC, 97); @@ -4727,7 +4728,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4748,20 +4749,20 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 98: DII */ - std::tuple __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __dii(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("DII"), @@ -4775,13 +4776,13 @@ private: 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 99: FLW */ - std::tuple __flw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLW"); this->gen_sync(iss::PRE_SYNC, 99); @@ -4793,7 +4794,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FLW f%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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4827,13 +4828,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 99); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 100: FSW */ - std::tuple __fsw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSW"); this->gen_sync(iss::PRE_SYNC, 100); @@ -4845,7 +4846,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSW f%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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4871,13 +4872,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 100); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 101: FMADD.S */ - std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.S"); this->gen_sync(iss::PRE_SYNC, 101); @@ -4891,7 +4892,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMADD.S x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4902,7 +4903,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -4946,7 +4947,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -4956,13 +4957,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 101); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 102: FMSUB.S */ - std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.S"); this->gen_sync(iss::PRE_SYNC, 102); @@ -4976,7 +4977,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMSUB.S x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4987,7 +4988,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5031,7 +5032,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5041,13 +5042,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 102); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 103: FNMADD.S */ - std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.S"); this->gen_sync(iss::PRE_SYNC, 103); @@ -5061,7 +5062,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FNMADD.S x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5072,7 +5073,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5116,7 +5117,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5126,13 +5127,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 103); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 104: FNMSUB.S */ - std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.S"); this->gen_sync(iss::PRE_SYNC, 104); @@ -5146,7 +5147,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FNMSUB.S x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5157,7 +5158,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5201,7 +5202,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5211,13 +5212,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 104); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 105: FADD.S */ - std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.S"); this->gen_sync(iss::PRE_SYNC, 105); @@ -5230,7 +5231,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FADD.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5241,7 +5242,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5277,7 +5278,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5287,13 +5288,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 105); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 106: FSUB.S */ - std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.S"); this->gen_sync(iss::PRE_SYNC, 106); @@ -5306,7 +5307,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSUB.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5317,7 +5318,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5353,7 +5354,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5363,13 +5364,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 106); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 107: FMUL.S */ - std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.S"); this->gen_sync(iss::PRE_SYNC, 107); @@ -5382,7 +5383,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMUL.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5393,7 +5394,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5429,7 +5430,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5439,13 +5440,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 107); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 108: FDIV.S */ - std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.S"); this->gen_sync(iss::PRE_SYNC, 108); @@ -5458,7 +5459,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FDIV.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5469,7 +5470,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5505,7 +5506,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5515,13 +5516,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 108); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 109: FSQRT.S */ - std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.S"); this->gen_sync(iss::PRE_SYNC, 109); @@ -5533,7 +5534,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSQRT.S f%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5544,7 +5545,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5576,7 +5577,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5586,13 +5587,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 109); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 110: FSGNJ.S */ - std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.S"); this->gen_sync(iss::PRE_SYNC, 110); @@ -5604,7 +5605,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSGNJ.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5645,13 +5646,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 110); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 111: FSGNJN.S */ - std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.S"); this->gen_sync(iss::PRE_SYNC, 111); @@ -5663,7 +5664,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSGNJN.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5704,13 +5705,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 111); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 112: FSGNJX.S */ - std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.S"); this->gen_sync(iss::PRE_SYNC, 112); @@ -5722,7 +5723,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSGNJX.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5761,13 +5762,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 112); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 113: FMIN.S */ - std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.S"); this->gen_sync(iss::PRE_SYNC, 113); @@ -5779,7 +5780,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMIN.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5790,7 +5791,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5819,7 +5820,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5829,13 +5830,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 113); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 114: FMAX.S */ - std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.S"); this->gen_sync(iss::PRE_SYNC, 114); @@ -5847,7 +5848,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMAX.S f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5858,7 +5859,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5887,7 +5888,7 @@ private: false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5897,13 +5898,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 114); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 115: FCVT.W.S */ - std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.S"); this->gen_sync(iss::PRE_SYNC, 115); @@ -5915,7 +5916,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.W.S x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5927,7 +5928,7 @@ private: pc=pc+4; Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5941,7 +5942,7 @@ private: 32, true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -5951,13 +5952,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 115); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 116: FCVT.WU.S */ - std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.S"); this->gen_sync(iss::PRE_SYNC, 116); @@ -5969,7 +5970,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.WU.S x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -5981,7 +5982,7 @@ private: pc=pc+4; Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -5995,7 +5996,7 @@ private: 32, false); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6005,13 +6006,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 116); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 117: FEQ.S */ - std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.S"); this->gen_sync(iss::PRE_SYNC, 117); @@ -6023,7 +6024,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FEQ.S x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6034,7 +6035,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -6049,7 +6050,7 @@ private: false) }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6059,13 +6060,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 117); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 118: FLT.S */ - std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.S"); this->gen_sync(iss::PRE_SYNC, 118); @@ -6077,7 +6078,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FLT.S x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6088,7 +6089,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -6103,7 +6104,7 @@ private: false) }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6113,13 +6114,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 118); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 119: FLE.S */ - std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.S"); this->gen_sync(iss::PRE_SYNC, 119); @@ -6131,7 +6132,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FLE.S x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6142,7 +6143,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -6157,7 +6158,7 @@ private: false) }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6167,13 +6168,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 119); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 120: FCLASS.S */ - std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.S"); this->gen_sync(iss::PRE_SYNC, 120); @@ -6184,7 +6185,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCLASS.S x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6195,7 +6196,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -6204,13 +6205,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 120); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 121: FCVT.S.W */ - std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.W"); this->gen_sync(iss::PRE_SYNC, 121); @@ -6222,7 +6223,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.S.W f%1$d, x%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6233,7 +6234,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::X0, 0), this-> get_type(32) @@ -6261,13 +6262,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 121); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 122: FCVT.S.WU */ - std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.WU"); this->gen_sync(iss::PRE_SYNC, 122); @@ -6279,7 +6280,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.S.WU f%1$d, x%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6290,7 +6291,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::X0, 0), this-> get_type(32) @@ -6318,13 +6319,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 122); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 123: FMV.X.W */ - std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.X.W"); this->gen_sync(iss::PRE_SYNC, 123); @@ -6335,7 +6336,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMV.X.W x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6356,13 +6357,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 123); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 124: FMV.W.X */ - std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.W.X"); this->gen_sync(iss::PRE_SYNC, 124); @@ -6373,7 +6374,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMV.W.X f%1$d, x%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6401,13 +6402,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 124); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 125: C.FLW */ - std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLW"); this->gen_sync(iss::PRE_SYNC, 125); @@ -6419,7 +6420,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FLW f(8+%1$d), %2%(x(8+%3$d))"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6451,13 +6452,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 125); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 126: C.FSW */ - std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSW"); this->gen_sync(iss::PRE_SYNC, 126); @@ -6469,7 +6470,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FSW f(8+%1$d), %2%(x(8+%3$d))"); ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6493,13 +6494,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 126); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 127: C.FLWSP */ - std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLWSP"); this->gen_sync(iss::PRE_SYNC, 127); @@ -6510,7 +6511,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FLWSP f%1$d, %2%(x2)"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6542,13 +6543,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 127); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 128: C.FSWSP */ - std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSWSP"); this->gen_sync(iss::PRE_SYNC, 128); @@ -6559,7 +6560,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FSWSP f%1$d, %2%(x2), "); ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6583,13 +6584,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 128); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 129: FLD */ - std::tuple __fld(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLD"); this->gen_sync(iss::PRE_SYNC, 129); @@ -6601,7 +6602,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FLD f%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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6632,13 +6633,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 129); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 130: FSD */ - std::tuple __fsd(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSD"); this->gen_sync(iss::PRE_SYNC, 130); @@ -6650,7 +6651,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSD f%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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6676,13 +6677,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 130); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 131: FMADD.D */ - std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.D"); this->gen_sync(iss::PRE_SYNC, 131); @@ -6696,7 +6697,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMADD.D x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6707,7 +6708,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -6748,7 +6749,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6758,13 +6759,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 131); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 132: FMSUB.D */ - std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.D"); this->gen_sync(iss::PRE_SYNC, 132); @@ -6778,7 +6779,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMSUB.D x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6789,7 +6790,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -6830,7 +6831,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6840,13 +6841,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 132); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 133: FNMADD.D */ - std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.D"); this->gen_sync(iss::PRE_SYNC, 133); @@ -6860,7 +6861,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FNMADD.D x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6871,7 +6872,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -6912,7 +6913,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -6922,13 +6923,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 133); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 134: FNMSUB.D */ - std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.D"); this->gen_sync(iss::PRE_SYNC, 134); @@ -6942,7 +6943,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FNMSUB.D x%1$d, f%2$d, f%3$d, f%4$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -6953,7 +6954,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -6994,7 +6995,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7004,13 +7005,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 134); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 135: FADD.D */ - std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.D"); this->gen_sync(iss::PRE_SYNC, 135); @@ -7023,7 +7024,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FADD.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7034,7 +7035,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7067,7 +7068,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7077,13 +7078,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 135); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 136: FSUB.D */ - std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.D"); this->gen_sync(iss::PRE_SYNC, 136); @@ -7096,7 +7097,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSUB.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7107,7 +7108,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7140,7 +7141,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7150,13 +7151,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 136); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 137: FMUL.D */ - std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.D"); this->gen_sync(iss::PRE_SYNC, 137); @@ -7169,7 +7170,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMUL.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7180,7 +7181,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7213,7 +7214,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7223,13 +7224,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 137); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 138: FDIV.D */ - std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.D"); this->gen_sync(iss::PRE_SYNC, 138); @@ -7242,7 +7243,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FDIV.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7253,7 +7254,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7286,7 +7287,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7296,13 +7297,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 138); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 139: FSQRT.D */ - std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.D"); this->gen_sync(iss::PRE_SYNC, 139); @@ -7314,7 +7315,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSQRT.D x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7325,7 +7326,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7354,7 +7355,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7364,13 +7365,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 139); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 140: FSGNJ.D */ - std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.D"); this->gen_sync(iss::PRE_SYNC, 140); @@ -7382,7 +7383,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSGNJ.D f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7420,13 +7421,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 140); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 141: FSGNJN.D */ - std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.D"); this->gen_sync(iss::PRE_SYNC, 141); @@ -7438,7 +7439,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSGNJN.D f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7476,13 +7477,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 141); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 142: FSGNJX.D */ - std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.D"); this->gen_sync(iss::PRE_SYNC, 142); @@ -7494,7 +7495,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FSGNJX.D f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7530,13 +7531,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 142); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 143: FMIN.D */ - std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.D"); this->gen_sync(iss::PRE_SYNC, 143); @@ -7548,7 +7549,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMIN.D f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7559,7 +7560,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7585,7 +7586,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7595,13 +7596,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 143); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 144: FMAX.D */ - std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.D"); this->gen_sync(iss::PRE_SYNC, 144); @@ -7613,7 +7614,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FMAX.D f%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7624,7 +7625,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7650,7 +7651,7 @@ private: res_val); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7660,13 +7661,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 144); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 145: FCVT.S.D */ - std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.D"); this->gen_sync(iss::PRE_SYNC, 145); @@ -7678,7 +7679,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.S.D f%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7689,7 +7690,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_d2f"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_d2f"), std::vector{ this->gen_reg_load(fld_rs1_val + traits::F0, 0), this->gen_const(8U, fld_rm_val) }); @@ -7705,13 +7706,13 @@ private: this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 145); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 146: FCVT.D.S */ - std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.S"); this->gen_sync(iss::PRE_SYNC, 146); @@ -7723,7 +7724,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.D.S f%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7734,7 +7735,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_f2d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_f2d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(32) @@ -7755,13 +7756,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 146); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 147: FEQ.D */ - std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.D"); this->gen_sync(iss::PRE_SYNC, 147); @@ -7773,7 +7774,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FEQ.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7784,7 +7785,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7799,7 +7800,7 @@ private: false) }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7809,13 +7810,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 147); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 148: FLT.D */ - std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.D"); this->gen_sync(iss::PRE_SYNC, 148); @@ -7827,7 +7828,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FLT.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7838,7 +7839,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7853,7 +7854,7 @@ private: false) }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7863,13 +7864,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 148); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 149: FLE.D */ - std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.D"); this->gen_sync(iss::PRE_SYNC, 149); @@ -7881,7 +7882,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FLE.D x%1$d, f%2$d, f%3$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7892,7 +7893,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7907,7 +7908,7 @@ private: false) }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -7917,13 +7918,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 149); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 150: FCLASS.D */ - std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.D"); this->gen_sync(iss::PRE_SYNC, 150); @@ -7934,7 +7935,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCLASS.D x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7945,7 +7946,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_d"), std::vector{ + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7954,13 +7955,13 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 150); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 151: FCVT.W.D */ - std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.D"); this->gen_sync(iss::PRE_SYNC, 151); @@ -7972,7 +7973,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.W.D x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -7984,7 +7985,7 @@ private: pc=pc+4; Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -7998,7 +7999,7 @@ private: 32, true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -8008,13 +8009,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 151); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 152: FCVT.WU.D */ - std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.D"); this->gen_sync(iss::PRE_SYNC, 152); @@ -8026,7 +8027,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.WU.D x%1$d, f%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8038,7 +8039,7 @@ private: pc=pc+4; Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(fld_rs1_val + traits::F0, 0), this-> get_type(64) @@ -8052,7 +8053,7 @@ private: 32, false); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( this->builder.CreateAnd( @@ -8062,13 +8063,13 @@ private: this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 152); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 153: FCVT.D.W */ - std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.W"); this->gen_sync(iss::PRE_SYNC, 153); @@ -8080,7 +8081,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.D.W f%1$d, x%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8091,7 +8092,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->gen_ext( this->gen_reg_load(fld_rs1_val + traits::X0, 0), 64, @@ -8116,13 +8117,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 153); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 154: FCVT.D.WU */ - std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.WU"); this->gen_sync(iss::PRE_SYNC, 154); @@ -8134,7 +8135,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("FCVT.D.WU f%1$d, x%2$d"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8145,7 +8146,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->gen_ext( this->gen_reg_load(fld_rs1_val + traits::X0, 0), 64, @@ -8170,13 +8171,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 154); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 155: C.FLD */ - std::tuple __c_fld(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLD"); this->gen_sync(iss::PRE_SYNC, 155); @@ -8188,7 +8189,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FLD f(8+%1$d), %2%(x(8+%3$d))"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8217,13 +8218,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 155); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 156: C.FSD */ - std::tuple __c_fsd(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSD"); this->gen_sync(iss::PRE_SYNC, 156); @@ -8235,7 +8236,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FSD f(8+%1$d), %2%(x(8+%3$d))"); ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8259,13 +8260,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 156); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 157: C.FLDSP */ - std::tuple __c_fldsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_fldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLDSP"); this->gen_sync(iss::PRE_SYNC, 157); @@ -8276,7 +8277,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FLDSP f%1$d, %2%(x2)"); ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8308,13 +8309,13 @@ private: } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 157); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 158: C.FSDSP */ - std::tuple __c_fsdsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_fsdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSDSP"); this->gen_sync(iss::PRE_SYNC, 158); @@ -8325,7 +8326,7 @@ private: /* generate console output when executing the command */ boost::format ins_fmter("C.FSDSP f%1$d, %2%(x2), "); ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val; - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -8349,16 +8350,16 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(iss::POST_SYNC, 158); - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /**************************************************************************** * end opcode definitions ****************************************************************************/ - std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, - llvm::BasicBlock *bb) { + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, + 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); @@ -8370,7 +8371,7 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } }; @@ -8383,7 +8384,7 @@ 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) { +: vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -8395,8 +8396,8 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) } template -std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, llvm::BasicBlock *this_block) { +std::tuple +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, 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; @@ -8428,7 +8429,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return (this->*f)(pc, insn, this_block); } -template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { +template void vm_impl::gen_leave_behavior(BasicBlock *leave_blk) { this->builder.SetInsertPoint(leave_blk); this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } @@ -8440,8 +8441,8 @@ template void vm_impl::gen_raise_trap(uint16_t trap_id, ui } template void vm_impl::gen_leave_trap(unsigned lvl) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), + std::vector args{ + this->core_ptr, ConstantInt::get(getContext(), 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); @@ -8450,17 +8451,17 @@ template void vm_impl::gen_leave_trap(unsigned lvl) { } template void vm_impl::gen_wait(unsigned type) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), + std::vector args{ + this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)), }; this->builder.CreateCall(this->mod->getFunction("wait"), args); } -template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { +template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{ + std::vector args{ this->core_ptr, this->adj_to64(trap_state_val), this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; @@ -8469,11 +8470,11 @@ template void vm_impl::gen_trap_behavior(llvm::BasicBlock this->builder.CreateRet(trap_addr_val); } -template inline void vm_impl::gen_trap_check(llvm::BasicBlock *bb) { +template inline void vm_impl::gen_trap_check(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))), + ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); } diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index df40e5f..c8efdc1 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -54,10 +54,11 @@ namespace rv32imac { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; +using namespace iss::vm::llvm; -template class vm_impl : public vm::vm_base { +template class vm_impl : public vm_base { public: - using super = typename vm::vm_base; + using super = typename iss::vm::llvm::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; @@ -71,13 +72,13 @@ public: target_adapter_if *accquire_target_adapter(server_if *srv) override { 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; + if (vm_base::tgt_adapter == nullptr) + vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); + return vm_base::tgt_adapter; } protected: - using vm::vm_base::get_reg_ptr; + using vm_base::get_reg_ptr; template inline llvm::ConstantInt *size(T type) { return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); @@ -92,7 +93,7 @@ protected: 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 &, + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, llvm::BasicBlock *) override; void gen_leave_behavior(llvm::BasicBlock *leave_blk) override; @@ -124,7 +125,7 @@ protected: 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, + using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, code_word_t instr, llvm::BasicBlock *bb); std::array lut; @@ -388,7 +389,7 @@ private: /* instruction definitions */ /* instruction 0: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LUI"); this->gen_sync(iss::PRE_SYNC, 0); @@ -418,11 +419,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 1: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AUIPC"); this->gen_sync(iss::PRE_SYNC, 1); @@ -456,11 +457,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 2: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("JAL"); this->gen_sync(iss::PRE_SYNC, 2); @@ -498,11 +499,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 2); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 3: JALR */ - std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("JALR"); this->gen_sync(iss::PRE_SYNC, 3); @@ -569,11 +570,11 @@ private: this->builder.SetInsertPoint(bb); this->gen_sync(iss::POST_SYNC, 3); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 4: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BEQ"); this->gen_sync(iss::PRE_SYNC, 4); @@ -615,11 +616,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 4); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 5: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BNE"); this->gen_sync(iss::PRE_SYNC, 5); @@ -661,11 +662,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 5); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 6: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BLT"); this->gen_sync(iss::PRE_SYNC, 6); @@ -711,11 +712,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 6); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 7: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BGE"); this->gen_sync(iss::PRE_SYNC, 7); @@ -761,11 +762,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 7); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 8: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BLTU"); this->gen_sync(iss::PRE_SYNC, 8); @@ -807,11 +808,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 8); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 9: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("BGEU"); this->gen_sync(iss::PRE_SYNC, 9); @@ -853,11 +854,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 9); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 10: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LB"); this->gen_sync(iss::PRE_SYNC, 10); @@ -896,11 +897,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 11: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LH"); this->gen_sync(iss::PRE_SYNC, 11); @@ -939,11 +940,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 12: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LW"); this->gen_sync(iss::PRE_SYNC, 12); @@ -982,11 +983,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 13: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LBU"); this->gen_sync(iss::PRE_SYNC, 13); @@ -1025,11 +1026,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 14: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("LHU"); this->gen_sync(iss::PRE_SYNC, 14); @@ -1068,11 +1069,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 15: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SB"); this->gen_sync(iss::PRE_SYNC, 15); @@ -1109,11 +1110,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 16: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SH"); this->gen_sync(iss::PRE_SYNC, 16); @@ -1150,11 +1151,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 17: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SW"); this->gen_sync(iss::PRE_SYNC, 17); @@ -1191,11 +1192,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 18: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ADDI"); this->gen_sync(iss::PRE_SYNC, 18); @@ -1230,11 +1231,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 19: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLTI"); this->gen_sync(iss::PRE_SYNC, 19); @@ -1274,11 +1275,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 20: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLTIU"); this->gen_sync(iss::PRE_SYNC, 20); @@ -1317,11 +1318,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 21: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("XORI"); this->gen_sync(iss::PRE_SYNC, 21); @@ -1354,11 +1355,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 22: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ORI"); this->gen_sync(iss::PRE_SYNC, 22); @@ -1391,11 +1392,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 23: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ANDI"); this->gen_sync(iss::PRE_SYNC, 23); @@ -1428,11 +1429,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 24: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLLI"); this->gen_sync(iss::PRE_SYNC, 24); @@ -1469,11 +1470,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 25: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRLI"); this->gen_sync(iss::PRE_SYNC, 25); @@ -1510,11 +1511,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 26: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRAI"); this->gen_sync(iss::PRE_SYNC, 26); @@ -1551,11 +1552,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 27: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ADD"); this->gen_sync(iss::PRE_SYNC, 27); @@ -1588,11 +1589,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 28: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SUB"); this->gen_sync(iss::PRE_SYNC, 28); @@ -1625,11 +1626,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 29: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLL"); this->gen_sync(iss::PRE_SYNC, 29); @@ -1664,11 +1665,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 30: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLT"); this->gen_sync(iss::PRE_SYNC, 30); @@ -1710,11 +1711,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 31: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SLTU"); this->gen_sync(iss::PRE_SYNC, 31); @@ -1758,11 +1759,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 32: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("XOR"); this->gen_sync(iss::PRE_SYNC, 32); @@ -1795,11 +1796,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 33: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRL"); this->gen_sync(iss::PRE_SYNC, 33); @@ -1834,11 +1835,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 34: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRA"); this->gen_sync(iss::PRE_SYNC, 34); @@ -1873,11 +1874,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 35: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("OR"); this->gen_sync(iss::PRE_SYNC, 35); @@ -1910,11 +1911,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 36: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("AND"); this->gen_sync(iss::PRE_SYNC, 36); @@ -1947,11 +1948,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 37: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("FENCE"); this->gen_sync(iss::PRE_SYNC, 37); @@ -1986,11 +1987,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 38: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -2020,11 +2021,11 @@ private: 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); + return std::make_tuple(FLUSH, nullptr); } /* instruction 39: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ECALL"); this->gen_sync(iss::PRE_SYNC, 39); @@ -2045,11 +2046,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 40: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("EBREAK"); this->gen_sync(iss::PRE_SYNC, 40); @@ -2070,11 +2071,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 41: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("URET"); this->gen_sync(iss::PRE_SYNC, 41); @@ -2095,11 +2096,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 42: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("SRET"); this->gen_sync(iss::PRE_SYNC, 42); @@ -2120,11 +2121,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 43: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MRET"); this->gen_sync(iss::PRE_SYNC, 43); @@ -2145,11 +2146,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 44: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("WFI"); this->gen_sync(iss::PRE_SYNC, 44); @@ -2172,11 +2173,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 45: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -2210,11 +2211,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 46: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRW"); this->gen_sync(iss::PRE_SYNC, 46); @@ -2258,11 +2259,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 47: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRS"); this->gen_sync(iss::PRE_SYNC, 47); @@ -2304,11 +2305,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 48: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRC"); this->gen_sync(iss::PRE_SYNC, 48); @@ -2350,11 +2351,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 49: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRWI"); this->gen_sync(iss::PRE_SYNC, 49); @@ -2393,11 +2394,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 50: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRSI"); this->gen_sync(iss::PRE_SYNC, 50); @@ -2441,11 +2442,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 51: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("CSRRCI"); this->gen_sync(iss::PRE_SYNC, 51); @@ -2489,11 +2490,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 52: MUL */ - std::tuple __mul(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mul(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MUL"); this->gen_sync(iss::PRE_SYNC, 52); @@ -2536,11 +2537,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 53: MULH */ - std::tuple __mulh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MULH"); this->gen_sync(iss::PRE_SYNC, 53); @@ -2585,11 +2586,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 54: MULHSU */ - std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MULHSU"); this->gen_sync(iss::PRE_SYNC, 54); @@ -2634,11 +2635,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 55: MULHU */ - std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("MULHU"); this->gen_sync(iss::PRE_SYNC, 55); @@ -2683,11 +2684,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 56: DIV */ - std::tuple __div(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __div(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("DIV"); this->gen_sync(iss::PRE_SYNC, 56); @@ -2812,11 +2813,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 57: DIVU */ - std::tuple __divu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __divu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("DIVU"); this->gen_sync(iss::PRE_SYNC, 57); @@ -2879,11 +2880,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 58: REM */ - std::tuple __rem(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __rem(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("REM"); this->gen_sync(iss::PRE_SYNC, 58); @@ -3012,11 +3013,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 59: REMU */ - std::tuple __remu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __remu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("REMU"); this->gen_sync(iss::PRE_SYNC, 59); @@ -3079,11 +3080,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 60: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3127,11 +3128,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 61: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3195,11 +3196,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 62: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3241,11 +3242,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 63: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3291,11 +3292,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 64: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3341,11 +3342,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 65: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3391,11 +3392,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 66: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3441,11 +3442,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 67: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3500,11 +3501,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 68: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3559,11 +3560,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 69: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3614,11 +3615,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 70: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3669,11 +3670,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 71: C.ADDI4SPN */ - std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3706,11 +3707,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 72: C.LW */ - std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3742,11 +3743,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 73: C.SW */ - std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3781,11 +3782,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 74: C.ADDI */ - std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3817,11 +3818,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 75: C.NOP */ - std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3844,11 +3845,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 76: C.JAL */ - std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3883,11 +3884,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 76); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 77: C.LI */ - std::tuple __c_li(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3918,11 +3919,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 78: C.LUI */ - std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3956,11 +3957,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 79: C.ADDI16SP */ - std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -3991,11 +3992,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 80: C.SRLI */ - std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4026,11 +4027,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 81: C.SRAI */ - std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4061,11 +4062,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 82: C.ANDI */ - std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4096,11 +4097,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 83: C.SUB */ - std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4131,11 +4132,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 84: C.XOR */ - std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4166,11 +4167,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 85: C.OR */ - std::tuple __c_or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4201,11 +4202,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 86: C.AND */ - std::tuple __c_and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4236,11 +4237,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 87: C.J */ - std::tuple __c_j(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4271,11 +4272,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 87); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 88: C.BEQZ */ - std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4316,11 +4317,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 88); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 89: C.BNEZ */ - std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4361,11 +4362,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 89); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 90: C.SLLI */ - std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4398,11 +4399,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 91: C.LWSP */ - std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4433,11 +4434,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 92: C.MV */ - std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4465,11 +4466,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 93: C.JR */ - std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4495,11 +4496,11 @@ private: this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 93); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 94: C.ADD */ - std::tuple __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4529,11 +4530,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 95: C.JALR */ - std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4563,11 +4564,11 @@ private: this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 95); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 96: C.EBREAK */ - std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4588,11 +4589,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 97: C.SWSP */ - std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + 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); @@ -4626,11 +4627,11 @@ private: 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); + return std::make_tuple(CONT, bb); } /* instruction 98: DII */ - std::tuple __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("DII"); this->gen_sync(iss::PRE_SYNC, 98); @@ -4653,13 +4654,13 @@ private: 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); + return std::make_tuple(CONT, bb); } /**************************************************************************** * end opcode definitions ****************************************************************************/ - std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, + 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), @@ -4672,7 +4673,7 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } }; @@ -4685,7 +4686,7 @@ 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) { +: vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -4697,7 +4698,7 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) } template -std::tuple +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; diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index 60c603e..5e3c2e1 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -58,10 +58,11 @@ namespace rv64ia { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; +using namespace iss::vm::llvm; -template class vm_impl : public vm::vm_base { +template class vm_impl : public vm_base { public: - using super = typename vm::vm_base; + using super = typename iss::vm::llvm::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; @@ -75,31 +76,31 @@ public: 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; + if (vm_base::tgt_adapter == nullptr) + vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); + return vm_base::tgt_adapter; } protected: - using vm::vm_base::get_reg_ptr; + using vm_base::get_reg_ptr; - template inline llvm::ConstantInt *size(T type) { - return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); + template inline ConstantInt *size(T type) { + return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); } - void setup_module(llvm::Module* m) override { + void setup_module(Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } - inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { + inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } - std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, - llvm::BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, + BasicBlock *) override; - void gen_leave_behavior(llvm::BasicBlock *leave_blk) override; + void gen_leave_behavior(BasicBlock *leave_blk) override; void gen_raise_trap(uint16_t trap_id, uint16_t cause); @@ -107,16 +108,16 @@ protected: void gen_wait(unsigned type); - void gen_trap_behavior(llvm::BasicBlock *) override; + void gen_trap_behavior(BasicBlock *) override; - void gen_trap_check(llvm::BasicBlock *bb); + void gen_trap_check(BasicBlock *bb); - inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { + inline 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), + 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); } @@ -128,9 +129,9 @@ protected: 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, + using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, code_word_t instr, - llvm::BasicBlock *bb); + BasicBlock *bb); std::array lut; std::array lut_00, lut_01, lut_10; @@ -366,7 +367,7 @@ private: /* instruction definitions */ /* instruction 0: LWU */ - std::tuple __lwu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LWU"); this->gen_sync(iss::PRE_SYNC, 0); @@ -378,7 +379,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -403,13 +404,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 1: LD */ - std::tuple __ld(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LD"); this->gen_sync(iss::PRE_SYNC, 1); @@ -421,7 +422,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -446,13 +447,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 2: SD */ - std::tuple __sd(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SD"); this->gen_sync(iss::PRE_SYNC, 2); @@ -464,7 +465,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -487,13 +488,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 3: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); this->gen_sync(iss::PRE_SYNC, 3); @@ -505,7 +506,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -528,13 +529,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 4: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); this->gen_sync(iss::PRE_SYNC, 4); @@ -546,7 +547,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -569,13 +570,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 5: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); this->gen_sync(iss::PRE_SYNC, 5); @@ -587,7 +588,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -610,13 +611,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 6: ADDIW */ - std::tuple __addiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDIW"); this->gen_sync(iss::PRE_SYNC, 6); @@ -628,7 +629,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -656,13 +657,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 7: SLLIW */ - std::tuple __slliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLIW"); this->gen_sync(iss::PRE_SYNC, 7); @@ -674,7 +675,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -700,13 +701,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 8: SRLIW */ - std::tuple __srliw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLIW"); this->gen_sync(iss::PRE_SYNC, 8); @@ -718,7 +719,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -744,13 +745,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 9: SRAIW */ - std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAIW"); this->gen_sync(iss::PRE_SYNC, 9); @@ -762,7 +763,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -788,13 +789,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 10: ADDW */ - std::tuple __addw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDW"); this->gen_sync(iss::PRE_SYNC, 10); @@ -804,7 +805,7 @@ private: uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("ADDW"), @@ -833,13 +834,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 11: SUBW */ - std::tuple __subw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUBW"); this->gen_sync(iss::PRE_SYNC, 11); @@ -849,7 +850,7 @@ private: uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("SUBW"), @@ -878,13 +879,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 12: SLLW */ - std::tuple __sllw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLW"); this->gen_sync(iss::PRE_SYNC, 12); @@ -896,7 +897,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -929,13 +930,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 13: SRLW */ - std::tuple __srlw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLW"); this->gen_sync(iss::PRE_SYNC, 13); @@ -947,7 +948,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -980,13 +981,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 14: SRAW */ - std::tuple __sraw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAW"); this->gen_sync(iss::PRE_SYNC, 14); @@ -998,7 +999,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1031,13 +1032,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 15: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LUI"); this->gen_sync(iss::PRE_SYNC, 15); @@ -1048,7 +1049,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1065,13 +1066,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 16: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AUIPC"); this->gen_sync(iss::PRE_SYNC, 16); @@ -1082,7 +1083,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1103,13 +1104,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 17: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JAL"); this->gen_sync(iss::PRE_SYNC, 17); @@ -1120,7 +1121,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1147,11 +1148,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 17); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 18: JALR */ - std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); this->gen_sync(iss::PRE_SYNC, 18); @@ -1163,7 +1164,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1183,9 +1184,9 @@ private: new_pc_val, this->gen_const(64U, 0x2)); { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -1218,11 +1219,11 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 19: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); this->gen_sync(iss::PRE_SYNC, 19); @@ -1234,7 +1235,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1264,11 +1265,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 19); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 20: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); this->gen_sync(iss::PRE_SYNC, 20); @@ -1280,7 +1281,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1310,11 +1311,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 20); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 21: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); this->gen_sync(iss::PRE_SYNC, 21); @@ -1326,7 +1327,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1360,11 +1361,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 21); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 22: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); this->gen_sync(iss::PRE_SYNC, 22); @@ -1376,7 +1377,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1410,11 +1411,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 22); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 23: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); this->gen_sync(iss::PRE_SYNC, 23); @@ -1426,7 +1427,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1456,11 +1457,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 23); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 24: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); this->gen_sync(iss::PRE_SYNC, 24); @@ -1472,7 +1473,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1502,11 +1503,11 @@ private: this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_sync(iss::POST_SYNC, 24); this->gen_trap_check(this->leave_blk); - return std::make_tuple(iss::vm::BRANCH, nullptr); + return std::make_tuple(BRANCH, nullptr); } /* instruction 25: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); this->gen_sync(iss::PRE_SYNC, 25); @@ -1518,7 +1519,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1543,13 +1544,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 26: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); this->gen_sync(iss::PRE_SYNC, 26); @@ -1561,7 +1562,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1586,13 +1587,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 27: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); this->gen_sync(iss::PRE_SYNC, 27); @@ -1604,7 +1605,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1629,13 +1630,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 28: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); this->gen_sync(iss::PRE_SYNC, 28); @@ -1647,7 +1648,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1672,13 +1673,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 29: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); this->gen_sync(iss::PRE_SYNC, 29); @@ -1690,7 +1691,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1715,13 +1716,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 30: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); this->gen_sync(iss::PRE_SYNC, 30); @@ -1733,7 +1734,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1756,13 +1757,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 31: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); this->gen_sync(iss::PRE_SYNC, 31); @@ -1774,7 +1775,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1797,13 +1798,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 32: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); this->gen_sync(iss::PRE_SYNC, 32); @@ -1815,7 +1816,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1838,13 +1839,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 33: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); this->gen_sync(iss::PRE_SYNC, 33); @@ -1856,7 +1857,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1877,13 +1878,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 34: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); this->gen_sync(iss::PRE_SYNC, 34); @@ -1895,7 +1896,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1921,13 +1922,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 35: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); this->gen_sync(iss::PRE_SYNC, 35); @@ -1939,7 +1940,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -1964,13 +1965,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 36: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); this->gen_sync(iss::PRE_SYNC, 36); @@ -1982,7 +1983,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2001,13 +2002,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 37: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); this->gen_sync(iss::PRE_SYNC, 37); @@ -2019,7 +2020,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2038,13 +2039,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 38: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); this->gen_sync(iss::PRE_SYNC, 38); @@ -2056,7 +2057,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2075,13 +2076,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 39: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); this->gen_sync(iss::PRE_SYNC, 39); @@ -2093,7 +2094,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2112,13 +2113,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 40: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); this->gen_sync(iss::PRE_SYNC, 40); @@ -2130,7 +2131,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2149,13 +2150,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 41: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); this->gen_sync(iss::PRE_SYNC, 41); @@ -2167,7 +2168,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2188,13 +2189,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 42: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); this->gen_sync(iss::PRE_SYNC, 42); @@ -2206,7 +2207,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2234,13 +2235,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 43: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); this->gen_sync(iss::PRE_SYNC, 43); @@ -2252,7 +2253,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2282,13 +2283,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 44: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); this->gen_sync(iss::PRE_SYNC, 44); @@ -2300,7 +2301,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2319,13 +2320,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 45: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); this->gen_sync(iss::PRE_SYNC, 45); @@ -2337,7 +2338,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2358,13 +2359,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 46: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); this->gen_sync(iss::PRE_SYNC, 46); @@ -2376,7 +2377,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2397,13 +2398,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 47: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); this->gen_sync(iss::PRE_SYNC, 47); @@ -2415,7 +2416,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2434,13 +2435,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 48: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); this->gen_sync(iss::PRE_SYNC, 48); @@ -2452,7 +2453,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2471,13 +2472,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 49: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); this->gen_sync(iss::PRE_SYNC, 49); @@ -2488,7 +2489,7 @@ private: uint8_t fld_pred_val = ((bit_sub<24,4>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("FENCE"), @@ -2510,13 +2511,13 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp0_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 50: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); this->gen_sync(iss::PRE_SYNC, 50); @@ -2526,7 +2527,7 @@ private: uint16_t fld_imm_val = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("FENCE_I"), @@ -2546,18 +2547,18 @@ private: 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); + return std::make_tuple(FLUSH, nullptr); } /* instruction 51: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("ECALL"), @@ -2571,18 +2572,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 52: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("EBREAK"), @@ -2596,18 +2597,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 53: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("URET"), @@ -2621,18 +2622,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 54: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("SRET"), @@ -2646,18 +2647,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 55: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("MRET"), @@ -2671,18 +2672,18 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } /* instruction 56: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("WFI"), @@ -2696,13 +2697,13 @@ private: 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 57: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); this->gen_sync(iss::PRE_SYNC, 57); @@ -2711,7 +2712,7 @@ private: uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr("SFENCE.VMA"), @@ -2734,13 +2735,13 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 58: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); this->gen_sync(iss::PRE_SYNC, 58); @@ -2752,7 +2753,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2782,13 +2783,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 59: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); this->gen_sync(iss::PRE_SYNC, 59); @@ -2800,7 +2801,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2828,13 +2829,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 60: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); this->gen_sync(iss::PRE_SYNC, 60); @@ -2846,7 +2847,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2874,13 +2875,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 61: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); this->gen_sync(iss::PRE_SYNC, 61); @@ -2892,7 +2893,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2917,13 +2918,13 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 62: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); this->gen_sync(iss::PRE_SYNC, 62); @@ -2935,7 +2936,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -2965,13 +2966,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 63: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); this->gen_sync(iss::PRE_SYNC, 63); @@ -2983,7 +2984,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3013,13 +3014,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 64: LR.D */ - std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.D"); this->gen_sync(iss::PRE_SYNC, 64); @@ -3032,7 +3033,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3061,13 +3062,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 65: SC.D */ - std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.D"); this->gen_sync(iss::PRE_SYNC, 65); @@ -3081,7 +3082,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3095,9 +3096,9 @@ private: Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3130,13 +3131,13 @@ private: 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 66: AMOSWAP.D */ - std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.D"); this->gen_sync(iss::PRE_SYNC, 66); @@ -3150,7 +3151,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3176,13 +3177,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 67: AMOADD.D */ - std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.D"); this->gen_sync(iss::PRE_SYNC, 67); @@ -3196,7 +3197,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3226,13 +3227,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 68: AMOXOR.D */ - std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.D"); this->gen_sync(iss::PRE_SYNC, 68); @@ -3246,7 +3247,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3276,13 +3277,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 69: AMOAND.D */ - std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.D"); this->gen_sync(iss::PRE_SYNC, 69); @@ -3296,7 +3297,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3326,13 +3327,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 70: AMOOR.D */ - std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.D"); this->gen_sync(iss::PRE_SYNC, 70); @@ -3346,7 +3347,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3376,13 +3377,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 71: AMOMIN.D */ - std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.D"); this->gen_sync(iss::PRE_SYNC, 71); @@ -3396,7 +3397,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3435,13 +3436,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 72: AMOMAX.D */ - std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.D"); this->gen_sync(iss::PRE_SYNC, 72); @@ -3455,7 +3456,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3494,13 +3495,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 73: AMOMINU.D */ - std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.D"); this->gen_sync(iss::PRE_SYNC, 73); @@ -3514,7 +3515,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3549,13 +3550,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 74: AMOMAXU.D */ - std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.D"); this->gen_sync(iss::PRE_SYNC, 74); @@ -3569,7 +3570,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3604,13 +3605,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 75: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); this->gen_sync(iss::PRE_SYNC, 75); @@ -3623,7 +3624,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3652,13 +3653,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 76: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); this->gen_sync(iss::PRE_SYNC, 76); @@ -3672,7 +3673,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3686,8 +3687,8 @@ private: Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3720,13 +3721,13 @@ private: } 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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 77: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); this->gen_sync(iss::PRE_SYNC, 77); @@ -3740,7 +3741,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3766,13 +3767,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 78: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); this->gen_sync(iss::PRE_SYNC, 78); @@ -3786,7 +3787,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3816,13 +3817,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 79: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); this->gen_sync(iss::PRE_SYNC, 79); @@ -3836,7 +3837,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3866,13 +3867,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 80: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); this->gen_sync(iss::PRE_SYNC, 80); @@ -3886,7 +3887,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3916,13 +3917,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 81: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); this->gen_sync(iss::PRE_SYNC, 81); @@ -3936,7 +3937,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -3966,13 +3967,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 82: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); this->gen_sync(iss::PRE_SYNC, 82); @@ -3986,7 +3987,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4025,13 +4026,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 83: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); this->gen_sync(iss::PRE_SYNC, 83); @@ -4045,7 +4046,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4084,13 +4085,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 84: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); this->gen_sync(iss::PRE_SYNC, 84); @@ -4104,7 +4105,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4139,13 +4140,13 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /* instruction 85: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); this->gen_sync(iss::PRE_SYNC, 85); @@ -4159,7 +4160,7 @@ private: /* 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 { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), this->builder.CreateGlobalStringPtr(ins_fmter.str()), @@ -4194,16 +4195,16 @@ private: this->builder.CreateZExtOrTrunc(MEMtmp1_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 */ + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); + return std::make_tuple(CONT, bb); } /**************************************************************************** * end opcode definitions ****************************************************************************/ - std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, - llvm::BasicBlock *bb) { + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, + 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); @@ -4215,7 +4216,7 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } }; @@ -4228,7 +4229,7 @@ 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) { +: vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -4240,8 +4241,8 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) } template -std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, llvm::BasicBlock *this_block) { +std::tuple +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, 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; @@ -4273,7 +4274,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return (this->*f)(pc, insn, this_block); } -template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { +template void vm_impl::gen_leave_behavior(BasicBlock *leave_blk) { this->builder.SetInsertPoint(leave_blk); this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } @@ -4285,8 +4286,8 @@ template void vm_impl::gen_raise_trap(uint16_t trap_id, ui } template void vm_impl::gen_leave_trap(unsigned lvl) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), + std::vector args{ + this->core_ptr, ConstantInt::get(getContext(), 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); @@ -4295,17 +4296,17 @@ template void vm_impl::gen_leave_trap(unsigned lvl) { } template void vm_impl::gen_wait(unsigned type) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), + std::vector args{ + this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)), }; this->builder.CreateCall(this->mod->getFunction("wait"), args); } -template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { +template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{ + std::vector args{ this->core_ptr, this->adj_to64(trap_state_val), this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; @@ -4314,11 +4315,11 @@ template void vm_impl::gen_trap_behavior(llvm::BasicBlock this->builder.CreateRet(trap_addr_val); } -template inline void vm_impl::gen_trap_check(llvm::BasicBlock *bb) { +template inline void vm_impl::gen_trap_check(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))), + ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); } diff --git a/riscv/src/main.cpp b/riscv/src/main.cpp index 32c4650..80370ef 100644 --- a/riscv/src/main.cpp +++ b/riscv/src/main.cpp @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include #include From 769610d6fc227efa4970808741ef0a857503152d Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 24 Nov 2018 20:29:24 +0100 Subject: [PATCH 4/7] Improved disassembly of running ISS --- conanfile.txt | 8 +- dbt-core | 2 +- riscv/gen_input/RV32A.core_desc | 22 +- riscv/gen_input/RV32C.core_desc | 74 +- riscv/gen_input/RV32D.core_desc | 52 +- riscv/gen_input/RV32F.core_desc | 52 +- riscv/gen_input/RV32IBase.core_desc | 119 +- riscv/gen_input/RV32M.core_desc | 16 +- riscv/gen_input/RV64A.core_desc | 22 +- riscv/gen_input/RV64IBase.core_desc | 26 +- riscv/gen_input/RV64M.core_desc | 10 +- riscv/gen_input/templates/incl-CORENAME.h.gtl | 58 +- .../gen_input/templates/src-CORENAME.cpp.gtl | 4 +- .../templates/vm-vm_CORENAME.cpp.gtl | 87 +- riscv/gen_input/templates/vm_riscv.in.cpp | 322 -- riscv/incl/iss/arch/riscv_hart_msu_vp.h | 7 +- riscv/incl/iss/arch/rv32gc.h | 136 +- riscv/incl/iss/arch/rv32imac.h | 105 +- riscv/incl/iss/arch/rv64ia.h | 134 +- .../incl/iss/debugger/riscv_target_adapter.h | 25 +- riscv/src/internal/vm_rv32gc.cpp | 3917 +++++++++-------- riscv/src/internal/vm_rv32imac.cpp | 2938 +++++++------ riscv/src/internal/vm_rv64ia.cpp | 2229 +++++----- riscv/src/iss/rv32gc.cpp | 5 + riscv/src/iss/rv32imac.cpp | 6 +- riscv/src/iss/rv64ia.cpp | 5 + sc-components | 2 +- 27 files changed, 5277 insertions(+), 5106 deletions(-) delete mode 100644 riscv/gen_input/templates/vm_riscv.in.cpp diff --git a/conanfile.txt b/conanfile.txt index c1205ab..3d6f0e2 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,6 +1,7 @@ [requires] - gsl_microsoft/20180102@bincrafters/stable - spdlog/0.16.3@bincrafters/stable + gsl_microsoft/20180102@bincrafters/stable + spdlog/0.16.3@bincrafters/stable + fmt/5.2.1@bincrafters/stable Seasocks/1.3.2@minres/stable SystemC/2.3.2@minres/stable SystemCVerification/2.0.1@minres/stable @@ -11,7 +12,8 @@ [options] Seasocks:shared=True + fmt:header_only=True SystemC:stdcxx=14 SystemC:shared=True SystemCVerification:stdcxx=14 - SystemC-CCI:stdcxx=14 \ No newline at end of file + SystemC-CCI:stdcxx=14 diff --git a/dbt-core b/dbt-core index 0b499d2..83cd591 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit 0b499d216a2835015b889180ca5108b2daaed9b9 +Subproject commit 83cd591e4935d5c1916e4e56d9c6147e3aab8480 diff --git a/riscv/gen_input/RV32A.core_desc b/riscv/gen_input/RV32A.core_desc index 16638c5..694da0f 100644 --- a/riscv/gen_input/RV32A.core_desc +++ b/riscv/gen_input/RV32A.core_desc @@ -9,7 +9,7 @@ InsructionSet RV32A extends RV32IBase{ instructions{ LR.W { encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d"; + args_disass: "{name(rd)}, {name(rs1)}"; if(rd!=0){ val offs[XLEN] <= X[rs1]; X[rd]<= sext(MEM[offs]{32}, XLEN); @@ -18,7 +18,7 @@ InsructionSet RV32A extends RV32IBase{ } SC.W { encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)}"; val offs[XLEN] <= X[rs1]; val res1[32] <= RES[offs]{32}; if(res1!=0) @@ -27,14 +27,14 @@ InsructionSet RV32A extends RV32IBase{ } AMOSWAP.W{ encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; if(rd!=0) X[rd]<=sext(MEM[offs]{32}); MEM[offs]{32}<=X[rs2]; } AMOADD.W{ encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -43,7 +43,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOXOR.W{ encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -52,7 +52,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOAND.W{ encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -61,7 +61,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOOR.W { encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -70,7 +70,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOMIN.W{ encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -79,7 +79,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOMAX.W{ encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -88,7 +88,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOMINU.W{ encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= zext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; @@ -97,7 +97,7 @@ InsructionSet RV32A extends RV32IBase{ } AMOMAXU.W{ encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= zext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; diff --git a/riscv/gen_input/RV32C.core_desc b/riscv/gen_input/RV32C.core_desc index f7de2f6..7c92b55 100644 --- a/riscv/gen_input/RV32C.core_desc +++ b/riscv/gen_input/RV32C.core_desc @@ -14,7 +14,7 @@ InsructionSet RV32IC { instructions{ JALR(no_cont){ // overwriting the implementation if rv32i, alignment does not need to be word encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; - args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; + args_disass: "{name(rd)}, {name(rs1)}, {imm:#0x}"; val new_pc[XLEN] <= X[rs1]s+ imm; val align[XLEN] <= new_pc & 0x1; if(align != 0){ @@ -26,25 +26,25 @@ InsructionSet RV32IC { } C.ADDI4SPN { //(RES, imm=0) encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00; - args_disass: "x%rd$d, 0x%imm$05x"; + args_disass: "{name(rd)}, {imm:#05x}"; if(imm == 0) raise(0, 2); X[rd+8] <= X[2] + imm; } C.LW { // (RV32) encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; - args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x"; + args_disass: "{name(8+rd)}, {name(8+rs1)}, {uimm:#05x}"; val offs[XLEN] <= X[rs1+8]+uimm; X[rd+8] <= MEM[offs]{32}; } C.SW {//(RV32) encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; - args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x"; + args_disass: "{name(8+rs1)}, {name(8+rs2)}, {uimm:#05x}"; val offs[XLEN] <= X[rs1+8]+uimm; MEM[offs]{32} <= X[rs2+8]; } C.ADDI {//(RV32) encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01; - args_disass: "x%rs1$d, 0x%imm$05x"; + args_disass: "{name(rs1)}, {imm:#05x}"; X[rs1] <= X[rs1]'s + imm; } C.NOP { @@ -53,118 +53,118 @@ InsructionSet RV32IC { // C.JAL will be overwritten by C.ADDIW for RV64/128 C.JAL(no_cont) {//(RV32) encoding: b001 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; - args_disass: "0x%imm$05x"; + args_disass: "{imm:#05x}"; X[1] <= PC+2; PC<=PC's+imm; } C.LI {//(RV32) encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01; - args_disass: "x%rd$d, 0x%imm$05x"; + args_disass: "{name(rd)}, {imm:#05x}"; if(rd == 0) raise(0, 2); //TODO: should it be handled as trap? X[rd] <= imm; } // order matters here as C.ADDI16SP overwrites C.LUI vor rd==2 C.LUI {//(RV32) encoding:b011 | imm[17:17] | rd[4:0] | imm[16:12]s | b01; - args_disass: "x%rd$d, 0x%imm$05x"; + args_disass: "{name(rd)}, {imm:#05x}"; if(rd == 0) raise(0, 2); //TODO: should it be handled as trap? if(imm == 0) raise(0, 2); //TODO: should it be handled as trap? X[rd] <= imm; } C.ADDI16SP {//(RV32) encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01; - args_disass: "0x%imm$05x"; + args_disass: "{imm:#05x}"; X[2] <= X[2]s + imm; } C.SRLI {//(RV32 nse) encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01; - args_disass: "x(8+%rs1$d), %shamt$d"; + args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shrl(X[rs1_idx], shamt); } C.SRAI {//(RV32) encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01; - args_disass: "x(8+%rs1$d), %shamt$d"; + args_disass: "{name(8+rs1)}, {shamt}"; val rs1_idx[5] <= rs1+8; X[rs1_idx] <= shra(X[rs1_idx], shamt); } C.ANDI {//(RV32) encoding:b100 | imm[5:5] | b10 | rs1[2:0] | imm[4:0] | b01; - args_disass: "x(8+%rs1$d), 0x%imm$05x"; + args_disass: "{name(8+rs1)}, {imm:#05x}"; val rs1_idx[5] <= rs1 + 8; X[rs1_idx] <= X[rs1_idx] & imm; } C.SUB {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; - args_disass: "x(8+%rd$d), x(8+%rs2$d)"; + args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] - X[rs2 + 8]; } C.XOR {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; - args_disass: "x(8+%rd$d), x(8+%rs2$d)"; + args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] ^ X[rs2 + 8]; } C.OR {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b10 | rs2[2:0] | b01; - args_disass: "x(8+%rd$d), x(8+%rs2$d)"; + args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] | X[rs2 + 8]; } C.AND {//(RV32) encoding:b100 | b0 | b11 | rd[2:0] | b11 | rs2[2:0] | b01; - args_disass: "x(8+%rd$d), x(8+%rs2$d)"; + args_disass: "{name(8+rd)}, {name(8+rs2)}"; val rd_idx[5] <= rd + 8; X[rd_idx] <= X[rd_idx] & X[rs2 + 8]; } C.J(no_cont) {//(RV32) encoding:b101 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01; - args_disass: "0x%imm$05x"; + args_disass: "{imm:#05x}"; PC<=PC's+imm; } 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"; + args_disass: "{name(8+rs1)}, {imm:#05x}"; PC<=choose(X[rs1+8]==0, PC's+imm, PC+2); } 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"; + args_disass: "{name(8+rs1)}, {imm:#05x}"; PC<=choose(X[rs1+8]!=0, PC's+imm, PC+2); } C.SLLI {//(RV32) encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10; - args_disass: "x%rs1$d, %shamt$d"; + args_disass: "{name(rs1)}, {shamt}"; if(rs1 == 0) raise(0, 2); X[rs1] <= shll(X[rs1], shamt); } C.LWSP {// encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; - args_disass: "x%rd$d, sp, 0x%uimm$05x"; + args_disass: "{name(rd)}, sp, {uimm:#05x}"; val offs[XLEN] <= X[2] + uimm; X[rd] <= MEM[offs]{32}; } // order matters as C.JR is a special case of C.MV C.MV {//(RV32) encoding:b100 | b0 | rd[4:0] | rs2[4:0] | b10; - args_disass: "x%rd$d, x%rs2$d"; + args_disass: "{name(rd)}, {name(rs2)}"; X[rd] <= X[rs2]; } C.JR(no_cont) {//(RV32) encoding:b100 | b0 | rs1[4:0] | b00000 | b10; - args_disass: "x%rs1$d"; + args_disass: "{name(rs1)}"; PC <= X[rs1]; } // order matters as C.EBREAK is a special case of C.JALR which is a special case of C.ADD C.ADD {//(RV32) encoding:b100 | b1 | rd[4:0] | rs2[4:0] | b10; - args_disass: "x%rd$d, x%rs2$d"; + args_disass: "{name(rd)}, {name(rs2)}"; X[rd] <= X[rd] + X[rs2]; } C.JALR(no_cont) {//(RV32) encoding:b100 | b1 | rs1[4:0] | b00000 | b10; - args_disass: "x%rs1$d"; + args_disass: "{name(rs1)}"; X[1] <= PC+2; PC<=X[rs1]; } @@ -174,7 +174,7 @@ InsructionSet RV32IC { } C.SWSP {// encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; - args_disass: "x2+0x%uimm$05x, x%rs2$d"; + args_disass: "x2+{uimm:#05x}, {name(rs2)}"; val offs[XLEN] <= X[2] + uimm; MEM[offs]{32} <= X[rs2]; } @@ -199,7 +199,7 @@ InsructionSet RV32FC extends RV32IC{ instructions{ C.FLW { encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00; - args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; + args_disass:"f(8+{rd}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; val res[32] <= MEM[offs]{32}; if(FLEN==32) @@ -211,13 +211,13 @@ InsructionSet RV32FC extends RV32IC{ } C.FSW { encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00; - args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; + args_disass:"f(8+{rs2}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; MEM[offs]{32}<=F[rs2+8]{32}; } C.FLWSP { encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10; - args_disass:"f%rd$d, %uimm%(x2)"; + args_disass:"f{rd}, {uimm}(x2)"; val offs[XLEN] <= X[2]+uimm; val res[32] <= MEM[offs]{32}; if(FLEN==32) @@ -229,7 +229,7 @@ InsructionSet RV32FC extends RV32IC{ } C.FSWSP { encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10; - args_disass:"f%rs2$d, %uimm%(x2), "; + args_disass:"f{rs2}, {uimm}(x2), "; val offs[XLEN] <= X[2]+uimm; MEM[offs]{32}<=F[rs2]{32}; } @@ -250,7 +250,7 @@ InsructionSet RV32DC extends RV32IC{ instructions{ C.FLD { //(RV32/64) encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; - args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))"; + args_disass:"f(8+{rd}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; val res[64] <= MEM[offs]{64}; if(FLEN==64) @@ -262,13 +262,13 @@ InsructionSet RV32DC extends RV32IC{ } C.FSD { //(RV32/64) encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00; - args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))"; + args_disass:"f(8+{rs2}), {uimm}({name(8+rs1)})"; val offs[XLEN] <= X[rs1+8]+uimm; MEM[offs]{64}<=F[rs2+8]{64}; } C.FLDSP {//(RV32/64) encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; - args_disass:"f%rd$d, %uimm%(x2)"; + args_disass:"f{rd}, {uimm}(x2)"; val offs[XLEN] <= X[2]+uimm; val res[64] <= MEM[offs]{64}; if(FLEN==64) @@ -280,7 +280,7 @@ InsructionSet RV32DC extends RV32IC{ } C.FSDSP {//(RV32/64) encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; - args_disass:"f%rs2$d, %uimm%(x2), "; + args_disass:"f{rs2}, {uimm}(x2), "; val offs[XLEN] <= X[2]+uimm; MEM[offs]{64}<=F[rs2]{64}; } @@ -307,11 +307,11 @@ InsructionSet RV64IC extends RV32IC { } C.SUBW {//(RV64/128, RV32 res) encoding:b100 | b1 | b11 | rd[2:0] | b00 | rs2[2:0] | b01; - args_disass: "x%rd$d, sp, 0x%imm$05x"; + args_disass: "{name(rd)}, sp, {imm:#05x}"; } C.ADDW {//(RV64/128 RV32 res) encoding:b100 | b1 | b11 | rd[2:0] | b01 | rs2[2:0] | b01; - args_disass: "x%rd$d, sp, 0x%imm$05x"; + args_disass: "{name(rd)}, sp, {imm:#05x}"; } C.ADDIW {//(RV64/128) encoding:b001 | imm[5:5] | rs1[4:0] | imm[4:0] | b01; @@ -327,7 +327,7 @@ InsructionSet RV64IC extends RV32IC { } C.LDSP {//(RV64/128 encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10; - args_disass: "x%rd$d, sp, 0x%imm$05x"; + args_disass: "{name(rd)}, sp, {imm:#05x}"; } C.SDSP {//(RV64/128) encoding:b111 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10; diff --git a/riscv/gen_input/RV32D.core_desc b/riscv/gen_input/RV32D.core_desc index caefac5..4b579b7 100644 --- a/riscv/gen_input/RV32D.core_desc +++ b/riscv/gen_input/RV32D.core_desc @@ -10,7 +10,7 @@ InsructionSet RV32D extends RV32IBase{ instructions{ FLD { encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111; - args_disass:"f%rd$d, %imm%(x%rs1$d)"; + args_disass:"f{rd}, {imm}({rs1})"; val offs[XLEN] <= X[rs1]'s + imm; val res[64] <= MEM[offs]{64}; if(FLEN==64) @@ -22,13 +22,13 @@ InsructionSet RV32D extends RV32IBase{ } FSD { encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111; - args_disass:"f%rs2$d, %imm%(x%rs1$d)"; + args_disass:"f{rs2}, {imm}({rs1})"; val offs[XLEN] <= X[rs1]'s + imm; MEM[offs]{64}<=F[rs2]{64}; } FMADD.D { encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -42,7 +42,7 @@ InsructionSet RV32D extends RV32IBase{ } FMSUB.D { encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -56,7 +56,7 @@ InsructionSet RV32D extends RV32IBase{ } FNMADD.D { encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -70,7 +70,7 @@ InsructionSet RV32D extends RV32IBase{ } FNMSUB.D { encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -84,7 +84,7 @@ InsructionSet RV32D extends RV32IBase{ } FADD.D { encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f + F[rs2]f; val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -98,7 +98,7 @@ InsructionSet RV32D extends RV32IBase{ } FSUB.D { encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f - F[rs2]f; val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -112,7 +112,7 @@ InsructionSet RV32D extends RV32IBase{ } FMUL.D { encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f * F[rs2]f; val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -126,7 +126,7 @@ InsructionSet RV32D extends RV32IBase{ } FDIV.D { encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f / F[rs2]f; val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -140,7 +140,7 @@ InsructionSet RV32D extends RV32IBase{ } FSQRT.D { encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"{name(rd)}, f{rs1}"; //F[rd]f<=sqrt(F[rs1]f); val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==64) @@ -154,7 +154,7 @@ InsructionSet RV32D extends RV32IBase{ } FSGNJ.D { encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000); if(FLEN==64) F[rd] <= res; @@ -165,7 +165,7 @@ InsructionSet RV32D extends RV32IBase{ } FSGNJN.D { encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000); if(FLEN==64) F[rd] <= res; @@ -176,7 +176,7 @@ InsructionSet RV32D extends RV32IBase{ } FSGNJX.D { encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000); if(FLEN==64) F[rd] <= res; @@ -187,7 +187,7 @@ InsructionSet RV32D extends RV32IBase{ } FMIN.D { encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; //F[rd]f<= choose(F[rs1]fF[rs2]f, F[rs1]f, F[rs2]f); val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); if(FLEN==64) @@ -215,7 +215,7 @@ InsructionSet RV32D extends RV32IBase{ } FCVT.S.D { encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d"; + args_disass:"f{rd}, f{rs1}"; val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8}); // NaN boxing val upper[FLEN] <= -1; @@ -223,7 +223,7 @@ InsructionSet RV32D extends RV32IBase{ } FCVT.D.S { encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d"; + args_disass:"f{rd}, f{rs1}"; val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8}); if(FLEN==64){ F[rd] <= res; @@ -234,47 +234,47 @@ InsructionSet RV32D extends RV32IBase{ } FEQ.D { encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FLT.D { encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FLE.D { encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCLASS.D { encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"{name(rd)}, f{rs1}"; X[rd]<=fdispatch_fclass_d(F[rs1]{64}); } FCVT.W.D { encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"{name(rd)}, f{rs1}"; X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCVT.WU.D { encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"{name(rd)}, f{rs1}"; X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCVT.D.W { encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, x%rs1$d"; + args_disass:"f{rd}, {rs1}"; val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8}); if(FLEN==64) F[rd] <= res; @@ -285,7 +285,7 @@ InsructionSet RV32D extends RV32IBase{ } FCVT.D.WU { encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, x%rs1$d"; + args_disass:"f{rd}, {rs1}"; val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8}); if(FLEN==64) F[rd] <= res; diff --git a/riscv/gen_input/RV32F.core_desc b/riscv/gen_input/RV32F.core_desc index 1fc02b2..5723a4f 100644 --- a/riscv/gen_input/RV32F.core_desc +++ b/riscv/gen_input/RV32F.core_desc @@ -10,7 +10,7 @@ InsructionSet RV32F extends RV32IBase{ instructions{ FLW { encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111; - args_disass:"f%rd$d, %imm%(x%rs1$d)"; + args_disass:"f{rd}, {imm}(x{rs1})"; val offs[XLEN] <= X[rs1]'s + imm; val res[32] <= MEM[offs]{32}; if(FLEN==32) @@ -22,13 +22,13 @@ InsructionSet RV32F extends RV32IBase{ } FSW { encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111; - args_disass:"f%rs2$d, %imm%(x%rs1$d)"; + args_disass:"f{rs2}, {imm}(x{rs1})"; val offs[XLEN] <= X[rs1]'s + imm; MEM[offs]{32}<=F[rs2]{32}; } FMADD.S { encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f; val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -42,7 +42,7 @@ InsructionSet RV32F extends RV32IBase{ } FMSUB.S { encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f; val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -56,7 +56,7 @@ InsructionSet RV32F extends RV32IBase{ } FNMADD.S { encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f; val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -70,7 +70,7 @@ InsructionSet RV32F extends RV32IBase{ } FNMSUB.S { encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}, f{rs3}"; //F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f; val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -84,7 +84,7 @@ InsructionSet RV32F extends RV32IBase{ } FADD.S { encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f + F[rs2]f; val res[32] <= fdispatch_fadd_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -98,7 +98,7 @@ InsructionSet RV32F extends RV32IBase{ } FSUB.S { encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f - F[rs2]f; val res[32] <= fdispatch_fsub_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -112,7 +112,7 @@ InsructionSet RV32F extends RV32IBase{ } FMUL.S { encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f * F[rs2]f; val res[32] <= fdispatch_fmul_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -126,7 +126,7 @@ InsructionSet RV32F extends RV32IBase{ } FDIV.S { encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; // F[rd]f <= F[rs1]f / F[rs2]f; val res[32] <= fdispatch_fdiv_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -140,7 +140,7 @@ InsructionSet RV32F extends RV32IBase{ } FSQRT.S { encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d"; + args_disass:"f{rd}, f{rs1}"; //F[rd]f<=sqrt(F[rs1]f); val res[32] <= fdispatch_fsqrt_s(F[rs1]{32}, choose(rm<7, rm{8}, FCSR{8})); if(FLEN==32) @@ -154,7 +154,7 @@ InsructionSet RV32F extends RV32IBase{ } FSGNJ.S { encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000); if(FLEN==32) F[rd] <= res; @@ -165,7 +165,7 @@ InsructionSet RV32F extends RV32IBase{ } FSGNJN.S { encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000); if(FLEN==32) F[rd] <= res; @@ -176,7 +176,7 @@ InsructionSet RV32F extends RV32IBase{ } FSGNJX.S { encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000); if(FLEN==32) F[rd] <= res; @@ -187,7 +187,7 @@ InsructionSet RV32F extends RV32IBase{ } FMIN.S { encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"f%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"f{rd}, f{rs1}, f{rs2}"; //F[rd]f<= choose(F[rs1]fF[rs2]f, F[rs1]f, F[rs2]f); val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); if(FLEN==32) @@ -215,47 +215,47 @@ InsructionSet RV32F extends RV32IBase{ } FCVT.W.S { encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"x{rd}, f{rs1}"; X[rd]<= sext(fdispatch_fcvt_s(F[rs1]{32}, zext(0, 32), rm{8}), XLEN); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCVT.WU.S { encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"x{rd}, f{rs1}"; X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FEQ.S { encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}"; X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FLT.S { encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}"; X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FLE.S { encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d, f%rs2$d"; + args_disass:"x{rd}, f{rs1}, f{rs2}"; X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCLASS.S { encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"x{rd}, f{rs1}"; X[rd]<=fdispatch_fclass_s(F[rs1]{32}); } FCVT.S.W { encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, x%rs1$d"; + args_disass:"f{rd}, x{rs1}"; val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); if(FLEN==32) F[rd] <= res; @@ -266,7 +266,7 @@ InsructionSet RV32F extends RV32IBase{ } FCVT.S.WU { encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f%rd$d, x%rs1$d"; + args_disass:"f{rd}, x{rs1}"; val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); if(FLEN==32) F[rd] <= res; @@ -277,12 +277,12 @@ InsructionSet RV32F extends RV32IBase{ } FMV.X.W { encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"x%rd$d, f%rs1$d"; + args_disass:"x{rd}, f{rs1}"; X[rd]<=sext(F[rs1]{32}); } FMV.W.X { encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"f%rd$d, x%rs1$d"; + args_disass:"f{rd}, x{rs1}"; if(FLEN==32) F[rd] <= X[rs1]; else { // NaN boxing diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32IBase.core_desc index 123e1d1..b93351c 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32IBase.core_desc @@ -14,29 +14,60 @@ InsructionSet RV32IBase { registers { [31:0] X[XLEN], PC[XLEN](is_pc), - alias ZERO[XLEN] is X[0] + alias ZERO[XLEN] is X[0], + alias RA[XLEN] is X[1], + alias SP[XLEN] is X[2], + alias GP[XLEN] is X[3], + alias TP[XLEN] is X[4], + alias T0[XLEN] is X[5], + alias T1[XLEN] is X[6], + alias T2[XLEN] is X[7], + alias S0[XLEN] is X[8], + alias S1[XLEN] is X[9], + alias A0[XLEN] is X[10], + alias A1[XLEN] is X[11], + alias A2[XLEN] is X[12], + alias A3[XLEN] is X[13], + alias A4[XLEN] is X[14], + alias A5[XLEN] is X[15], + alias A6[XLEN] is X[16], + alias A7[XLEN] is X[17], + alias S2[XLEN] is X[18], + alias S3[XLEN] is X[19], + alias S4[XLEN] is X[20], + alias S5[XLEN] is X[21], + alias S6[XLEN] is X[22], + alias S7[XLEN] is X[23], + alias S8[XLEN] is X[24], + alias S9[XLEN] is X[25], + alias S10[XLEN] is X[26], + alias S11[XLEN] is X[27], + alias T3[XLEN] is X[28], + alias T4[XLEN] is X[29], + alias T5[XLEN] is X[30], + alias T6[XLEN] is X[31] } instructions { LUI{ encoding: imm[31:12]s | rd[4:0] | b0110111; - args_disass: "x%rd$d, 0x%imm$05x"; + args_disass: "{name(rd)}, {imm:#05x}"; if(rd!=0) X[rd] <= imm; } AUIPC{ encoding: imm[31:12]s | rd[4:0] | b0010111; - args_disass: "x%rd%, 0x%imm$08x"; + args_disass: "{name(rd)}, {imm:#08x}"; if(rd!=0) X[rd] <= PC's+imm; } JAL(no_cont){ encoding: imm[20:20]s | imm[10:1]s | imm[11:11]s | imm[19:12]s | rd[4:0] | b1101111; - args_disass: "x%rd$d, 0x%imm$x"; + args_disass: "{name(rd)}, {imm:#0x}"; if(rd!=0) X[rd] <= PC+4; PC<=PC's+imm; } JALR(no_cont){ encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; - args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; + args_disass: "{name(rd)}, {name(rs1)}, {imm:#0x}"; val new_pc[XLEN] <= X[rs1]'s+ imm; val align[XLEN] <= new_pc & 0x2; if(align != 0){ @@ -48,116 +79,116 @@ InsructionSet RV32IBase { } 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"; + args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}"; PC<=choose(X[rs1]==X[rs2], PC's+imm, PC+4); } 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"; + args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}"; PC<=choose(X[rs1]!=X[rs2], PC's+imm, PC+4); } 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"; + args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}"; PC<=choose(X[rs1]s=X[rs2]s, PC's+imm, PC+4); } 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"; + args_disass:"{name(rs1)}, {name(rs2)}, {imm:#0x}"; PC<=choose(X[rs1]=X[rs2], PC's+imm, PC+4); } LB { encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s+imm; if(rd!=0) X[rd]<=sext(MEM[offs]); } LH { encoding: imm[11:0]s | rs1[4:0] | b001 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s+imm; if(rd!=0) X[rd]<=sext(MEM[offs]{16}); } LW { encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s+imm; if(rd!=0) X[rd]<=sext(MEM[offs]{32}); } LBU { encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s+imm; if(rd!=0) X[rd]<=zext(MEM[offs]); } LHU { encoding: imm[11:0]s | rs1[4:0] | b101 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s+imm; if(rd!=0) X[rd]<=zext(MEM[offs]{16}); } SB { encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:0]s | b0100011; - args_disass:"x%rs2$d, %imm%(x%rs1$d)"; + args_disass:"{name(rs2)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s + imm; MEM[offs] <= X[rs2]; } SH { encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b001 | imm[4:0]s | b0100011; - args_disass:"x%rs2$d, %imm%(x%rs1$d)"; + args_disass:"{name(rs2)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s + imm; MEM[offs]{16} <= X[rs2]; } SW { encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100011; - args_disass:"x%rs2$d, %imm%(x%rs1$d)"; + args_disass:"{name(rs2)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s + imm; MEM[offs]{32} <= X[rs2]; } ADDI { encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; if(rd != 0) X[rd] <= X[rs1]'s + imm; } SLTI { encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; if (rd != 0) X[rd] <= choose(X[rs1]s < imm's, 1, 0); } SLTIU { encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; val full_imm[XLEN] <= imm's; if (rd != 0) X[rd] <= choose(X[rs1]'u < full_imm'u, 1, 0); } XORI { encoding: imm[11:0]s | rs1[4:0] | b100 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; if(rd != 0) X[rd] <= X[rs1]s ^ imm; } ORI { encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; if(rd != 0) X[rd] <= X[rs1]s | imm; } ANDI { encoding: imm[11:0]s | rs1[4:0] | b111 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; if(rd != 0) X[rd] <= X[rs1]s & imm; } SLLI { encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(shamt > 31){ raise(0,0); } else { @@ -166,7 +197,7 @@ InsructionSet RV32IBase { } SRLI { encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(shamt > 31){ raise(0,0); } else { @@ -175,7 +206,7 @@ InsructionSet RV32IBase { } SRAI { encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(shamt > 31){ raise(0,0); } else { @@ -184,52 +215,52 @@ InsructionSet RV32IBase { } ADD { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= X[rs1] + X[rs2]; } SUB { encoding: b0100000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= X[rs1] - X[rs2]; } SLL { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&(XLEN-1)); } SLT { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if (rd != 0) X[rd] <= choose(X[rs1]s < X[rs2]s, 1, 0); } SLTU { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if (rd != 0) X[rd] <= choose(zext(X[rs1]) < zext(X[rs2]), 1, 0); } XOR { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= X[rs1] ^ X[rs2]; } SRL { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&(XLEN-1)); } SRA { encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&(XLEN-1)); } OR { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= X[rs1] | X[rs2]; } AND { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0) X[rd] <= X[rs1] & X[rs2]; } FENCE { @@ -271,7 +302,7 @@ InsructionSet RV32IBase { } CSRRW { encoding: csr[11:0] | rs1[4:0] | b001 | rd[4:0] | b1110011; - args_disass:"x%rd$d, %csr$d, x%rs1$d"; + args_disass:"{name(rd)}, {csr}, {name(rs1)}"; val rs_val[XLEN] <= X[rs1]; if(rd!=0){ val csr_val[XLEN] <= CSR[csr]; @@ -284,7 +315,7 @@ InsructionSet RV32IBase { } CSRRS { encoding: csr[11:0] | rs1[4:0] | b010 | rd[4:0] | b1110011; - args_disass:"x%rd$d, %csr$d, x%rs1$d"; + args_disass:"{name(rd)}, {csr}, {name(rs1)}"; val xrd[XLEN] <= CSR[csr]; val xrs1[XLEN] <= X[rs1]; if(rd!=0) X[rd] <= xrd; @@ -292,7 +323,7 @@ InsructionSet RV32IBase { } CSRRC { encoding: csr[11:0] | rs1[4:0] | b011 | rd[4:0] | b1110011; - args_disass:"x%rd$d, %csr$d, x%rs1$d"; + args_disass:"{name(rd)}, {csr}, {name(rs1)}"; val xrd[XLEN] <= CSR[csr]; val xrs1[XLEN] <= X[rs1]; if(rd!=0) X[rd] <= xrd; @@ -300,13 +331,13 @@ InsructionSet RV32IBase { } CSRRWI { encoding: csr[11:0] | zimm[4:0] | b101 | rd[4:0] | b1110011; - args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; + args_disass:"{name(rd)}, {csr}, {zimm:#0x}"; if(rd!=0) X[rd] <= CSR[csr]; CSR[csr] <= zext(zimm); } CSRRSI { encoding: csr[11:0] | zimm[4:0] | b110 | rd[4:0] | b1110011; - args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; + args_disass:"{name(rd)}, {csr}, {zimm:#0x}"; val res[XLEN] <= CSR[csr]; if(zimm!=0) CSR[csr] <= res | zext(zimm); // make sure rd is written after csr write succeeds @@ -314,7 +345,7 @@ InsructionSet RV32IBase { } CSRRCI { encoding: csr[11:0] | zimm[4:0] | b111 | rd[4:0] | b1110011; - args_disass:"x%rd$d, %csr$d, 0x%zimm$x"; + args_disass:"{name(rd)}, {csr}, {zimm:#0x}"; val res[XLEN] <= CSR[csr]; if(rd!=0) X[rd] <= res; if(zimm!=0) CSR[csr] <= res & ~zext(zimm, XLEN); diff --git a/riscv/gen_input/RV32M.core_desc b/riscv/gen_input/RV32M.core_desc index a115295..c1c456c 100644 --- a/riscv/gen_input/RV32M.core_desc +++ b/riscv/gen_input/RV32M.core_desc @@ -7,7 +7,7 @@ InsructionSet RV32M extends RV32IBase { instructions{ MUL{ encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); X[rd]<= zext(res , XLEN); @@ -15,7 +15,7 @@ InsructionSet RV32M extends RV32IBase { } MULH { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= sext(X[rs1], MAXLEN) * sext(X[rs2], MAXLEN); X[rd]<= zext(res >> XLEN, XLEN); @@ -23,7 +23,7 @@ InsructionSet RV32M extends RV32IBase { } MULHSU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= sext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); X[rd]<= zext(res >> XLEN, XLEN); @@ -31,7 +31,7 @@ InsructionSet RV32M extends RV32IBase { } MULHU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val res[MAXLEN] <= zext(X[rs1], MAXLEN) * zext(X[rs2], MAXLEN); X[rd]<= zext(res >> XLEN, XLEN); @@ -39,7 +39,7 @@ InsructionSet RV32M extends RV32IBase { } DIV { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0){ val M1[XLEN] <= -1; @@ -57,7 +57,7 @@ InsructionSet RV32M extends RV32IBase { } DIVU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) X[rd] <= zext(X[rs1], 32) / zext(X[rs2], 32); @@ -67,7 +67,7 @@ InsructionSet RV32M extends RV32IBase { } REM { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) { val M1[XLEN] <= -1; @@ -85,7 +85,7 @@ InsructionSet RV32M extends RV32IBase { } REMU { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0110011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ if(X[rs2]!=0) X[rd] <= zext(X[rs1], 32) % zext(X[rs2], 32); diff --git a/riscv/gen_input/RV64A.core_desc b/riscv/gen_input/RV64A.core_desc index 5080d11..c95f7d2 100644 --- a/riscv/gen_input/RV64A.core_desc +++ b/riscv/gen_input/RV64A.core_desc @@ -10,7 +10,7 @@ InsructionSet RV64A extends RV64IBase { instructions{ LR.D { encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d"; + args_disass: "{name(rd)}, {name(rs1)}"; if(rd!=0){ val offs[XLEN] <= X[rs1]; X[rd]<= sext(MEM[offs]{64}, XLEN); @@ -19,7 +19,7 @@ InsructionSet RV64A extends RV64IBase { } SC.D { encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)}"; val offs[XLEN] <= X[rs1]; val res[64] <= RES[offs]; if(res!=0){ @@ -31,14 +31,14 @@ InsructionSet RV64A extends RV64IBase { } AMOSWAP.D{ encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; if(rd!=0) X[rd] <= sext(MEM[offs]{64}); MEM[offs]{64} <= X[rs2]; } AMOADD.D{ encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd]<=res; @@ -47,7 +47,7 @@ InsructionSet RV64A extends RV64IBase { } AMOXOR.D{ encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; @@ -56,7 +56,7 @@ InsructionSet RV64A extends RV64IBase { } AMOAND.D{ encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; @@ -65,7 +65,7 @@ InsructionSet RV64A extends RV64IBase { } AMOOR.D { encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; @@ -74,7 +74,7 @@ InsructionSet RV64A extends RV64IBase { } AMOMIN.D{ encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; @@ -83,7 +83,7 @@ InsructionSet RV64A extends RV64IBase { } AMOMAX.D{ encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; @@ -92,7 +92,7 @@ InsructionSet RV64A extends RV64IBase { } AMOMINU.D{ encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= zext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; @@ -101,7 +101,7 @@ InsructionSet RV64A extends RV64IBase { } AMOMAXU.D{ encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; - args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%a,rel=%rl)"; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; val res[XLEN] <= zext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; diff --git a/riscv/gen_input/RV64IBase.core_desc b/riscv/gen_input/RV64IBase.core_desc index e44f754..45c2242 100644 --- a/riscv/gen_input/RV64IBase.core_desc +++ b/riscv/gen_input/RV64IBase.core_desc @@ -4,40 +4,40 @@ InsructionSet RV64IBase extends RV32IBase { instructions{ LWU { // 80000104: 0000ef03 lwu t5,0(ra) encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s+imm; if(rd!=0) X[rd]<=zext(MEM[offs]{32}); } LD{ encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000011; - args_disass:"x%rd$d, %imm%(x%rs1$d)"; + args_disass:"{name(rd)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s + imm; if(rd!=0) X[rd]<=sext(MEM[offs]{64}); } SD{ encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100011; - args_disass:"x%rs2$d, %imm%(x%rs1$d)"; + args_disass:"{name(rs2)}, {imm}({name(rs1)})"; val offs[XLEN] <= X[rs1]'s + imm; MEM[offs]{64} <= X[rs2]; } SLLI { encoding: b000000 | shamt[5:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(rd != 0) X[rd] <= shll(X[rs1], shamt); } SRLI { encoding: b000000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(rd != 0) X[rd] <= shrl(X[rs1], shamt); } SRAI { encoding: b010000 | shamt[5:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(rd != 0) X[rd] <= shra(X[rs1], shamt); } ADDIW { encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011; - args_disass:"x%rd$d, x%rs1$d, %imm%"; + args_disass:"{name(rd)}, {name(rs1)}, {imm}"; if(rd != 0){ val res[32] <= X[rs1]{32}'s + imm; X[rd] <= sext(res); @@ -45,7 +45,7 @@ InsructionSet RV64IBase extends RV32IBase { } SLLIW { encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0011011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(rd != 0){ val sh_val[32] <= shll(X[rs1]{32}, shamt); X[rd] <= sext(sh_val); @@ -53,7 +53,7 @@ InsructionSet RV64IBase extends RV32IBase { } SRLIW { encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(rd != 0){ val sh_val[32] <= shrl(X[rs1]{32}, shamt); X[rd] <= sext(sh_val); @@ -61,7 +61,7 @@ InsructionSet RV64IBase extends RV32IBase { } SRAIW { encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0011011; - args_disass:"x%rd$d, x%rs1$d, %shamt%"; + args_disass:"{name(rd)}, {name(rs1)}, {shamt}"; if(rd != 0){ val sh_val[32] <= shra(X[rs1]{32}, shamt); X[rd] <= sext(sh_val); @@ -83,7 +83,7 @@ InsructionSet RV64IBase extends RV32IBase { } SLLW { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val mask[32] <= 0x1f; val count[32] <= X[rs2]{32} & mask; @@ -93,7 +93,7 @@ InsructionSet RV64IBase extends RV32IBase { } SRLW { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val mask[32] <= 0x1f; val count[32] <= X[rs2]{32} & mask; @@ -103,7 +103,7 @@ InsructionSet RV64IBase extends RV32IBase { } SRAW { encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ val mask[32] <= 0x1f; val count[32] <= X[rs2]{32} & mask; diff --git a/riscv/gen_input/RV64M.core_desc b/riscv/gen_input/RV64M.core_desc index cb53da9..fa8b210 100644 --- a/riscv/gen_input/RV64M.core_desc +++ b/riscv/gen_input/RV64M.core_desc @@ -4,35 +4,35 @@ InsructionSet RV64M extends RV64IBase { instructions{ MULW{ encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ X[rd]<= X[rs1] * X[rs2]; } } DIVW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ X[rd] <= X[rs1]s / X[rs2]s; } } DIVUW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ X[rd] <= X[rs1] / X[rs2]; } } REMW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ X[rd] <= X[rs1]s % X[rs2]s; } } REMUW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; - args_disass:"x%rd$d, x%rs1$d, x%rs2$d"; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ X[rd] <= X[rs1] % X[rs2]; } diff --git a/riscv/gen_input/templates/incl-CORENAME.h.gtl b/riscv/gen_input/templates/incl-CORENAME.h.gtl index 95052f8..139d39d 100644 --- a/riscv/gen_input/templates/incl-CORENAME.h.gtl +++ b/riscv/gen_input/templates/incl-CORENAME.h.gtl @@ -33,9 +33,44 @@ <% import com.minres.coredsl.coreDsl.Register import com.minres.coredsl.coreDsl.RegisterFile +import com.minres.coredsl.coreDsl.RegisterAlias def getTypeSize(size){ if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8 } +def getOriginalName(reg){ + if( reg.original instanceof RegisterFile) { + if( reg.index != null ) { + return reg.original.name+generator.generateHostCode(reg.index) + } else { + return reg.original.name + } + } else if(reg.original instanceof Register){ + return reg.original.name + } +} +def getRegisterNames(){ + def regNames = [] + allRegs.each { reg -> + if( reg instanceof RegisterFile) { + (reg.range.right..reg.range.left).each{ + regNames+=reg.name.toLowerCase()+it + } + } else if(reg instanceof Register){ + regNames+=reg.name.toLowerCase() + } + } + return regNames +} +def getRegisterAliasNames(){ + def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} + return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> + if( reg instanceof RegisterFile) { + return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } + } else if(reg instanceof Register){ + regMap[reg.name]?:reg.name.toLowerCase() + } + }.flatten() +} %> #ifndef _${coreDef.name.toUpperCase()}_H_ #define _${coreDef.name.toUpperCase()}_H_ @@ -54,6 +89,12 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { constexpr static char const* const core_type = "${coreDef.name}"; + static constexpr std::array reg_names{ + {"${getRegisterNames().join("\", \"")}"}}; + + static constexpr std::array reg_aliases{ + {"${getRegisterAliasNames().join("\", \"")}"}}; + enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}}; constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0}; @@ -65,7 +106,7 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { ${reg.name}${it},<% } } else if(reg instanceof Register){ %> - ${reg.name},<% + ${reg.name},<% } }%> NUM_REGS, @@ -74,7 +115,12 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, - ICOUNT + ICOUNT<% + allRegs.each { reg -> + if(reg instanceof RegisterAlias){ def aliasname=getOriginalName(reg)%>, + ${reg.name} = ${aliasname}<% + } + }%> }; using reg_t = uint${regDataWidth}_t; @@ -87,16 +133,12 @@ template <> struct traits<${coreDef.name.toLowerCase()}> { using phys_addr_t = iss::typed_addr_t; - static constexpr std::array ${coreDef.name}_reg_size{ + static constexpr std::array reg_bit_widths{ {${regSizes.join(",")}}}; - static constexpr unsigned reg_bit_width(unsigned r) { return ${coreDef.name}_reg_size[r]; } - - static constexpr std::array ${coreDef.name}_reg_byte_offset{ + static constexpr std::array reg_byte_offsets{ {${regOffsets.join(",")}}}; - constexpr static unsigned reg_byte_offset(unsigned r) { 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 }; diff --git a/riscv/gen_input/templates/src-CORENAME.cpp.gtl b/riscv/gen_input/templates/src-CORENAME.cpp.gtl index 58d0342..83dd26c 100644 --- a/riscv/gen_input/templates/src-CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/src-CORENAME.cpp.gtl @@ -49,8 +49,8 @@ extern "C" { using namespace iss::arch; -constexpr std::array iss::arch::traits::${coreDef.name}_reg_size; -constexpr std::array iss::arch::traits::${coreDef.name}_reg_byte_offset; +constexpr std::array iss::arch::traits::reg_sizes; +constexpr std::array iss::arch::traits::reg_byte_offset; ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { reg.icount = 0; diff --git a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl index c6f8d37..c989810 100644 --- a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include @@ -54,10 +54,11 @@ namespace ${coreDef.name.toLowerCase()} { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; +using namespace iss::vm::llvm; -template class vm_impl : public vm::vm_base { +template class vm_impl : public vm_base { public: - using super = typename vm::vm_base; + using super = typename iss::vm::llvm::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; @@ -71,31 +72,32 @@ public: target_adapter_if *accquire_target_adapter(server_if *srv) override { 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; + if (vm_base::tgt_adapter == nullptr) + vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); + return vm_base::tgt_adapter; } protected: - using vm::vm_base::get_reg_ptr; + using vm_base::get_reg_ptr; - template inline llvm::ConstantInt *size(T type) { - return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); + inline const char *name(size_t index){return traits::reg_aliases.at(index);} + + template inline ConstantInt *size(T type) { + return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); } - void setup_module(llvm::Module *m) override { + void setup_module(Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } - inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { + inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } - std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, - llvm::BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override; - void gen_leave_behavior(llvm::BasicBlock *leave_blk) override; + void gen_leave_behavior(BasicBlock *leave_blk) override; void gen_raise_trap(uint16_t trap_id, uint16_t cause); @@ -103,17 +105,17 @@ protected: void gen_wait(unsigned type); - void gen_trap_behavior(llvm::BasicBlock *) override; + void gen_trap_behavior(BasicBlock *) override; - void gen_trap_check(llvm::BasicBlock *bb); + void gen_trap_check(BasicBlock *bb); - inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { + inline 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)); + 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); } @@ -124,9 +126,9 @@ protected: 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); + using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, + code_word_t instr, + BasicBlock *bb); std::array lut; std::array lut_00, lut_01, lut_10; @@ -192,15 +194,14 @@ private: /* 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{%> + std::tuple __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){<%instr.code.eachLine{%> ${it}<%}%> } <%}%> /**************************************************************************** * end opcode definitions ****************************************************************************/ - std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, - llvm::BasicBlock *bb) { + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, 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); @@ -212,7 +213,7 @@ private: 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); + return std::make_tuple(BRANCH, nullptr); } }; @@ -225,7 +226,7 @@ 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) { +: vm_base(core, core_id, cluster_id) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -237,8 +238,8 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) } template -std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, llvm::BasicBlock *this_block) { +std::tuple +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, 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; @@ -270,7 +271,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return (this->*f)(pc, insn, this_block); } -template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { +template void vm_impl::gen_leave_behavior(BasicBlock *leave_blk) { this->builder.SetInsertPoint(leave_blk); this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } @@ -278,45 +279,39 @@ template void vm_impl::gen_leave_behavior(llvm::BasicBlock template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), 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); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_wait(unsigned type) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) }; this->builder.CreateCall(this->mod->getFunction("wait"), args); } -template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { +template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{this->core_ptr, this->adj_to64(trap_state_val), - this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; + 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) { +template inline void vm_impl::gen_trap_check(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))), + ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); } diff --git a/riscv/gen_input/templates/vm_riscv.in.cpp b/riscv/gen_input/templates/vm_riscv.in.cpp deleted file mode 100644 index cead0af..0000000 --- a/riscv/gen_input/templates/vm_riscv.in.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2017, 2018 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 -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -namespace iss { -namespace vm { -namespace fp_impl { -void add_fp_functions_2_module(llvm::Module *, unsigned); -} -} - -namespace CORE_DEF_NAME { -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) override { - 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())); - } - - void setup_module(llvm::Module *m) override { - super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); - } - - inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { - return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); - } - - std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, - 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; - }; - - /* «start generated code» */ - std::array instr_descr = {{}}; - /* «end generated code» */ - /**************************************************************************** - * 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 { - auto *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 - ++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); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); -} - -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); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), 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); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); - 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 CORE_DEF_NAME - -template <> std::unique_ptr create(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { - auto ret = new CORE_DEF_NAME::vm_impl(*core, dump); - if (port != 0) debugger::server::run_server(ret, port); - return std::unique_ptr(ret); -} - -} // namespace iss diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h index a8a9bab..d6fbc76 100644 --- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h +++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h @@ -40,6 +40,7 @@ #include "iss/instrumentation_if.h" #include "iss/log_categories.h" #include "iss/vm_if.h" +#include #include #include #include @@ -478,10 +479,8 @@ public: void wait_until(uint64_t flags) override; void disass_output(uint64_t pc, const std::string instr) override { - std::stringstream s; - s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0') - << std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]"; - CLOG(INFO, disass) << "0x" << std::setw(16) << std::setfill('0') << std::hex << pc << "\t\t" << instr << "\t" << s.str(); + CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", + pc, instr, lvl[this->reg.machine_state], (reg_t)state.mstatus, this->reg.icount); }; iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; } diff --git a/riscv/incl/iss/arch/rv32gc.h b/riscv/incl/iss/arch/rv32gc.h index da24040..649a4c5 100644 --- a/riscv/incl/iss/arch/rv32gc.h +++ b/riscv/incl/iss/arch/rv32gc.h @@ -1,53 +1,59 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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. + * + *******************************************************************************/ + #ifndef _RV32GC_H_ #define _RV32GC_H_ +#include +#include #include #include -#include -#include namespace iss { namespace arch { struct rv32gc; -template<> -struct traits { +template <> struct traits { constexpr static char const* const core_type = "RV32GC"; + static constexpr std::array reg_names{ + {"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}}; + + static constexpr std::array reg_aliases{ + {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}}; + enum constants {XLEN=32, FLEN=64, PCLEN=32, MISA_VAL=0b1000000000101000001000100101101, PGSIZE=0x1000, PGMASK=0xfff}; constexpr static unsigned FP_REGS_SIZE = 64; @@ -125,7 +131,39 @@ struct traits { PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, - ICOUNT + ICOUNT, + ZERO = X0, + RA = X1, + SP = X2, + GP = X3, + TP = X4, + T0 = X5, + T1 = X6, + T2 = X7, + S0 = X8, + S1 = X9, + A0 = X10, + A1 = X11, + A2 = X12, + A3 = X13, + A4 = X14, + A5 = X15, + A6 = X16, + A7 = X17, + S2 = X18, + S3 = X19, + S4 = X20, + S5 = X21, + S6 = X22, + S7 = X23, + S8 = X24, + S9 = X25, + S10 = X26, + S11 = X27, + T3 = X28, + T4 = X29, + T5 = X30, + T6 = X31 }; using reg_t = uint32_t; @@ -138,21 +176,17 @@ struct traits { using phys_addr_t = iss::typed_addr_t; - constexpr static unsigned reg_bit_width(unsigned r) { - constexpr std::array RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,32,64}}; - return RV32GC_reg_size[r]; - } + static constexpr std::array reg_bit_widths{ + {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,32,32,64}}; - constexpr static unsigned reg_byte_offset(unsigned r) { - constexpr std::array RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,412,416,424}}; - return RV32GC_reg_byte_offset[r]; - } + static constexpr std::array reg_byte_offsets{ + {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,396,400,404,408,412,416,424}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); - enum sreg_flag_e {FLAGS}; + enum sreg_flag_e { FLAGS }; - enum mem_type_e {MEM, CSR, FENCE, RES}; + enum mem_type_e { MEM, CSR, FENCE, RES }; }; struct rv32gc: public arch_if { @@ -177,14 +211,13 @@ struct rv32gc: public arch_if { /// deprecated void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; - uint64_t get_icount() { return reg.icount;} + inline uint64_t get_icount() { return reg.icount; } inline bool should_stop() { return interrupt_sim; } inline phys_addr_t v2p(const iss::addr_t& addr){ - if(addr.space != traits::MEM || - addr.type == iss::address_type::PHYSICAL || - addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL){ + if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || + addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); } else return virt2phys(addr); @@ -194,8 +227,7 @@ struct rv32gc: public arch_if { virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - inline - uint32_t get_last_branch(){return reg.last_branch;} + inline uint32_t get_last_branch() { return reg.last_branch; } protected: struct RV32GC_regs { diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index 74a0183..d187084 100644 --- a/riscv/incl/iss/arch/rv32imac.h +++ b/riscv/incl/iss/arch/rv32imac.h @@ -30,6 +30,7 @@ * *******************************************************************************/ + #ifndef _RV32IMAC_H_ #define _RV32IMAC_H_ @@ -45,15 +46,15 @@ struct rv32imac; template <> struct traits { - constexpr static char const *const core_type = "RV32IMAC"; + constexpr static char const* const core_type = "RV32IMAC"; + + static constexpr std::array reg_names{ + {"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}}; + + static constexpr std::array reg_aliases{ + {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}}; - enum constants { - XLEN = 32, - PCLEN = 32, - MISA_VAL = 0b1000000000101000001000100000101, - PGSIZE = 0x1000, - PGMASK = 0xfff - }; + enum constants {XLEN=32, PCLEN=32, MISA_VAL=0b1000000000101000001000100000101, PGSIZE=0x1000, PGMASK=0xfff}; constexpr static unsigned FP_REGS_SIZE = 0; @@ -92,35 +93,61 @@ template <> struct traits { X31, PC, NUM_REGS, - NEXT_PC = NUM_REGS, + NEXT_PC=NUM_REGS, TRAP_STATE, PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, - ICOUNT + ICOUNT, + ZERO = X0, + RA = X1, + SP = X2, + GP = X3, + TP = X4, + T0 = X5, + T1 = X6, + T2 = X7, + S0 = X8, + S1 = X9, + A0 = X10, + A1 = X11, + A2 = X12, + A3 = X13, + A4 = X14, + A5 = X15, + A6 = X16, + A7 = X17, + S2 = X18, + S3 = X19, + S4 = X20, + S5 = X21, + S6 = X22, + S7 = X23, + S8 = X24, + S9 = X25, + S10 = X26, + S11 = X27, + T3 = X28, + T4 = X29, + T5 = X30, + T6 = X31 }; using reg_t = uint32_t; using addr_t = uint32_t; - using code_word_t = uint32_t; // TODO: check removal + using code_word_t = uint32_t; //TODO: check removal using virt_addr_t = iss::typed_addr_t; using phys_addr_t = iss::typed_addr_t; - static constexpr std::array RV32IMAC_reg_size{ - {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 64}}; + static constexpr std::array reg_bit_widths{ + {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; - constexpr static unsigned reg_bit_width(unsigned r) { return RV32IMAC_reg_size[r]; } - - static constexpr std::array RV32IMAC_reg_byte_offset{ - {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, - 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 160}}; - - constexpr static unsigned reg_byte_offset(unsigned r) { return RV32IMAC_reg_byte_offset[r]; } + static constexpr std::array reg_byte_offsets{ + {0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,160}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); @@ -129,41 +156,41 @@ template <> struct traits { enum mem_type_e { MEM, CSR, FENCE, RES }; }; -struct rv32imac : public arch_if { +struct rv32imac: public arch_if { using virt_addr_t = typename traits::virt_addr_t; using phys_addr_t = typename traits::phys_addr_t; - using reg_t = typename traits::reg_t; + using reg_t = typename traits::reg_t; using addr_t = typename traits::addr_t; rv32imac(); ~rv32imac(); - void reset(uint64_t address = 0) override; + void reset(uint64_t address=0) override; - uint8_t *get_regs_base_ptr() 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 {} + 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{}; + 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{}; + void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; inline uint64_t get_icount() { return reg.icount; } inline bool should_stop() { return interrupt_sim; } - inline phys_addr_t v2p(const iss::addr_t &addr) { + inline phys_addr_t v2p(const iss::addr_t& addr){ if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || - addr_mode[static_cast(addr.access) & 0x3] == address_type::PHYSICAL) { - return phys_addr_t(addr.access, addr.space, addr.val & traits::addr_mask); + addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { + return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); } else return virt2phys(addr); } - virtual phys_addr_t virt2phys(const iss::addr_t &addr); + virtual phys_addr_t virt2phys(const iss::addr_t& addr); virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } @@ -210,12 +237,14 @@ protected: } reg; std::array addr_mode; + + bool interrupt_sim=false; - bool interrupt_sim = false; + uint32_t get_fcsr(){return 0;} + void set_fcsr(uint32_t val){} - uint32_t get_fcsr() { return 0; } - void set_fcsr(uint32_t val) {} }; + } -} +} #endif /* _RV32IMAC_H_ */ diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h index be17b06..c14584f 100644 --- a/riscv/incl/iss/arch/rv64ia.h +++ b/riscv/incl/iss/arch/rv64ia.h @@ -1,53 +1,59 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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. + * + *******************************************************************************/ + #ifndef _RV64IA_H_ #define _RV64IA_H_ +#include +#include #include #include -#include -#include namespace iss { namespace arch { struct rv64ia; -template<> -struct traits { +template <> struct traits { constexpr static char const* const core_type = "RV64IA"; + static constexpr std::array reg_names{ + {"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}}; + + static constexpr std::array reg_aliases{ + {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}}; + enum constants {XLEN=64, PCLEN=64, MISA_VAL=0b10000000000001000000000100000001, PGSIZE=0x1000, PGMASK=0xfff}; constexpr static unsigned FP_REGS_SIZE = 0; @@ -92,7 +98,39 @@ struct traits { PENDING_TRAP, MACHINE_STATE, LAST_BRANCH, - ICOUNT + ICOUNT, + ZERO = X0, + RA = X1, + SP = X2, + GP = X3, + TP = X4, + T0 = X5, + T1 = X6, + T2 = X7, + S0 = X8, + S1 = X9, + A0 = X10, + A1 = X11, + A2 = X12, + A3 = X13, + A4 = X14, + A5 = X15, + A6 = X16, + A7 = X17, + S2 = X18, + S3 = X19, + S4 = X20, + S5 = X21, + S6 = X22, + S7 = X23, + S8 = X24, + S9 = X25, + S10 = X26, + S11 = X27, + T3 = X28, + T4 = X29, + T5 = X30, + T6 = X31 }; using reg_t = uint64_t; @@ -105,21 +143,17 @@ struct traits { using phys_addr_t = iss::typed_addr_t; - constexpr static unsigned reg_bit_width(unsigned r) { - constexpr std::array RV64IA_reg_size{{64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,64}}; - return RV64IA_reg_size[r]; - } + static constexpr std::array reg_bit_widths{ + {64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,32,64}}; - constexpr static unsigned reg_byte_offset(unsigned r) { - constexpr std::array RV64IA_reg_byte_offset{{0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,276,280,284,288,296}}; - return RV64IA_reg_byte_offset[r]; - } + static constexpr std::array reg_byte_offsets{ + {0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,276,280,284,288,296}}; static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); - enum sreg_flag_e {FLAGS}; + enum sreg_flag_e { FLAGS }; - enum mem_type_e {MEM, CSR, FENCE, RES}; + enum mem_type_e { MEM, CSR, FENCE, RES }; }; struct rv64ia: public arch_if { @@ -149,9 +183,8 @@ struct rv64ia: public arch_if { inline bool should_stop() { return interrupt_sim; } inline phys_addr_t v2p(const iss::addr_t& addr){ - if(addr.space != traits::MEM || - addr.type == iss::address_type::PHYSICAL || - addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL){ + if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || + addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); } else return virt2phys(addr); @@ -161,8 +194,7 @@ struct rv64ia: public arch_if { virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } - inline - uint32_t get_last_branch(){return reg.last_branch;} + inline uint32_t get_last_branch() { return reg.last_branch; } protected: struct RV64IA_regs { diff --git a/riscv/incl/iss/debugger/riscv_target_adapter.h b/riscv/incl/iss/debugger/riscv_target_adapter.h index 7133e34..e6ec40e 100644 --- a/riscv/incl/iss/debugger/riscv_target_adapter.h +++ b/riscv/incl/iss/debugger/riscv_target_adapter.h @@ -40,6 +40,7 @@ #include #include +#include #include namespace iss { @@ -180,8 +181,8 @@ status riscv_target_adapter::read_registers(std::vector &data, st avail.clear(); const uint8_t *reg_base = core->get_regs_base_ptr(); for (size_t reg_no = 0; reg_no < arch::traits::NUM_REGS; ++reg_no) { - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; - unsigned offset = traits::reg_byte_offset(reg_no); + auto reg_width = arch::traits::reg_bit_widths[static_cast::reg_e>(reg_no)] / 8; + unsigned offset = traits::reg_byte_offsets[reg_no]; for (size_t j = 0; j < reg_width; ++j) { data.push_back(*(reg_base + offset + j)); avail.push_back(0xff); @@ -215,8 +216,8 @@ template status riscv_target_adapter::write_registers(cons auto *reg_base = core->get_regs_base_ptr(); auto iter = data.data(); for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; - auto offset = traits::reg_byte_offset(reg_no); + auto reg_width = arch::traits::reg_bit_widths[static_cast::reg_e>(reg_no)] / 8; + auto offset = traits::reg_byte_offsets[reg_no]; std::copy(iter, iter + reg_width, reg_base); iter += 4; reg_base += offset; @@ -231,10 +232,10 @@ status riscv_target_adapter::read_single_register(unsigned int reg_no, std // auto reg_size = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; auto *reg_base = core->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(reg_no) / 8; + auto reg_width = arch::traits::reg_bit_widths[reg_no] / 8; data.resize(reg_width); avail.resize(reg_width); - auto offset = traits::reg_byte_offset(reg_no); + auto offset = traits::reg_byte_offsets[reg_no]; std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin()); std::fill(avail.begin(), avail.end(), 0xff); } else { @@ -251,8 +252,8 @@ template status riscv_target_adapter::write_single_register(unsigned int reg_no, const std::vector &data) { if (reg_no < 65) { auto *reg_base = core->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; - auto offset = traits::reg_byte_offset(reg_no); + auto reg_width = arch::traits::reg_bit_widths[static_cast::reg_e>(reg_no)] / 8; + auto offset = traits::reg_byte_offsets[reg_no]; std::copy(data.begin(), data.begin() + reg_width, reg_base + offset); } else { typed_addr_t a(iss::access_type::DEBUG_WRITE, traits::CSR, reg_no - 65); @@ -296,9 +297,7 @@ template status riscv_target_adapter::raw_query(std::strin template status riscv_target_adapter::threadinfo_query(int first, std::string &out_buf) { if (first) { - std::stringstream ss; - ss << "m" << std::hex << thread_idx.val; - out_buf = ss.str(); + out_buf = fmt::format("m{:x}", thread_idx.val); } else { out_buf = "l"; } @@ -348,8 +347,8 @@ template status riscv_target_adapter::resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, std::function stop_callback) { auto *reg_base = core->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(arch::traits::PC) / 8; - auto offset = traits::reg_byte_offset(arch::traits::PC); + auto reg_width = arch::traits::reg_bit_widths[arch::traits::PC] / 8; + auto offset = traits::reg_byte_offsets[arch::traits::PC]; const uint8_t *iter = reinterpret_cast(&addr); std::copy(iter, iter + reg_width, reg_base); return resume_from_current(step, sig, thread, stop_callback); diff --git a/riscv/src/internal/vm_rv32gc.cpp b/riscv/src/internal/vm_rv32gc.cpp index e6d195d..67c44ef 100644 --- a/riscv/src/internal/vm_rv32gc.cpp +++ b/riscv/src/internal/vm_rv32gc.cpp @@ -1,38 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 -// -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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 #include @@ -42,14 +38,14 @@ #include #include -#include +#include -#include #include +#include namespace iss { namespace vm { -namespace fp_impl{ +namespace fp_impl { void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -74,7 +70,7 @@ public: void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } - target_adapter_if *accquire_target_adapter(server_if *srv) { + target_adapter_if *accquire_target_adapter(server_if *srv) override { debugger_if::dbg_enabled = true; if (vm_base::tgt_adapter == nullptr) vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); @@ -84,6 +80,8 @@ public: protected: using vm_base::get_reg_ptr; + inline const char *name(size_t index){return traits::reg_aliases.at(index);} + template inline ConstantInt *size(T type) { return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); } @@ -97,8 +95,7 @@ protected: 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 &, - BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override; void gen_leave_behavior(BasicBlock *leave_blk) override; @@ -118,7 +115,7 @@ protected: inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), - this->get_type(traits::XLEN)); + this->get_type(traits::XLEN)); this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } @@ -130,16 +127,16 @@ protected: using this_class = vm_impl; using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, - code_word_t instr, - BasicBlock *bb); + code_word_t instr, + BasicBlock *bb); std::array lut; std::array lut_00, lut_01, lut_10; std::array lut_11; - std::array qlut; + std::array qlut; - std::array lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; + 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) { @@ -516,18 +513,19 @@ private: std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LUI"); - this->gen_sync(iss::PRE_SYNC, 0); + this->gen_sync(PRE_SYNC, 0); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -535,12 +533,12 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* Xtmp0_val = this->gen_const(32U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 0); + this->gen_sync(POST_SYNC, 0); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -550,18 +548,19 @@ private: std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AUIPC"); - this->gen_sync(iss::PRE_SYNC, 1); + this->gen_sync(PRE_SYNC, 1); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -569,16 +568,16 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 1); + this->gen_sync(POST_SYNC, 1); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -588,18 +587,19 @@ private: std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JAL"); - this->gen_sync(iss::PRE_SYNC, 2); + this->gen_sync(PRE_SYNC, 2); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -607,21 +607,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* PC_val = this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 2); + this->gen_sync(POST_SYNC, 2); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -630,19 +630,20 @@ private: std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); - this->gen_sync(iss::PRE_SYNC, 3); + this->gen_sync(PRE_SYNC, 3); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -652,9 +653,9 @@ private: Value* new_pc_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* align_val = this->builder.CreateAnd( new_pc_val, this->gen_const(32U, 0x1)); @@ -676,11 +677,11 @@ private: this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* PC_val = this->builder.CreateAnd( new_pc_val, @@ -692,7 +693,7 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - this->gen_sync(iss::POST_SYNC, 3); + this->gen_sync(POST_SYNC, 3); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -701,19 +702,20 @@ private: std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); - this->gen_sync(iss::PRE_SYNC, 4); + this->gen_sync(PRE_SYNC, 4); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -724,13 +726,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_EQ, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -738,7 +740,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 4); + this->gen_sync(POST_SYNC, 4); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -747,19 +749,20 @@ private: std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); - this->gen_sync(iss::PRE_SYNC, 5); + this->gen_sync(PRE_SYNC, 5); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -770,13 +773,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -784,7 +787,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 5); + this->gen_sync(POST_SYNC, 5); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -793,19 +796,20 @@ private: std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); - this->gen_sync(iss::PRE_SYNC, 6); + this->gen_sync(PRE_SYNC, 6); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -817,16 +821,16 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -834,7 +838,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 6); + this->gen_sync(POST_SYNC, 6); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -843,19 +847,20 @@ private: std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); - this->gen_sync(iss::PRE_SYNC, 7); + this->gen_sync(PRE_SYNC, 7); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -867,16 +872,16 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_SGE, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -884,7 +889,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 7); + this->gen_sync(POST_SYNC, 7); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -893,19 +898,20 @@ private: std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); - this->gen_sync(iss::PRE_SYNC, 8); + this->gen_sync(PRE_SYNC, 8); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -916,13 +922,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -930,7 +936,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 8); + this->gen_sync(POST_SYNC, 8); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -939,19 +945,20 @@ private: std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); - this->gen_sync(iss::PRE_SYNC, 9); + this->gen_sync(PRE_SYNC, 9); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -962,13 +969,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGE, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -976,7 +983,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 9); + this->gen_sync(POST_SYNC, 9); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -985,19 +992,20 @@ private: std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); - this->gen_sync(iss::PRE_SYNC, 10); + this->gen_sync(PRE_SYNC, 10); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1007,18 +1015,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 8/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 10); + this->gen_sync(POST_SYNC, 10); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1028,19 +1036,20 @@ private: std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); - this->gen_sync(iss::PRE_SYNC, 11); + this->gen_sync(PRE_SYNC, 11); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1050,18 +1059,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 16/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 11); + this->gen_sync(POST_SYNC, 11); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1071,19 +1080,20 @@ private: std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); - this->gen_sync(iss::PRE_SYNC, 12); + this->gen_sync(PRE_SYNC, 12); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1093,18 +1103,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 12); + this->gen_sync(POST_SYNC, 12); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1114,19 +1124,20 @@ private: std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); - this->gen_sync(iss::PRE_SYNC, 13); + this->gen_sync(PRE_SYNC, 13); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1136,18 +1147,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 8/8), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 13); + this->gen_sync(POST_SYNC, 13); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1157,19 +1168,20 @@ private: std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); - this->gen_sync(iss::PRE_SYNC, 14); + this->gen_sync(PRE_SYNC, 14); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1179,18 +1191,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 16/8), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 14); + this->gen_sync(POST_SYNC, 14); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1200,19 +1212,20 @@ private: std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); - this->gen_sync(iss::PRE_SYNC, 15); + this->gen_sync(PRE_SYNC, 15); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1222,16 +1235,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 15); + this->gen_sync(POST_SYNC, 15); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1241,19 +1254,20 @@ private: std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); - this->gen_sync(iss::PRE_SYNC, 16); + this->gen_sync(PRE_SYNC, 16); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1263,16 +1277,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 16); + this->gen_sync(POST_SYNC, 16); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1282,19 +1296,20 @@ private: std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); - this->gen_sync(iss::PRE_SYNC, 17); + this->gen_sync(PRE_SYNC, 17); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1304,16 +1319,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 17); + this->gen_sync(POST_SYNC, 17); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1323,19 +1338,20 @@ private: std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); - this->gen_sync(iss::PRE_SYNC, 18); + this->gen_sync(PRE_SYNC, 18); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1343,16 +1359,16 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 18); + this->gen_sync(POST_SYNC, 18); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1362,19 +1378,20 @@ private: std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); - this->gen_sync(iss::PRE_SYNC, 19); + this->gen_sync(PRE_SYNC, 19); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1382,21 +1399,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 19); + this->gen_sync(POST_SYNC, 19); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1406,19 +1423,20 @@ private: std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_sync(iss::PRE_SYNC, 20); + this->gen_sync(PRE_SYNC, 20); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1426,20 +1444,20 @@ private: 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){ + int32_t full_imm_val = imm; + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->gen_const(32U, full_imm_val)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 20); + this->gen_sync(POST_SYNC, 20); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1449,19 +1467,20 @@ private: std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); - this->gen_sync(iss::PRE_SYNC, 21); + this->gen_sync(PRE_SYNC, 21); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1469,14 +1488,16 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 21); + this->gen_sync(POST_SYNC, 21); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1486,19 +1507,20 @@ private: std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); - this->gen_sync(iss::PRE_SYNC, 22); + this->gen_sync(PRE_SYNC, 22); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1506,14 +1528,16 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 22); + this->gen_sync(POST_SYNC, 22); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1523,19 +1547,20 @@ private: std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); - this->gen_sync(iss::PRE_SYNC, 23); + this->gen_sync(PRE_SYNC, 23); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1543,14 +1568,16 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 23); + this->gen_sync(POST_SYNC, 23); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1560,19 +1587,20 @@ private: std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); - this->gen_sync(iss::PRE_SYNC, 24); + this->gen_sync(PRE_SYNC, 24); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1580,18 +1608,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 24); + this->gen_sync(POST_SYNC, 24); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1601,19 +1629,20 @@ private: std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); - this->gen_sync(iss::PRE_SYNC, 25); + this->gen_sync(PRE_SYNC, 25); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1621,18 +1650,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 25); + this->gen_sync(POST_SYNC, 25); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1642,19 +1671,20 @@ private: std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); - this->gen_sync(iss::PRE_SYNC, 26); + this->gen_sync(PRE_SYNC, 26); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1662,18 +1692,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 26); + this->gen_sync(POST_SYNC, 26); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1683,19 +1713,20 @@ private: std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); - this->gen_sync(iss::PRE_SYNC, 27); + this->gen_sync(PRE_SYNC, 27); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1703,14 +1734,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 27); + this->gen_sync(POST_SYNC, 27); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1720,19 +1751,20 @@ private: std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); - this->gen_sync(iss::PRE_SYNC, 28); + this->gen_sync(PRE_SYNC, 28); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1740,14 +1772,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 28); + this->gen_sync(POST_SYNC, 28); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1757,19 +1789,20 @@ private: std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); - this->gen_sync(iss::PRE_SYNC, 29); + this->gen_sync(PRE_SYNC, 29); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1777,16 +1810,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(32U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 29); + this->gen_sync(POST_SYNC, 29); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1796,19 +1831,20 @@ private: std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); - this->gen_sync(iss::PRE_SYNC, 30); + this->gen_sync(PRE_SYNC, 30); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1816,23 +1852,23 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 30); + this->gen_sync(POST_SYNC, 30); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1842,19 +1878,20 @@ private: std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); - this->gen_sync(iss::PRE_SYNC, 31); + this->gen_sync(PRE_SYNC, 31); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1862,25 +1899,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, false)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 31); + this->gen_sync(POST_SYNC, 31); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1890,19 +1927,20 @@ private: std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); - this->gen_sync(iss::PRE_SYNC, 32); + this->gen_sync(PRE_SYNC, 32); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1910,14 +1948,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 32); + this->gen_sync(POST_SYNC, 32); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1927,19 +1965,20 @@ private: std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); - this->gen_sync(iss::PRE_SYNC, 33); + this->gen_sync(PRE_SYNC, 33); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1947,16 +1986,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(32U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 33); + this->gen_sync(POST_SYNC, 33); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1966,19 +2007,20 @@ private: std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); - this->gen_sync(iss::PRE_SYNC, 34); + this->gen_sync(PRE_SYNC, 34); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1986,16 +2028,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(32U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 34); + this->gen_sync(POST_SYNC, 34); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2005,19 +2049,20 @@ private: std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); - this->gen_sync(iss::PRE_SYNC, 35); + this->gen_sync(PRE_SYNC, 35); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2025,14 +2070,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 35); + this->gen_sync(POST_SYNC, 35); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2042,19 +2087,20 @@ private: std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); - this->gen_sync(iss::PRE_SYNC, 36); + this->gen_sync(PRE_SYNC, 36); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2062,14 +2108,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 36); + this->gen_sync(POST_SYNC, 36); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2079,18 +2125,18 @@ private: std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); - this->gen_sync(iss::PRE_SYNC, 37); + this->gen_sync(PRE_SYNC, 37); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_succ_val = ((bit_sub<20,4>(instr))); - uint8_t fld_pred_val = ((bit_sub<24,4>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((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.CreateGlobalStringPtr("fence"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2100,15 +2146,15 @@ private: Value* FENCEtmp0_val = this->builder.CreateOr( this->builder.CreateShl( - this->gen_const(32U, fld_pred_val), + this->gen_const(32U, pred), this->gen_const(32U, 4)), - this->gen_const(32U, fld_succ_val)); + this->gen_const(32U, succ)); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 0), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 37); + this->gen_sync(POST_SYNC, 37); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2118,17 +2164,17 @@ private: std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_sync(iss::PRE_SYNC, 38); + this->gen_sync(PRE_SYNC, 38); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_imm_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((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.CreateGlobalStringPtr("fence_i"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2136,14 +2182,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* FENCEtmp0_val = this->gen_const(32U, fld_imm_val); + Value* FENCEtmp0_val = this->gen_const(32U, imm); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 1), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 38); + this->gen_sync(POST_SYNC, 38); this->gen_trap_check(this->leave_blk); return std::make_tuple(FLUSH, nullptr); } @@ -2152,14 +2198,14 @@ private: std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ECALL"); - this->gen_sync(iss::PRE_SYNC, 39); + this->gen_sync(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.CreateGlobalStringPtr("ecall"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2168,7 +2214,7 @@ private: pc=pc+4; this->gen_raise_trap(0, 11); - this->gen_sync(iss::POST_SYNC, 39); + this->gen_sync(POST_SYNC, 39); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2177,14 +2223,14 @@ private: std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_sync(iss::PRE_SYNC, 40); + this->gen_sync(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.CreateGlobalStringPtr("ebreak"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2193,7 +2239,7 @@ private: pc=pc+4; this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 40); + this->gen_sync(POST_SYNC, 40); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2202,14 +2248,14 @@ private: std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("URET"); - this->gen_sync(iss::PRE_SYNC, 41); + this->gen_sync(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.CreateGlobalStringPtr("uret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2218,7 +2264,7 @@ private: pc=pc+4; this->gen_leave_trap(0); - this->gen_sync(iss::POST_SYNC, 41); + this->gen_sync(POST_SYNC, 41); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2227,14 +2273,14 @@ private: std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRET"); - this->gen_sync(iss::PRE_SYNC, 42); + this->gen_sync(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.CreateGlobalStringPtr("sret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2243,7 +2289,7 @@ private: pc=pc+4; this->gen_leave_trap(1); - this->gen_sync(iss::POST_SYNC, 42); + this->gen_sync(POST_SYNC, 42); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2252,14 +2298,14 @@ private: std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MRET"); - this->gen_sync(iss::PRE_SYNC, 43); + this->gen_sync(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.CreateGlobalStringPtr("mret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2268,7 +2314,7 @@ private: pc=pc+4; this->gen_leave_trap(3); - this->gen_sync(iss::POST_SYNC, 43); + this->gen_sync(POST_SYNC, 43); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2277,14 +2323,14 @@ private: std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("WFI"); - this->gen_sync(iss::PRE_SYNC, 44); + this->gen_sync(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.CreateGlobalStringPtr("wfi"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2294,7 +2340,7 @@ private: this->gen_wait(1); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 44); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2304,16 +2350,16 @@ private: std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_sync(iss::PRE_SYNC, 45); + this->gen_sync(PRE_SYNC, 45); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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.CreateGlobalStringPtr("sfence.vma"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2321,18 +2367,18 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* FENCEtmp0_val = this->gen_const(32U, fld_rs1_val); + Value* FENCEtmp0_val = this->gen_const(32U, rs1); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 2), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - Value* FENCEtmp1_val = this->gen_const(32U, fld_rs2_val); + Value* FENCEtmp1_val = this->gen_const(32U, rs2); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 3), this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 45); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2342,19 +2388,20 @@ private: std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_sync(iss::PRE_SYNC, 46); + this->gen_sync(PRE_SYNC, 46); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2362,25 +2409,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* rs_val_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); + Value* rs_val_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); Value* CSRtmp0_val = rs_val_val; this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); Value* Xtmp1_val = csr_val_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } else { Value* CSRtmp2_val = rs_val_val; this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 46); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2390,19 +2437,20 @@ private: std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_sync(iss::PRE_SYNC, 47); + this->gen_sync(PRE_SYNC, 47); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2410,23 +2458,23 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - Value* xrs1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_rs1_val != 0){ + if(rs1 != 0){ Value* CSRtmp1_val = this->builder.CreateOr( xrd_val, xrs1_val); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 47); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2436,19 +2484,20 @@ private: std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_sync(iss::PRE_SYNC, 48); + this->gen_sync(PRE_SYNC, 48); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2456,23 +2505,23 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - Value* xrs1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_rs1_val != 0){ + if(rs1 != 0){ Value* CSRtmp1_val = this->builder.CreateAnd( xrd_val, this->builder.CreateNot(xrs1_val)); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 48); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2482,19 +2531,20 @@ private: std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_sync(iss::PRE_SYNC, 49); + this->gen_sync(PRE_SYNC, 49); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2502,20 +2552,20 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* CSRtmp1_val = this->gen_ext( - this->gen_const(32U, fld_zimm_val), + this->gen_const(32U, zimm), 32, false); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 49); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2525,19 +2575,20 @@ private: std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_sync(iss::PRE_SYNC, 50); + this->gen_sync(PRE_SYNC, 50); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2545,25 +2596,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - if(fld_zimm_val != 0){ + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + if(zimm != 0){ Value* CSRtmp0_val = this->builder.CreateOr( res_val, this->gen_ext( - this->gen_const(32U, fld_zimm_val), + this->gen_const(32U, zimm), 32, false)); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); } - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp1_val = res_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 50); + this->gen_sync(POST_SYNC, 50); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2573,19 +2624,20 @@ private: std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_sync(iss::PRE_SYNC, 51); + this->gen_sync(PRE_SYNC, 51); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2593,25 +2645,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - if(fld_rd_val != 0){ + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_zimm_val != 0){ + if(zimm != 0){ Value* CSRtmp1_val = this->builder.CreateAnd( res_val, this->builder.CreateNot(this->gen_ext( - this->gen_const(32U, fld_zimm_val), + this->gen_const(32U, zimm), 32, false))); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 51); + this->gen_sync(POST_SYNC, 51); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2621,19 +2673,20 @@ private: std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MUL"); - this->gen_sync(iss::PRE_SYNC, 52); + this->gen_sync(PRE_SYNC, 52); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2641,24 +2694,24 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, false)); Value* Xtmp0_val = this->gen_ext( res_val, 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 52); + this->gen_sync(POST_SYNC, 52); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2668,19 +2721,20 @@ private: std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULH"); - this->gen_sync(iss::PRE_SYNC, 53); + this->gen_sync(PRE_SYNC, 53); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2688,14 +2742,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, true)); Value* Xtmp0_val = this->gen_ext( @@ -2704,10 +2758,10 @@ private: this->gen_const(32U, 32)), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 53); + this->gen_sync(POST_SYNC, 53); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2717,19 +2771,20 @@ private: std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHSU"); - this->gen_sync(iss::PRE_SYNC, 54); + this->gen_sync(PRE_SYNC, 54); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2737,14 +2792,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, false)); Value* Xtmp0_val = this->gen_ext( @@ -2753,10 +2808,10 @@ private: this->gen_const(32U, 32)), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 54); + this->gen_sync(POST_SYNC, 54); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2766,19 +2821,20 @@ private: std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHU"); - this->gen_sync(iss::PRE_SYNC, 55); + this->gen_sync(PRE_SYNC, 55); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2786,14 +2842,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, false)); Value* Xtmp0_val = this->gen_ext( @@ -2802,10 +2858,10 @@ private: this->gen_const(32U, 32)), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 55); + this->gen_sync(POST_SYNC, 55); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2815,19 +2871,20 @@ private: std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIV"); - this->gen_sync(iss::PRE_SYNC, 56); + this->gen_sync(PRE_SYNC, 56); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2835,7 +2892,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -2843,7 +2900,7 @@ private: // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -2859,7 +2916,7 @@ private: this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, true), this->gen_ext( this->gen_const(32U, MMIN_val), @@ -2876,7 +2933,7 @@ private: this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true), this->gen_ext( this->gen_const(32U, M1_val), @@ -2886,19 +2943,19 @@ private: this->builder.SetInsertPoint(bb_then); { Value* Xtmp0_val = this->gen_const(32U, MMIN_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { Value* Xtmp1_val = this->builder.CreateSDiv( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 3), + this->gen_reg_load(rs1 + traits::X0, 3), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 3), + this->gen_reg_load(rs2 + traits::X0, 3), 32, true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2910,12 +2967,12 @@ private: { Value* Xtmp2_val = this->builder.CreateSDiv( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 2), + this->gen_reg_load(rs1 + traits::X0, 2), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2926,7 +2983,7 @@ private: this->builder.SetInsertPoint(bb_else); { Value* Xtmp3_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2934,7 +2991,7 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 56); + this->gen_sync(POST_SYNC, 56); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2944,19 +3001,20 @@ private: std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVU"); - this->gen_sync(iss::PRE_SYNC, 57); + this->gen_sync(PRE_SYNC, 57); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2964,7 +3022,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -2972,7 +3030,7 @@ private: // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -2980,20 +3038,20 @@ private: { Value* Xtmp0_val = this->builder.CreateUDiv( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1), 32, false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3001,7 +3059,7 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 57); + this->gen_sync(POST_SYNC, 57); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3011,19 +3069,20 @@ private: std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REM"); - this->gen_sync(iss::PRE_SYNC, 58); + this->gen_sync(PRE_SYNC, 58); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3031,7 +3090,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -3039,7 +3098,7 @@ private: // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3055,7 +3114,7 @@ private: this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, true), this->gen_ext( this->gen_const(32U, MMIN_val), @@ -3072,7 +3131,7 @@ private: this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true), this->gen_ext( this->gen_const(32U, M1_val), @@ -3082,21 +3141,21 @@ private: this->builder.SetInsertPoint(bb_then); { Value* Xtmp0_val = this->gen_const(32U, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { Value* Xtmp1_val = this->builder.CreateURem( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 3), + this->gen_reg_load(rs1 + traits::X0, 3), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 3), + this->gen_reg_load(rs2 + traits::X0, 3), 32, true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3108,14 +3167,14 @@ private: { Value* Xtmp2_val = this->builder.CreateURem( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 2), + this->gen_reg_load(rs1 + traits::X0, 2), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3125,8 +3184,8 @@ private: this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - Value* Xtmp3_val = this->gen_reg_load(fld_rs1_val + traits::X0, 1); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp3_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3134,7 +3193,7 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 58); + this->gen_sync(POST_SYNC, 58); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3144,19 +3203,20 @@ private: std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMU"); - this->gen_sync(iss::PRE_SYNC, 59); + this->gen_sync(PRE_SYNC, 59); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3164,7 +3224,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -3172,7 +3232,7 @@ private: // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3180,20 +3240,20 @@ private: { Value* Xtmp0_val = this->builder.CreateURem( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1), 32, false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - Value* Xtmp1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 1); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3201,7 +3261,7 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 59); + this->gen_sync(POST_SYNC, 59); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3211,20 +3271,21 @@ private: std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); - this->gen_sync(iss::PRE_SYNC, 60); + this->gen_sync(PRE_SYNC, 60); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3232,13 +3293,13 @@ private: 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 + traits::X0, 0); + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* REStmp1_val = this->gen_ext( this->builder.CreateNeg(this->gen_const(8U, 1)), 32, @@ -3249,7 +3310,7 @@ private: this->builder.CreateZExtOrTrunc(REStmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 60); + this->gen_sync(POST_SYNC, 60); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3259,21 +3320,22 @@ private: std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); - this->gen_sync(iss::PRE_SYNC, 61); + this->gen_sync(PRE_SYNC, 61); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3281,7 +3343,7 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); @@ -3295,7 +3357,7 @@ private: bbnext); this->builder.SetInsertPoint(bb_then); { - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 1); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); this->gen_write_mem( traits::MEM, offs_val, @@ -3305,7 +3367,7 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp1_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3314,10 +3376,10 @@ private: this->gen_const(32U, 0), this->gen_const(32U, 1), 32); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 61); + this->gen_sync(POST_SYNC, 61); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3327,21 +3389,22 @@ private: std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); - this->gen_sync(iss::PRE_SYNC, 62); + this->gen_sync(PRE_SYNC, 62); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3349,21 +3412,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - Value* MEMtmp1_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 62); + this->gen_sync(POST_SYNC, 62); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3373,21 +3436,22 @@ private: std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); - this->gen_sync(iss::PRE_SYNC, 63); + this->gen_sync(PRE_SYNC, 63); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3395,25 +3459,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAdd( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 63); + this->gen_sync(POST_SYNC, 63); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3423,21 +3487,22 @@ private: std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); - this->gen_sync(iss::PRE_SYNC, 64); + this->gen_sync(PRE_SYNC, 64); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3445,25 +3510,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateXor( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 64); + this->gen_sync(POST_SYNC, 64); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3473,21 +3538,22 @@ private: std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); - this->gen_sync(iss::PRE_SYNC, 65); + this->gen_sync(PRE_SYNC, 65); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3495,25 +3561,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAnd( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 65); + this->gen_sync(POST_SYNC, 65); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3523,21 +3589,22 @@ private: std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); - this->gen_sync(iss::PRE_SYNC, 66); + this->gen_sync(PRE_SYNC, 66); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3545,25 +3612,25 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateOr( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 66); + this->gen_sync(POST_SYNC, 66); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3573,21 +3640,22 @@ private: std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); - this->gen_sync(iss::PRE_SYNC, 67); + this->gen_sync(PRE_SYNC, 67); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3595,14 +3663,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -3611,9 +3679,9 @@ private: res1_val, 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3622,7 +3690,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 67); + this->gen_sync(POST_SYNC, 67); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3632,21 +3700,22 @@ private: std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); - this->gen_sync(iss::PRE_SYNC, 68); + this->gen_sync(PRE_SYNC, 68); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3654,14 +3723,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -3670,9 +3739,9 @@ private: res1_val, 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3681,7 +3750,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 68); + this->gen_sync(POST_SYNC, 68); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3691,21 +3760,22 @@ private: std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); - this->gen_sync(iss::PRE_SYNC, 69); + this->gen_sync(PRE_SYNC, 69); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3713,21 +3783,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGT, res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3736,7 +3806,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 69); + this->gen_sync(POST_SYNC, 69); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3746,21 +3816,22 @@ private: std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); - this->gen_sync(iss::PRE_SYNC, 70); + this->gen_sync(PRE_SYNC, 70); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3768,21 +3839,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3791,7 +3862,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 70); + this->gen_sync(POST_SYNC, 70); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3801,18 +3872,19 @@ private: std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI4SPN"); - this->gen_sync(iss::PRE_SYNC, 71); + this->gen_sync(PRE_SYNC, 71); - uint8_t fld_rd_val = ((bit_sub<2,3>(instr))); - uint16_t fld_imm_val = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4)); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint16_t imm = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3820,15 +3892,15 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_imm_val == 0){ + if(imm == 0){ this->gen_raise_trap(0, 2); } Value* Xtmp0_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 71); + this->gen_sync(POST_SYNC, 71); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3838,19 +3910,20 @@ private: std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LW"); - this->gen_sync(iss::PRE_SYNC, 72); + this->gen_sync(PRE_SYNC, 72); - uint8_t fld_rd_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {uimm:#05x}", fmt::arg("mnemonic", "c.lw"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs1", name(8+rs1)), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3859,12 +3932,12 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 72); + this->gen_sync(POST_SYNC, 72); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3874,19 +3947,20 @@ private: std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SW"); - this->gen_sync(iss::PRE_SYNC, 73); + this->gen_sync(PRE_SYNC, 73); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {uimm:#05x}", fmt::arg("mnemonic", "c.sw"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3895,15 +3969,15 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 73); + this->gen_sync(POST_SYNC, 73); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3913,18 +3987,19 @@ private: std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI"); - this->gen_sync(iss::PRE_SYNC, 74); + this->gen_sync(PRE_SYNC, 74); - int8_t fld_imm_val = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3934,12 +4009,12 @@ private: Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rs1_val + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 74); + this->gen_sync(POST_SYNC, 74); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3949,14 +4024,14 @@ private: std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.NOP"); - this->gen_sync(iss::PRE_SYNC, 75); + this->gen_sync(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.CreateGlobalStringPtr("c.nop"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3966,7 +4041,7 @@ private: /* TODO: describe operations for C.NOP ! */ this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 75); + this->gen_sync(POST_SYNC, 75); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3976,17 +4051,18 @@ private: std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JAL"); - this->gen_sync(iss::PRE_SYNC, 76); + this->gen_sync(PRE_SYNC, 76); - int16_t fld_imm_val = signextend((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) | (bit_sub<12,1>(instr) << 11)); + int16_t imm = signextend((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) | (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; + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), + fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4002,11 +4078,11 @@ private: this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 76); + this->gen_sync(POST_SYNC, 76); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4015,18 +4091,19 @@ private: std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LI"); - this->gen_sync(iss::PRE_SYNC, 77); + this->gen_sync(PRE_SYNC, 77); - int8_t fld_imm_val = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4034,13 +4111,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_rd_val == 0){ + if(rd == 0){ this->gen_raise_trap(0, 2); } - Value* Xtmp0_val = this->gen_const(32U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 77); + this->gen_sync(POST_SYNC, 77); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4050,18 +4127,19 @@ private: std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LUI"); - this->gen_sync(iss::PRE_SYNC, 78); + this->gen_sync(PRE_SYNC, 78); - int32_t fld_imm_val = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); + uint8_t rd = ((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 % (uint64_t)fld_imm_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4069,16 +4147,16 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_rd_val == 0){ + if(rd == 0){ this->gen_raise_trap(0, 2); } - if(fld_imm_val == 0){ + if(imm == 0){ this->gen_raise_trap(0, 2); } - Value* Xtmp0_val = this->gen_const(32U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 78); + this->gen_sync(POST_SYNC, 78); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4088,17 +4166,18 @@ private: std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI16SP"); - this->gen_sync(iss::PRE_SYNC, 79); + this->gen_sync(PRE_SYNC, 79); - int16_t fld_imm_val = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (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; + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), + fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4110,10 +4189,10 @@ private: this->gen_ext( this->gen_reg_load(2 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 79); + this->gen_sync(POST_SYNC, 79); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4123,18 +4202,19 @@ private: std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SRLI"); - this->gen_sync(iss::PRE_SYNC, 80); + this->gen_sync(PRE_SYNC, 80); - uint8_t fld_shamt_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4142,13 +4222,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rs1_idx_val = fld_rs1_val + 8; + uint8_t rs1_idx_val = rs1 + 8; Value* Xtmp0_val = this->builder.CreateLShr( this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 80); + this->gen_sync(POST_SYNC, 80); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4158,18 +4238,19 @@ private: std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SRAI"); - this->gen_sync(iss::PRE_SYNC, 81); + this->gen_sync(PRE_SYNC, 81); - uint8_t fld_shamt_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4177,13 +4258,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rs1_idx_val = fld_rs1_val + 8; + uint8_t rs1_idx_val = rs1 + 8; Value* Xtmp0_val = this->builder.CreateAShr( this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 81); + this->gen_sync(POST_SYNC, 81); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4193,18 +4274,19 @@ private: std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ANDI"); - this->gen_sync(iss::PRE_SYNC, 82); + this->gen_sync(PRE_SYNC, 82); - uint8_t fld_imm_val = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((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 % (uint64_t)fld_imm_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4212,13 +4294,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rs1_idx_val = fld_rs1_val + 8; + uint8_t rs1_idx_val = rs1 + 8; Value* Xtmp0_val = this->builder.CreateAnd( this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 82); + this->gen_sync(POST_SYNC, 82); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4228,18 +4310,19 @@ private: std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SUB"); - this->gen_sync(iss::PRE_SYNC, 83); + this->gen_sync(PRE_SYNC, 83); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4247,13 +4330,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateSub( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 83); + this->gen_sync(POST_SYNC, 83); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4263,18 +4346,19 @@ private: std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.XOR"); - this->gen_sync(iss::PRE_SYNC, 84); + this->gen_sync(PRE_SYNC, 84); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4282,13 +4366,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateXor( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 84); + this->gen_sync(POST_SYNC, 84); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4298,18 +4382,19 @@ private: std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.OR"); - this->gen_sync(iss::PRE_SYNC, 85); + this->gen_sync(PRE_SYNC, 85); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4317,13 +4402,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateOr( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 85); + this->gen_sync(POST_SYNC, 85); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4333,18 +4418,19 @@ private: std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.AND"); - this->gen_sync(iss::PRE_SYNC, 86); + this->gen_sync(PRE_SYNC, 86); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4352,13 +4438,13 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateAnd( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 86); + this->gen_sync(POST_SYNC, 86); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4368,17 +4454,18 @@ private: std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.J"); - this->gen_sync(iss::PRE_SYNC, 87); + this->gen_sync(PRE_SYNC, 87); - int16_t fld_imm_val = signextend((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) | (bit_sub<12,1>(instr) << 11)); + int16_t imm = signextend((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) | (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; + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), + fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4390,11 +4477,11 @@ private: this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 87); + this->gen_sync(POST_SYNC, 87); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4403,18 +4490,19 @@ private: std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.BEQZ"); - this->gen_sync(iss::PRE_SYNC, 88); + this->gen_sync(PRE_SYNC, 88); - int16_t fld_imm_val = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4425,13 +4513,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_EQ, - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), + this->gen_reg_load(rs1 + 8 + traits::X0, 0), this->gen_const(32U, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 2)), @@ -4439,7 +4527,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 88); + this->gen_sync(POST_SYNC, 88); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4448,18 +4536,19 @@ private: std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.BNEZ"); - this->gen_sync(iss::PRE_SYNC, 89); + this->gen_sync(PRE_SYNC, 89); - int16_t fld_imm_val = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4470,13 +4559,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), + this->gen_reg_load(rs1 + 8 + traits::X0, 0), this->gen_const(32U, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 2)), @@ -4484,7 +4573,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 89); + this->gen_sync(POST_SYNC, 89); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4493,18 +4582,19 @@ private: std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SLLI"); - this->gen_sync(iss::PRE_SYNC, 90); + this->gen_sync(PRE_SYNC, 90); - uint8_t fld_shamt_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), + fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4512,15 +4602,15 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_rs1_val == 0){ + if(rs1 == 0){ this->gen_raise_trap(0, 2); } Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rs1_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 90); + this->gen_sync(POST_SYNC, 90); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4530,18 +4620,19 @@ private: std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LWSP"); - this->gen_sync(iss::PRE_SYNC, 91); + this->gen_sync(PRE_SYNC, 91); - uint8_t fld_uimm_val = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4551,11 +4642,11 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_const(32U, uimm)); Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 91); + this->gen_sync(POST_SYNC, 91); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4565,18 +4656,19 @@ private: std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.MV"); - this->gen_sync(iss::PRE_SYNC, 92); + this->gen_sync(PRE_SYNC, 92); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4584,10 +4676,10 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - Value* Xtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 92); + this->gen_sync(POST_SYNC, 92); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4597,17 +4689,18 @@ private: std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JR"); - this->gen_sync(iss::PRE_SYNC, 93); + this->gen_sync(PRE_SYNC, 93); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), + fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4615,10 +4708,10 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - Value* PC_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 93); + this->gen_sync(POST_SYNC, 93); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4627,18 +4720,19 @@ private: std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADD"); - this->gen_sync(iss::PRE_SYNC, 94); + this->gen_sync(PRE_SYNC, 94); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4647,11 +4741,11 @@ private: pc=pc+2; Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rd_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rd + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 94); + this->gen_sync(POST_SYNC, 94); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4661,17 +4755,18 @@ private: std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JALR"); - this->gen_sync(iss::PRE_SYNC, 95); + this->gen_sync(PRE_SYNC, 95); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), + fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4683,10 +4778,10 @@ private: cur_pc_val, this->gen_const(32U, 2)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); - Value* PC_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 95); + this->gen_sync(POST_SYNC, 95); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4695,14 +4790,14 @@ private: std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.EBREAK"); - this->gen_sync(iss::PRE_SYNC, 96); + this->gen_sync(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.CreateGlobalStringPtr("c.ebreak"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4711,7 +4806,7 @@ private: pc=pc+2; this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 96); + this->gen_sync(POST_SYNC, 96); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -4720,18 +4815,19 @@ private: std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SWSP"); - this->gen_sync(iss::PRE_SYNC, 97); + this->gen_sync(PRE_SYNC, 97); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_uimm_val = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} x2+{uimm:#05x}, {rs2}", fmt::arg("mnemonic", "c.swsp"), + fmt::arg("uimm", uimm), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4741,14 +4837,14 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 97); + this->gen_sync(POST_SYNC, 97); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4758,14 +4854,14 @@ private: std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DII"); - this->gen_sync(iss::PRE_SYNC, 98); + this->gen_sync(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.CreateGlobalStringPtr("dii"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4775,7 +4871,7 @@ private: this->gen_raise_trap(0, 2); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 98); + this->gen_sync(POST_SYNC, 98); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4785,19 +4881,20 @@ private: std::tuple __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLW"); - this->gen_sync(iss::PRE_SYNC, 99); + this->gen_sync(PRE_SYNC, 99); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FLW f%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {imm}(x{rs1})", fmt::arg("mnemonic", "flw"), + fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4807,13 +4904,13 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -4824,10 +4921,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 99); + this->gen_sync(POST_SYNC, 99); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4837,19 +4934,20 @@ private: std::tuple __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSW"); - this->gen_sync(iss::PRE_SYNC, 100); + this->gen_sync(PRE_SYNC, 100); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSW f%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {imm}(x{rs1})", fmt::arg("mnemonic", "fsw"), + fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4859,11 +4957,11 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ); this->gen_write_mem( @@ -4871,7 +4969,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 100); + this->gen_sync(POST_SYNC, 100); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4881,21 +4979,22 @@ private: std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.S"); - this->gen_sync(iss::PRE_SYNC, 101); + this->gen_sync(PRE_SYNC, 101); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMADD.S x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4905,15 +5004,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -4923,9 +5022,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -4934,7 +5033,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -4945,7 +5044,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -4956,7 +5055,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 101); + this->gen_sync(POST_SYNC, 101); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4966,21 +5065,22 @@ private: std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.S"); - this->gen_sync(iss::PRE_SYNC, 102); + this->gen_sync(PRE_SYNC, 102); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMSUB.S x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4990,15 +5090,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -5008,9 +5108,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5019,7 +5119,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5030,7 +5130,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5041,7 +5141,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 102); + this->gen_sync(POST_SYNC, 102); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5051,21 +5151,22 @@ private: std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.S"); - this->gen_sync(iss::PRE_SYNC, 103); + this->gen_sync(PRE_SYNC, 103); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FNMADD.S x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5075,15 +5176,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -5093,9 +5194,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5104,7 +5205,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5115,7 +5216,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5126,7 +5227,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 103); + this->gen_sync(POST_SYNC, 103); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5136,21 +5237,22 @@ private: std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.S"); - this->gen_sync(iss::PRE_SYNC, 104); + this->gen_sync(PRE_SYNC, 104); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FNMSUB.S x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5160,15 +5262,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -5178,9 +5280,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5189,7 +5291,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5200,7 +5302,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5211,7 +5313,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 104); + this->gen_sync(POST_SYNC, 104); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5221,20 +5323,21 @@ private: std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.S"); - this->gen_sync(iss::PRE_SYNC, 105); + this->gen_sync(PRE_SYNC, 105); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FADD.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5244,19 +5347,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5265,7 +5368,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5276,7 +5379,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5287,7 +5390,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 105); + this->gen_sync(POST_SYNC, 105); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5297,20 +5400,21 @@ private: std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.S"); - this->gen_sync(iss::PRE_SYNC, 106); + this->gen_sync(PRE_SYNC, 106); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSUB.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5320,19 +5424,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5341,7 +5445,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5352,7 +5456,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5363,7 +5467,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 106); + this->gen_sync(POST_SYNC, 106); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5373,20 +5477,21 @@ private: std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.S"); - this->gen_sync(iss::PRE_SYNC, 107); + this->gen_sync(PRE_SYNC, 107); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMUL.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5396,19 +5501,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5417,7 +5522,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5428,7 +5533,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5439,7 +5544,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 107); + this->gen_sync(POST_SYNC, 107); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5449,20 +5554,21 @@ private: std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.S"); - this->gen_sync(iss::PRE_SYNC, 108); + this->gen_sync(PRE_SYNC, 108); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FDIV.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5472,19 +5578,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5493,7 +5599,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5504,7 +5610,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5515,7 +5621,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 108); + this->gen_sync(POST_SYNC, 108); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5525,19 +5631,20 @@ private: std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.S"); - this->gen_sync(iss::PRE_SYNC, 109); + this->gen_sync(PRE_SYNC, 109); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSQRT.S f%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5547,15 +5654,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -5564,7 +5671,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5575,7 +5682,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5586,7 +5693,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 109); + this->gen_sync(POST_SYNC, 109); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5596,19 +5703,20 @@ private: std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.S"); - this->gen_sync(iss::PRE_SYNC, 110); + this->gen_sync(PRE_SYNC, 110); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSGNJ.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5619,19 +5727,19 @@ private: Value* res_val = this->builder.CreateOr( this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->gen_const(32U, 0x7fffffff)), this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_const(32U, 0x80000000))); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5642,10 +5750,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 110); + this->gen_sync(POST_SYNC, 110); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5655,19 +5763,20 @@ private: std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.S"); - this->gen_sync(iss::PRE_SYNC, 111); + this->gen_sync(PRE_SYNC, 111); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSGNJN.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5678,19 +5787,19 @@ private: Value* res_val = this->builder.CreateOr( this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->gen_const(32U, 0x7fffffff)), this->builder.CreateAnd( this->builder.CreateNot(this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) )), this->gen_const(32U, 0x80000000))); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5701,10 +5810,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 111); + this->gen_sync(POST_SYNC, 111); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5714,19 +5823,20 @@ private: std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.S"); - this->gen_sync(iss::PRE_SYNC, 112); + this->gen_sync(PRE_SYNC, 112); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSGNJX.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5736,18 +5846,18 @@ private: Value* res_val = this->builder.CreateXor( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_const(32U, 0x80000000))); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5758,10 +5868,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 112); + this->gen_sync(POST_SYNC, 112); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5771,19 +5881,20 @@ private: std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.S"); - this->gen_sync(iss::PRE_SYNC, 113); + this->gen_sync(PRE_SYNC, 113); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMIN.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5793,11 +5904,11 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -5807,7 +5918,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5818,7 +5929,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5829,7 +5940,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 113); + this->gen_sync(POST_SYNC, 113); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5839,19 +5950,20 @@ private: std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.S"); - this->gen_sync(iss::PRE_SYNC, 114); + this->gen_sync(PRE_SYNC, 114); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMAX.S f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5861,11 +5973,11 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -5875,7 +5987,7 @@ private: }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -5886,7 +5998,7 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -5897,7 +6009,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 114); + this->gen_sync(POST_SYNC, 114); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5907,19 +6019,20 @@ private: std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.S"); - this->gen_sync(iss::PRE_SYNC, 115); + this->gen_sync(PRE_SYNC, 115); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.W.S x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5930,18 +6043,18 @@ private: Value* Xtmp0_val = this->gen_ext( this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( this->gen_const(64U, 0LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -5951,7 +6064,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 115); + this->gen_sync(POST_SYNC, 115); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -5961,19 +6074,20 @@ private: std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.S"); - this->gen_sync(iss::PRE_SYNC, 116); + this->gen_sync(PRE_SYNC, 116); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.WU.S x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -5984,18 +6098,18 @@ private: Value* Xtmp0_val = this->gen_ext( this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( this->gen_const(64U, 1LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -6005,7 +6119,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 116); + this->gen_sync(POST_SYNC, 116); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6015,19 +6129,20 @@ private: std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.S"); - this->gen_sync(iss::PRE_SYNC, 117); + this->gen_sync(PRE_SYNC, 117); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FEQ.S x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6037,11 +6152,11 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -6049,7 +6164,7 @@ private: 32, false) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -6059,7 +6174,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 117); + this->gen_sync(POST_SYNC, 117); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6069,19 +6184,20 @@ private: std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.S"); - this->gen_sync(iss::PRE_SYNC, 118); + this->gen_sync(PRE_SYNC, 118); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FLT.S x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6091,11 +6207,11 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -6103,7 +6219,7 @@ private: 32, false) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -6113,7 +6229,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 118); + this->gen_sync(POST_SYNC, 118); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6123,19 +6239,20 @@ private: std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.S"); - this->gen_sync(iss::PRE_SYNC, 119); + this->gen_sync(PRE_SYNC, 119); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FLE.S x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6145,11 +6262,11 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ), this->gen_ext( @@ -6157,7 +6274,7 @@ private: 32, false) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -6167,7 +6284,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 119); + this->gen_sync(POST_SYNC, 119); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6177,18 +6294,19 @@ private: std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.S"); - this->gen_sync(iss::PRE_SYNC, 120); + this->gen_sync(PRE_SYNC, 120); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCLASS.S x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fclass.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6198,13 +6316,13 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 120); + this->gen_sync(POST_SYNC, 120); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6214,19 +6332,20 @@ private: std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.W"); - this->gen_sync(iss::PRE_SYNC, 121); + this->gen_sync(PRE_SYNC, 121); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.S.W f%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.w"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6236,18 +6355,18 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), this->gen_ext( this->gen_const(64U, 2LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6258,10 +6377,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 121); + this->gen_sync(POST_SYNC, 121); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6271,19 +6390,20 @@ private: std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.WU"); - this->gen_sync(iss::PRE_SYNC, 122); + this->gen_sync(PRE_SYNC, 122); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.S.WU f%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.wu"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6293,18 +6413,18 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), this->gen_ext( this->gen_const(64U, 3LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6315,10 +6435,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 122); + this->gen_sync(POST_SYNC, 122); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6328,18 +6448,19 @@ private: std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.X.W"); - this->gen_sync(iss::PRE_SYNC, 123); + this->gen_sync(PRE_SYNC, 123); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMV.X.W x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.w"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6349,14 +6470,14 @@ private: Value* Xtmp0_val = this->gen_ext( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 123); + this->gen_sync(POST_SYNC, 123); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6366,18 +6487,19 @@ private: std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.W.X"); - this->gen_sync(iss::PRE_SYNC, 124); + this->gen_sync(PRE_SYNC, 124); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMV.W.X f%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fmv.w.x"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6386,8 +6508,8 @@ private: pc=pc+4; if(64 == 32){ - Value* Ftmp0_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + Value* Ftmp0_val = this->gen_reg_load(rs1 + traits::X0, 0); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6395,13 +6517,13 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 32)), this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 124); + this->gen_sync(POST_SYNC, 124); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6411,19 +6533,20 @@ private: std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLW"); - this->gen_sync(iss::PRE_SYNC, 125); + this->gen_sync(PRE_SYNC, 125); - uint8_t fld_rd_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FLW f(8+%1$d), %2%(x(8+%3$d))"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6432,12 +6555,12 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6448,10 +6571,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + 8 + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 125); + this->gen_sync(POST_SYNC, 125); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6461,19 +6584,20 @@ private: std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSW"); - this->gen_sync(iss::PRE_SYNC, 126); + this->gen_sync(PRE_SYNC, 126); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FSW f(8+%1$d), %2%(x(8+%3$d))"); - ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6482,10 +6606,10 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + 8 + traits::F0, 0), + this->gen_reg_load(rs2 + 8 + traits::F0, 0), this-> get_type(32) ); this->gen_write_mem( @@ -6493,7 +6617,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 126); + this->gen_sync(POST_SYNC, 126); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6503,18 +6627,19 @@ private: std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLWSP"); - this->gen_sync(iss::PRE_SYNC, 127); + this->gen_sync(PRE_SYNC, 127); - uint8_t fld_uimm_val = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FLWSP f%1$d, %2%(x2)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6524,11 +6649,11 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_const(32U, uimm)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); if(64 == 32){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6539,10 +6664,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 127); + this->gen_sync(POST_SYNC, 127); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6552,18 +6677,19 @@ private: std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSWSP"); - this->gen_sync(iss::PRE_SYNC, 128); + this->gen_sync(PRE_SYNC, 128); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_uimm_val = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((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.FSWSP f%1$d, %2%(x2), "); - ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6573,9 +6699,9 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_const(32U, uimm)); Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(32) ); this->gen_write_mem( @@ -6583,7 +6709,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 128); + this->gen_sync(POST_SYNC, 128); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6593,19 +6719,20 @@ private: std::tuple __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLD"); - this->gen_sync(iss::PRE_SYNC, 129); + this->gen_sync(PRE_SYNC, 129); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FLD f%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rd_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {imm}({rs1})", fmt::arg("mnemonic", "fld"), + fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6615,13 +6742,13 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6629,10 +6756,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 129); + this->gen_sync(POST_SYNC, 129); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6642,19 +6769,20 @@ private: std::tuple __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSD"); - this->gen_sync(iss::PRE_SYNC, 130); + this->gen_sync(PRE_SYNC, 130); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSD f%1$d, %2%(x%3$d)"); - ins_fmter % (uint64_t)fld_rs2_val % (int64_t)fld_imm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {imm}({rs1})", fmt::arg("mnemonic", "fsd"), + fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6664,11 +6792,11 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ); this->gen_write_mem( @@ -6676,7 +6804,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 130); + this->gen_sync(POST_SYNC, 130); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6686,21 +6814,22 @@ private: std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.D"); - this->gen_sync(iss::PRE_SYNC, 131); + this->gen_sync(PRE_SYNC, 131); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMADD.D x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6710,15 +6839,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -6728,9 +6857,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -6739,7 +6868,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6747,7 +6876,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -6758,7 +6887,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 131); + this->gen_sync(POST_SYNC, 131); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6768,21 +6897,22 @@ private: std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.D"); - this->gen_sync(iss::PRE_SYNC, 132); + this->gen_sync(PRE_SYNC, 132); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMSUB.D x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6792,15 +6922,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -6810,9 +6940,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -6821,7 +6951,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6829,7 +6959,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -6840,7 +6970,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 132); + this->gen_sync(POST_SYNC, 132); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6850,21 +6980,22 @@ private: std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.D"); - this->gen_sync(iss::PRE_SYNC, 133); + this->gen_sync(PRE_SYNC, 133); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FNMADD.D x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6874,15 +7005,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -6892,9 +7023,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -6903,7 +7034,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6911,7 +7042,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -6922,7 +7053,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 133); + this->gen_sync(POST_SYNC, 133); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -6932,21 +7063,22 @@ private: std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.D"); - this->gen_sync(iss::PRE_SYNC, 134); + this->gen_sync(PRE_SYNC, 134); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rs3_val = ((bit_sub<27,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FNMSUB.D x%1$d, f%2$d, f%3$d, f%4$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_rs3_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -6956,15 +7088,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs3_val + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -6974,9 +7106,9 @@ private: this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -6985,7 +7117,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -6993,7 +7125,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7004,7 +7136,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 134); + this->gen_sync(POST_SYNC, 134); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7014,20 +7146,21 @@ private: std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.D"); - this->gen_sync(iss::PRE_SYNC, 135); + this->gen_sync(PRE_SYNC, 135); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FADD.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7037,19 +7170,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -7058,7 +7191,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7066,7 +7199,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7077,7 +7210,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 135); + this->gen_sync(POST_SYNC, 135); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7087,20 +7220,21 @@ private: std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.D"); - this->gen_sync(iss::PRE_SYNC, 136); + this->gen_sync(PRE_SYNC, 136); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSUB.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7110,19 +7244,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -7131,7 +7265,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7139,7 +7273,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7150,7 +7284,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 136); + this->gen_sync(POST_SYNC, 136); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7160,20 +7294,21 @@ private: std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.D"); - this->gen_sync(iss::PRE_SYNC, 137); + this->gen_sync(PRE_SYNC, 137); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMUL.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7183,19 +7318,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -7204,7 +7339,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7212,7 +7347,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7223,7 +7358,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 137); + this->gen_sync(POST_SYNC, 137); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7233,20 +7368,21 @@ private: std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.D"); - this->gen_sync(iss::PRE_SYNC, 138); + this->gen_sync(PRE_SYNC, 138); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FDIV.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7256,19 +7392,19 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -7277,7 +7413,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7285,7 +7421,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7296,7 +7432,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 138); + this->gen_sync(POST_SYNC, 138); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7306,19 +7442,20 @@ private: std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.D"); - this->gen_sync(iss::PRE_SYNC, 139); + this->gen_sync(PRE_SYNC, 139); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSQRT.D x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7328,15 +7465,15 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->gen_const(8U, 7)), - this->gen_const(8U, fld_rm_val), + this->gen_const(8U, rm), this->builder.CreateTrunc( this->gen_reg_load(traits::FCSR, 0), this-> get_type(8) @@ -7345,7 +7482,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7353,7 +7490,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7364,7 +7501,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 139); + this->gen_sync(POST_SYNC, 139); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7374,19 +7511,20 @@ private: std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.D"); - this->gen_sync(iss::PRE_SYNC, 140); + this->gen_sync(PRE_SYNC, 140); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSGNJ.D f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7397,19 +7535,19 @@ private: Value* res_val = this->builder.CreateOr( this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->gen_const(64U, 0x7fffffff)), this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_const(64U, 0x80000000))); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7417,10 +7555,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 140); + this->gen_sync(POST_SYNC, 140); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7430,19 +7568,20 @@ private: std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.D"); - this->gen_sync(iss::PRE_SYNC, 141); + this->gen_sync(PRE_SYNC, 141); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSGNJN.D f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7453,19 +7592,19 @@ private: Value* res_val = this->builder.CreateOr( this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->gen_const(64U, 0x7fffffff)), this->builder.CreateAnd( this->builder.CreateNot(this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) )), this->gen_const(64U, 0x80000000))); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7473,10 +7612,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 141); + this->gen_sync(POST_SYNC, 141); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7486,19 +7625,20 @@ private: std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.D"); - this->gen_sync(iss::PRE_SYNC, 142); + this->gen_sync(PRE_SYNC, 142); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FSGNJX.D f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7508,18 +7648,18 @@ private: Value* res_val = this->builder.CreateXor( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_const(64U, 0x80000000))); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7527,10 +7667,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 142); + this->gen_sync(POST_SYNC, 142); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7540,19 +7680,20 @@ private: std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.D"); - this->gen_sync(iss::PRE_SYNC, 143); + this->gen_sync(PRE_SYNC, 143); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMIN.D f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7562,11 +7703,11 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -7576,7 +7717,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7584,7 +7725,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7595,7 +7736,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 143); + this->gen_sync(POST_SYNC, 143); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7605,19 +7746,20 @@ private: std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.D"); - this->gen_sync(iss::PRE_SYNC, 144); + this->gen_sync(PRE_SYNC, 144); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FMAX.D f%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7627,11 +7769,11 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -7641,7 +7783,7 @@ private: }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7649,7 +7791,7 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7660,7 +7802,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 144); + this->gen_sync(POST_SYNC, 144); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7670,19 +7812,20 @@ private: std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.D"); - this->gen_sync(iss::PRE_SYNC, 145); + this->gen_sync(PRE_SYNC, 145); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.S.D f%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.s.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7691,8 +7834,8 @@ private: pc=pc+4; Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_d2f"), std::vector{ - this->gen_reg_load(fld_rs1_val + traits::F0, 0), - this->gen_const(8U, fld_rm_val) + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_const(8U, rm) }); uint64_t upper_val = - 1; Value* Ftmp0_val = this->builder.CreateOr( @@ -7703,9 +7846,9 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 145); + this->gen_sync(POST_SYNC, 145); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7715,19 +7858,20 @@ private: std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.S"); - this->gen_sync(iss::PRE_SYNC, 146); + this->gen_sync(PRE_SYNC, 146); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.D.S f%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.d.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7737,14 +7881,14 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fconv_f2d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(32) ), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -7752,10 +7896,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 146); + this->gen_sync(POST_SYNC, 146); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7765,19 +7909,20 @@ private: std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.D"); - this->gen_sync(iss::PRE_SYNC, 147); + this->gen_sync(PRE_SYNC, 147); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FEQ.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7787,11 +7932,11 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -7799,7 +7944,7 @@ private: 32, false) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -7809,7 +7954,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 147); + this->gen_sync(POST_SYNC, 147); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7819,19 +7964,20 @@ private: std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.D"); - this->gen_sync(iss::PRE_SYNC, 148); + this->gen_sync(PRE_SYNC, 148); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FLT.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7841,11 +7987,11 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -7853,7 +7999,7 @@ private: 32, false) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -7863,7 +8009,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 148); + this->gen_sync(POST_SYNC, 148); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7873,19 +8019,20 @@ private: std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.D"); - this->gen_sync(iss::PRE_SYNC, 149); + this->gen_sync(PRE_SYNC, 149); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FLE.D x%1$d, f%2$d, f%3$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7895,11 +8042,11 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( @@ -7907,7 +8054,7 @@ private: 32, false) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -7917,7 +8064,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 149); + this->gen_sync(POST_SYNC, 149); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7927,18 +8074,19 @@ private: std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.D"); - this->gen_sync(iss::PRE_SYNC, 150); + this->gen_sync(PRE_SYNC, 150); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCLASS.D x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fclass.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7948,13 +8096,13 @@ private: Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ) }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 150); + this->gen_sync(POST_SYNC, 150); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -7964,19 +8112,20 @@ private: std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.D"); - this->gen_sync(iss::PRE_SYNC, 151); + this->gen_sync(PRE_SYNC, 151); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.W.D x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -7987,18 +8136,18 @@ private: Value* Xtmp0_val = this->gen_ext( this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( this->gen_const(64U, 0LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -8008,7 +8157,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 151); + this->gen_sync(POST_SYNC, 151); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8018,19 +8167,20 @@ private: std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.D"); - this->gen_sync(iss::PRE_SYNC, 152); + this->gen_sync(PRE_SYNC, 152); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.WU.D x%1$d, f%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8041,18 +8191,18 @@ private: Value* Xtmp0_val = this->gen_ext( this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::F0, 0), + this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), this->gen_ext( this->gen_const(64U, 1LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); Value* FCSR_val = this->builder.CreateAdd( @@ -8062,7 +8212,7 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 152); + this->gen_sync(POST_SYNC, 152); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8072,19 +8222,20 @@ private: std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.W"); - this->gen_sync(iss::PRE_SYNC, 153); + this->gen_sync(PRE_SYNC, 153); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.D.W f%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.w"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8094,18 +8245,18 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), this->gen_ext( this->gen_const(64U, 2LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -8113,10 +8264,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 153); + this->gen_sync(POST_SYNC, 153); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8126,19 +8277,20 @@ private: std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.WU"); - this->gen_sync(iss::PRE_SYNC, 154); + this->gen_sync(PRE_SYNC, 154); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rm_val = ((bit_sub<12,3>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("FCVT.D.WU f%1$d, x%2$d"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.wu"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8148,18 +8300,18 @@ private: Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, false), this->gen_ext( this->gen_const(64U, 3LL), 32, false), - this->gen_const(8U, fld_rm_val) + this->gen_const(8U, rm) }); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -8167,10 +8319,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 154); + this->gen_sync(POST_SYNC, 154); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8180,19 +8332,20 @@ private: std::tuple __c_fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLD"); - this->gen_sync(iss::PRE_SYNC, 155); + this->gen_sync(PRE_SYNC, 155); - uint8_t fld_rd_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FLD f(8+%1$d), %2%(x(8+%3$d))"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fld"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8201,12 +8354,12 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -8214,10 +8367,10 @@ private: this->gen_const(64U, upper_val), this->gen_const(64U, 64)), res_val); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + 8 + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 155); + this->gen_sync(POST_SYNC, 155); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8227,19 +8380,20 @@ private: std::tuple __c_fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSD"); - this->gen_sync(iss::PRE_SYNC, 156); + this->gen_sync(PRE_SYNC, 156); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FSD f(8+%1$d), %2%(x(8+%3$d))"); - ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val % (uint64_t)fld_rs1_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsd"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8248,10 +8402,10 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + 8 + traits::F0, 0), + this->gen_reg_load(rs2 + 8 + traits::F0, 0), this-> get_type(64) ); this->gen_write_mem( @@ -8259,7 +8413,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 156); + this->gen_sync(POST_SYNC, 156); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8269,18 +8423,19 @@ private: std::tuple __c_fldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FLDSP"); - this->gen_sync(iss::PRE_SYNC, 157); + this->gen_sync(PRE_SYNC, 157); - uint16_t fld_uimm_val = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FLDSP f%1$d, %2%(x2)"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_uimm_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.fldsp"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8290,11 +8445,11 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_const(32U, uimm)); Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); if(64 == 64){ Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { uint64_t upper_val = - 1; Value* Ftmp1_val = this->builder.CreateOr( @@ -8305,10 +8460,10 @@ private: res_val, 64, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(fld_rd_val + traits::F0), false); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 157); + this->gen_sync(POST_SYNC, 157); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8318,18 +8473,19 @@ private: std::tuple __c_fsdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.FSDSP"); - this->gen_sync(iss::PRE_SYNC, 158); + this->gen_sync(PRE_SYNC, 158); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint16_t fld_uimm_val = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); if(this->disass_enabled){ /* generate console output when executing the command */ - boost::format ins_fmter("C.FSDSP f%1$d, %2%(x2), "); - ins_fmter % (uint64_t)fld_rs2_val % (uint64_t)fld_uimm_val; + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fsdsp"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -8339,9 +8495,9 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_const(32U, uimm)); Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ); this->gen_write_mem( @@ -8349,7 +8505,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 158); + this->gen_sync(POST_SYNC, 158); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -8358,8 +8514,7 @@ private: /**************************************************************************** * end opcode definitions ****************************************************************************/ - std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, - BasicBlock *bb) { + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, 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); @@ -8403,7 +8558,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); try { - uint8_t *const data = (uint8_t *)&insn; + auto *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); @@ -8441,9 +8596,7 @@ template void vm_impl::gen_raise_trap(uint16_t trap_id, ui } template void vm_impl::gen_leave_trap(unsigned lvl) { - std::vector args{ - this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), 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); @@ -8451,20 +8604,17 @@ template void vm_impl::gen_leave_trap(unsigned lvl) { } template void vm_impl::gen_wait(unsigned type) { - std::vector args{ - this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) }; this->builder.CreateCall(this->mod->getFunction("wait"), args); } template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - 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.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); + 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); @@ -8482,10 +8632,9 @@ template inline void vm_impl::gen_trap_check(BasicBlock *b template <> std::unique_ptr create(arch::rv32gc *core, unsigned short port, bool dump) { - std::unique_ptr> ret = - std::make_unique>(*core, dump); - if (port != 0) debugger::server::run_server(ret.get(), port); - return ret; + auto ret = new rv32gc::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); } } // namespace iss diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index c8efdc1..c867a5e 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -30,15 +30,15 @@ * *******************************************************************************/ -#include #include +#include #include #include #include #include #include -#include +#include #include #include @@ -80,23 +80,24 @@ public: protected: using vm_base::get_reg_ptr; - template inline llvm::ConstantInt *size(T type) { - return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits())); + inline const char *name(size_t index){return traits::reg_aliases.at(index);} + + template inline ConstantInt *size(T type) { + return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); } - void setup_module(llvm::Module *m) override { + void setup_module(Module* m) override { super::setup_module(m); - vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); } - inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) { + inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); } - std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, - llvm::BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override; - void gen_leave_behavior(llvm::BasicBlock *leave_blk) override; + void gen_leave_behavior(BasicBlock *leave_blk) override; void gen_raise_trap(uint16_t trap_id, uint16_t cause); @@ -104,17 +105,17 @@ protected: void gen_wait(unsigned type); - void gen_trap_behavior(llvm::BasicBlock *) override; + void gen_trap_behavior(BasicBlock *) override; - void gen_trap_check(llvm::BasicBlock *bb); + void gen_trap_check(BasicBlock *bb); - inline llvm::Value *gen_reg_load(unsigned i, unsigned level = 0) { + inline 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)); + 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); } @@ -125,17 +126,17 @@ protected: 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); + using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, + code_word_t instr, + BasicBlock *bb); std::array lut; std::array lut_00, lut_01, lut_10; std::array lut_11; - std::array qlut; + std::array qlut; - std::array lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}}; + 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) { @@ -186,7 +187,7 @@ private: }; const std::array instr_descr = {{ - /* entries are: size, 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 */ @@ -389,21 +390,22 @@ private: /* instruction definitions */ /* instruction 0: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LUI"); - this->gen_sync(iss::PRE_SYNC, 0); + this->gen_sync(PRE_SYNC, 0); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -411,33 +413,34 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* Xtmp0_val = this->gen_const(32U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 0); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 1: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AUIPC"); - this->gen_sync(iss::PRE_SYNC, 1); + this->gen_sync(PRE_SYNC, 1); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -445,37 +448,38 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 1); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 2: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JAL"); - this->gen_sync(iss::PRE_SYNC, 2); + this->gen_sync(PRE_SYNC, 2); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -483,42 +487,43 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* PC_val = this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 2); + this->gen_sync(POST_SYNC, 2); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 3: JALR */ - std::tuple __jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); - this->gen_sync(iss::PRE_SYNC, 3); + this->gen_sync(PRE_SYNC, 3); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -528,16 +533,16 @@ private: Value* new_pc_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* align_val = this->builder.CreateAnd( new_pc_val, this->gen_const(32U, 0x1)); { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -552,11 +557,11 @@ private: this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* PC_val = this->builder.CreateAnd( new_pc_val, @@ -568,28 +573,29 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - this->gen_sync(iss::POST_SYNC, 3); + this->gen_sync(POST_SYNC, 3); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 4: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); - this->gen_sync(iss::PRE_SYNC, 4); + this->gen_sync(PRE_SYNC, 4); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -600,13 +606,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_EQ, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -614,28 +620,29 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 4); + this->gen_sync(POST_SYNC, 4); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 5: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); - this->gen_sync(iss::PRE_SYNC, 5); + this->gen_sync(PRE_SYNC, 5); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -646,13 +653,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -660,28 +667,29 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 5); + this->gen_sync(POST_SYNC, 5); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 6: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); - this->gen_sync(iss::PRE_SYNC, 6); + this->gen_sync(PRE_SYNC, 6); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -693,16 +701,16 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -710,28 +718,29 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 6); + this->gen_sync(POST_SYNC, 6); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 7: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); - this->gen_sync(iss::PRE_SYNC, 7); + this->gen_sync(PRE_SYNC, 7); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -743,16 +752,16 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_SGE, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -760,28 +769,29 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 7); + this->gen_sync(POST_SYNC, 7); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 8: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); - this->gen_sync(iss::PRE_SYNC, 8); + this->gen_sync(PRE_SYNC, 8); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -792,13 +802,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -806,28 +816,29 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 8); + this->gen_sync(POST_SYNC, 8); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 9: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); - this->gen_sync(iss::PRE_SYNC, 9); + this->gen_sync(PRE_SYNC, 9); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -838,13 +849,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGE, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 4)), @@ -852,28 +863,29 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 9); + this->gen_sync(POST_SYNC, 9); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 10: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); - this->gen_sync(iss::PRE_SYNC, 10); + this->gen_sync(PRE_SYNC, 10); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -883,40 +895,41 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 8/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 10); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 11: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); - this->gen_sync(iss::PRE_SYNC, 11); + this->gen_sync(PRE_SYNC, 11); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -926,40 +939,41 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 16/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 11); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 12: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); - this->gen_sync(iss::PRE_SYNC, 12); + this->gen_sync(PRE_SYNC, 12); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -969,40 +983,41 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 12); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 13: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); - this->gen_sync(iss::PRE_SYNC, 13); + this->gen_sync(PRE_SYNC, 13); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1012,40 +1027,41 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 8/8), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 13); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 14: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); - this->gen_sync(iss::PRE_SYNC, 14); + this->gen_sync(PRE_SYNC, 14); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1055,40 +1071,41 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(32U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 16/8), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 14); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 15: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); - this->gen_sync(iss::PRE_SYNC, 15); + this->gen_sync(PRE_SYNC, 15); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1098,38 +1115,39 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_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_sync(POST_SYNC, 15); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 16: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); - this->gen_sync(iss::PRE_SYNC, 16); + this->gen_sync(PRE_SYNC, 16); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1139,38 +1157,39 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_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_sync(POST_SYNC, 16); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 17: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); - this->gen_sync(iss::PRE_SYNC, 17); + this->gen_sync(PRE_SYNC, 17); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1180,38 +1199,39 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_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_sync(POST_SYNC, 17); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 18: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); - this->gen_sync(iss::PRE_SYNC, 18); + this->gen_sync(PRE_SYNC, 18); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1219,38 +1239,39 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 18); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 19: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); - this->gen_sync(iss::PRE_SYNC, 19); + this->gen_sync(PRE_SYNC, 19); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1258,43 +1279,44 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 19); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 20: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_sync(iss::PRE_SYNC, 20); + this->gen_sync(PRE_SYNC, 20); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1302,42 +1324,43 @@ private: 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){ + int32_t full_imm_val = imm; + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->gen_const(32U, full_imm_val)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 20); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 21: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); - this->gen_sync(iss::PRE_SYNC, 21); + this->gen_sync(PRE_SYNC, 21); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1345,36 +1368,39 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 21); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 22: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); - this->gen_sync(iss::PRE_SYNC, 22); + this->gen_sync(PRE_SYNC, 22); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1382,36 +1408,39 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 22); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 23: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); - this->gen_sync(iss::PRE_SYNC, 23); + this->gen_sync(PRE_SYNC, 23); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1419,36 +1448,39 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 23); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 24: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); - this->gen_sync(iss::PRE_SYNC, 24); + this->gen_sync(PRE_SYNC, 24); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1456,40 +1488,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 24); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 25: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); - this->gen_sync(iss::PRE_SYNC, 25); + this->gen_sync(PRE_SYNC, 25); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1497,40 +1530,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 25); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 26: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); - this->gen_sync(iss::PRE_SYNC, 26); + this->gen_sync(PRE_SYNC, 26); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1538,40 +1572,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 26); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 27: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); - this->gen_sync(iss::PRE_SYNC, 27); + this->gen_sync(PRE_SYNC, 27); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1579,36 +1614,37 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 27); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 28: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); - this->gen_sync(iss::PRE_SYNC, 28); + this->gen_sync(PRE_SYNC, 28); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1616,36 +1652,37 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 28); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 29: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); - this->gen_sync(iss::PRE_SYNC, 29); + this->gen_sync(PRE_SYNC, 29); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1653,38 +1690,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(32U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 29); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 30: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); - this->gen_sync(iss::PRE_SYNC, 30); + this->gen_sync(PRE_SYNC, 30); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1692,45 +1732,46 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 30); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 31: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); - this->gen_sync(iss::PRE_SYNC, 31); + this->gen_sync(PRE_SYNC, 31); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1738,47 +1779,48 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, false)), this->gen_const(32U, 1), this->gen_const(32U, 0), 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 31); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 32: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); - this->gen_sync(iss::PRE_SYNC, 32); + this->gen_sync(PRE_SYNC, 32); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1786,36 +1828,37 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 32); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 33: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); - this->gen_sync(iss::PRE_SYNC, 33); + this->gen_sync(PRE_SYNC, 33); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1823,38 +1866,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(32U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 33); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 34: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); - this->gen_sync(iss::PRE_SYNC, 34); + this->gen_sync(PRE_SYNC, 34); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1862,38 +1908,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(32U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 34); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 35: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); - this->gen_sync(iss::PRE_SYNC, 35); + this->gen_sync(PRE_SYNC, 35); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1901,36 +1950,37 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 35); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 36: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); - this->gen_sync(iss::PRE_SYNC, 36); + this->gen_sync(PRE_SYNC, 36); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1938,35 +1988,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 36); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 37: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); - this->gen_sync(iss::PRE_SYNC, 37); + this->gen_sync(PRE_SYNC, 37); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_succ_val = ((bit_sub<20,4>(instr))); - uint8_t fld_pred_val = ((bit_sub<24,4>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((bit_sub<24,4>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("FENCE"), + this->builder.CreateGlobalStringPtr("fence"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1976,35 +2026,35 @@ private: Value* FENCEtmp0_val = this->builder.CreateOr( this->builder.CreateShl( - this->gen_const(32U, fld_pred_val), + this->gen_const(32U, pred), this->gen_const(32U, 4)), - this->gen_const(32U, fld_succ_val)); + this->gen_const(32U, succ)); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 0), this->builder.CreateZExtOrTrunc(FENCEtmp0_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_sync(POST_SYNC, 37); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 38: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_sync(iss::PRE_SYNC, 38); + this->gen_sync(PRE_SYNC, 38); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_imm_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("FENCE_I"), + this->builder.CreateGlobalStringPtr("fence_i"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2012,30 +2062,30 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* FENCEtmp0_val = this->gen_const(32U, fld_imm_val); + Value* FENCEtmp0_val = this->gen_const(32U, imm); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 1), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 38); + this->gen_sync(POST_SYNC, 38); this->gen_trap_check(this->leave_blk); return std::make_tuple(FLUSH, nullptr); } /* instruction 39: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ECALL"); - this->gen_sync(iss::PRE_SYNC, 39); + this->gen_sync(PRE_SYNC, 39); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("ECALL"), + this->builder.CreateGlobalStringPtr("ecall"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2044,23 +2094,23 @@ private: pc=pc+4; this->gen_raise_trap(0, 11); - this->gen_sync(iss::POST_SYNC, 39); + this->gen_sync(POST_SYNC, 39); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 40: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_sync(iss::PRE_SYNC, 40); + this->gen_sync(PRE_SYNC, 40); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("EBREAK"), + this->builder.CreateGlobalStringPtr("ebreak"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2069,23 +2119,23 @@ private: pc=pc+4; this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 40); + this->gen_sync(POST_SYNC, 40); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 41: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("URET"); - this->gen_sync(iss::PRE_SYNC, 41); + this->gen_sync(PRE_SYNC, 41); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("URET"), + this->builder.CreateGlobalStringPtr("uret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2094,23 +2144,23 @@ private: pc=pc+4; this->gen_leave_trap(0); - this->gen_sync(iss::POST_SYNC, 41); + this->gen_sync(POST_SYNC, 41); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 42: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRET"); - this->gen_sync(iss::PRE_SYNC, 42); + this->gen_sync(PRE_SYNC, 42); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("SRET"), + this->builder.CreateGlobalStringPtr("sret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2119,23 +2169,23 @@ private: pc=pc+4; this->gen_leave_trap(1); - this->gen_sync(iss::POST_SYNC, 42); + this->gen_sync(POST_SYNC, 42); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 43: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MRET"); - this->gen_sync(iss::PRE_SYNC, 43); + this->gen_sync(PRE_SYNC, 43); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("MRET"), + this->builder.CreateGlobalStringPtr("mret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2144,23 +2194,23 @@ private: pc=pc+4; this->gen_leave_trap(3); - this->gen_sync(iss::POST_SYNC, 43); + this->gen_sync(POST_SYNC, 43); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 44: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("WFI"); - this->gen_sync(iss::PRE_SYNC, 44); + this->gen_sync(PRE_SYNC, 44); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("WFI"), + this->builder.CreateGlobalStringPtr("wfi"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2170,26 +2220,26 @@ private: 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_sync(POST_SYNC, 44); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 45: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_sync(iss::PRE_SYNC, 45); + this->gen_sync(PRE_SYNC, 45); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("SFENCE.VMA"), + this->builder.CreateGlobalStringPtr("sfence.vma"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2197,40 +2247,41 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* FENCEtmp0_val = this->gen_const(32U, fld_rs1_val); + Value* FENCEtmp0_val = this->gen_const(32U, rs1); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 2), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - Value* FENCEtmp1_val = this->gen_const(32U, fld_rs2_val); + Value* FENCEtmp1_val = this->gen_const(32U, rs2); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 3), this->builder.CreateZExtOrTrunc(FENCEtmp1_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_sync(POST_SYNC, 45); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 46: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_sync(iss::PRE_SYNC, 46); + this->gen_sync(PRE_SYNC, 46); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2238,47 +2289,48 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* rs_val_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); + Value* rs_val_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); Value* CSRtmp0_val = rs_val_val; this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); Value* Xtmp1_val = csr_val_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } else { Value* CSRtmp2_val = rs_val_val; this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp2_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_sync(POST_SYNC, 46); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 47: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_sync(iss::PRE_SYNC, 47); + this->gen_sync(PRE_SYNC, 47); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2286,45 +2338,46 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - Value* xrs1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_rs1_val != 0){ + if(rs1 != 0){ Value* CSRtmp1_val = this->builder.CreateOr( xrd_val, xrs1_val); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_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_sync(POST_SYNC, 47); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 48: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_sync(iss::PRE_SYNC, 48); + this->gen_sync(PRE_SYNC, 48); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2332,45 +2385,46 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - Value* xrs1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_rs1_val != 0){ + if(rs1 != 0){ Value* CSRtmp1_val = this->builder.CreateAnd( xrd_val, this->builder.CreateNot(xrs1_val)); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_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_sync(POST_SYNC, 48); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 49: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_sync(iss::PRE_SYNC, 49); + this->gen_sync(PRE_SYNC, 49); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2378,42 +2432,43 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* CSRtmp1_val = this->gen_ext( - this->gen_const(32U, fld_zimm_val), + this->gen_const(32U, zimm), 32, false); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_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_sync(POST_SYNC, 49); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 50: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_sync(iss::PRE_SYNC, 50); + this->gen_sync(PRE_SYNC, 50); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2421,47 +2476,48 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - if(fld_zimm_val != 0){ + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + if(zimm != 0){ Value* CSRtmp0_val = this->builder.CreateOr( res_val, this->gen_ext( - this->gen_const(32U, fld_zimm_val), + this->gen_const(32U, zimm), 32, false)); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); } - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp1_val = res_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 50); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 51: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_sync(iss::PRE_SYNC, 51); + this->gen_sync(PRE_SYNC, 51); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2469,47 +2525,48 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 32/8); - if(fld_rd_val != 0){ + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_zimm_val != 0){ + if(zimm != 0){ Value* CSRtmp1_val = this->builder.CreateAnd( res_val, this->builder.CreateNot(this->gen_ext( - this->gen_const(32U, fld_zimm_val), + this->gen_const(32U, zimm), 32, false))); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_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_sync(POST_SYNC, 51); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 52: MUL */ - std::tuple __mul(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MUL"); - this->gen_sync(iss::PRE_SYNC, 52); + this->gen_sync(PRE_SYNC, 52); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2517,46 +2574,47 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, false)); Value* Xtmp0_val = this->gen_ext( res_val, 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 52); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 53: MULH */ - std::tuple __mulh(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULH"); - this->gen_sync(iss::PRE_SYNC, 53); + this->gen_sync(PRE_SYNC, 53); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2564,14 +2622,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, true)); Value* Xtmp0_val = this->gen_ext( @@ -2580,32 +2638,33 @@ private: this->gen_const(32U, 32)), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 53); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 54: MULHSU */ - std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHSU"); - this->gen_sync(iss::PRE_SYNC, 54); + this->gen_sync(PRE_SYNC, 54); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2613,14 +2672,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, false)); Value* Xtmp0_val = this->gen_ext( @@ -2629,32 +2688,33 @@ private: this->gen_const(32U, 32)), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 54); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 55: MULHU */ - std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHU"); - this->gen_sync(iss::PRE_SYNC, 55); + this->gen_sync(PRE_SYNC, 55); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2662,14 +2722,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateMul( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 128, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 128, false)); Value* Xtmp0_val = this->gen_ext( @@ -2678,32 +2738,33 @@ private: this->gen_const(32U, 32)), 32, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 55); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 56: DIV */ - std::tuple __div(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIV"); - this->gen_sync(iss::PRE_SYNC, 56); + this->gen_sync(PRE_SYNC, 56); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2711,15 +2772,15 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -2728,14 +2789,14 @@ private: uint32_t M1_val = - 1; uint32_t MMIN_val = - 1 << 32 - 1; { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, true), this->gen_ext( this->gen_const(32U, MMIN_val), @@ -2745,14 +2806,14 @@ private: this->builder.SetInsertPoint(bb_then); { { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true), this->gen_ext( this->gen_const(32U, M1_val), @@ -2762,19 +2823,19 @@ private: this->builder.SetInsertPoint(bb_then); { Value* Xtmp0_val = this->gen_const(32U, MMIN_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { Value* Xtmp1_val = this->builder.CreateSDiv( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 3), + this->gen_reg_load(rs1 + traits::X0, 3), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 3), + this->gen_reg_load(rs2 + traits::X0, 3), 32, true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2786,12 +2847,12 @@ private: { Value* Xtmp2_val = this->builder.CreateSDiv( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 2), + this->gen_reg_load(rs1 + traits::X0, 2), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2802,7 +2863,7 @@ private: this->builder.SetInsertPoint(bb_else); { Value* Xtmp3_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2810,29 +2871,30 @@ private: 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_sync(POST_SYNC, 56); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 57: DIVU */ - std::tuple __divu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVU"); - this->gen_sync(iss::PRE_SYNC, 57); + this->gen_sync(PRE_SYNC, 57); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2840,15 +2902,15 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -2856,20 +2918,20 @@ private: { Value* Xtmp0_val = this->builder.CreateUDiv( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1), 32, false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2877,29 +2939,30 @@ private: 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_sync(POST_SYNC, 57); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 58: REM */ - std::tuple __rem(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REM"); - this->gen_sync(iss::PRE_SYNC, 58); + this->gen_sync(PRE_SYNC, 58); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2907,15 +2970,15 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -2924,14 +2987,14 @@ private: uint32_t M1_val = - 1; uint32_t MMIN_val = - 1 << 32 - 1; { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, true), this->gen_ext( this->gen_const(32U, MMIN_val), @@ -2941,14 +3004,14 @@ private: this->builder.SetInsertPoint(bb_then); { { - 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_EQ, this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true), this->gen_ext( this->gen_const(32U, M1_val), @@ -2958,21 +3021,21 @@ private: this->builder.SetInsertPoint(bb_then); { Value* Xtmp0_val = this->gen_const(32U, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { Value* Xtmp1_val = this->builder.CreateURem( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 3), + this->gen_reg_load(rs1 + traits::X0, 3), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 3), + this->gen_reg_load(rs2 + traits::X0, 3), 32, true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -2984,14 +3047,14 @@ private: { Value* Xtmp2_val = this->builder.CreateURem( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 2), + this->gen_reg_load(rs1 + traits::X0, 2), 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 2), + this->gen_reg_load(rs2 + traits::X0, 2), 32, true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3001,8 +3064,8 @@ private: this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - Value* Xtmp3_val = this->gen_reg_load(fld_rs1_val + traits::X0, 1); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp3_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3010,29 +3073,30 @@ private: 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_sync(POST_SYNC, 58); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 59: REMU */ - std::tuple __remu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMU"); - this->gen_sync(iss::PRE_SYNC, 59); + this->gen_sync(PRE_SYNC, 59); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3040,15 +3104,15 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this->gen_const(32U, 0)), bb_then, bb_else); @@ -3056,20 +3120,20 @@ private: { Value* Xtmp0_val = this->builder.CreateURem( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 1), + this->gen_reg_load(rs1 + traits::X0, 1), 32, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1), 32, false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - Value* Xtmp1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 1); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->builder.CreateBr(bbnext); bb=bbnext; @@ -3077,30 +3141,31 @@ private: 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_sync(POST_SYNC, 59); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 60: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); - this->gen_sync(iss::PRE_SYNC, 60); + this->gen_sync(PRE_SYNC, 60); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3108,13 +3173,13 @@ private: 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 + traits::X0, 0); + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* REStmp1_val = this->gen_ext( this->builder.CreateNeg(this->gen_const(8U, 1)), 32, @@ -3125,31 +3190,32 @@ private: this->builder.CreateZExtOrTrunc(REStmp1_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_sync(POST_SYNC, 60); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 61: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); - this->gen_sync(iss::PRE_SYNC, 61); + this->gen_sync(PRE_SYNC, 61); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3157,11 +3223,11 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 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); + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); // this->builder.SetInsertPoint(bb); this->gen_cond_branch(this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3171,7 +3237,7 @@ private: bbnext); this->builder.SetInsertPoint(bb_then); { - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 1); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); this->gen_write_mem( traits::MEM, offs_val, @@ -3181,7 +3247,7 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp1_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3190,34 +3256,35 @@ private: this->gen_const(32U, 0), this->gen_const(32U, 1), 32); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 61); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 62: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); - this->gen_sync(iss::PRE_SYNC, 62); + this->gen_sync(PRE_SYNC, 62); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3225,45 +3292,46 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - Value* MEMtmp1_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 62); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 63: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); - this->gen_sync(iss::PRE_SYNC, 63); + this->gen_sync(PRE_SYNC, 63); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3271,49 +3339,50 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAdd( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 63); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 64: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); - this->gen_sync(iss::PRE_SYNC, 64); + this->gen_sync(PRE_SYNC, 64); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3321,49 +3390,50 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateXor( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 64); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 65: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); - this->gen_sync(iss::PRE_SYNC, 65); + this->gen_sync(PRE_SYNC, 65); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3371,49 +3441,50 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAnd( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 65); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 66: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); - this->gen_sync(iss::PRE_SYNC, 66); + this->gen_sync(PRE_SYNC, 66); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3421,49 +3492,50 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateOr( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 66); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 67: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); - this->gen_sync(iss::PRE_SYNC, 67); + this->gen_sync(PRE_SYNC, 67); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3471,14 +3543,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -3487,9 +3559,9 @@ private: res1_val, 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3498,31 +3570,32 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 67); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 68: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); - this->gen_sync(iss::PRE_SYNC, 68); + this->gen_sync(PRE_SYNC, 68); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3530,14 +3603,14 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -3546,9 +3619,9 @@ private: res1_val, 32, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 32, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3557,31 +3630,32 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 68); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 69: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); - this->gen_sync(iss::PRE_SYNC, 69); + this->gen_sync(PRE_SYNC, 69); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3589,21 +3663,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGT, res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3612,31 +3686,32 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 69); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 70: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); - this->gen_sync(iss::PRE_SYNC, 70); + this->gen_sync(PRE_SYNC, 70); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3644,21 +3719,21 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 32); Value* MEMtmp1_val = res2_val; @@ -3667,28 +3742,29 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_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_sync(POST_SYNC, 70); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 71: C.ADDI4SPN */ - std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI4SPN"); - this->gen_sync(iss::PRE_SYNC, 71); + this->gen_sync(PRE_SYNC, 71); - uint8_t fld_rd_val = ((bit_sub<2,3>(instr))); - uint16_t fld_imm_val = ((bit_sub<5,1>(instr) << 3) | (bit_sub<6,1>(instr) << 2) | (bit_sub<7,4>(instr) << 6) | (bit_sub<11,2>(instr) << 4)); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint16_t imm = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3696,37 +3772,38 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_imm_val == 0){ + if(imm == 0){ this->gen_raise_trap(0, 2); } Value* Xtmp0_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), 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_sync(POST_SYNC, 71); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 72: C.LW */ - std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LW"); - this->gen_sync(iss::PRE_SYNC, 72); + this->gen_sync(PRE_SYNC, 72); - uint8_t fld_rd_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {uimm:#05x}", fmt::arg("mnemonic", "c.lw"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs1", name(8+rs1)), fmt::arg("uimm", uimm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3735,34 +3812,35 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + 8 + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), 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_sync(POST_SYNC, 72); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 73: C.SW */ - std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SW"); - this->gen_sync(iss::PRE_SYNC, 73); + this->gen_sync(PRE_SYNC, 73); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_uimm_val = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {uimm:#05x}", fmt::arg("mnemonic", "c.sw"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3771,36 +3849,37 @@ private: pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0); + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_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_sync(POST_SYNC, 73); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 74: C.ADDI */ - std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI"); - this->gen_sync(iss::PRE_SYNC, 74); + this->gen_sync(PRE_SYNC, 74); - int8_t fld_imm_val = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3810,29 +3889,29 @@ private: Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rs1_val + traits::X0), false); + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), 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_sync(POST_SYNC, 74); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 75: C.NOP */ - std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.NOP"); - this->gen_sync(iss::PRE_SYNC, 75); + this->gen_sync(PRE_SYNC, 75); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("C.NOP"), + this->builder.CreateGlobalStringPtr("c.nop"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3842,27 +3921,28 @@ private: /* 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_sync(POST_SYNC, 75); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 76: C.JAL */ - std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JAL"); - this->gen_sync(iss::PRE_SYNC, 76); + this->gen_sync(PRE_SYNC, 76); - int16_t fld_imm_val = signextend((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) | (bit_sub<12,1>(instr) << 11)); + int16_t imm = signextend((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) | (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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), + fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3878,31 +3958,32 @@ private: this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 76); + this->gen_sync(POST_SYNC, 76); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 77: C.LI */ - std::tuple __c_li(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LI"); - this->gen_sync(iss::PRE_SYNC, 77); + this->gen_sync(PRE_SYNC, 77); - int8_t fld_imm_val = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3910,34 +3991,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_rd_val == 0){ + if(rd == 0){ this->gen_raise_trap(0, 2); } - Value* Xtmp0_val = this->gen_const(32U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 77); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 78: C.LUI */ - std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LUI"); - this->gen_sync(iss::PRE_SYNC, 78); + this->gen_sync(PRE_SYNC, 78); - int32_t fld_imm_val = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); + uint8_t rd = ((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 % (uint64_t)fld_imm_val; - std::vector args { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3945,36 +4027,37 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_rd_val == 0){ + if(rd == 0){ this->gen_raise_trap(0, 2); } - if(fld_imm_val == 0){ + if(imm == 0){ this->gen_raise_trap(0, 2); } - Value* Xtmp0_val = this->gen_const(32U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 78); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 79: C.ADDI16SP */ - std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADDI16SP"); - this->gen_sync(iss::PRE_SYNC, 79); + this->gen_sync(PRE_SYNC, 79); - int16_t fld_imm_val = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), + fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3986,31 +4069,32 @@ private: this->gen_ext( this->gen_reg_load(2 + traits::X0, 0), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), 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_sync(POST_SYNC, 79); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 80: C.SRLI */ - std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SRLI"); - this->gen_sync(iss::PRE_SYNC, 80); + this->gen_sync(PRE_SYNC, 80); - uint8_t fld_shamt_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4018,34 +4102,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rs1_idx_val = fld_rs1_val + 8; + uint8_t rs1_idx_val = rs1 + 8; Value* Xtmp0_val = this->builder.CreateLShr( this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), 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_sync(POST_SYNC, 80); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 81: C.SRAI */ - std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SRAI"); - this->gen_sync(iss::PRE_SYNC, 81); + this->gen_sync(PRE_SYNC, 81); - uint8_t fld_shamt_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4053,34 +4138,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rs1_idx_val = fld_rs1_val + 8; + uint8_t rs1_idx_val = rs1 + 8; Value* Xtmp0_val = this->builder.CreateAShr( this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), 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_sync(POST_SYNC, 81); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 82: C.ANDI */ - std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ANDI"); - this->gen_sync(iss::PRE_SYNC, 82); + this->gen_sync(PRE_SYNC, 82); - uint8_t fld_imm_val = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((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 % (uint64_t)fld_imm_val; - std::vector args { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4088,34 +4174,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rs1_idx_val = fld_rs1_val + 8; + uint8_t rs1_idx_val = rs1 + 8; Value* Xtmp0_val = this->builder.CreateAnd( this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), 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_sync(POST_SYNC, 82); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 83: C.SUB */ - std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SUB"); - this->gen_sync(iss::PRE_SYNC, 83); + this->gen_sync(PRE_SYNC, 83); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4123,34 +4210,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateSub( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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_sync(POST_SYNC, 83); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 84: C.XOR */ - std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.XOR"); - this->gen_sync(iss::PRE_SYNC, 84); + this->gen_sync(PRE_SYNC, 84); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4158,34 +4246,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateXor( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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_sync(POST_SYNC, 84); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 85: C.OR */ - std::tuple __c_or(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.OR"); - this->gen_sync(iss::PRE_SYNC, 85); + this->gen_sync(PRE_SYNC, 85); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4193,34 +4282,35 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateOr( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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_sync(POST_SYNC, 85); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 86: C.AND */ - std::tuple __c_and(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.AND"); - this->gen_sync(iss::PRE_SYNC, 86); + this->gen_sync(PRE_SYNC, 86); - uint8_t fld_rs2_val = ((bit_sub<2,3>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,3>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4228,33 +4318,34 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - uint8_t rd_idx_val = fld_rd_val + 8; + uint8_t rd_idx_val = rd + 8; Value* Xtmp0_val = this->builder.CreateAnd( this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + 8 + traits::X0, 0)); + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), 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_sync(POST_SYNC, 86); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 87: C.J */ - std::tuple __c_j(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.J"); - this->gen_sync(iss::PRE_SYNC, 87); + this->gen_sync(PRE_SYNC, 87); - int16_t fld_imm_val = signextend((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) | (bit_sub<12,1>(instr) << 11)); + int16_t imm = signextend((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) | (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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), + fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4266,31 +4357,32 @@ private: this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 87); + this->gen_sync(POST_SYNC, 87); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 88: C.BEQZ */ - std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.BEQZ"); - this->gen_sync(iss::PRE_SYNC, 88); + this->gen_sync(PRE_SYNC, 88); - int16_t fld_imm_val = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4301,13 +4393,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_EQ, - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), + this->gen_reg_load(rs1 + 8 + traits::X0, 0), this->gen_const(32U, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 2)), @@ -4315,27 +4407,28 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 88); + this->gen_sync(POST_SYNC, 88); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 89: C.BNEZ */ - std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.BNEZ"); - this->gen_sync(iss::PRE_SYNC, 89); + this->gen_sync(PRE_SYNC, 89); - int16_t fld_imm_val = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t fld_rs1_val = ((bit_sub<7,3>(instr))); + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4346,13 +4439,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs1_val + 8 + traits::X0, 0), + this->gen_reg_load(rs1 + 8 + traits::X0, 0), this->gen_const(32U, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 32, true), - this->gen_const(32U, fld_imm_val)), + this->gen_const(32U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(32U, 2)), @@ -4360,27 +4453,28 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 89); + this->gen_sync(POST_SYNC, 89); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 90: C.SLLI */ - std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SLLI"); - this->gen_sync(iss::PRE_SYNC, 90); + this->gen_sync(PRE_SYNC, 90); - uint8_t fld_shamt_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), + fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4388,36 +4482,37 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - if(fld_rs1_val == 0){ + if(rs1 == 0){ this->gen_raise_trap(0, 2); } Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(32U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rs1_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), 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_sync(POST_SYNC, 90); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 91: C.LWSP */ - std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.LWSP"); - this->gen_sync(iss::PRE_SYNC, 91); + this->gen_sync(PRE_SYNC, 91); - uint8_t fld_uimm_val = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4427,32 +4522,33 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); + this->gen_const(32U, uimm)); Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 91); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 92: C.MV */ - std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.MV"); - this->gen_sync(iss::PRE_SYNC, 92); + this->gen_sync(PRE_SYNC, 92); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4460,30 +4556,31 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - Value* Xtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 92); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 93: C.JR */ - std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JR"); - this->gen_sync(iss::PRE_SYNC, 93); + this->gen_sync(PRE_SYNC, 93); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), + fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4491,30 +4588,31 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+2; - Value* PC_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 93); + this->gen_sync(POST_SYNC, 93); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 94: C.ADD */ - std::tuple __c_add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.ADD"); - this->gen_sync(iss::PRE_SYNC, 94); + this->gen_sync(PRE_SYNC, 94); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4523,31 +4621,32 @@ private: pc=pc+2; Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rd_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rd + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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_sync(POST_SYNC, 94); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 95: C.JALR */ - std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.JALR"); - this->gen_sync(iss::PRE_SYNC, 95); + this->gen_sync(PRE_SYNC, 95); - uint8_t fld_rs1_val = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), + fmt::arg("rs1", name(rs1))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4559,26 +4658,26 @@ private: cur_pc_val, this->gen_const(32U, 2)); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); - Value* PC_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 95); + this->gen_sync(POST_SYNC, 95); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 96: C.EBREAK */ - std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.EBREAK"); - this->gen_sync(iss::PRE_SYNC, 96); + this->gen_sync(PRE_SYNC, 96); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("C.EBREAK"), + this->builder.CreateGlobalStringPtr("c.ebreak"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4587,27 +4686,28 @@ private: pc=pc+2; this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 96); + this->gen_sync(POST_SYNC, 96); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } /* instruction 97: C.SWSP */ - std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("C.SWSP"); - this->gen_sync(iss::PRE_SYNC, 97); + this->gen_sync(PRE_SYNC, 97); - uint8_t fld_rs2_val = ((bit_sub<2,5>(instr))); - uint8_t fld_uimm_val = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((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 { + auto mnemonic = fmt::format( + "{mnemonic:10} x2+{uimm:#05x}, {rs2}", fmt::arg("mnemonic", "c.swsp"), + fmt::arg("uimm", uimm), fmt::arg("rs2", name(rs2))); + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4617,31 +4717,31 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, fld_uimm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_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_sync(POST_SYNC, 97); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } /* instruction 98: DII */ - std::tuple __dii(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DII"); - this->gen_sync(iss::PRE_SYNC, 98); + this->gen_sync(PRE_SYNC, 98); if(this->disass_enabled){ /* generate console output when executing the command */ - std::vector args { + std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("DII"), + this->builder.CreateGlobalStringPtr("dii"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4651,8 +4751,8 @@ private: 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_sync(POST_SYNC, 98); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } @@ -4660,18 +4760,17 @@ private: /**************************************************************************** * 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()); + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, 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); + 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)), + 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_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(BRANCH, nullptr); } @@ -4698,8 +4797,8 @@ vm_impl::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id) } template -std::tuple -vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, llvm::BasicBlock *this_block) { +std::tuple +vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, 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; @@ -4720,7 +4819,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, } catch (trap_access &ta) { throw trap_access(ta.id, pc.val); } - if (insn == 0x0000006f || (insn & 0xffff) == 0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' + if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack ++inst_cnt; auto lut_val = extract_fields(insn); @@ -4731,7 +4830,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, return (this->*f)(pc, insn, this_block); } -template void vm_impl::gen_leave_behavior(llvm::BasicBlock *leave_blk) { +template void vm_impl::gen_leave_behavior(BasicBlock *leave_blk) { this->builder.SetInsertPoint(leave_blk); this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits::NEXT_PC), false)); } @@ -4739,51 +4838,46 @@ template void vm_impl::gen_leave_behavior(llvm::BasicBlock template void vm_impl::gen_raise_trap(uint16_t trap_id, uint16_t cause) { auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id); this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_leave_trap(unsigned lvl) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, lvl)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), 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); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), - get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); } template void vm_impl::gen_wait(unsigned type) { - std::vector args{ - this->core_ptr, llvm::ConstantInt::get(getContext(), llvm::APInt(64, type)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) }; this->builder.CreateCall(this->mod->getFunction("wait"), args); } -template void vm_impl::gen_trap_behavior(llvm::BasicBlock *trap_blk) { +template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - std::vector args{this->core_ptr, this->adj_to64(trap_state_val), - this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits::PC), false))}; + 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) { +template inline void vm_impl::gen_trap_check(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))), + ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), bb, this->trap_blk, 1); } } // namespace rv32imac -template <> std::unique_ptr create(arch::rv32imac *core, unsigned short port, bool dump) { +template <> +std::unique_ptr create(arch::rv32imac *core, unsigned short port, bool dump) { auto ret = new rv32imac::vm_impl(*core, dump); if (port != 0) debugger::server::run_server(ret, port); return std::unique_ptr(ret); diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index 5e3c2e1..d48e2e6 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -1,38 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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 -// -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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 #include @@ -42,14 +38,14 @@ #include #include -#include +#include -#include #include +#include namespace iss { namespace vm { -namespace fp_impl{ +namespace fp_impl { void add_fp_functions_2_module(llvm::Module *, unsigned); } } @@ -74,7 +70,7 @@ public: void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; } - target_adapter_if *accquire_target_adapter(server_if *srv) { + target_adapter_if *accquire_target_adapter(server_if *srv) override { debugger_if::dbg_enabled = true; if (vm_base::tgt_adapter == nullptr) vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); @@ -84,6 +80,8 @@ public: protected: using vm_base::get_reg_ptr; + inline const char *name(size_t index){return traits::reg_aliases.at(index);} + template inline ConstantInt *size(T type) { return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); } @@ -97,8 +95,7 @@ protected: 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 &, - BasicBlock *) override; + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override; void gen_leave_behavior(BasicBlock *leave_blk) override; @@ -118,7 +115,7 @@ protected: inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) { Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val), - this->get_type(traits::XLEN)); + this->get_type(traits::XLEN)); this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true); } @@ -130,16 +127,16 @@ protected: using this_class = vm_impl; using compile_func = std::tuple (this_class::*)(virt_addr_t &pc, - code_word_t instr, - BasicBlock *bb); + code_word_t instr, + BasicBlock *bb); std::array lut; std::array lut_00, lut_01, lut_10; std::array lut_11; - std::array qlut; + std::array qlut; - std::array lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } }; + 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) { @@ -370,19 +367,20 @@ private: std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LWU"); - this->gen_sync(iss::PRE_SYNC, 0); + this->gen_sync(PRE_SYNC, 0); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -392,18 +390,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 0); + this->gen_sync(POST_SYNC, 0); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -413,19 +411,20 @@ private: std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LD"); - this->gen_sync(iss::PRE_SYNC, 1); + this->gen_sync(PRE_SYNC, 1); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -435,18 +434,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 1); + this->gen_sync(POST_SYNC, 1); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -456,19 +455,20 @@ private: std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SD"); - this->gen_sync(iss::PRE_SYNC, 2); + this->gen_sync(PRE_SYNC, 2); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -478,16 +478,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 2); + this->gen_sync(POST_SYNC, 2); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -497,19 +497,20 @@ private: std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); - this->gen_sync(iss::PRE_SYNC, 3); + this->gen_sync(PRE_SYNC, 3); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -517,18 +518,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 3); + this->gen_sync(POST_SYNC, 3); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -538,19 +539,20 @@ private: std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); - this->gen_sync(iss::PRE_SYNC, 4); + this->gen_sync(PRE_SYNC, 4); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -558,18 +560,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 4); + this->gen_sync(POST_SYNC, 4); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -579,19 +581,20 @@ private: std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); - this->gen_sync(iss::PRE_SYNC, 5); + this->gen_sync(PRE_SYNC, 5); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -599,18 +602,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_shamt_val > 31){ + if(shamt > 31){ this->gen_raise_trap(0, 0); } else { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 5); + this->gen_sync(POST_SYNC, 5); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -620,19 +623,20 @@ private: std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDIW"); - this->gen_sync(iss::PRE_SYNC, 6); + this->gen_sync(PRE_SYNC, 6); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -640,23 +644,23 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateAdd( this->gen_ext( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), 32, true), - this->gen_const(32U, fld_imm_val)); + this->gen_const(32U, imm)); Value* Xtmp0_val = this->gen_ext( res_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 6); + this->gen_sync(POST_SYNC, 6); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -666,19 +670,20 @@ private: std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLIW"); - this->gen_sync(iss::PRE_SYNC, 7); + this->gen_sync(PRE_SYNC, 7); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -686,21 +691,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* sh_val_val = this->builder.CreateShl( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); Value* Xtmp0_val = this->gen_ext( sh_val_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 7); + this->gen_sync(POST_SYNC, 7); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -710,19 +715,20 @@ private: std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLIW"); - this->gen_sync(iss::PRE_SYNC, 8); + this->gen_sync(PRE_SYNC, 8); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -730,21 +736,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* sh_val_val = this->builder.CreateLShr( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); Value* Xtmp0_val = this->gen_ext( sh_val_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 8); + this->gen_sync(POST_SYNC, 8); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -754,19 +760,20 @@ private: std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAIW"); - this->gen_sync(iss::PRE_SYNC, 9); + this->gen_sync(PRE_SYNC, 9); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_shamt_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -774,21 +781,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* sh_val_val = this->builder.CreateAShr( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), - this->gen_const(32U, fld_shamt_val)); + this->gen_const(32U, shamt)); Value* Xtmp0_val = this->gen_ext( sh_val_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 9); + this->gen_sync(POST_SYNC, 9); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -798,17 +805,17 @@ private: std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDW"); - this->gen_sync(iss::PRE_SYNC, 10); + this->gen_sync(PRE_SYNC, 10); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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.CreateGlobalStringPtr("addw"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -816,24 +823,24 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateAdd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this-> get_type(32) )); Value* Xtmp0_val = this->gen_ext( res_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 10); + this->gen_sync(POST_SYNC, 10); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -843,17 +850,17 @@ private: std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUBW"); - this->gen_sync(iss::PRE_SYNC, 11); + this->gen_sync(PRE_SYNC, 11); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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.CreateGlobalStringPtr("subw"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -861,24 +868,24 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* res_val = this->builder.CreateSub( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this-> get_type(32) )); Value* Xtmp0_val = this->gen_ext( res_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 11); + this->gen_sync(POST_SYNC, 11); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -888,19 +895,20 @@ private: std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLW"); - this->gen_sync(iss::PRE_SYNC, 12); + this->gen_sync(PRE_SYNC, 12); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -908,17 +916,17 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ uint32_t mask_val = 0x1f; Value* count_val = this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this-> get_type(32) ), this->gen_const(32U, mask_val)); Value* sh_val_val = this->builder.CreateShl( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), count_val); @@ -926,10 +934,10 @@ private: sh_val_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 12); + this->gen_sync(POST_SYNC, 12); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -939,19 +947,20 @@ private: std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLW"); - this->gen_sync(iss::PRE_SYNC, 13); + this->gen_sync(PRE_SYNC, 13); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -959,17 +968,17 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ uint32_t mask_val = 0x1f; Value* count_val = this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this-> get_type(32) ), this->gen_const(32U, mask_val)); Value* sh_val_val = this->builder.CreateLShr( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), count_val); @@ -977,10 +986,10 @@ private: sh_val_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 13); + this->gen_sync(POST_SYNC, 13); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -990,19 +999,20 @@ private: std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAW"); - this->gen_sync(iss::PRE_SYNC, 14); + this->gen_sync(PRE_SYNC, 14); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1010,17 +1020,17 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ uint32_t mask_val = 0x1f; Value* count_val = this->builder.CreateAnd( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), this-> get_type(32) ), this->gen_const(32U, mask_val)); Value* sh_val_val = this->builder.CreateAShr( this->builder.CreateTrunc( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this-> get_type(32) ), count_val); @@ -1028,10 +1038,10 @@ private: sh_val_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 14); + this->gen_sync(POST_SYNC, 14); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1041,18 +1051,19 @@ private: std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LUI"); - this->gen_sync(iss::PRE_SYNC, 15); + this->gen_sync(PRE_SYNC, 15); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1060,12 +1071,12 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* Xtmp0_val = this->gen_const(64U, fld_imm_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(64U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 15); + this->gen_sync(POST_SYNC, 15); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1075,18 +1086,19 @@ private: std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AUIPC"); - this->gen_sync(iss::PRE_SYNC, 16); + this->gen_sync(PRE_SYNC, 16); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1094,16 +1106,16 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 16); + this->gen_sync(POST_SYNC, 16); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1113,18 +1125,19 @@ private: std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JAL"); - this->gen_sync(iss::PRE_SYNC, 17); + this->gen_sync(PRE_SYNC, 17); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - int32_t fld_imm_val = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1132,21 +1145,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* PC_val = this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)); + this->gen_const(64U, imm)); this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 17); + this->gen_sync(POST_SYNC, 17); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1155,19 +1168,20 @@ private: std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); - this->gen_sync(iss::PRE_SYNC, 18); + this->gen_sync(PRE_SYNC, 18); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1177,9 +1191,9 @@ private: Value* new_pc_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); + this->gen_const(64U, imm)); Value* align_val = this->builder.CreateAnd( new_pc_val, this->gen_const(64U, 0x2)); @@ -1201,11 +1215,11 @@ private: this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* PC_val = this->builder.CreateAnd( new_pc_val, @@ -1217,7 +1231,7 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - this->gen_sync(iss::POST_SYNC, 18); + this->gen_sync(POST_SYNC, 18); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1226,19 +1240,20 @@ private: std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); - this->gen_sync(iss::PRE_SYNC, 19); + this->gen_sync(PRE_SYNC, 19); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1249,13 +1264,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_EQ, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)), @@ -1263,7 +1278,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 19); + this->gen_sync(POST_SYNC, 19); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1272,19 +1287,20 @@ private: std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); - this->gen_sync(iss::PRE_SYNC, 20); + this->gen_sync(PRE_SYNC, 20); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1295,13 +1311,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)), @@ -1309,7 +1325,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 20); + this->gen_sync(POST_SYNC, 20); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1318,19 +1334,20 @@ private: std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); - this->gen_sync(iss::PRE_SYNC, 21); + this->gen_sync(PRE_SYNC, 21); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1342,16 +1359,16 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)), @@ -1359,7 +1376,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 21); + this->gen_sync(POST_SYNC, 21); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1368,19 +1385,20 @@ private: std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); - this->gen_sync(iss::PRE_SYNC, 22); + this->gen_sync(PRE_SYNC, 22); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1392,16 +1410,16 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_SGE, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)), @@ -1409,7 +1427,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 22); + this->gen_sync(POST_SYNC, 22); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1418,19 +1436,20 @@ private: std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); - this->gen_sync(iss::PRE_SYNC, 23); + this->gen_sync(PRE_SYNC, 23); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1441,13 +1460,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)), @@ -1455,7 +1474,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 23); + this->gen_sync(POST_SYNC, 23); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1464,19 +1483,20 @@ private: std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); - this->gen_sync(iss::PRE_SYNC, 24); + this->gen_sync(PRE_SYNC, 24); - int16_t fld_imm_val = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1487,13 +1507,13 @@ private: Value* PC_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGE, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), this->builder.CreateAdd( this->gen_ext( cur_pc_val, 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->builder.CreateAdd( cur_pc_val, this->gen_const(64U, 4)), @@ -1501,7 +1521,7 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(iss::POST_SYNC, 24); + this->gen_sync(POST_SYNC, 24); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -1510,19 +1530,20 @@ private: std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); - this->gen_sync(iss::PRE_SYNC, 25); + this->gen_sync(PRE_SYNC, 25); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1532,18 +1553,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 8/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 25); + this->gen_sync(POST_SYNC, 25); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1553,19 +1574,20 @@ private: std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); - this->gen_sync(iss::PRE_SYNC, 26); + this->gen_sync(PRE_SYNC, 26); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1575,18 +1597,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 16/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 26); + this->gen_sync(POST_SYNC, 26); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1596,19 +1618,20 @@ private: std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); - this->gen_sync(iss::PRE_SYNC, 27); + this->gen_sync(PRE_SYNC, 27); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1618,18 +1641,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 27); + this->gen_sync(POST_SYNC, 27); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1639,19 +1662,20 @@ private: std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); - this->gen_sync(iss::PRE_SYNC, 28); + this->gen_sync(PRE_SYNC, 28); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1661,18 +1685,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 8/8), 64, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 28); + this->gen_sync(POST_SYNC, 28); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1682,19 +1706,20 @@ private: std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); - this->gen_sync(iss::PRE_SYNC, 29); + this->gen_sync(PRE_SYNC, 29); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1704,18 +1729,18 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - if(fld_rd_val != 0){ + this->gen_const(64U, imm)); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 16/8), 64, false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 29); + this->gen_sync(POST_SYNC, 29); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1725,19 +1750,20 @@ private: std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); - this->gen_sync(iss::PRE_SYNC, 30); + this->gen_sync(PRE_SYNC, 30); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1747,16 +1773,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 30); + this->gen_sync(POST_SYNC, 30); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1766,19 +1792,20 @@ private: std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); - this->gen_sync(iss::PRE_SYNC, 31); + this->gen_sync(PRE_SYNC, 31); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1788,16 +1815,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 31); + this->gen_sync(POST_SYNC, 31); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1807,19 +1834,20 @@ private: std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); - this->gen_sync(iss::PRE_SYNC, 32); + this->gen_sync(PRE_SYNC, 32); - int16_t fld_imm_val = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1829,16 +1857,16 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 32); + this->gen_sync(POST_SYNC, 32); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1848,19 +1876,20 @@ private: std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); - this->gen_sync(iss::PRE_SYNC, 33); + this->gen_sync(PRE_SYNC, 33); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1868,16 +1897,16 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 33); + this->gen_sync(POST_SYNC, 33); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1887,19 +1916,20 @@ private: std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); - this->gen_sync(iss::PRE_SYNC, 34); + this->gen_sync(PRE_SYNC, 34); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1907,21 +1937,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), - this->gen_const(64U, fld_imm_val)), + this->gen_const(64U, imm)), this->gen_const(64U, 1), this->gen_const(64U, 0), 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 34); + this->gen_sync(POST_SYNC, 34); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1931,19 +1961,20 @@ private: std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_sync(iss::PRE_SYNC, 35); + this->gen_sync(PRE_SYNC, 35); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1951,20 +1982,20 @@ private: 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){ + int64_t full_imm_val = imm; + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->gen_const(64U, full_imm_val)), this->gen_const(64U, 1), this->gen_const(64U, 0), 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 35); + this->gen_sync(POST_SYNC, 35); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -1974,19 +2005,20 @@ private: std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); - this->gen_sync(iss::PRE_SYNC, 36); + this->gen_sync(PRE_SYNC, 36); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -1994,14 +2026,16 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(64U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 36); + this->gen_sync(POST_SYNC, 36); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2011,19 +2045,20 @@ private: std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); - this->gen_sync(iss::PRE_SYNC, 37); + this->gen_sync(PRE_SYNC, 37); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2031,14 +2066,16 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(64U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 37); + this->gen_sync(POST_SYNC, 37); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2048,19 +2085,20 @@ private: std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); - this->gen_sync(iss::PRE_SYNC, 38); + this->gen_sync(PRE_SYNC, 38); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - int16_t fld_imm_val = signextend((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2068,14 +2106,16 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_const(64U, fld_imm_val)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 38); + this->gen_sync(POST_SYNC, 38); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2085,19 +2125,20 @@ private: std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); - this->gen_sync(iss::PRE_SYNC, 39); + this->gen_sync(PRE_SYNC, 39); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2105,14 +2146,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 39); + this->gen_sync(POST_SYNC, 39); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2122,19 +2163,20 @@ private: std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); - this->gen_sync(iss::PRE_SYNC, 40); + this->gen_sync(PRE_SYNC, 40); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2142,14 +2184,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 40); + this->gen_sync(POST_SYNC, 40); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2159,19 +2201,20 @@ private: std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); - this->gen_sync(iss::PRE_SYNC, 41); + this->gen_sync(PRE_SYNC, 41); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2179,16 +2222,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(64U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 41); + this->gen_sync(POST_SYNC, 41); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2198,19 +2243,20 @@ private: std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); - this->gen_sync(iss::PRE_SYNC, 42); + this->gen_sync(PRE_SYNC, 42); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2218,23 +2264,23 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_SLT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), this->gen_const(64U, 1), this->gen_const(64U, 0), 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 42); + this->gen_sync(POST_SYNC, 42); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2244,19 +2290,20 @@ private: std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); - this->gen_sync(iss::PRE_SYNC, 43); + this->gen_sync(PRE_SYNC, 43); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2264,25 +2311,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, this->gen_ext( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), 64, false), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, false)), this->gen_const(64U, 1), this->gen_const(64U, 0), 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 43); + this->gen_sync(POST_SYNC, 43); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2292,19 +2339,20 @@ private: std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); - this->gen_sync(iss::PRE_SYNC, 44); + this->gen_sync(PRE_SYNC, 44); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2312,14 +2360,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 44); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2329,19 +2377,20 @@ private: std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); - this->gen_sync(iss::PRE_SYNC, 45); + this->gen_sync(PRE_SYNC, 45); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2349,16 +2398,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(64U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 45); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2368,19 +2419,20 @@ private: std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); - this->gen_sync(iss::PRE_SYNC, 46); + this->gen_sync(PRE_SYNC, 46); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2388,16 +2440,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), + this->gen_reg_load(rs1 + traits::X0, 0), this->builder.CreateAnd( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), - this->gen_const(64U, 0x1f))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 46); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2407,19 +2461,20 @@ private: std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); - this->gen_sync(iss::PRE_SYNC, 47); + this->gen_sync(PRE_SYNC, 47); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2427,14 +2482,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 47); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2444,19 +2499,20 @@ private: std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); - this->gen_sync(iss::PRE_SYNC, 48); + this->gen_sync(PRE_SYNC, 48); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2464,14 +2520,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(fld_rs1_val + traits::X0, 0), - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 48); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2481,18 +2537,18 @@ private: std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); - this->gen_sync(iss::PRE_SYNC, 49); + this->gen_sync(PRE_SYNC, 49); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_succ_val = ((bit_sub<20,4>(instr))); - uint8_t fld_pred_val = ((bit_sub<24,4>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((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.CreateGlobalStringPtr("fence"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2502,15 +2558,15 @@ private: Value* FENCEtmp0_val = this->builder.CreateOr( this->builder.CreateShl( - this->gen_const(64U, fld_pred_val), + this->gen_const(64U, pred), this->gen_const(64U, 4)), - this->gen_const(64U, fld_succ_val)); + this->gen_const(64U, succ)); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 0), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 49); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2520,17 +2576,17 @@ private: std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_sync(iss::PRE_SYNC, 50); + this->gen_sync(PRE_SYNC, 50); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_imm_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((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.CreateGlobalStringPtr("fence_i"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2538,14 +2594,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* FENCEtmp0_val = this->gen_const(64U, fld_imm_val); + Value* FENCEtmp0_val = this->gen_const(64U, imm); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 1), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 50); + this->gen_sync(POST_SYNC, 50); this->gen_trap_check(this->leave_blk); return std::make_tuple(FLUSH, nullptr); } @@ -2554,14 +2610,14 @@ private: std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ECALL"); - this->gen_sync(iss::PRE_SYNC, 51); + this->gen_sync(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.CreateGlobalStringPtr("ecall"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2570,7 +2626,7 @@ private: pc=pc+4; this->gen_raise_trap(0, 11); - this->gen_sync(iss::POST_SYNC, 51); + this->gen_sync(POST_SYNC, 51); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2579,14 +2635,14 @@ private: std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_sync(iss::PRE_SYNC, 52); + this->gen_sync(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.CreateGlobalStringPtr("ebreak"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2595,7 +2651,7 @@ private: pc=pc+4; this->gen_raise_trap(0, 3); - this->gen_sync(iss::POST_SYNC, 52); + this->gen_sync(POST_SYNC, 52); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2604,14 +2660,14 @@ private: std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("URET"); - this->gen_sync(iss::PRE_SYNC, 53); + this->gen_sync(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.CreateGlobalStringPtr("uret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2620,7 +2676,7 @@ private: pc=pc+4; this->gen_leave_trap(0); - this->gen_sync(iss::POST_SYNC, 53); + this->gen_sync(POST_SYNC, 53); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2629,14 +2685,14 @@ private: std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRET"); - this->gen_sync(iss::PRE_SYNC, 54); + this->gen_sync(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.CreateGlobalStringPtr("sret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2645,7 +2701,7 @@ private: pc=pc+4; this->gen_leave_trap(1); - this->gen_sync(iss::POST_SYNC, 54); + this->gen_sync(POST_SYNC, 54); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2654,14 +2710,14 @@ private: std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MRET"); - this->gen_sync(iss::PRE_SYNC, 55); + this->gen_sync(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.CreateGlobalStringPtr("mret"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2670,7 +2726,7 @@ private: pc=pc+4; this->gen_leave_trap(3); - this->gen_sync(iss::POST_SYNC, 55); + this->gen_sync(POST_SYNC, 55); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } @@ -2679,14 +2735,14 @@ private: std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("WFI"); - this->gen_sync(iss::PRE_SYNC, 56); + this->gen_sync(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.CreateGlobalStringPtr("wfi"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2696,7 +2752,7 @@ private: this->gen_wait(1); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 56); + this->gen_sync(POST_SYNC, 56); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2706,16 +2762,16 @@ private: std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_sync(iss::PRE_SYNC, 57); + this->gen_sync(PRE_SYNC, 57); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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.CreateGlobalStringPtr("sfence.vma"), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2723,18 +2779,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* FENCEtmp0_val = this->gen_const(64U, fld_rs1_val); + Value* FENCEtmp0_val = this->gen_const(64U, rs1); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 2), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); - Value* FENCEtmp1_val = this->gen_const(64U, fld_rs2_val); + Value* FENCEtmp1_val = this->gen_const(64U, rs2); this->gen_write_mem( traits::FENCE, this->gen_const(64U, 3), this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 57); + this->gen_sync(POST_SYNC, 57); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2744,19 +2800,20 @@ private: std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_sync(iss::PRE_SYNC, 58); + this->gen_sync(PRE_SYNC, 58); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2764,25 +2821,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* rs_val_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 64/8); + Value* rs_val_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); Value* CSRtmp0_val = rs_val_val; this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); Value* Xtmp1_val = csr_val_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } else { Value* CSRtmp2_val = rs_val_val; this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 58); + this->gen_sync(POST_SYNC, 58); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2792,19 +2849,20 @@ private: std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_sync(iss::PRE_SYNC, 59); + this->gen_sync(PRE_SYNC, 59); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2812,23 +2870,23 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 64/8); - Value* xrs1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_rs1_val != 0){ + if(rs1 != 0){ Value* CSRtmp1_val = this->builder.CreateOr( xrd_val, xrs1_val); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 59); + this->gen_sync(POST_SYNC, 59); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2838,19 +2896,20 @@ private: std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_sync(iss::PRE_SYNC, 60); + this->gen_sync(PRE_SYNC, 60); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2858,23 +2917,23 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 64/8); - Value* xrs1_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* xrd_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_rs1_val != 0){ + if(rs1 != 0){ Value* CSRtmp1_val = this->builder.CreateAnd( xrd_val, this->builder.CreateNot(xrs1_val)); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 60); + this->gen_sync(POST_SYNC, 60); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2884,19 +2943,20 @@ private: std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_sync(iss::PRE_SYNC, 61); + this->gen_sync(PRE_SYNC, 61); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2904,20 +2964,20 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - if(fld_rd_val != 0){ - Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 64/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* CSRtmp1_val = this->gen_ext( - this->gen_const(64U, fld_zimm_val), + this->gen_const(64U, zimm), 64, false); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 61); + this->gen_sync(POST_SYNC, 61); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2927,19 +2987,20 @@ private: std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_sync(iss::PRE_SYNC, 62); + this->gen_sync(PRE_SYNC, 62); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2947,25 +3008,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 64/8); - if(fld_zimm_val != 0){ + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + if(zimm != 0){ Value* CSRtmp0_val = this->builder.CreateOr( res_val, this->gen_ext( - this->gen_const(64U, fld_zimm_val), + this->gen_const(64U, zimm), 64, false)); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); } - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp1_val = res_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 62); + this->gen_sync(POST_SYNC, 62); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -2975,19 +3036,20 @@ private: std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_sync(iss::PRE_SYNC, 63); + this->gen_sync(PRE_SYNC, 63); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_zimm_val = ((bit_sub<15,5>(instr))); - uint16_t fld_csr_val = ((bit_sub<20,12>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -2995,25 +3057,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, fld_csr_val), 64/8); - if(fld_rd_val != 0){ + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - if(fld_zimm_val != 0){ + if(zimm != 0){ Value* CSRtmp1_val = this->builder.CreateAnd( res_val, this->builder.CreateNot(this->gen_ext( - this->gen_const(64U, fld_zimm_val), + this->gen_const(64U, zimm), 64, false))); this->gen_write_mem( traits::CSR, - this->gen_const(16U, fld_csr_val), + this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 63); + this->gen_sync(POST_SYNC, 63); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3023,20 +3085,21 @@ private: std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.D"); - this->gen_sync(iss::PRE_SYNC, 64); + this->gen_sync(PRE_SYNC, 64); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3044,13 +3107,13 @@ private: 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 + traits::X0, 0); + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* REStmp1_val = this->gen_ext( this->builder.CreateNeg(this->gen_const(8U, 1)), 64, @@ -3061,7 +3124,7 @@ private: this->builder.CreateZExtOrTrunc(REStmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 64); + this->gen_sync(POST_SYNC, 64); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3071,21 +3134,22 @@ private: std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.D"); - this->gen_sync(iss::PRE_SYNC, 65); + this->gen_sync(PRE_SYNC, 65); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3093,7 +3157,7 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/8); { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); @@ -3108,21 +3172,21 @@ private: bb_else); this->builder.SetInsertPoint(bb_then); { - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 1); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); this->gen_write_mem( traits::MEM, offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));if(fld_rd_val != 0){ + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));if(rd != 0){ Value* Xtmp1_val = this->gen_const(64U, 0); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } } this->builder.CreateBr(bbnext); this->builder.SetInsertPoint(bb_else); { - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp2_val = this->gen_const(64U, 1); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); } } this->builder.CreateBr(bbnext); @@ -3130,7 +3194,7 @@ private: } this->builder.SetInsertPoint(bb); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 65); + this->gen_sync(POST_SYNC, 65); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3140,21 +3204,22 @@ private: std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.D"); - this->gen_sync(iss::PRE_SYNC, 66); + this->gen_sync(PRE_SYNC, 66); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3162,21 +3227,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - Value* MEMtmp1_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 66); + this->gen_sync(POST_SYNC, 66); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3186,21 +3251,22 @@ private: std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.D"); - this->gen_sync(iss::PRE_SYNC, 67); + this->gen_sync(PRE_SYNC, 67); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3208,25 +3274,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAdd( res_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 67); + this->gen_sync(POST_SYNC, 67); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3236,21 +3302,22 @@ private: std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.D"); - this->gen_sync(iss::PRE_SYNC, 68); + this->gen_sync(PRE_SYNC, 68); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3258,25 +3325,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateXor( res_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 68); + this->gen_sync(POST_SYNC, 68); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3286,21 +3353,22 @@ private: std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.D"); - this->gen_sync(iss::PRE_SYNC, 69); + this->gen_sync(PRE_SYNC, 69); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3308,25 +3376,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAnd( res_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 69); + this->gen_sync(POST_SYNC, 69); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3336,21 +3404,22 @@ private: std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.D"); - this->gen_sync(iss::PRE_SYNC, 70); + this->gen_sync(PRE_SYNC, 70); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3358,25 +3427,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateOr( res_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 70); + this->gen_sync(POST_SYNC, 70); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3386,21 +3455,22 @@ private: std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.D"); - this->gen_sync(iss::PRE_SYNC, 71); + this->gen_sync(PRE_SYNC, 71); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3408,14 +3478,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -3424,9 +3494,9 @@ private: res_val, 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res_val, 64); Value* MEMtmp1_val = res_val; @@ -3435,7 +3505,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 71); + this->gen_sync(POST_SYNC, 71); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3445,21 +3515,22 @@ private: std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.D"); - this->gen_sync(iss::PRE_SYNC, 72); + this->gen_sync(PRE_SYNC, 72); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3467,14 +3538,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -3483,9 +3554,9 @@ private: res_val, 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res_val, 64); Value* MEMtmp1_val = res2_val; @@ -3494,7 +3565,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 72); + this->gen_sync(POST_SYNC, 72); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3504,21 +3575,22 @@ private: std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.D"); - this->gen_sync(iss::PRE_SYNC, 73); + this->gen_sync(PRE_SYNC, 73); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3526,21 +3598,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGT, res_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res_val, 64); Value* MEMtmp1_val = res2_val; @@ -3549,7 +3621,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 73); + this->gen_sync(POST_SYNC, 73); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3559,21 +3631,22 @@ private: std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.D"); - this->gen_sync(iss::PRE_SYNC, 74); + this->gen_sync(PRE_SYNC, 74); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3581,21 +3654,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 64/8), 64, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, res_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res_val, 64); Value* MEMtmp1_val = res2_val; @@ -3604,7 +3677,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 74); + this->gen_sync(POST_SYNC, 74); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3614,20 +3687,21 @@ private: std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); - this->gen_sync(iss::PRE_SYNC, 75); + this->gen_sync(PRE_SYNC, 75); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3635,13 +3709,13 @@ private: 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 + traits::X0, 0); + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* REStmp1_val = this->gen_ext( this->builder.CreateNeg(this->gen_const(8U, 1)), 32, @@ -3652,7 +3726,7 @@ private: this->builder.CreateZExtOrTrunc(REStmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 75); + this->gen_sync(POST_SYNC, 75); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3662,21 +3736,22 @@ private: std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); - this->gen_sync(iss::PRE_SYNC, 76); + this->gen_sync(PRE_SYNC, 76); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3684,7 +3759,7 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); @@ -3698,7 +3773,7 @@ private: bbnext); this->builder.SetInsertPoint(bb_then); { - Value* MEMtmp0_val = this->gen_reg_load(fld_rs2_val + traits::X0, 1); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); this->gen_write_mem( traits::MEM, offs_val, @@ -3708,7 +3783,7 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp1_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_NE, @@ -3717,10 +3792,10 @@ private: this->gen_const(64U, 0), this->gen_const(64U, 1), 64); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 76); + this->gen_sync(POST_SYNC, 76); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3730,21 +3805,22 @@ private: std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); - this->gen_sync(iss::PRE_SYNC, 77); + this->gen_sync(PRE_SYNC, 77); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3752,21 +3828,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); - if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ Value* Xtmp0_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - Value* MEMtmp1_val = this->gen_reg_load(fld_rs2_val + traits::X0, 0); + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 77); + this->gen_sync(POST_SYNC, 77); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3776,21 +3852,22 @@ private: std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); - this->gen_sync(iss::PRE_SYNC, 78); + this->gen_sync(PRE_SYNC, 78); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3798,25 +3875,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAdd( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 78); + this->gen_sync(POST_SYNC, 78); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3826,21 +3903,22 @@ private: std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); - this->gen_sync(iss::PRE_SYNC, 79); + this->gen_sync(PRE_SYNC, 79); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3848,25 +3926,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateXor( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 79); + this->gen_sync(POST_SYNC, 79); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3876,21 +3954,22 @@ private: std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); - this->gen_sync(iss::PRE_SYNC, 80); + this->gen_sync(PRE_SYNC, 80); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3898,25 +3977,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateAnd( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 80); + this->gen_sync(POST_SYNC, 80); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3926,21 +4005,22 @@ private: std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); - this->gen_sync(iss::PRE_SYNC, 81); + this->gen_sync(PRE_SYNC, 81); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3948,25 +4028,25 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->builder.CreateOr( res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)); + this->gen_reg_load(rs2 + traits::X0, 0)); Value* MEMtmp1_val = res2_val; this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 81); + this->gen_sync(POST_SYNC, 81); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -3976,21 +4056,22 @@ private: std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); - this->gen_sync(iss::PRE_SYNC, 82); + this->gen_sync(PRE_SYNC, 82); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -3998,14 +4079,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -4014,9 +4095,9 @@ private: res1_val, 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 64); Value* MEMtmp1_val = res2_val; @@ -4025,7 +4106,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 82); + this->gen_sync(POST_SYNC, 82); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4035,21 +4116,22 @@ private: std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); - this->gen_sync(iss::PRE_SYNC, 83); + this->gen_sync(PRE_SYNC, 83); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4057,14 +4139,14 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, true); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( @@ -4073,9 +4155,9 @@ private: res1_val, 64, true), this->gen_ext( - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), 64, true)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 64); Value* MEMtmp1_val = res2_val; @@ -4084,7 +4166,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 83); + this->gen_sync(POST_SYNC, 83); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4094,21 +4176,22 @@ private: std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); - this->gen_sync(iss::PRE_SYNC, 84); + this->gen_sync(PRE_SYNC, 84); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4116,21 +4199,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_UGT, res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 64); Value* MEMtmp1_val = res2_val; @@ -4139,7 +4222,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 84); + this->gen_sync(POST_SYNC, 84); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4149,21 +4232,22 @@ private: std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); - this->gen_sync(iss::PRE_SYNC, 85); + this->gen_sync(PRE_SYNC, 85); - uint8_t fld_rd_val = ((bit_sub<7,5>(instr))); - uint8_t fld_rs1_val = ((bit_sub<15,5>(instr))); - uint8_t fld_rs2_val = ((bit_sub<20,5>(instr))); - uint8_t fld_rl_val = ((bit_sub<25,1>(instr))); - uint8_t fld_aq_val = ((bit_sub<26,1>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((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; + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(ins_fmter.str()), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } @@ -4171,21 +4255,21 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(fld_rs1_val + traits::X0, 0); + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 64, false); - if(fld_rd_val != 0){ + if(rd != 0){ Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(fld_rd_val + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } Value* res2_val = this->gen_choose( this->builder.CreateICmp( ICmpInst::ICMP_ULT, res1_val, - this->gen_reg_load(fld_rs2_val + traits::X0, 0)), - this->gen_reg_load(fld_rs2_val + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), res1_val, 64); Value* MEMtmp1_val = res2_val; @@ -4194,7 +4278,7 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC, 85); + this->gen_sync(POST_SYNC, 85); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); @@ -4203,8 +4287,7 @@ private: /**************************************************************************** * end opcode definitions ****************************************************************************/ - std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, - BasicBlock *bb) { + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, 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); @@ -4248,7 +4331,7 @@ vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); try { - uint8_t *const data = (uint8_t *)&insn; + auto *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); @@ -4286,9 +4369,7 @@ template void vm_impl::gen_raise_trap(uint16_t trap_id, ui } template void vm_impl::gen_leave_trap(unsigned lvl) { - std::vector args{ - this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), 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); @@ -4296,20 +4377,17 @@ template void vm_impl::gen_leave_trap(unsigned lvl) { } template void vm_impl::gen_wait(unsigned type) { - std::vector args{ - this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)), - }; + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) }; this->builder.CreateCall(this->mod->getFunction("wait"), args); } template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { this->builder.SetInsertPoint(trap_blk); auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - 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.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); + 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); @@ -4327,10 +4405,9 @@ template inline void vm_impl::gen_trap_check(BasicBlock *b template <> std::unique_ptr create(arch::rv64ia *core, unsigned short port, bool dump) { - std::unique_ptr> ret = - std::make_unique>(*core, dump); - if (port != 0) debugger::server::run_server(ret.get(), port); - return ret; + auto ret = new rv64ia::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); } } // namespace iss diff --git a/riscv/src/iss/rv32gc.cpp b/riscv/src/iss/rv32gc.cpp index 0e9bb96..489a56c 100644 --- a/riscv/src/iss/rv32gc.cpp +++ b/riscv/src/iss/rv32gc.cpp @@ -49,6 +49,11 @@ extern "C" { using namespace iss::arch; +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; + rv32gc::rv32gc() { reg.icount=0; } diff --git a/riscv/src/iss/rv32imac.cpp b/riscv/src/iss/rv32imac.cpp index 86500d8..b9e4dd7 100644 --- a/riscv/src/iss/rv32imac.cpp +++ b/riscv/src/iss/rv32imac.cpp @@ -49,8 +49,10 @@ extern "C" { using namespace iss::arch; -constexpr std::array iss::arch::traits::RV32IMAC_reg_size; -constexpr std::array iss::arch::traits::RV32IMAC_reg_byte_offset; +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; rv32imac::rv32imac() { reg.icount = 0; diff --git a/riscv/src/iss/rv64ia.cpp b/riscv/src/iss/rv64ia.cpp index f5f542e..8e71d07 100644 --- a/riscv/src/iss/rv64ia.cpp +++ b/riscv/src/iss/rv64ia.cpp @@ -52,6 +52,11 @@ extern "C" { using namespace iss::arch; +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; + rv64ia::rv64ia() { reg.icount = 0; reg.machine_state = 0x3;} rv64ia::~rv64ia(){} diff --git a/sc-components b/sc-components index 0f5b5f6..a21b2e5 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit 0f5b5f68e7d5d481b4f8da2620df633495c989d9 +Subproject commit a21b2e57a2f18ff9e683d529a106ae2a8d2639c9 From d5d236bf10c2edf8bd16f3a55aedc75ae5428793 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 24 Nov 2018 21:38:02 +0100 Subject: [PATCH 5/7] Adapted changes in SCC --- dbt-core | 2 +- platform/src/sysc/fe310.cpp | 6 +++--- sc-components | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dbt-core b/dbt-core index 83cd591..2f4aab8 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit 83cd591e4935d5c1916e4e56d9c6147e3aab8480 +Subproject commit 2f4aab87b0f86504a26cd8a6e781fc43bfd6e00f diff --git a/platform/src/sysc/fe310.cpp b/platform/src/sysc/fe310.cpp index 70bbed6..1cab7e2 100644 --- a/platform/src/sysc/fe310.cpp +++ b/platform/src/sysc/fe310.cpp @@ -83,13 +83,13 @@ fe310::fe310(sc_core::sc_module_name nm) size_t i = 0; for (const auto &e : e300_plat_t_map) { i_router->initiator.at(i)(e.target); - i_router->add_target_range(i, e.start, e.size); + i_router->set_target_range(i, e.start, e.size); i++; } i_router->initiator.at(i)(i_mem_qspi->target); - i_router->add_target_range(i, 0x20000000, 512_MB); + i_router->set_target_range(i, 0x20000000, 512_MB); i_router->initiator.at(++i)(i_mem_ram->target); - i_router->add_target_range(i, 0x80000000, 128_kB); + i_router->set_target_range(i, 0x80000000, 128_kB); i_uart0->clk_i(s_tlclk); i_uart1->clk_i(s_tlclk); diff --git a/sc-components b/sc-components index a21b2e5..d334928 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit a21b2e57a2f18ff9e683d529a106ae2a8d2639c9 +Subproject commit d334928b3627d8abbdbe5b047782901250e2270d From f69b529cab39fae2f5b38c91c1ff2eb345d726f2 Mon Sep 17 00:00:00 2001 From: eyck Date: Thu, 10 Jan 2019 10:35:20 +0000 Subject: [PATCH 6/7] Fixed implementation of RV64 so that remaining riscv-test pass --- CMakeLists.txt | 4 +- platform/src/CMakeLists.txt | 14 +- riscv/gen_input/RV32A.core_desc | 22 +- riscv/gen_input/RV32C.core_desc | 94 +- riscv/gen_input/RV32D.core_desc | 98 +- riscv/gen_input/RV32F.core_desc | 219 +- riscv/gen_input/RV32IBase.core_desc | 2 +- riscv/gen_input/RV32M.core_desc | 30 +- riscv/gen_input/RV64A.core_desc | 23 +- riscv/gen_input/RV64M.core_desc | 36 +- riscv/gen_input/minres_rv.core_desc | 21 +- .../gen_input/templates/src-CORENAME.cpp.gtl | 58 +- .../templates/vm-vm_CORENAME.cpp.gtl | 29 +- riscv/incl/iss/arch/rv64gc.h | 316 + riscv/incl/iss/arch/{rv64ia.h => rv64i.h} | 34 +- riscv/src/CMakeLists.txt | 33 +- riscv/src/internal/fp_functions.cpp | 82 +- riscv/src/internal/vm_rv32gc.cpp | 9580 ++++++------- riscv/src/internal/vm_rv32imac.cpp | 3616 +++-- riscv/src/internal/vm_rv64gc.cpp | 11342 ++++++++++++++++ .../internal/{vm_rv64ia.cpp => vm_rv64i.cpp} | 2996 ++-- riscv/src/iss/rv32gc.cpp | 62 +- riscv/src/iss/rv64gc.cpp | 81 + riscv/src/iss/rv64i.cpp | 79 + riscv/src/iss/rv64ia.cpp | 78 - riscv/src/main.cpp | 9 +- sc-components | 2 +- 27 files changed, 19993 insertions(+), 8967 deletions(-) create mode 100644 riscv/incl/iss/arch/rv64gc.h rename riscv/incl/iss/arch/{rv64ia.h => rv64i.h} (91%) create mode 100644 riscv/src/internal/vm_rv64gc.cpp rename riscv/src/internal/{vm_rv64ia.cpp => vm_rv64i.cpp} (69%) create mode 100644 riscv/src/iss/rv64gc.cpp create mode 100644 riscv/src/iss/rv64i.cpp delete mode 100644 riscv/src/iss/rv64ia.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 29243a7..8b70e49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.3) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_CURRENT_SOURCE_DIR}/sc-components/cmake) set(ENABLE_SCV TRUE CACHE BOOL "Enable use of SCV") +set(ENABLE_SHARED TRUE CACHE BOOL "Build shared libraries") include(GitFunctions) get_branch_from_git() @@ -32,7 +33,8 @@ include(Conan) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) - +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE) if(COMPILER_SUPPORTS_MARCH_NATIVE) diff --git a/platform/src/CMakeLists.txt b/platform/src/CMakeLists.txt index 381aa6c..fd1f117 100644 --- a/platform/src/CMakeLists.txt +++ b/platform/src/CMakeLists.txt @@ -30,7 +30,17 @@ set(LIBRARY_NAME platform) #add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS) # Define the library -add_library(${LIBRARY_NAME} ${LIB_SOURCES}) +add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES}) + +# Links the target exe against the libraries +target_link_libraries(${LIBRARY_NAME} riscv_sc) +target_link_libraries(${LIBRARY_NAME} dbt-core) +target_link_libraries(${LIBRARY_NAME} softfloat) +target_link_libraries(${LIBRARY_NAME} sc-components) +target_link_libraries(${LIBRARY_NAME} ${CONAN_LIBS_SEASOCKS}) +target_link_libraries(${LIBRARY_NAME} external) +target_link_libraries(${LIBRARY_NAME} ${llvm_libs}) +target_link_libraries(${LIBRARY_NAME} ${Boost_LIBRARIES} ) set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. @@ -61,7 +71,7 @@ add_executable(${APPLICATION_NAME} ${APP_SOURCES}) target_include_directories(${APPLICATION_NAME} SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS}) # Links the target exe against the libraries target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME}) -target_link_libraries(${APPLICATION_NAME} riscv) +target_link_libraries(${APPLICATION_NAME} riscv_sc) target_link_libraries(${APPLICATION_NAME} dbt-core) target_link_libraries(${APPLICATION_NAME} softfloat) target_link_libraries(${APPLICATION_NAME} sc-components) diff --git a/riscv/gen_input/RV32A.core_desc b/riscv/gen_input/RV32A.core_desc index 694da0f..6f1b644 100644 --- a/riscv/gen_input/RV32A.core_desc +++ b/riscv/gen_input/RV32A.core_desc @@ -2,10 +2,6 @@ import "RV32IBase.core_desc" InsructionSet RV32A extends RV32IBase{ - address_spaces { - RES[8] - } - instructions{ LR.W { encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; @@ -23,7 +19,7 @@ InsructionSet RV32A extends RV32IBase{ val res1[32] <= RES[offs]{32}; if(res1!=0) MEM[offs]{32} <= X[rs2]; - if(rd!=0) X[rd]<= choose(res1!=0, 0, 1); + if(rd!=0) X[rd]<= choose(res1!=zext(0, 32), 0, 1); } AMOSWAP.W{ encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; @@ -73,9 +69,9 @@ InsructionSet RV32A extends RV32IBase{ args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1); - MEM[offs]{32}<=res2; + if(rd!=0) X[rd] <= res1; + val res2[XLEN] <= choose(res1's > X[rs2]s, X[rs2], res1); + MEM[offs]{32} <= res2; } AMOMAX.W{ encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; @@ -90,7 +86,7 @@ InsructionSet RV32A extends RV32IBase{ encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= zext(MEM[offs]{32}); + val res1[XLEN] <= sext(MEM[offs]{32}); if(rd!=0) X[rd]<=res1; val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1); MEM[offs]{32}<=res2; @@ -99,10 +95,10 @@ InsructionSet RV32A extends RV32IBase{ encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= zext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN]<= choose(res1'uF[rs2]f, F[rs1]f, F[rs2]f); - val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); if(FLEN==32) - F[rd] <= res; + F[rd] <= fdispatch_fsel_s(F[rs1], F[rs2], zext(1, 32)); else { // NaN boxing + val frs1[32] <= fdispatch_unbox_s(F[rs1]); + val frs2[32] <= fdispatch_unbox_s(F[rs2]); + val res[32] <= fdispatch_fsel_s(frs1, frs2, zext(1, 32)); val upper[FLEN] <= -1; F[rd] <= (upper<<32) | zext(res, FLEN); } @@ -215,59 +246,142 @@ InsructionSet RV32F extends RV32IBase{ } FCVT.W.S { encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}"; - X[rd]<= sext(fdispatch_fcvt_s(F[rs1]{32}, zext(0, 32), rm{8}), XLEN); + args_disass:"{name(rd)}, f{rs1}"; + if(FLEN==32) + X[rd] <= sext(fdispatch_fcvt_s(F[rs1], zext(0, 32), rm{8}), XLEN); + else { // NaN boxing + val frs1[32] <= fdispatch_unbox_s(F[rs1]); + X[rd]<= sext(fdispatch_fcvt_s(frs1, zext(0, 32), rm{8}), XLEN); + } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCVT.WU.S { encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}"; - X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN); + args_disass:"{name(rd)}, f{rs1}"; + //FIXME: according to the spec it should be zero-extended not sign extended + if(FLEN==32) + X[rd]<= sext(fdispatch_fcvt_s(F[rs1], zext(1, 32), rm{8}), XLEN); + else { // NaN boxing + val frs1[32] <= fdispatch_unbox_s(F[rs1]); + X[rd]<= sext(fdispatch_fcvt_s(frs1, zext(1, 32), rm{8}), XLEN); + } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FEQ.S { encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}, f{rs2}"; - X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32)); + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; + if(FLEN==32) + X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(0, 32))); + else { + val frs1[32] <= fdispatch_unbox_s(F[rs1]); + val frs2[32] <= fdispatch_unbox_s(F[rs2]); + X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(0, 32))); + } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FLT.S { encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}, f{rs2}"; + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; + if(FLEN==32) + X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(2, 32))); + else { + val frs1[32] <= fdispatch_unbox_s(F[rs1]); + val frs2[32] <= fdispatch_unbox_s(F[rs2]); + X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(2, 32))); + } X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32)); val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FLE.S { encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}, f{rs2}"; - X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32)); + args_disass:"{name(rd)}, f{rs1}, f{rs2}"; + if(FLEN==32) + X[rd]<=zext(fdispatch_fcmp_s(F[rs1], F[rs2], zext(1, 32))); + else { + val frs1[32] <= fdispatch_unbox_s(F[rs1]); + val frs2[32] <= fdispatch_unbox_s(F[rs2]); + X[rd]<=zext(fdispatch_fcmp_s(frs1, frs2, zext(1, 32))); + } val flags[32] <= fdispatch_fget_flags(); FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; } FCLASS.S { encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}"; - X[rd]<=fdispatch_fclass_s(F[rs1]{32}); + args_disass:"{name(rd)}, f{rs1}"; + X[rd]<=fdispatch_fclass_s(fdispatch_unbox_s(F[rs1])); } FCVT.S.W { encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; - args_disass:"f{rd}, x{rs1}"; - val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); + args_disass:"f{rd}, {name(rs1)}"; if(FLEN==32) - F[rd] <= res; + F[rd] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); else { // NaN boxing + val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8}); val upper[FLEN] <= -1; F[rd] <= (upper<<32) | zext(res, FLEN); } } FCVT.S.WU { encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"f{rd}, {name(rs1)}"; + if(FLEN==32) + F[rd] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); + else { // NaN boxing + val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(res, FLEN); + } + } + FMV.X.W { + encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; + args_disass:"{name(rd)}, f{rs1}"; + X[rd]<=sext(F[rs1]{32}); + } + FMV.W.X { + encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; + args_disass:"f{rd}, {name(rs1)}"; + if(FLEN==32) + F[rd] <= X[rs1]{32}; + else { // NaN boxing + val upper[FLEN] <= -1; + F[rd] <= (upper<<32) | zext(X[rs1]{32}, FLEN); + } + } + } +} + +InsructionSet RV64F extends RV32F{ + constants { + FLEN, FFLAG_MASK := 0x1f + } + registers { + [31:0] F[FLEN], FCSR[32] + } + instructions{ + FCVT.L.S { // fp to 64bit signed integer + encoding: b1100000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x{rd}, f{rs1}"; + val res[64] <= fdispatch_fcvt_32_64(fdispatch_unbox_s(F[rs1]), zext(0, 32), rm{8}); + X[rd]<= sext(res); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FCVT.LU.S { // fp to 64bit unsigned integer + encoding: b1100000 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; + args_disass:"x{rd}, f{rs1}"; + val res[64] <= fdispatch_fcvt_32_64(fdispatch_unbox_s(F[rs1]), zext(1, 32), rm{8}); + X[rd]<= zext(res); + val flags[32] <= fdispatch_fget_flags(); + FCSR <= (FCSR & ~FFLAG_MASK) + flags{5}; + } + FCVT.S.L { // 64bit signed int to to fp + encoding: b1101000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; args_disass:"f{rd}, x{rs1}"; - val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8}); + val res[32] <= fdispatch_fcvt_64_32(X[rs1], zext(2, 32)); if(FLEN==32) F[rd] <= res; else { // NaN boxing @@ -275,20 +389,17 @@ InsructionSet RV32F extends RV32IBase{ F[rd] <= (upper<<32) | zext(res, FLEN); } } - FMV.X.W { - encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; - args_disass:"x{rd}, f{rs1}"; - X[rd]<=sext(F[rs1]{32}); - } - FMV.W.X { - encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011; + FCVT.S.LU { // 64bit unsigned int to to fp + encoding: b1101000 | b00011 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; args_disass:"f{rd}, x{rs1}"; + val res[32] <=fdispatch_fcvt_64_32(X[rs1], zext(3,32)); if(FLEN==32) - F[rd] <= X[rs1]; + F[rd] <= res; else { // NaN boxing val upper[FLEN] <= -1; - F[rd] <= (upper<<32) | zext(X[rs1], FLEN); + F[rd] <= (upper<<32) | zext(res, FLEN); } } - } -} \ No newline at end of file + } +} + \ No newline at end of file diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32IBase.core_desc index b93351c..994a5fe 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32IBase.core_desc @@ -8,7 +8,7 @@ InsructionSet RV32IBase { } address_spaces { - MEM[8], CSR[XLEN], FENCE[XLEN] + MEM[8], CSR[XLEN], FENCE[XLEN], RES[8] } registers { diff --git a/riscv/gen_input/RV32M.core_desc b/riscv/gen_input/RV32M.core_desc index c1c456c..ab35fb1 100644 --- a/riscv/gen_input/RV32M.core_desc +++ b/riscv/gen_input/RV32M.core_desc @@ -43,12 +43,11 @@ InsructionSet RV32M extends RV32IBase { if(rd != 0){ if(X[rs2]!=0){ val M1[XLEN] <= -1; - val MMIN[XLEN] <= -1<<(XLEN-1); - if(X[rs1]s==MMIN's) - if(X[rs2]s==M1's) - X[rd]<=MMIN; - else - X[rd] <= X[rs1]s / X[rs2]s; + val XLM1[8] <= XLEN-1; + val ONE[XLEN] <= 1; + val MMIN[XLEN] <= ONE< X[rs2]s, X[rs2], res); - MEM[offs]{64} <= res; + val res1[XLEN] <= sext(MEM[offs]{64}); + if(rd!=0) X[rd] <= res1; + val res2[XLEN] <= choose(res1's > X[rs2]s, X[rs2], res1); + MEM[offs]{64} <= res2; } AMOMAX.D{ encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; @@ -94,7 +89,7 @@ InsructionSet RV64A extends RV64IBase { encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; - val res[XLEN] <= zext(MEM[offs]{64}); + val res[XLEN] <= sext(MEM[offs]{64}); if(rd!=0) X[rd] <= res; val res2[XLEN] <= choose(res > X[rs2], X[rs2], res); MEM[offs]{64} <= res2; @@ -103,10 +98,10 @@ InsructionSet RV64A extends RV64IBase { encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b011 | rd[4:0] | b0101111; args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; val offs[XLEN] <= X[rs1]; - val res[XLEN] <= zext(MEM[offs]{64}); - if(rd!=0) X[rd] <= res; - val res2[XLEN] <= choose(res < X[rs2], X[rs2], res); - MEM[offs]{64} <= res2; + val res1[XLEN] <= sext(MEM[offs]{64}); + if(rd!=0) X[rd] <= res1; + val res2[XLEN] <= choose(res1 < X[rs2], X[rs2], res1); + MEM[offs]{64} <= res2; } } } \ No newline at end of file diff --git a/riscv/gen_input/RV64M.core_desc b/riscv/gen_input/RV64M.core_desc index fa8b210..6b7cd6d 100644 --- a/riscv/gen_input/RV64M.core_desc +++ b/riscv/gen_input/RV64M.core_desc @@ -6,35 +6,59 @@ InsructionSet RV64M extends RV64IBase { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ - X[rd]<= X[rs1] * X[rs2]; + X[rd]<= sext(X[rs1]{32} * X[rs2]{32}); } } DIVW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ - X[rd] <= X[rs1]s / X[rs2]s; + if(X[rs2]!=0){ + val M1[32] <= -1; + val ONE[32] <= 1; + val MMIN[32] <= ONE<<31; + if(X[rs1]{32}==MMIN && X[rs2]{32}==M1) + X[rd] <= -1<<31; + else + X[rd] <= sext(X[rs1]{32}s / X[rs2]{32}s); + }else + X[rd] <= -1; } } DIVUW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ - X[rd] <= X[rs1] / X[rs2]; - } + if(X[rs2]{32}!=0) + X[rd] <= sext(X[rs1]{32} / X[rs2]{32}); + else + X[rd] <= -1; + } } REMW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ - X[rd] <= X[rs1]s % X[rs2]s; + if(X[rs2]!=0) { + val M1[32] <= -1; // constant -1 + val ONE[32] <= 1; + val MMIN[32] <= ONE<<31; // -2^(XLEN-1) + if(X[rs1]{32}==MMIN && X[rs2]==M1) + X[rd] <= 0; + else + X[rd] <= sext(X[rs1]{32}s % X[rs2]{32}s); + } else + X[rd] <= sext(X[rs1]{32}); } } REMUW { encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; if(rd != 0){ - X[rd] <= X[rs1] % X[rs2]; + if(X[rs2]{32}!=0) + X[rd] <= sext(X[rs1]{32} % X[rs2]{32}); + else + X[rd] <= sext(X[rs1]{32}); } } } diff --git a/riscv/gen_input/minres_rv.core_desc b/riscv/gen_input/minres_rv.core_desc index ca9301d..e1f3048 100644 --- a/riscv/gen_input/minres_rv.core_desc +++ b/riscv/gen_input/minres_rv.core_desc @@ -5,7 +5,7 @@ import "RV32C.core_desc" import "RV32F.core_desc" import "RV32D.core_desc" import "RV64IBase.core_desc" -//import "RV64M.core_desc" +import "RV64M.core_desc" import "RV64A.core_desc" Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { @@ -33,15 +33,28 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32 } } - -Core RV64IA provides RV64IBase, RV64A, RV32A { +Core RV64I provides RV64IBase { constants { XLEN:=64; PCLEN:=64; // definitions for the architecture wrapper // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b10000000000001000000000100000001; + MISA_VAL:=0b10000000000001000000000100000000; PGSIZE := 0x1000; //1 << 12; PGMASK := 0xfff; //PGSIZE-1 } } + +Core RV64GC provides RV64IC, RV64A, RV64M, RV32A, RV32M, RV64F, RV64D, RV32FC, RV32DC { + constants { + XLEN:=64; + FLEN:=64; + PCLEN:=64; + // definitions for the architecture wrapper + // XL ZYXWVUTSRQPONMLKJIHGFEDCBA + MISA_VAL:=0b01000000000101000001000100101101; + PGSIZE := 0x1000; //1 << 12; + PGMASK := 0xfff; //PGSIZE-1 + } +} + diff --git a/riscv/gen_input/templates/src-CORENAME.cpp.gtl b/riscv/gen_input/templates/src-CORENAME.cpp.gtl index 83dd26c..ee9641b 100644 --- a/riscv/gen_input/templates/src-CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/src-CORENAME.cpp.gtl @@ -29,7 +29,45 @@ * POSSIBILITY OF SUCH DAMAGE. * *******************************************************************************/ - + <% +import com.minres.coredsl.coreDsl.Register +import com.minres.coredsl.coreDsl.RegisterFile +import com.minres.coredsl.coreDsl.RegisterAlias +def getOriginalName(reg){ + if( reg.original instanceof RegisterFile) { + if( reg.index != null ) { + return reg.original.name+generator.generateHostCode(reg.index) + } else { + return reg.original.name + } + } else if(reg.original instanceof Register){ + return reg.original.name + } +} +def getRegisterNames(){ + def regNames = [] + allRegs.each { reg -> + if( reg instanceof RegisterFile) { + (reg.range.right..reg.range.left).each{ + regNames+=reg.name.toLowerCase()+it + } + } else if(reg instanceof Register){ + regNames+=reg.name.toLowerCase() + } + } + return regNames +} +def getRegisterAliasNames(){ + def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]} + return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg -> + if( reg instanceof RegisterFile) { + return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() } + } else if(reg instanceof Register){ + regMap[reg.name]?:reg.name.toLowerCase() + } + }.flatten() +} +%> #include "util/ities.h" #include @@ -49,27 +87,29 @@ extern "C" { using namespace iss::arch; -constexpr std::array iss::arch::traits::reg_sizes; -constexpr std::array iss::arch::traits::reg_byte_offset; +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; ${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() { reg.icount = 0; - reg.machine_state = 0x3; } ${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default; -} 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)); + 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=0x3; + reg.machine_state=0x0; + reg.icount=0; } -uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { return reinterpret_cast(®); } +uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { + return reinterpret_cast(®); +} ${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(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 index c989810..709da48 100644 --- a/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl +++ b/riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl @@ -46,7 +46,7 @@ namespace iss { namespace vm { namespace fp_impl { -void add_fp_functions_2_module(llvm::Module *, unsigned); +void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned); } } @@ -88,7 +88,7 @@ protected: void setup_module(Module* m) override { super::setup_module(m); - iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN); } inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { @@ -241,24 +241,21 @@ template std::tuple vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 + enum {TRAP_ID=1<<16}; code_word_t insn = 0; const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); - try { - auto *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); + auto *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(TRAP_ID, pc.val); + if ((insn & 0x3) == 0x3) { // this is a 32bit instruction + res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); } - } catch (trap_access &ta) { - throw trap_access(ta.id, pc.val); + } else { + auto res = this->core.read(paddr, 4, data); + if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); } if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack diff --git a/riscv/incl/iss/arch/rv64gc.h b/riscv/incl/iss/arch/rv64gc.h new file mode 100644 index 0000000..b10843d --- /dev/null +++ b/riscv/incl/iss/arch/rv64gc.h @@ -0,0 +1,316 @@ +/******************************************************************************* + * Copyright (C) 2017, 2018 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. + * + *******************************************************************************/ + + +#ifndef _RV64GC_H_ +#define _RV64GC_H_ + +#include +#include +#include +#include + +namespace iss { +namespace arch { + +struct rv64gc; + +template <> struct traits { + + constexpr static char const* const core_type = "RV64GC"; + + static constexpr std::array reg_names{ + {"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}}; + + static constexpr std::array reg_aliases{ + {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "fcsr"}}; + + enum constants {XLEN=64, FLEN=64, PCLEN=64, MISA_VAL=0b1000000000101000001000100101101, PGSIZE=0x1000, PGMASK=0xfff}; + + constexpr static unsigned FP_REGS_SIZE = 64; + + enum reg_e { + X0, + X1, + X2, + X3, + X4, + X5, + X6, + X7, + X8, + X9, + X10, + X11, + X12, + X13, + X14, + X15, + X16, + X17, + X18, + X19, + X20, + X21, + X22, + X23, + X24, + X25, + X26, + X27, + X28, + X29, + X30, + X31, + PC, + F0, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + F25, + F26, + F27, + F28, + F29, + F30, + F31, + FCSR, + NUM_REGS, + NEXT_PC=NUM_REGS, + TRAP_STATE, + PENDING_TRAP, + MACHINE_STATE, + LAST_BRANCH, + ICOUNT, + ZERO = X0, + RA = X1, + SP = X2, + GP = X3, + TP = X4, + T0 = X5, + T1 = X6, + T2 = X7, + S0 = X8, + S1 = X9, + A0 = X10, + A1 = X11, + A2 = X12, + A3 = X13, + A4 = X14, + A5 = X15, + A6 = X16, + A7 = X17, + S2 = X18, + S3 = X19, + S4 = X20, + S5 = X21, + S6 = X22, + S7 = X23, + S8 = X24, + S9 = X25, + S10 = X26, + S11 = X27, + T3 = X28, + T4 = X29, + T5 = X30, + T6 = X31 + }; + + using reg_t = uint64_t; + + using addr_t = uint64_t; + + using code_word_t = uint64_t; //TODO: check removal + + using virt_addr_t = iss::typed_addr_t; + + using phys_addr_t = iss::typed_addr_t; + + static constexpr std::array reg_bit_widths{ + {64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,64,32,32,32,32,64}}; + + static constexpr std::array reg_byte_offsets{ + {0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,256,264,272,280,288,296,304,312,320,328,336,344,352,360,368,376,384,392,400,408,416,424,432,440,448,456,464,472,480,488,496,504,512,520,528,536,540,544,548,552,560}}; + + static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); + + enum sreg_flag_e { FLAGS }; + + enum mem_type_e { MEM, CSR, FENCE, RES }; +}; + +struct rv64gc: public arch_if { + + using virt_addr_t = typename traits::virt_addr_t; + using phys_addr_t = typename traits::phys_addr_t; + using reg_t = typename traits::reg_t; + using addr_t = typename traits::addr_t; + + rv64gc(); + ~rv64gc(); + + 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 {}; + + inline uint64_t get_icount() { return reg.icount; } + + inline bool should_stop() { return interrupt_sim; } + + inline phys_addr_t v2p(const iss::addr_t& addr){ + if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || + addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { + return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); + } else + return virt2phys(addr); + } + + virtual phys_addr_t virt2phys(const iss::addr_t& addr); + + virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } + + inline uint32_t get_last_branch() { return reg.last_branch; } + +protected: + struct RV64GC_regs { + uint64_t X0 = 0; + uint64_t X1 = 0; + uint64_t X2 = 0; + uint64_t X3 = 0; + uint64_t X4 = 0; + uint64_t X5 = 0; + uint64_t X6 = 0; + uint64_t X7 = 0; + uint64_t X8 = 0; + uint64_t X9 = 0; + uint64_t X10 = 0; + uint64_t X11 = 0; + uint64_t X12 = 0; + uint64_t X13 = 0; + uint64_t X14 = 0; + uint64_t X15 = 0; + uint64_t X16 = 0; + uint64_t X17 = 0; + uint64_t X18 = 0; + uint64_t X19 = 0; + uint64_t X20 = 0; + uint64_t X21 = 0; + uint64_t X22 = 0; + uint64_t X23 = 0; + uint64_t X24 = 0; + uint64_t X25 = 0; + uint64_t X26 = 0; + uint64_t X27 = 0; + uint64_t X28 = 0; + uint64_t X29 = 0; + uint64_t X30 = 0; + uint64_t X31 = 0; + uint64_t PC = 0; + uint64_t F0 = 0; + uint64_t F1 = 0; + uint64_t F2 = 0; + uint64_t F3 = 0; + uint64_t F4 = 0; + uint64_t F5 = 0; + uint64_t F6 = 0; + uint64_t F7 = 0; + uint64_t F8 = 0; + uint64_t F9 = 0; + uint64_t F10 = 0; + uint64_t F11 = 0; + uint64_t F12 = 0; + uint64_t F13 = 0; + uint64_t F14 = 0; + uint64_t F15 = 0; + uint64_t F16 = 0; + uint64_t F17 = 0; + uint64_t F18 = 0; + uint64_t F19 = 0; + uint64_t F20 = 0; + uint64_t F21 = 0; + uint64_t F22 = 0; + uint64_t F23 = 0; + uint64_t F24 = 0; + uint64_t F25 = 0; + uint64_t F26 = 0; + uint64_t F27 = 0; + uint64_t F28 = 0; + uint64_t F29 = 0; + uint64_t F30 = 0; + uint64_t F31 = 0; + uint32_t FCSR = 0; + uint64_t NEXT_PC = 0; + uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0; + uint64_t icount = 0; + } reg; + + std::array addr_mode; + + bool interrupt_sim=false; + + uint32_t get_fcsr(){return reg.FCSR;} + void set_fcsr(uint32_t val){reg.FCSR = val;} + +}; + +} +} +#endif /* _RV64GC_H_ */ diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64i.h similarity index 91% rename from riscv/incl/iss/arch/rv64ia.h rename to riscv/incl/iss/arch/rv64i.h index c14584f..2f6c2bf 100644 --- a/riscv/incl/iss/arch/rv64ia.h +++ b/riscv/incl/iss/arch/rv64i.h @@ -31,8 +31,8 @@ *******************************************************************************/ -#ifndef _RV64IA_H_ -#define _RV64IA_H_ +#ifndef _RV64I_H_ +#define _RV64I_H_ #include #include @@ -42,11 +42,11 @@ namespace iss { namespace arch { -struct rv64ia; +struct rv64i; -template <> struct traits { +template <> struct traits { - constexpr static char const* const core_type = "RV64IA"; + constexpr static char const* const core_type = "RV64I"; static constexpr std::array reg_names{ {"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc"}}; @@ -54,7 +54,7 @@ template <> struct traits { static constexpr std::array reg_aliases{ {"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc"}}; - enum constants {XLEN=64, PCLEN=64, MISA_VAL=0b10000000000001000000000100000001, PGSIZE=0x1000, PGMASK=0xfff}; + enum constants {XLEN=64, PCLEN=64, MISA_VAL=0b10000000000001000000000100000000, PGSIZE=0x1000, PGMASK=0xfff}; constexpr static unsigned FP_REGS_SIZE = 0; @@ -156,15 +156,15 @@ template <> struct traits { enum mem_type_e { MEM, CSR, FENCE, RES }; }; -struct rv64ia: public arch_if { +struct rv64i: public arch_if { - using virt_addr_t = typename traits::virt_addr_t; - using phys_addr_t = typename traits::phys_addr_t; - using reg_t = typename traits::reg_t; - using addr_t = typename traits::addr_t; + using virt_addr_t = typename traits::virt_addr_t; + using phys_addr_t = typename traits::phys_addr_t; + using reg_t = typename traits::reg_t; + using addr_t = typename traits::addr_t; - rv64ia(); - ~rv64ia(); + rv64i(); + ~rv64i(); void reset(uint64_t address=0) override; @@ -183,9 +183,9 @@ struct rv64ia: public arch_if { inline bool should_stop() { return interrupt_sim; } inline phys_addr_t v2p(const iss::addr_t& addr){ - if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || + if (addr.space != traits::MEM || addr.type == iss::address_type::PHYSICAL || addr_mode[static_cast(addr.access)&0x3]==address_type::PHYSICAL) { - return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); + return phys_addr_t(addr.access, addr.space, addr.val&traits::addr_mask); } else return virt2phys(addr); } @@ -197,7 +197,7 @@ struct rv64ia: public arch_if { inline uint32_t get_last_branch() { return reg.last_branch; } protected: - struct RV64IA_regs { + struct RV64I_regs { uint64_t X0 = 0; uint64_t X1 = 0; uint64_t X2 = 0; @@ -247,4 +247,4 @@ protected: } } -#endif /* _RV64IA_H_ */ +#endif /* _RV64I_H_ */ diff --git a/riscv/src/CMakeLists.txt b/riscv/src/CMakeLists.txt index b16dbc1..845d769 100644 --- a/riscv/src/CMakeLists.txt +++ b/riscv/src/CMakeLists.txt @@ -4,22 +4,16 @@ set(LIB_HEADERS ${RiscVSCHeaders} ) set(LIB_SOURCES iss/rv32gc.cpp iss/rv32imac.cpp - iss/rv64ia.cpp + iss/rv64i.cpp + iss/rv64gc.cpp internal/fp_functions.cpp internal/vm_rv32gc.cpp internal/vm_rv32imac.cpp - internal/vm_rv64ia.cpp + internal/vm_rv64i.cpp + internal/vm_rv64gc.cpp plugin/instruction_count.cpp plugin/cycle_estimate.cpp) -if(SystemC_FOUND) - set(LIB_SOURCES ${LIB_SOURCES} sysc/core_complex.cpp) -endif() - -set(APP_HEADERS ) - -set(APP_SOURCES main.cpp) - # Define two variables in order not to repeat ourselves. set(LIBRARY_NAME riscv) @@ -31,8 +25,11 @@ set_target_properties(${LIBRARY_NAME} PROPERTIES FRAMEWORK FALSE PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers ) +#set_property(TARGET ${LIBRARY_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) if(SystemC_FOUND) + set(SC_LIBRARY_NAME riscv_sc) + add_library(${SC_LIBRARY_NAME} SHARED sysc/core_complex.cpp) add_definitions(-DWITH_SYSTEMC) include_directories(${SystemC_INCLUDE_DIRS}) @@ -42,18 +39,30 @@ if(SystemC_FOUND) add_definitions(-DWITH_SCV) include_directories(${SCV_INCLUDE_DIRS}) endif() + set_target_properties(${SC_LIBRARY_NAME} PROPERTIES + VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. + FRAMEWORK FALSE + PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers + ) + target_link_libraries(${SC_LIBRARY_NAME} ${LIBRARY_NAME}) + target_link_libraries(${SC_LIBRARY_NAME} dbt-core) + target_link_libraries(${SC_LIBRARY_NAME} softfloat) + target_link_libraries(${SC_LIBRARY_NAME} sc-components) + target_link_libraries(${SC_LIBRARY_NAME} external) + target_link_libraries(${SC_LIBRARY_NAME} ${llvm_libs}) + target_link_libraries(${SC_LIBRARY_NAME} ${Boost_LIBRARIES} ) endif() # This is a make target, so you can do a "make riscv-sc" set(APPLICATION_NAME riscv-sim) -add_executable(${APPLICATION_NAME} ${APP_SOURCES}) +add_executable(${APPLICATION_NAME} main.cpp) # Links the target exe against the libraries target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME}) +target_link_libraries(${APPLICATION_NAME} jsoncpp) target_link_libraries(${APPLICATION_NAME} dbt-core) target_link_libraries(${APPLICATION_NAME} softfloat) -target_link_libraries(${APPLICATION_NAME} sc-components) target_link_libraries(${APPLICATION_NAME} external) target_link_libraries(${APPLICATION_NAME} ${llvm_libs}) target_link_libraries(${APPLICATION_NAME} ${Boost_LIBRARIES} ) diff --git a/riscv/src/internal/fp_functions.cpp b/riscv/src/internal/fp_functions.cpp index 4c53f6f..1f0169a 100644 --- a/riscv/src/internal/fp_functions.cpp +++ b/riscv/src/internal/fp_functions.cpp @@ -70,7 +70,7 @@ using namespace std; using namespace llvm; -void add_fp_functions_2_module(Module *mod, uint32_t flen) { +void add_fp_functions_2_module(Module *mod, uint32_t flen, uint32_t xlen) { if(flen){ FDECL(fget_flags, INT_TYPE(32)); FDECL(fadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); @@ -83,6 +83,8 @@ void add_fp_functions_2_module(Module *mod, uint32_t flen) { FDECL(fmadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); FDECL(fsel_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32)); FDECL(fclass_s, INT_TYPE(32), INT_TYPE(32)); + FDECL(fcvt_32_64, INT_TYPE(64), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8)); + FDECL(fcvt_64_32, INT_TYPE(32), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); if(flen>32){ FDECL(fconv_d2f, INT_TYPE(32), INT_TYPE(64), INT_TYPE(8)); FDECL(fconv_f2d, INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); @@ -96,6 +98,8 @@ void add_fp_functions_2_module(Module *mod, uint32_t flen) { FDECL(fmadd_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8)); FDECL(fsel_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32)); FDECL(fclass_d, INT_TYPE(64), INT_TYPE(64)); + FDECL(unbox_s, INT_TYPE(32), INT_TYPE(64)); + } } } @@ -198,13 +202,15 @@ uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode) { float32_t v1f{v1}; softfloat_exceptionFlags=0; float32_t r; - int32_t res; switch(op){ - case 0: //w->s, fp to int32 - res = f32_to_i32(v1f,rmm_map[mode&0x7],true); + case 0:{ //w->s, fp to int32 + uint_fast32_t res = f32_to_i32(v1f,rmm_map[mode&0x7],true); return (uint32_t)res; - case 1: //wu->s - return f32_to_ui32(v1f,rmm_map[mode&0x7],true); + } + case 1:{ //wu->s + uint_fast32_t res = f32_to_ui32(v1f,rmm_map[mode&0x7],true); + return (uint32_t)res; + } case 2: //s->w r=i32_to_f32(v1); return r.v; @@ -373,17 +379,19 @@ uint64_t fcvt_d(uint64_t v1, uint32_t op, uint8_t mode) { float64_t v1f{v1}; softfloat_exceptionFlags=0; float64_t r; - int32_t res; switch(op){ - case 0: //w->s, fp to int32 - res = f64_to_i64(v1f,rmm_map[mode&0x7],true); + case 0:{ //l->d, fp to int32 + int64_t res = f64_to_i64(v1f,rmm_map[mode&0x7],true); return (uint64_t)res; - case 1: //wu->s - return f64_to_ui64(v1f,rmm_map[mode&0x7],true); - case 2: //s->w + } + case 1:{ //lu->s + uint64_t res = f64_to_ui64(v1f,rmm_map[mode&0x7],true); + return res; + } + case 2: //s->l r=i64_to_f64(v1); return r.v; - case 3: //s->wu + case 3: //s->lu r=ui64_to_f64(v1); return r.v; } @@ -454,5 +462,53 @@ uint64_t fclass_d(uint64_t v1 ){ ( isNaN && !isSNaN ) << 9; } +uint64_t fcvt_32_64(uint32_t v1, uint32_t op, uint8_t mode) { + float32_t v1f{v1}; + softfloat_exceptionFlags=0; + float64_t r; + switch(op){ + case 0: //l->s, fp to int32 + return f32_to_i64(v1f,rmm_map[mode&0x7],true); + case 1: //wu->s + return f32_to_ui64(v1f,rmm_map[mode&0x7],true); + case 2: //s->w + r=i32_to_f64(v1); + return r.v; + case 3: //s->wu + r=ui32_to_f64(v1); + return r.v; + } + return 0; +} + +uint32_t fcvt_64_32(uint64_t v1, uint32_t op, uint8_t mode) { + softfloat_exceptionFlags=0; + float32_t r; + switch(op){ + case 0:{ //wu->s + int32_t r=f64_to_i32(float64_t{v1}, rmm_map[mode&0x7],true); + return r; + } + case 1:{ //wu->s + uint32_t r=f64_to_ui32(float64_t{v1}, rmm_map[mode&0x7],true); + return r; + } + case 2: //l->s, fp to int32 + r=i64_to_f32(v1); + return r.v; + case 3: //wu->s + r=ui64_to_f32(v1); + return r.v; + } + return 0; +} + +uint32_t unbox_s(uint64_t v){ + constexpr uint64_t mask = std::numeric_limits::max() & ~((uint64_t)std::numeric_limits::max()); + if((v & mask) != mask) + return 0x7fc00000; + else + return v & std::numeric_limits::max(); +} } diff --git a/riscv/src/internal/vm_rv32gc.cpp b/riscv/src/internal/vm_rv32gc.cpp index 67c44ef..b394c76 100644 --- a/riscv/src/internal/vm_rv32gc.cpp +++ b/riscv/src/internal/vm_rv32gc.cpp @@ -46,7 +46,7 @@ namespace iss { namespace vm { namespace fp_impl { -void add_fp_functions_2_module(llvm::Module *, unsigned); +void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned); } } @@ -88,7 +88,7 @@ protected: void setup_module(Module* m) override { super::setup_module(m); - iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN); } inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { @@ -188,14 +188,78 @@ private: const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ + /* instruction JALR */ + {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr}, + /* instruction C.ADDI4SPN */ + {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, + /* instruction C.LW */ + {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, + /* instruction C.SW */ + {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, + /* instruction C.ADDI */ + {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, + /* instruction C.NOP */ + {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, + /* instruction C.JAL */ + {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, + /* instruction C.LI */ + {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li}, + /* instruction C.LUI */ + {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui}, + /* instruction C.ADDI16SP */ + {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, + /* instruction C.SRLI */ + {16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli}, + /* instruction C.SRAI */ + {16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai}, + /* instruction C.ANDI */ + {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, + /* instruction C.SUB */ + {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub}, + /* instruction C.XOR */ + {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor}, + /* instruction C.OR */ + {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or}, + /* instruction C.AND */ + {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and}, + /* instruction C.J */ + {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j}, + /* instruction C.BEQZ */ + {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz}, + /* instruction C.BNEZ */ + {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, + /* instruction C.SLLI */ + {16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli}, + /* instruction C.LWSP */ + {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, + /* instruction C.MV */ + {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, + /* instruction C.JR */ + {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, + /* instruction C.ADD */ + {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, + /* instruction C.JALR */ + {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, + /* instruction C.EBREAK */ + {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, + /* instruction C.SWSP */ + {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, + /* instruction DII */ + {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, + /* instruction C.FLD */ + {16, 0b0010000000000000, 0b1110000000000011, &this_class::__c_fld}, + /* instruction C.FSD */ + {16, 0b1010000000000000, 0b1110000000000011, &this_class::__c_fsd}, + /* instruction C.FLDSP */ + {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_fldsp}, + /* instruction C.FSDSP */ + {16, 0b1010000000000010, 0b1110000000000011, &this_class::__c_fsdsp}, /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, &this_class::__auipc}, /* instruction JAL */ {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, &this_class::__jal}, - /* instruction JALR */ - {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr}, /* instruction BEQ */ {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, &this_class::__beq}, /* instruction BNE */ @@ -292,160 +356,6 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, - /* instruction MUL */ - {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, - /* instruction MULH */ - {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, - /* instruction MULHSU */ - {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, - /* instruction MULHU */ - {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, - /* instruction DIV */ - {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, - /* instruction DIVU */ - {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, - /* instruction REM */ - {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, - /* instruction REMU */ - {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, - /* instruction LR.W */ - {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, - /* instruction SC.W */ - {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, - /* instruction AMOSWAP.W */ - {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, - /* instruction AMOADD.W */ - {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, - /* instruction AMOXOR.W */ - {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, - /* instruction AMOAND.W */ - {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, - /* instruction AMOOR.W */ - {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, - /* instruction AMOMIN.W */ - {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, - /* instruction AMOMAX.W */ - {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, - /* instruction AMOMINU.W */ - {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, - /* instruction AMOMAXU.W */ - {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, - /* instruction C.ADDI4SPN */ - {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, - /* instruction C.LW */ - {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, - /* instruction C.SW */ - {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, - /* instruction C.ADDI */ - {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, - /* instruction C.NOP */ - {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, - /* instruction C.JAL */ - {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, - /* instruction C.LI */ - {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li}, - /* instruction C.LUI */ - {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui}, - /* instruction C.ADDI16SP */ - {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, - /* instruction C.SRLI */ - {16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli}, - /* instruction C.SRAI */ - {16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai}, - /* instruction C.ANDI */ - {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, - /* instruction C.SUB */ - {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub}, - /* instruction C.XOR */ - {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor}, - /* instruction C.OR */ - {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or}, - /* instruction C.AND */ - {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and}, - /* instruction C.J */ - {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j}, - /* instruction C.BEQZ */ - {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz}, - /* instruction C.BNEZ */ - {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, - /* instruction C.SLLI */ - {16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli}, - /* instruction C.LWSP */ - {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, - /* instruction C.MV */ - {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, - /* instruction C.JR */ - {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, - /* instruction C.ADD */ - {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, - /* instruction C.JALR */ - {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, - /* instruction C.EBREAK */ - {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, - /* instruction C.SWSP */ - {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, - /* instruction DII */ - {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, - /* instruction FLW */ - {32, 0b00000000000000000010000000000111, 0b00000000000000000111000001111111, &this_class::__flw}, - /* instruction FSW */ - {32, 0b00000000000000000010000000100111, 0b00000000000000000111000001111111, &this_class::__fsw}, - /* instruction FMADD.S */ - {32, 0b00000000000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_s}, - /* instruction FMSUB.S */ - {32, 0b00000000000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_s}, - /* instruction FNMADD.S */ - {32, 0b00000000000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_s}, - /* instruction FNMSUB.S */ - {32, 0b00000000000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_s}, - /* instruction FADD.S */ - {32, 0b00000000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_s}, - /* instruction FSUB.S */ - {32, 0b00001000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_s}, - /* instruction FMUL.S */ - {32, 0b00010000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_s}, - /* instruction FDIV.S */ - {32, 0b00011000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_s}, - /* instruction FSQRT.S */ - {32, 0b01011000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_s}, - /* instruction FSGNJ.S */ - {32, 0b00100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_s}, - /* instruction FSGNJN.S */ - {32, 0b00100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_s}, - /* instruction FSGNJX.S */ - {32, 0b00100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_s}, - /* instruction FMIN.S */ - {32, 0b00101000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_s}, - /* instruction FMAX.S */ - {32, 0b00101000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_s}, - /* instruction FCVT.W.S */ - {32, 0b11000000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_s}, - /* instruction FCVT.WU.S */ - {32, 0b11000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_s}, - /* instruction FEQ.S */ - {32, 0b10100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_s}, - /* instruction FLT.S */ - {32, 0b10100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_s}, - /* instruction FLE.S */ - {32, 0b10100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_s}, - /* instruction FCLASS.S */ - {32, 0b11100000000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_s}, - /* instruction FCVT.S.W */ - {32, 0b11010000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_w}, - /* instruction FCVT.S.WU */ - {32, 0b11010000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_wu}, - /* instruction FMV.X.W */ - {32, 0b11100000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_w}, - /* instruction FMV.W.X */ - {32, 0b11110000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_w_x}, - /* instruction C.FLW */ - {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_flw}, - /* instruction C.FSW */ - {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_fsw}, - /* instruction C.FLWSP */ - {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, - /* instruction C.FSWSP */ - {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, /* instruction FLD */ {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, /* instruction FSD */ @@ -498,139 +408,112 @@ private: {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, /* instruction FCVT.D.WU */ {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, - /* instruction C.FLD */ - {16, 0b0010000000000000, 0b1110000000000011, &this_class::__c_fld}, - /* instruction C.FSD */ - {16, 0b1010000000000000, 0b1110000000000011, &this_class::__c_fsd}, - /* instruction C.FLDSP */ - {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_fldsp}, - /* instruction C.FSDSP */ - {16, 0b1010000000000010, 0b1110000000000011, &this_class::__c_fsdsp}, + /* instruction C.FLW */ + {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_flw}, + /* instruction C.FSW */ + {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_fsw}, + /* instruction C.FLWSP */ + {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, + /* instruction C.FSWSP */ + {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, + /* instruction FLW */ + {32, 0b00000000000000000010000000000111, 0b00000000000000000111000001111111, &this_class::__flw}, + /* instruction FSW */ + {32, 0b00000000000000000010000000100111, 0b00000000000000000111000001111111, &this_class::__fsw}, + /* instruction FMADD.S */ + {32, 0b00000000000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_s}, + /* instruction FMSUB.S */ + {32, 0b00000000000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_s}, + /* instruction FNMADD.S */ + {32, 0b00000000000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_s}, + /* instruction FNMSUB.S */ + {32, 0b00000000000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_s}, + /* instruction FADD.S */ + {32, 0b00000000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_s}, + /* instruction FSUB.S */ + {32, 0b00001000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_s}, + /* instruction FMUL.S */ + {32, 0b00010000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_s}, + /* instruction FDIV.S */ + {32, 0b00011000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_s}, + /* instruction FSQRT.S */ + {32, 0b01011000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_s}, + /* instruction FSGNJ.S */ + {32, 0b00100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_s}, + /* instruction FSGNJN.S */ + {32, 0b00100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_s}, + /* instruction FSGNJX.S */ + {32, 0b00100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_s}, + /* instruction FMIN.S */ + {32, 0b00101000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_s}, + /* instruction FMAX.S */ + {32, 0b00101000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_s}, + /* instruction FCVT.W.S */ + {32, 0b11000000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_s}, + /* instruction FCVT.WU.S */ + {32, 0b11000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_s}, + /* instruction FEQ.S */ + {32, 0b10100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_s}, + /* instruction FLT.S */ + {32, 0b10100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_s}, + /* instruction FLE.S */ + {32, 0b10100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_s}, + /* instruction FCLASS.S */ + {32, 0b11100000000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_s}, + /* instruction FCVT.S.W */ + {32, 0b11010000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_w}, + /* instruction FCVT.S.WU */ + {32, 0b11010000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_wu}, + /* instruction FMV.X.W */ + {32, 0b11100000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_w}, + /* instruction FMV.W.X */ + {32, 0b11110000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_w_x}, + /* instruction LR.W */ + {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, + /* instruction SC.W */ + {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, + /* instruction AMOSWAP.W */ + {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, + /* instruction AMOADD.W */ + {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, + /* instruction AMOXOR.W */ + {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, + /* instruction AMOAND.W */ + {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, + /* instruction AMOOR.W */ + {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, + /* instruction AMOMIN.W */ + {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, + /* instruction AMOMAX.W */ + {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, + /* instruction AMOMINU.W */ + {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, + /* instruction AMOMAXU.W */ + {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, + /* instruction MUL */ + {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, + /* instruction MULH */ + {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, + /* instruction MULHSU */ + {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, + /* instruction MULHU */ + {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, + /* instruction DIV */ + {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, + /* instruction DIVU */ + {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, + /* instruction REM */ + {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, + /* instruction REMU */ + {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, }}; /* instruction definitions */ - /* instruction 0: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LUI"); - - this->gen_sync(PRE_SYNC, 0); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 0); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 1: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AUIPC"); - - this->gen_sync(PRE_SYNC, 1); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 1); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 2: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("JAL"); - - this->gen_sync(PRE_SYNC, 2); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 2); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 3: JALR */ + /* instruction 0: JALR */ std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); - this->gen_sync(PRE_SYNC, 3); + this->gen_sync(PRE_SYNC, 0); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -658,7 +541,7 @@ private: this->gen_const(32U, imm)); Value* align_val = this->builder.CreateAnd( new_pc_val, - this->gen_const(32U, 0x1)); + this->gen_const(32U, 0x2)); { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -693,16 +576,1333 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - this->gen_sync(POST_SYNC, 3); + this->gen_sync(POST_SYNC, 0); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 4: BEQ */ + /* instruction 1: C.ADDI4SPN */ + std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI4SPN"); + + this->gen_sync(PRE_SYNC, 1); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint16_t imm = ((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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(imm == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 1); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 2: C.LW */ + std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LW"); + + this->gen_sync(PRE_SYNC, 2); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.lw"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 2); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 3: C.SW */ + std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SW"); + + this->gen_sync(PRE_SYNC, 3); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.sw"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 3); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 4: C.ADDI */ + std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI"); + + this->gen_sync(PRE_SYNC, 4); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 4); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 5: C.NOP */ + std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.NOP"); + + this->gen_sync(PRE_SYNC, 5); + + 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(POST_SYNC, 5); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 6: C.JAL */ + std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JAL"); + + this->gen_sync(PRE_SYNC, 6); + + int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 6); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 7: C.LI */ + std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LI"); + + this->gen_sync(PRE_SYNC, 7); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(rd == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 7); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 8: C.LUI */ + std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LUI"); + + this->gen_sync(PRE_SYNC, 8); + + int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(rd == 0){ + this->gen_raise_trap(0, 2); + } + if(imm == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 8); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 9: C.ADDI16SP */ + std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI16SP"); + + this->gen_sync(PRE_SYNC, 9); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(2 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 9); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 10: C.SRLI */ + std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SRLI"); + + this->gen_sync(PRE_SYNC, 10); + + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 10); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 11: C.SRAI */ + std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SRAI"); + + this->gen_sync(PRE_SYNC, 11); + + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 11); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 12: C.ANDI */ + std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ANDI"); + + this->gen_sync(PRE_SYNC, 12); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 12); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 13: C.SUB */ + std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SUB"); + + this->gen_sync(PRE_SYNC, 13); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 13); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 14: C.XOR */ + std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.XOR"); + + this->gen_sync(PRE_SYNC, 14); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 14); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 15: C.OR */ + std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.OR"); + + this->gen_sync(PRE_SYNC, 15); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 15); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 16: C.AND */ + std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.AND"); + + this->gen_sync(PRE_SYNC, 16); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 16); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 17: C.J */ + std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.J"); + + this->gen_sync(PRE_SYNC, 17); + + int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 17); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 18: C.BEQZ */ + std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.BEQZ"); + + this->gen_sync(PRE_SYNC, 18); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 18); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 19: C.BNEZ */ + std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.BNEZ"); + + this->gen_sync(PRE_SYNC, 19); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 19); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 20: C.SLLI */ + std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SLLI"); + + this->gen_sync(PRE_SYNC, 20); + + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), + fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(rs1 == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 20); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 21: C.LWSP */ + std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LWSP"); + + this->gen_sync(PRE_SYNC, 21); + + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 21); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 22: C.MV */ + std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.MV"); + + this->gen_sync(PRE_SYNC, 22); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 22); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 23: C.JR */ + std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JR"); + + this->gen_sync(PRE_SYNC, 23); + + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), + fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 23); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 24: C.ADD */ + std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADD"); + + this->gen_sync(PRE_SYNC, 24); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rd + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 24); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 25: C.JALR */ + std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JALR"); + + this->gen_sync(PRE_SYNC, 25); + + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), + fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 25); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 26: C.EBREAK */ + std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.EBREAK"); + + this->gen_sync(PRE_SYNC, 26); + + 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(POST_SYNC, 26); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 27: C.SWSP */ + std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SWSP"); + + this->gen_sync(PRE_SYNC, 27); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "c.swsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 27); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 28: DII */ + std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DII"); + + this->gen_sync(PRE_SYNC, 28); + + 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(POST_SYNC, 28); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 29: C.FLD */ + std::tuple __c_fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLD"); + + this->gen_sync(PRE_SYNC, 29); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fld"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 29); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 30: C.FSD */ + std::tuple __c_fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSD"); + + this->gen_sync(PRE_SYNC, 30); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsd"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::F0, 0), + this-> get_type(64) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 30); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 31: C.FLDSP */ + std::tuple __c_fldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLDSP"); + + this->gen_sync(PRE_SYNC, 31); + + uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.fldsp"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 31); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 32: C.FSDSP */ + std::tuple __c_fsdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSDSP"); + + this->gen_sync(PRE_SYNC, 32); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fsdsp"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 32); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 33: LUI */ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LUI"); + + this->gen_sync(PRE_SYNC, 33); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 33); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 34: AUIPC */ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(PRE_SYNC, 34); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 34); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 35: JAL */ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(PRE_SYNC, 35); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 35); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 36: BEQ */ std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); - this->gen_sync(PRE_SYNC, 4); + this->gen_sync(PRE_SYNC, 36); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -740,16 +1940,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 4); + this->gen_sync(POST_SYNC, 36); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 5: BNE */ + /* instruction 37: BNE */ std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); - this->gen_sync(PRE_SYNC, 5); + this->gen_sync(PRE_SYNC, 37); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -787,16 +1987,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 5); + this->gen_sync(POST_SYNC, 37); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 6: BLT */ + /* instruction 38: BLT */ std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); - this->gen_sync(PRE_SYNC, 6); + this->gen_sync(PRE_SYNC, 38); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -838,16 +2038,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 6); + this->gen_sync(POST_SYNC, 38); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 7: BGE */ + /* instruction 39: BGE */ std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); - this->gen_sync(PRE_SYNC, 7); + this->gen_sync(PRE_SYNC, 39); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -889,16 +2089,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 7); + this->gen_sync(POST_SYNC, 39); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 8: BLTU */ + /* instruction 40: BLTU */ std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); - this->gen_sync(PRE_SYNC, 8); + this->gen_sync(PRE_SYNC, 40); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -936,16 +2136,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 8); + this->gen_sync(POST_SYNC, 40); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 9: BGEU */ + /* instruction 41: BGEU */ std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); - this->gen_sync(PRE_SYNC, 9); + this->gen_sync(PRE_SYNC, 41); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -983,16 +2183,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 9); + this->gen_sync(POST_SYNC, 41); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 10: LB */ + /* instruction 42: LB */ std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); - this->gen_sync(PRE_SYNC, 10); + this->gen_sync(PRE_SYNC, 42); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1026,17 +2226,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 10); + this->gen_sync(POST_SYNC, 42); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 11: LH */ + /* instruction 43: LH */ std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); - this->gen_sync(PRE_SYNC, 11); + this->gen_sync(PRE_SYNC, 43); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1070,17 +2270,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 11); + this->gen_sync(POST_SYNC, 43); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 12: LW */ + /* instruction 44: LW */ std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); - this->gen_sync(PRE_SYNC, 12); + this->gen_sync(PRE_SYNC, 44); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1114,17 +2314,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 12); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 13: LBU */ + /* instruction 45: LBU */ std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); - this->gen_sync(PRE_SYNC, 13); + this->gen_sync(PRE_SYNC, 45); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1158,17 +2358,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 13); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 14: LHU */ + /* instruction 46: LHU */ std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); - this->gen_sync(PRE_SYNC, 14); + this->gen_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1202,17 +2402,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 14); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 15: SB */ + /* instruction 47: SB */ std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); - this->gen_sync(PRE_SYNC, 15); + this->gen_sync(PRE_SYNC, 47); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1244,17 +2444,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 15); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 16: SH */ + /* instruction 48: SH */ std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); - this->gen_sync(PRE_SYNC, 16); + this->gen_sync(PRE_SYNC, 48); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1286,17 +2486,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 16); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 17: SW */ + /* instruction 49: SW */ std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); - this->gen_sync(PRE_SYNC, 17); + this->gen_sync(PRE_SYNC, 49); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1328,17 +2528,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 17); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 18: ADDI */ + /* instruction 50: ADDI */ std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); - this->gen_sync(PRE_SYNC, 18); + this->gen_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1368,17 +2568,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 18); + this->gen_sync(POST_SYNC, 50); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 19: SLTI */ + /* instruction 51: SLTI */ std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); - this->gen_sync(PRE_SYNC, 19); + this->gen_sync(PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1413,17 +2613,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 19); + this->gen_sync(POST_SYNC, 51); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 20: SLTIU */ + /* instruction 52: SLTIU */ std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_sync(PRE_SYNC, 20); + this->gen_sync(PRE_SYNC, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1457,17 +2657,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 20); + this->gen_sync(POST_SYNC, 52); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 21: XORI */ + /* instruction 53: XORI */ std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); - this->gen_sync(PRE_SYNC, 21); + this->gen_sync(PRE_SYNC, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1497,17 +2697,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 21); + this->gen_sync(POST_SYNC, 53); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 22: ORI */ + /* instruction 54: ORI */ std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); - this->gen_sync(PRE_SYNC, 22); + this->gen_sync(PRE_SYNC, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1537,17 +2737,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 22); + this->gen_sync(POST_SYNC, 54); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 23: ANDI */ + /* instruction 55: ANDI */ std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); - this->gen_sync(PRE_SYNC, 23); + this->gen_sync(PRE_SYNC, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1577,17 +2777,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 23); + this->gen_sync(POST_SYNC, 55); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 24: SLLI */ + /* instruction 56: SLLI */ std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); - this->gen_sync(PRE_SYNC, 24); + this->gen_sync(PRE_SYNC, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1619,17 +2819,17 @@ private: } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 24); + this->gen_sync(POST_SYNC, 56); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 25: SRLI */ + /* instruction 57: SRLI */ std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); - this->gen_sync(PRE_SYNC, 25); + this->gen_sync(PRE_SYNC, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1661,17 +2861,17 @@ private: } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 25); + this->gen_sync(POST_SYNC, 57); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 26: SRAI */ + /* instruction 58: SRAI */ std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); - this->gen_sync(PRE_SYNC, 26); + this->gen_sync(PRE_SYNC, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1703,17 +2903,17 @@ private: } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 26); + this->gen_sync(POST_SYNC, 58); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 27: ADD */ + /* instruction 59: ADD */ std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); - this->gen_sync(PRE_SYNC, 27); + this->gen_sync(PRE_SYNC, 59); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1741,17 +2941,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 27); + this->gen_sync(POST_SYNC, 59); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 28: SUB */ + /* instruction 60: SUB */ std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); - this->gen_sync(PRE_SYNC, 28); + this->gen_sync(PRE_SYNC, 60); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1779,17 +2979,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 28); + this->gen_sync(POST_SYNC, 60); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 29: SLL */ + /* instruction 61: SLL */ std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); - this->gen_sync(PRE_SYNC, 29); + this->gen_sync(PRE_SYNC, 61); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1821,17 +3021,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 29); + this->gen_sync(POST_SYNC, 61); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 30: SLT */ + /* instruction 62: SLT */ std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); - this->gen_sync(PRE_SYNC, 30); + this->gen_sync(PRE_SYNC, 62); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1868,17 +3068,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 30); + this->gen_sync(POST_SYNC, 62); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 31: SLTU */ + /* instruction 63: SLTU */ std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); - this->gen_sync(PRE_SYNC, 31); + this->gen_sync(PRE_SYNC, 63); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1917,17 +3117,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 31); + this->gen_sync(POST_SYNC, 63); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 32: XOR */ + /* instruction 64: XOR */ std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); - this->gen_sync(PRE_SYNC, 32); + this->gen_sync(PRE_SYNC, 64); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1955,17 +3155,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 32); + this->gen_sync(POST_SYNC, 64); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 33: SRL */ + /* instruction 65: SRL */ std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); - this->gen_sync(PRE_SYNC, 33); + this->gen_sync(PRE_SYNC, 65); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1997,17 +3197,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 33); + this->gen_sync(POST_SYNC, 65); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 34: SRA */ + /* instruction 66: SRA */ std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); - this->gen_sync(PRE_SYNC, 34); + this->gen_sync(PRE_SYNC, 66); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2039,17 +3239,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 34); + this->gen_sync(POST_SYNC, 66); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 35: OR */ + /* instruction 67: OR */ std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); - this->gen_sync(PRE_SYNC, 35); + this->gen_sync(PRE_SYNC, 67); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2077,17 +3277,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 35); + this->gen_sync(POST_SYNC, 67); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 36: AND */ + /* instruction 68: AND */ std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); - this->gen_sync(PRE_SYNC, 36); + this->gen_sync(PRE_SYNC, 68); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2115,17 +3315,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 36); + this->gen_sync(POST_SYNC, 68); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 37: FENCE */ + /* instruction 69: FENCE */ std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); - this->gen_sync(PRE_SYNC, 37); + this->gen_sync(PRE_SYNC, 69); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2154,17 +3354,17 @@ private: this->gen_const(64U, 0), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 37); + this->gen_sync(POST_SYNC, 69); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 38: FENCE_I */ + /* instruction 70: FENCE_I */ std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_sync(PRE_SYNC, 38); + this->gen_sync(PRE_SYNC, 70); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2189,16 +3389,16 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 38); + this->gen_sync(POST_SYNC, 70); this->gen_trap_check(this->leave_blk); return std::make_tuple(FLUSH, nullptr); } - /* instruction 39: ECALL */ + /* instruction 71: ECALL */ std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ECALL"); - this->gen_sync(PRE_SYNC, 39); + this->gen_sync(PRE_SYNC, 71); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2214,16 +3414,16 @@ private: pc=pc+4; this->gen_raise_trap(0, 11); - this->gen_sync(POST_SYNC, 39); + this->gen_sync(POST_SYNC, 71); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 40: EBREAK */ + /* instruction 72: EBREAK */ std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_sync(PRE_SYNC, 40); + this->gen_sync(PRE_SYNC, 72); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2239,16 +3439,16 @@ private: pc=pc+4; this->gen_raise_trap(0, 3); - this->gen_sync(POST_SYNC, 40); + this->gen_sync(POST_SYNC, 72); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 41: URET */ + /* instruction 73: URET */ std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("URET"); - this->gen_sync(PRE_SYNC, 41); + this->gen_sync(PRE_SYNC, 73); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2264,16 +3464,16 @@ private: pc=pc+4; this->gen_leave_trap(0); - this->gen_sync(POST_SYNC, 41); + this->gen_sync(POST_SYNC, 73); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 42: SRET */ + /* instruction 74: SRET */ std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRET"); - this->gen_sync(PRE_SYNC, 42); + this->gen_sync(PRE_SYNC, 74); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2289,16 +3489,16 @@ private: pc=pc+4; this->gen_leave_trap(1); - this->gen_sync(POST_SYNC, 42); + this->gen_sync(POST_SYNC, 74); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 43: MRET */ + /* instruction 75: MRET */ std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MRET"); - this->gen_sync(PRE_SYNC, 43); + this->gen_sync(PRE_SYNC, 75); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2314,16 +3514,16 @@ private: pc=pc+4; this->gen_leave_trap(3); - this->gen_sync(POST_SYNC, 43); + this->gen_sync(POST_SYNC, 75); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 44: WFI */ + /* instruction 76: WFI */ std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("WFI"); - this->gen_sync(PRE_SYNC, 44); + this->gen_sync(PRE_SYNC, 76); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2340,17 +3540,17 @@ private: this->gen_wait(1); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 44); + this->gen_sync(POST_SYNC, 76); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 45: SFENCE.VMA */ + /* instruction 77: SFENCE.VMA */ std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_sync(PRE_SYNC, 45); + this->gen_sync(PRE_SYNC, 77); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2378,17 +3578,17 @@ private: this->gen_const(64U, 3), this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 45); + this->gen_sync(POST_SYNC, 77); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 46: CSRRW */ + /* instruction 78: CSRRW */ std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_sync(PRE_SYNC, 46); + this->gen_sync(PRE_SYNC, 78); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2427,17 +3627,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 46); + this->gen_sync(POST_SYNC, 78); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 47: CSRRS */ + /* instruction 79: CSRRS */ std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_sync(PRE_SYNC, 47); + this->gen_sync(PRE_SYNC, 79); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2474,17 +3674,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 47); + this->gen_sync(POST_SYNC, 79); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 48: CSRRC */ + /* instruction 80: CSRRC */ std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_sync(PRE_SYNC, 48); + this->gen_sync(PRE_SYNC, 80); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2521,17 +3721,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 48); + this->gen_sync(POST_SYNC, 80); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 49: CSRRWI */ + /* instruction 81: CSRRWI */ std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_sync(PRE_SYNC, 49); + this->gen_sync(PRE_SYNC, 81); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2565,17 +3765,17 @@ private: this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 49); + this->gen_sync(POST_SYNC, 81); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 50: CSRRSI */ + /* instruction 82: CSRRSI */ std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_sync(PRE_SYNC, 50); + this->gen_sync(PRE_SYNC, 82); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2614,17 +3814,17 @@ private: this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 50); + this->gen_sync(POST_SYNC, 82); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 51: CSRRCI */ + /* instruction 83: CSRRCI */ std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_sync(PRE_SYNC, 51); + this->gen_sync(PRE_SYNC, 83); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2663,4063 +3863,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 51); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 52: MUL */ - std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MUL"); - - this->gen_sync(PRE_SYNC, 52); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - false)); - Value* Xtmp0_val = this->gen_ext( - res_val, - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 52); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 53: MULH */ - std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MULH"); - - this->gen_sync(PRE_SYNC, 53); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - true)); - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - this->gen_const(32U, 32)), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 53); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 54: MULHSU */ - std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MULHSU"); - - this->gen_sync(PRE_SYNC, 54); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - false)); - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - this->gen_const(32U, 32)), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 54); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 55: MULHU */ - std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MULHU"); - - this->gen_sync(PRE_SYNC, 55); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - false)); - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - this->gen_const(32U, 32)), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 55); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 56: DIV */ - std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("DIV"); - - this->gen_sync(PRE_SYNC, 56); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - uint32_t M1_val = - 1; - uint32_t MMIN_val = - 1 << 32 - 1; - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, true), - this->gen_ext( - this->gen_const(32U, MMIN_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, true), - this->gen_ext( - this->gen_const(32U, M1_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->gen_const(32U, MMIN_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->builder.CreateSDiv( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 3), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 3), - 32, true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp2_val = this->builder.CreateSDiv( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 2), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp3_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 56); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 57: DIVU */ - std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("DIVU"); - - this->gen_sync(PRE_SYNC, 57); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->builder.CreateUDiv( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 1), - 32, - false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 57); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 58: REM */ - std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("REM"); - - this->gen_sync(PRE_SYNC, 58); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - uint32_t M1_val = - 1; - uint32_t MMIN_val = - 1 << 32 - 1; - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, true), - this->gen_ext( - this->gen_const(32U, MMIN_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, true), - this->gen_ext( - this->gen_const(32U, M1_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->gen_const(32U, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 3), - 32, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 3), - 32, - true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp2_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 2), - 32, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, - true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp3_val = this->gen_reg_load(rs1 + traits::X0, 1); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 58); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 59: REMU */ - std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("REMU"); - - this->gen_sync(PRE_SYNC, 59); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 1), - 32, - false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 59); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 60: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LR.W"); - - this->gen_sync(PRE_SYNC, 60); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* REStmp1_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(REStmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 60); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 61: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SC.W"); - - this->gen_sync(PRE_SYNC, 61); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - if(rd != 0){ - Value* Xtmp1_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(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 61); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 62: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOSWAP.W"); - - this->gen_sync(PRE_SYNC, 62); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 62); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 63: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOADD.W"); - - this->gen_sync(PRE_SYNC, 63); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAdd( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 63); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 64: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOXOR.W"); - - this->gen_sync(PRE_SYNC, 64); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateXor( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 64); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 65: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOAND.W"); - - this->gen_sync(PRE_SYNC, 65); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAnd( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 65); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 66: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOOR.W"); - - this->gen_sync(PRE_SYNC, 66); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateOr( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 66); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 67: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMIN.W"); - - this->gen_sync(PRE_SYNC, 67); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 32, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 32); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 67); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 68: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAX.W"); - - this->gen_sync(PRE_SYNC, 68); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 32, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 32); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 68); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 69: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMINU.W"); - - this->gen_sync(PRE_SYNC, 69); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - false); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 32); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 69); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 70: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAXU.W"); - - this->gen_sync(PRE_SYNC, 70); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - false); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 32); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 70); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 71: C.ADDI4SPN */ - std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDI4SPN"); - - this->gen_sync(PRE_SYNC, 71); - - uint8_t rd = ((bit_sub<2,3>(instr))); - uint16_t imm = ((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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(imm == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 71); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 72: C.LW */ - std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LW"); - - this->gen_sync(PRE_SYNC, 72); - - uint8_t rd = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {uimm:#05x}", fmt::arg("mnemonic", "c.lw"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs1", name(8+rs1)), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 72); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 73: C.SW */ - std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SW"); - - this->gen_sync(PRE_SYNC, 73); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {uimm:#05x}", fmt::arg("mnemonic", "c.sw"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 73); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 74: C.ADDI */ - std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDI"); - - this->gen_sync(PRE_SYNC, 74); - - int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), - fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 74); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 75: C.NOP */ - std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.NOP"); - - this->gen_sync(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(POST_SYNC, 75); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 76: C.JAL */ - std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.JAL"); - - this->gen_sync(PRE_SYNC, 76); - - int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), - fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 76); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 77: C.LI */ - std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LI"); - - this->gen_sync(PRE_SYNC, 77); - - int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(rd == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 77); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 78: C.LUI */ - std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LUI"); - - this->gen_sync(PRE_SYNC, 78); - - int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(rd == 0){ - this->gen_raise_trap(0, 2); - } - if(imm == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 78); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 79: C.ADDI16SP */ - std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDI16SP"); - - this->gen_sync(PRE_SYNC, 79); - - int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), - fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(2 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 79); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 80: C.SRLI */ - std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SRLI"); - - this->gen_sync(PRE_SYNC, 80); - - uint8_t shamt = ((bit_sub<2,5>(instr))); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rs1 + 8; - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 80); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 81: C.SRAI */ - std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SRAI"); - - this->gen_sync(PRE_SYNC, 81); - - uint8_t shamt = ((bit_sub<2,5>(instr))); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rs1 + 8; - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 81); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 82: C.ANDI */ - std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ANDI"); - - this->gen_sync(PRE_SYNC, 82); - - uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rs1 + 8; - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 82); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 83: C.SUB */ - std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SUB"); - - this->gen_sync(PRE_SYNC, 83); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 83); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 84: C.XOR */ - std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.XOR"); - - this->gen_sync(PRE_SYNC, 84); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 84); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 85: C.OR */ - std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.OR"); - - this->gen_sync(PRE_SYNC, 85); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 85); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 86: C.AND */ - std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.AND"); - - this->gen_sync(PRE_SYNC, 86); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 86); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 87: C.J */ - std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.J"); - - this->gen_sync(PRE_SYNC, 87); - - int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), - fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 87); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 88: C.BEQZ */ - std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.BEQZ"); - - this->gen_sync(PRE_SYNC, 88); - - int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 88); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 89: C.BNEZ */ - std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.BNEZ"); - - this->gen_sync(PRE_SYNC, 89); - - int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_NE, - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 89); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 90: C.SLLI */ - std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SLLI"); - - this->gen_sync(PRE_SYNC, 90); - - uint8_t shamt = ((bit_sub<2,5>(instr))); - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), - fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(rs1 == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 90); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 91: C.LWSP */ - std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LWSP"); - - this->gen_sync(PRE_SYNC, 91); - - uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), - fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 91); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 92: C.MV */ - std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.MV"); - - this->gen_sync(PRE_SYNC, 92); - - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 92); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 93: C.JR */ - std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.JR"); - - this->gen_sync(PRE_SYNC, 93); - - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), - fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 93); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 94: C.ADD */ - std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADD"); - - this->gen_sync(PRE_SYNC, 94); - - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(rd + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 94); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 95: C.JALR */ - std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.JALR"); - - this->gen_sync(PRE_SYNC, 95); - - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), - fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); - Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 95); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 96: C.EBREAK */ - std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.EBREAK"); - - this->gen_sync(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(POST_SYNC, 96); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 97: C.SWSP */ - std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SWSP"); - - this->gen_sync(PRE_SYNC, 97); - - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x2+{uimm:#05x}, {rs2}", fmt::arg("mnemonic", "c.swsp"), - fmt::arg("uimm", uimm), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 97); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 98: DII */ - std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("DII"); - - this->gen_sync(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(POST_SYNC, 98); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 99: FLW */ - std::tuple __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FLW"); - - this->gen_sync(PRE_SYNC, 99); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, {imm}(x{rs1})", fmt::arg("mnemonic", "flw"), - fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 99); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 100: FSW */ - std::tuple __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FSW"); - - this->gen_sync(PRE_SYNC, 100); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rs2}, {imm}(x{rs1})", fmt::arg("mnemonic", "fsw"), - fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 100); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 101: FMADD.S */ - std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMADD.S"); - - this->gen_sync(PRE_SYNC, 101); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rs3 = ((bit_sub<27,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs3 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 0LL), - 32, - false), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 101); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 102: FMSUB.S */ - std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMSUB.S"); - - this->gen_sync(PRE_SYNC, 102); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rs3 = ((bit_sub<27,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs3 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 1LL), - 32, - false), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 102); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 103: FNMADD.S */ - std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FNMADD.S"); - - this->gen_sync(PRE_SYNC, 103); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rs3 = ((bit_sub<27,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs3 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 2LL), - 32, - false), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 103); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 104: FNMSUB.S */ - std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FNMSUB.S"); - - this->gen_sync(PRE_SYNC, 104); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rs3 = ((bit_sub<27,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs3 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 3LL), - 32, - false), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 104); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 105: FADD.S */ - std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FADD.S"); - - this->gen_sync(PRE_SYNC, 105); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 105); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 106: FSUB.S */ - std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FSUB.S"); - - this->gen_sync(PRE_SYNC, 106); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 106); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 107: FMUL.S */ - std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMUL.S"); - - this->gen_sync(PRE_SYNC, 107); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 107); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 108: FDIV.S */ - std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FDIV.S"); - - this->gen_sync(PRE_SYNC, 108); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 108); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 109: FSQRT.S */ - std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FSQRT.S"); - - this->gen_sync(PRE_SYNC, 109); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_const(8U, rm), - this->gen_const(8U, 7)), - this->gen_const(8U, rm), - this->builder.CreateTrunc( - this->gen_reg_load(traits::FCSR, 0), - this-> get_type(8) - ), - 8) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 109); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 110: FSGNJ.S */ - std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FSGNJ.S"); - - this->gen_sync(PRE_SYNC, 110); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateOr( - this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_const(32U, 0x7fffffff)), - this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_const(32U, 0x80000000))); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 110); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 111: FSGNJN.S */ - std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FSGNJN.S"); - - this->gen_sync(PRE_SYNC, 111); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateOr( - this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_const(32U, 0x7fffffff)), - this->builder.CreateAnd( - this->builder.CreateNot(this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - )), - this->gen_const(32U, 0x80000000))); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 111); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 112: FSGNJX.S */ - std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FSGNJX.S"); - - this->gen_sync(PRE_SYNC, 112); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateXor( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_const(32U, 0x80000000))); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 112); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 113: FMIN.S */ - std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMIN.S"); - - this->gen_sync(PRE_SYNC, 113); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 0LL), - 32, - false) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 113); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 114: FMAX.S */ - std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMAX.S"); - - this->gen_sync(PRE_SYNC, 114); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 1LL), - 32, - false) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 114); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 115: FCVT.W.S */ - std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FCVT.W.S"); - - this->gen_sync(PRE_SYNC, 115); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 0LL), - 32, - false), - this->gen_const(8U, rm) - }), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 115); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 116: FCVT.WU.S */ - std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FCVT.WU.S"); - - this->gen_sync(PRE_SYNC, 116); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 1LL), - 32, - false), - this->gen_const(8U, rm) - }), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 116); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 117: FEQ.S */ - std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FEQ.S"); - - this->gen_sync(PRE_SYNC, 117); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 0LL), - 32, - false) - }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 117); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 118: FLT.S */ - std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FLT.S"); - - this->gen_sync(PRE_SYNC, 118); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 2LL), - 32, - false) - }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 118); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 119: FLE.S */ - std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FLE.S"); - - this->gen_sync(PRE_SYNC, 119); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 1LL), - 32, - false) - }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ - }); - Value* FCSR_val = this->builder.CreateAdd( - this->builder.CreateAnd( - this->gen_reg_load(traits::FCSR, 0), - this->builder.CreateNot(this->gen_const(32U, 0x1f))), - flags_val); - this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 119); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 120: FCLASS.S */ - std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FCLASS.S"); - - this->gen_sync(PRE_SYNC, 120); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fclass.s"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ) - }); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 120); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 121: FCVT.S.W */ - std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FCVT.S.W"); - - this->gen_sync(PRE_SYNC, 121); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.w"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 2LL), - 32, - false), - this->gen_const(8U, rm) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 121); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 122: FCVT.S.WU */ - std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FCVT.S.WU"); - - this->gen_sync(PRE_SYNC, 122); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rm = ((bit_sub<12,3>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.wu"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_ext( - this->gen_const(64U, 3LL), - 32, - false), - this->gen_const(8U, rm) - }); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 122); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 123: FMV.X.W */ - std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMV.X.W"); - - this->gen_sync(PRE_SYNC, 123); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.w"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(32) - ), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 123); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 124: FMV.W.X */ - std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FMV.W.X"); - - this->gen_sync(PRE_SYNC, 124); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fmv.w.x"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(64 == 32){ - Value* Ftmp0_val = this->gen_reg_load(rs1 + traits::X0, 0); - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 124); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 125: C.FLW */ - std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FLW"); - - this->gen_sync(PRE_SYNC, 125); - - uint8_t rd = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"), - fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 125); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 126: C.FSW */ - std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FSW"); - - this->gen_sync(PRE_SYNC, 126); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"), - fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(rs2 + 8 + traits::F0, 0), - this-> get_type(32) - ); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 126); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 127: C.FLWSP */ - std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FLWSP"); - - this->gen_sync(PRE_SYNC, 127); - - uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"), - fmt::arg("rd", rd), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), - this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 127); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 128: C.FSWSP */ - std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FSWSP"); - - this->gen_sync(PRE_SYNC, 128); - - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"), - fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 128); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 129: FLD */ + /* instruction 84: FLD */ std::tuple __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLD"); - this->gen_sync(PRE_SYNC, 129); + this->gen_sync(PRE_SYNC, 84); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -6728,7 +3882,7 @@ private: /* generate console output when executing the command */ auto mnemonic = fmt::format( "{mnemonic:10} f{rd}, {imm}({rs1})", fmt::arg("mnemonic", "fld"), - fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); + fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -6759,17 +3913,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 129); + this->gen_sync(POST_SYNC, 84); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 130: FSD */ + /* instruction 85: FSD */ std::tuple __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSD"); - this->gen_sync(PRE_SYNC, 130); + this->gen_sync(PRE_SYNC, 85); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -6778,7 +3932,7 @@ private: /* generate console output when executing the command */ auto mnemonic = fmt::format( "{mnemonic:10} f{rs2}, {imm}({rs1})", fmt::arg("mnemonic", "fsd"), - fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); + fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -6804,17 +3958,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 130); + this->gen_sync(POST_SYNC, 85); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 131: FMADD.D */ + /* instruction 86: FMADD.D */ std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.D"); - this->gen_sync(PRE_SYNC, 131); + this->gen_sync(PRE_SYNC, 86); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6887,17 +4041,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 131); + this->gen_sync(POST_SYNC, 86); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 132: FMSUB.D */ + /* instruction 87: FMSUB.D */ std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.D"); - this->gen_sync(PRE_SYNC, 132); + this->gen_sync(PRE_SYNC, 87); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6970,17 +4124,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 132); + this->gen_sync(POST_SYNC, 87); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 133: FNMADD.D */ + /* instruction 88: FNMADD.D */ std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.D"); - this->gen_sync(PRE_SYNC, 133); + this->gen_sync(PRE_SYNC, 88); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7053,17 +4207,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 133); + this->gen_sync(POST_SYNC, 88); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 134: FNMSUB.D */ + /* instruction 89: FNMSUB.D */ std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.D"); - this->gen_sync(PRE_SYNC, 134); + this->gen_sync(PRE_SYNC, 89); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7136,17 +4290,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 134); + this->gen_sync(POST_SYNC, 89); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 135: FADD.D */ + /* instruction 90: FADD.D */ std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.D"); - this->gen_sync(PRE_SYNC, 135); + this->gen_sync(PRE_SYNC, 90); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7210,17 +4364,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 135); + this->gen_sync(POST_SYNC, 90); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 136: FSUB.D */ + /* instruction 91: FSUB.D */ std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.D"); - this->gen_sync(PRE_SYNC, 136); + this->gen_sync(PRE_SYNC, 91); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7284,17 +4438,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 136); + this->gen_sync(POST_SYNC, 91); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 137: FMUL.D */ + /* instruction 92: FMUL.D */ std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.D"); - this->gen_sync(PRE_SYNC, 137); + this->gen_sync(PRE_SYNC, 92); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7358,17 +4512,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 137); + this->gen_sync(POST_SYNC, 92); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 138: FDIV.D */ + /* instruction 93: FDIV.D */ std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.D"); - this->gen_sync(PRE_SYNC, 138); + this->gen_sync(PRE_SYNC, 93); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7432,17 +4586,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 138); + this->gen_sync(POST_SYNC, 93); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 139: FSQRT.D */ + /* instruction 94: FSQRT.D */ std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.D"); - this->gen_sync(PRE_SYNC, 139); + this->gen_sync(PRE_SYNC, 94); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7501,17 +4655,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 139); + this->gen_sync(POST_SYNC, 94); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 140: FSGNJ.D */ + /* instruction 95: FSGNJ.D */ std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.D"); - this->gen_sync(PRE_SYNC, 140); + this->gen_sync(PRE_SYNC, 95); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7532,19 +4686,22 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; + uint64_t ONE_val = 1; + uint64_t MSK1_val = ONE_val << 63; + uint64_t MSK2_val = MSK1_val - 1; Value* res_val = this->builder.CreateOr( this->builder.CreateAnd( this->builder.CreateTrunc( this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), - this->gen_const(64U, 0x7fffffff)), + this->gen_const(64U, MSK2_val)), this->builder.CreateAnd( this->builder.CreateTrunc( this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), - this->gen_const(64U, 0x80000000))); + this->gen_const(64U, MSK1_val))); if(64 == 64){ Value* Ftmp0_val = res_val; this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); @@ -7558,17 +4715,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 140); + this->gen_sync(POST_SYNC, 95); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 141: FSGNJN.D */ + /* instruction 96: FSGNJN.D */ std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.D"); - this->gen_sync(PRE_SYNC, 141); + this->gen_sync(PRE_SYNC, 96); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7589,19 +4746,22 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; + uint64_t ONE_val = 1; + uint64_t MSK1_val = ONE_val << 63; + uint64_t MSK2_val = MSK1_val - 1; Value* res_val = this->builder.CreateOr( this->builder.CreateAnd( this->builder.CreateTrunc( this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) ), - this->gen_const(64U, 0x7fffffff)), + this->gen_const(64U, MSK2_val)), this->builder.CreateAnd( this->builder.CreateNot(this->builder.CreateTrunc( this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) )), - this->gen_const(64U, 0x80000000))); + this->gen_const(64U, MSK1_val))); if(64 == 64){ Value* Ftmp0_val = res_val; this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); @@ -7615,17 +4775,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 141); + this->gen_sync(POST_SYNC, 96); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 142: FSGNJX.D */ + /* instruction 97: FSGNJX.D */ std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.D"); - this->gen_sync(PRE_SYNC, 142); + this->gen_sync(PRE_SYNC, 97); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7646,6 +4806,8 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; + uint64_t ONE_val = 1; + uint64_t MSK1_val = ONE_val << 63; Value* res_val = this->builder.CreateXor( this->builder.CreateTrunc( this->gen_reg_load(rs1 + traits::F0, 0), @@ -7656,7 +4818,7 @@ private: this->gen_reg_load(rs2 + traits::F0, 0), this-> get_type(64) ), - this->gen_const(64U, 0x80000000))); + this->gen_const(64U, MSK1_val))); if(64 == 64){ Value* Ftmp0_val = res_val; this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); @@ -7670,17 +4832,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 142); + this->gen_sync(POST_SYNC, 97); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 143: FMIN.D */ + /* instruction 98: FMIN.D */ std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.D"); - this->gen_sync(PRE_SYNC, 143); + this->gen_sync(PRE_SYNC, 98); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7736,17 +4898,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 143); + this->gen_sync(POST_SYNC, 98); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 144: FMAX.D */ + /* instruction 99: FMAX.D */ std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.D"); - this->gen_sync(PRE_SYNC, 144); + this->gen_sync(PRE_SYNC, 99); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7802,17 +4964,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 144); + this->gen_sync(POST_SYNC, 99); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 145: FCVT.S.D */ + /* instruction 100: FCVT.S.D */ std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.D"); - this->gen_sync(PRE_SYNC, 145); + this->gen_sync(PRE_SYNC, 100); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7848,17 +5010,17 @@ private: false)); this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 145); + this->gen_sync(POST_SYNC, 100); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 146: FCVT.D.S */ + /* instruction 101: FCVT.D.S */ std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.S"); - this->gen_sync(PRE_SYNC, 146); + this->gen_sync(PRE_SYNC, 101); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7899,17 +5061,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 146); + this->gen_sync(POST_SYNC, 101); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 147: FEQ.D */ + /* instruction 102: FEQ.D */ std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.D"); - this->gen_sync(PRE_SYNC, 147); + this->gen_sync(PRE_SYNC, 102); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7930,20 +5092,23 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(64) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(64) - ), - this->gen_ext( - this->gen_const(64U, 0LL), - 32, - false) - }); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }), + 32, + false); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -7954,17 +5119,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 147); + this->gen_sync(POST_SYNC, 102); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 148: FLT.D */ + /* instruction 103: FLT.D */ std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.D"); - this->gen_sync(PRE_SYNC, 148); + this->gen_sync(PRE_SYNC, 103); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7985,20 +5150,23 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(64) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(64) - ), - this->gen_ext( - this->gen_const(64U, 2LL), - 32, - false) - }); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }), + 32, + false); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -8009,17 +5177,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 148); + this->gen_sync(POST_SYNC, 103); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 149: FLE.D */ + /* instruction 104: FLE.D */ std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.D"); - this->gen_sync(PRE_SYNC, 149); + this->gen_sync(PRE_SYNC, 104); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8040,20 +5208,23 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::F0, 0), - this-> get_type(64) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(64) - ), - this->gen_ext( - this->gen_const(64U, 1LL), - 32, - false) - }); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }), + 32, + false); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -8064,17 +5235,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 149); + this->gen_sync(POST_SYNC, 104); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 150: FCLASS.D */ + /* instruction 105: FCLASS.D */ std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.D"); - this->gen_sync(PRE_SYNC, 150); + this->gen_sync(PRE_SYNC, 105); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8102,17 +5273,17 @@ private: }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 150); + this->gen_sync(POST_SYNC, 105); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 151: FCVT.W.D */ + /* instruction 106: FCVT.W.D */ std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.D"); - this->gen_sync(PRE_SYNC, 151); + this->gen_sync(PRE_SYNC, 106); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8134,7 +5305,7 @@ private: pc=pc+4; Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) @@ -8157,17 +5328,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 151); + this->gen_sync(POST_SYNC, 106); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 152: FCVT.WU.D */ + /* instruction 107: FCVT.WU.D */ std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.D"); - this->gen_sync(PRE_SYNC, 152); + this->gen_sync(PRE_SYNC, 107); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8189,7 +5360,7 @@ private: pc=pc+4; Value* Xtmp0_val = this->gen_ext( - this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector{ this->builder.CreateTrunc( this->gen_reg_load(rs1 + traits::F0, 0), this-> get_type(64) @@ -8201,7 +5372,7 @@ private: this->gen_const(8U, rm) }), 32, - false); + true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ }); @@ -8212,17 +5383,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 152); + this->gen_sync(POST_SYNC, 107); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 153: FCVT.D.W */ + /* instruction 108: FCVT.D.W */ std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.W"); - this->gen_sync(PRE_SYNC, 153); + this->gen_sync(PRE_SYNC, 108); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8231,7 +5402,7 @@ private: /* generate console output when executing the command */ auto mnemonic = fmt::format( "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.w"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -8243,9 +5414,12 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector{ this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), 64, true), this->gen_ext( @@ -8267,17 +5441,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 153); + this->gen_sync(POST_SYNC, 108); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 154: FCVT.D.WU */ + /* instruction 109: FCVT.D.WU */ std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.WU"); - this->gen_sync(PRE_SYNC, 154); + this->gen_sync(PRE_SYNC, 109); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8286,7 +5460,7 @@ private: /* generate console output when executing the command */ auto mnemonic = fmt::format( "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.wu"), - fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -8298,9 +5472,12 @@ private: Value* cur_pc_val = this->gen_const(32, pc.val); pc=pc+4; - Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector{ this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), 64, false), this->gen_ext( @@ -8322,25 +5499,25 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 154); + this->gen_sync(POST_SYNC, 109); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 155: C.FLD */ - std::tuple __c_fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FLD"); + /* instruction 110: C.FLW */ + std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLW"); - this->gen_sync(PRE_SYNC, 155); + this->gen_sync(PRE_SYNC, 110); uint8_t rd = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fld"), + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"), fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, @@ -8356,8 +5533,8 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(rs1 + 8 + traits::X0, 0), this->gen_const(32U, uimm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); - if(64 == 64){ + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ Value* Ftmp0_val = res_val; this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); } else { @@ -8365,30 +5542,33 @@ private: Value* Ftmp1_val = this->builder.CreateOr( this->builder.CreateShl( this->gen_const(64U, upper_val), - this->gen_const(64U, 64)), - res_val); + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 155); + this->gen_sync(POST_SYNC, 110); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 156: C.FSD */ - std::tuple __c_fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FSD"); + /* instruction 111: C.FSW */ + std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSW"); - this->gen_sync(PRE_SYNC, 156); + this->gen_sync(PRE_SYNC, 111); uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsd"), + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"), fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, @@ -8406,31 +5586,31 @@ private: this->gen_const(32U, uimm)); Value* MEMtmp0_val = this->builder.CreateTrunc( this->gen_reg_load(rs2 + 8 + traits::F0, 0), - this-> get_type(64) + this-> get_type(32) ); this->gen_write_mem( traits::MEM, offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 156); + this->gen_sync(POST_SYNC, 111); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 157: C.FLDSP */ - std::tuple __c_fldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FLDSP"); + /* instruction 112: C.FLWSP */ + std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLWSP"); - this->gen_sync(PRE_SYNC, 157); + this->gen_sync(PRE_SYNC, 112); - uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.fldsp"), + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"), fmt::arg("rd", rd), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, @@ -8446,8 +5626,8 @@ private: Value* offs_val = this->builder.CreateAdd( this->gen_reg_load(2 + traits::X0, 0), this->gen_const(32U, uimm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); - if(64 == 64){ + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ Value* Ftmp0_val = res_val; this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); } else { @@ -8455,7 +5635,7 @@ private: Value* Ftmp1_val = this->builder.CreateOr( this->builder.CreateShl( this->gen_const(64U, upper_val), - this->gen_const(64U, 64)), + this->gen_const(64U, 32)), this->gen_ext( res_val, 64, @@ -8463,24 +5643,24 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 157); + this->gen_sync(POST_SYNC, 112); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 158: C.FSDSP */ - std::tuple __c_fsdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FSDSP"); + /* instruction 113: C.FSWSP */ + std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSWSP"); - this->gen_sync(PRE_SYNC, 158); + this->gen_sync(PRE_SYNC, 113); uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fsdsp"), + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"), fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, @@ -8498,12 +5678,3087 @@ private: this->gen_const(32U, uimm)); Value* MEMtmp0_val = this->builder.CreateTrunc( this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(64) + this-> get_type(32) ); this->gen_write_mem( traits::MEM, offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 113); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 114: FLW */ + std::tuple __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLW"); + + this->gen_sync(PRE_SYNC, 114); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {imm}(x{rs1})", fmt::arg("mnemonic", "flw"), + fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 114); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 115: FSW */ + std::tuple __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSW"); + + this->gen_sync(PRE_SYNC, 115); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {imm}(x{rs1})", fmt::arg("mnemonic", "fsw"), + fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(32) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 115); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 116: FMADD.S */ + std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMADD.S"); + + this->gen_sync(PRE_SYNC, 116); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 116); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 117: FMSUB.S */ + std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMSUB.S"); + + this->gen_sync(PRE_SYNC, 117); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 117); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 118: FNMADD.S */ + std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FNMADD.S"); + + this->gen_sync(PRE_SYNC, 118); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 118); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 119: FNMSUB.S */ + std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FNMSUB.S"); + + this->gen_sync(PRE_SYNC, 119); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 119); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 120: FADD.S */ + std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FADD.S"); + + this->gen_sync(PRE_SYNC, 120); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 120); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 121: FSUB.S */ + std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSUB.S"); + + this->gen_sync(PRE_SYNC, 121); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 121); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 122: FMUL.S */ + std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMUL.S"); + + this->gen_sync(PRE_SYNC, 122); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 122); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 123: FDIV.S */ + std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FDIV.S"); + + this->gen_sync(PRE_SYNC, 123); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 123); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 124: FSQRT.S */ + std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSQRT.S"); + + this->gen_sync(PRE_SYNC, 124); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ + frs1_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 124); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 125: FSGNJ.S */ + std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJ.S"); + + this->gen_sync(PRE_SYNC, 125); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_const(64U, 0x7fffffff)), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_const(64U, 0x80000000))); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + frs1_val, + this->gen_const(32U, 0x7fffffff)), + this->builder.CreateAnd( + frs2_val, + this->gen_const(32U, 0x80000000))); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 125); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 126: FSGNJN.S */ + std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJN.S"); + + this->gen_sync(PRE_SYNC, 126); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_const(64U, 0x7fffffff)), + this->builder.CreateAnd( + this->builder.CreateNot(this->gen_reg_load(rs2 + traits::F0, 0)), + this->gen_const(64U, 0x80000000))); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + frs1_val, + this->gen_const(32U, 0x7fffffff)), + this->builder.CreateAnd( + this->builder.CreateNot(frs2_val), + this->gen_const(32U, 0x80000000))); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 126); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 127: FSGNJX.S */ + std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJX.S"); + + this->gen_sync(PRE_SYNC, 127); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateXor( + this->gen_reg_load(rs1 + traits::F0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_const(64U, 0x80000000))); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateXor( + frs1_val, + this->builder.CreateAnd( + frs2_val, + this->gen_const(32U, 0x80000000))); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 127); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 128: FMIN.S */ + std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMIN.S"); + + this->gen_sync(PRE_SYNC, 128); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 128); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 129: FMAX.S */ + std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMAX.S"); + + this->gen_sync(PRE_SYNC, 129); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 129); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 130: FCVT.W.S */ + std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.W.S"); + + this->gen_sync(PRE_SYNC, 130); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + frs1_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }), + 32, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 130); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 131: FCVT.WU.S */ + std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.WU.S"); + + this->gen_sync(PRE_SYNC, 131); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + frs1_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }), + 32, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 131); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 132: FEQ.S */ + std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FEQ.S"); + + this->gen_sync(PRE_SYNC, 132); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }), + 32, + false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 132); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 133: FLT.S */ + std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLT.S"); + + this->gen_sync(PRE_SYNC, 133); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }), + 32, + false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* Xtmp2_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 133); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 134: FLE.S */ + std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLE.S"); + + this->gen_sync(PRE_SYNC, 134); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }), + 32, + false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 134); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 135: FCLASS.S */ + std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCLASS.S"); + + this->gen_sync(PRE_SYNC, 135); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fclass.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }) + }); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 135); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 136: FCVT.S.W */ + std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.W"); + + this->gen_sync(PRE_SYNC, 136); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.s.w"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, rm) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, rm) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 136); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 137: FCVT.S.WU */ + std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.WU"); + + this->gen_sync(PRE_SYNC, 137); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.s.wu"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, rm) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, rm) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 137); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 138: FMV.X.W */ + std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMV.X.W"); + + this->gen_sync(PRE_SYNC, 138); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(32) + ), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 138); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 139: FMV.W.X */ + std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMV.W.X"); + + this->gen_sync(PRE_SYNC, 139); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fmv.w.x"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 139); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 140: LR.W */ + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LR.W"); + + this->gen_sync(PRE_SYNC, 140); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* REStmp1_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(REStmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 140); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 141: SC.W */ + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SC.W"); + + this->gen_sync(PRE_SYNC, 141); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + if(rd != 0){ + Value* Xtmp1_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + res1_val, + this->gen_ext( + this->gen_const(32U, 0), + 32, + false)), + this->gen_const(32U, 0), + this->gen_const(32U, 1), + 32); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 141); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 142: AMOSWAP.W */ + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOSWAP.W"); + + this->gen_sync(PRE_SYNC, 142); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 142); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 143: AMOADD.W */ + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOADD.W"); + + this->gen_sync(PRE_SYNC, 143); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAdd( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 143); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 144: AMOXOR.W */ + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOXOR.W"); + + this->gen_sync(PRE_SYNC, 144); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateXor( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 144); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 145: AMOAND.W */ + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOAND.W"); + + this->gen_sync(PRE_SYNC, 145); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAnd( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 145); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 146: AMOOR.W */ + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOOR.W"); + + this->gen_sync(PRE_SYNC, 146); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateOr( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 146); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 147: AMOMIN.W */ + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMIN.W"); + + this->gen_sync(PRE_SYNC, 147); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 32, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 32); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 147); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 148: AMOMAX.W */ + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAX.W"); + + this->gen_sync(PRE_SYNC, 148); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 32, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 32); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 148); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 149: AMOMINU.W */ + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMINU.W"); + + this->gen_sync(PRE_SYNC, 149); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 32); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 149); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 150: AMOMAXU.W */ + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAXU.W"); + + this->gen_sync(PRE_SYNC, 150); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 32); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 150); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 151: MUL */ + std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MUL"); + + this->gen_sync(PRE_SYNC, 151); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 151); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 152: MULH */ + std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULH"); + + this->gen_sync(PRE_SYNC, 152); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + true)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(32U, 32)), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 152); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 153: MULHSU */ + std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULHSU"); + + this->gen_sync(PRE_SYNC, 153); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(32U, 32)), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 153); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 154: MULHU */ + std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULHU"); + + this->gen_sync(PRE_SYNC, 154); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(32U, 32)), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 154); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 155: DIV */ + std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIV"); + + this->gen_sync(PRE_SYNC, 155); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint32_t M1_val = - 1; + uint8_t XLM1_val = 32 - 1; + uint32_t ONE_val = 1; + uint32_t MMIN_val = ONE_val << XLM1_val; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_const(32U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(32U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(32U, MMIN_val); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateSDiv( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 2), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 2), + 32, true)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->builder.CreateNeg(this->gen_const(32U, 1)); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 155); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 156: DIVU */ + std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIVU"); + + this->gen_sync(PRE_SYNC, 156); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateUDiv( + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(32U, 1)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 156); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 157: REM */ + std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REM"); + + this->gen_sync(PRE_SYNC, 157); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint32_t M1_val = - 1; + uint32_t XLM1_val = 32 - 1; + uint32_t ONE_val = 1; + uint32_t MMIN_val = ONE_val << XLM1_val; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_const(32U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(32U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(32U, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateSRem( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 2), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 2), + 32, true)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 157); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 158: REMU */ + std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REMU"); + + this->gen_sync(PRE_SYNC, 158); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateURem( + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 158); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -8554,24 +8809,21 @@ template std::tuple vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 + enum {TRAP_ID=1<<16}; code_word_t insn = 0; const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); - try { - auto *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); + auto *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(TRAP_ID, pc.val); + if ((insn & 0x3) == 0x3) { // this is a 32bit instruction + res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); } - } catch (trap_access &ta) { - throw trap_access(ta.id, pc.val); + } else { + auto res = this->core.read(paddr, 4, data); + if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); } if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index c867a5e..b3a3cc3 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -46,7 +46,7 @@ namespace iss { namespace vm { namespace fp_impl { -void add_fp_functions_2_module(llvm::Module *, unsigned); +void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned); } } @@ -88,7 +88,7 @@ protected: void setup_module(Module* m) override { super::setup_module(m); - iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN); } inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { @@ -188,14 +188,70 @@ private: const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ + /* instruction JALR */ + {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr}, + /* instruction C.ADDI4SPN */ + {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, + /* instruction C.LW */ + {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, + /* instruction C.SW */ + {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, + /* instruction C.ADDI */ + {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, + /* instruction C.NOP */ + {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, + /* instruction C.JAL */ + {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, + /* instruction C.LI */ + {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li}, + /* instruction C.LUI */ + {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui}, + /* instruction C.ADDI16SP */ + {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, + /* instruction C.SRLI */ + {16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli}, + /* instruction C.SRAI */ + {16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai}, + /* instruction C.ANDI */ + {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, + /* instruction C.SUB */ + {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub}, + /* instruction C.XOR */ + {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor}, + /* instruction C.OR */ + {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or}, + /* instruction C.AND */ + {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and}, + /* instruction C.J */ + {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j}, + /* instruction C.BEQZ */ + {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz}, + /* instruction C.BNEZ */ + {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, + /* instruction C.SLLI */ + {16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli}, + /* instruction C.LWSP */ + {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, + /* instruction C.MV */ + {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, + /* instruction C.JR */ + {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, + /* instruction C.ADD */ + {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, + /* instruction C.JALR */ + {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, + /* instruction C.EBREAK */ + {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, + /* instruction C.SWSP */ + {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, + /* instruction DII */ + {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, &this_class::__auipc}, /* instruction JAL */ {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, &this_class::__jal}, - /* instruction JALR */ - {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr}, /* instruction BEQ */ {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, &this_class::__beq}, /* instruction BNE */ @@ -292,22 +348,6 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, - /* instruction MUL */ - {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, - /* instruction MULH */ - {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, - /* instruction MULHSU */ - {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, - /* instruction MULHU */ - {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, - /* instruction DIV */ - {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, - /* instruction DIVU */ - {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, - /* instruction REM */ - {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, - /* instruction REMU */ - {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, /* instruction LR.W */ {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, /* instruction SC.W */ @@ -330,187 +370,30 @@ private: {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, /* instruction AMOMAXU.W */ {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, - /* instruction C.ADDI4SPN */ - {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, - /* instruction C.LW */ - {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, - /* instruction C.SW */ - {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, - /* instruction C.ADDI */ - {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, - /* instruction C.NOP */ - {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, - /* instruction C.JAL */ - {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, - /* instruction C.LI */ - {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li}, - /* instruction C.LUI */ - {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui}, - /* instruction C.ADDI16SP */ - {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, - /* instruction C.SRLI */ - {16, 0b1000000000000001, 0b1111110000000011, &this_class::__c_srli}, - /* instruction C.SRAI */ - {16, 0b1000010000000001, 0b1111110000000011, &this_class::__c_srai}, - /* instruction C.ANDI */ - {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, - /* instruction C.SUB */ - {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub}, - /* instruction C.XOR */ - {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor}, - /* instruction C.OR */ - {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or}, - /* instruction C.AND */ - {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and}, - /* instruction C.J */ - {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j}, - /* instruction C.BEQZ */ - {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz}, - /* instruction C.BNEZ */ - {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, - /* instruction C.SLLI */ - {16, 0b0000000000000010, 0b1111000000000011, &this_class::__c_slli}, - /* instruction C.LWSP */ - {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, - /* instruction C.MV */ - {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, - /* instruction C.JR */ - {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, - /* instruction C.ADD */ - {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, - /* instruction C.JALR */ - {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, - /* instruction C.EBREAK */ - {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, - /* instruction C.SWSP */ - {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, - /* instruction DII */ - {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, + /* instruction MUL */ + {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, + /* instruction MULH */ + {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, + /* instruction MULHSU */ + {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, + /* instruction MULHU */ + {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, + /* instruction DIV */ + {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, + /* instruction DIVU */ + {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, + /* instruction REM */ + {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, + /* instruction REMU */ + {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, }}; /* instruction definitions */ - /* instruction 0: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LUI"); - - this->gen_sync(PRE_SYNC, 0); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 0); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 1: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AUIPC"); - - this->gen_sync(PRE_SYNC, 1); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 1); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 2: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("JAL"); - - this->gen_sync(PRE_SYNC, 2); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 2); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 3: JALR */ + /* instruction 0: JALR */ std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); - this->gen_sync(PRE_SYNC, 3); + this->gen_sync(PRE_SYNC, 0); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -538,7 +421,7 @@ private: this->gen_const(32U, imm)); Value* align_val = this->builder.CreateAnd( new_pc_val, - this->gen_const(32U, 0x1)); + this->gen_const(32U, 0x2)); { BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); @@ -573,16 +456,1150 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - this->gen_sync(POST_SYNC, 3); + this->gen_sync(POST_SYNC, 0); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 4: BEQ */ + /* instruction 1: C.ADDI4SPN */ + std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI4SPN"); + + this->gen_sync(PRE_SYNC, 1); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint16_t imm = ((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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(imm == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 1); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 2: C.LW */ + std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LW"); + + this->gen_sync(PRE_SYNC, 2); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.lw"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 2); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 3: C.SW */ + std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SW"); + + this->gen_sync(PRE_SYNC, 3); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.sw"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 3); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 4: C.ADDI */ + std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI"); + + this->gen_sync(PRE_SYNC, 4); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 4); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 5: C.NOP */ + std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.NOP"); + + this->gen_sync(PRE_SYNC, 5); + + 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(POST_SYNC, 5); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 6: C.JAL */ + std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JAL"); + + this->gen_sync(PRE_SYNC, 6); + + int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 6); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 7: C.LI */ + std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LI"); + + this->gen_sync(PRE_SYNC, 7); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(rd == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 7); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 8: C.LUI */ + std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LUI"); + + this->gen_sync(PRE_SYNC, 8); + + int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(rd == 0){ + this->gen_raise_trap(0, 2); + } + if(imm == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 8); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 9: C.ADDI16SP */ + std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI16SP"); + + this->gen_sync(PRE_SYNC, 9); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(2 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 9); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 10: C.SRLI */ + std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SRLI"); + + this->gen_sync(PRE_SYNC, 10); + + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 10); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 11: C.SRAI */ + std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SRAI"); + + this->gen_sync(PRE_SYNC, 11); + + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 11); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 12: C.ANDI */ + std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ANDI"); + + this->gen_sync(PRE_SYNC, 12); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 12); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 13: C.SUB */ + std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SUB"); + + this->gen_sync(PRE_SYNC, 13); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 13); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 14: C.XOR */ + std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.XOR"); + + this->gen_sync(PRE_SYNC, 14); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 14); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 15: C.OR */ + std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.OR"); + + this->gen_sync(PRE_SYNC, 15); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 15); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 16: C.AND */ + std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.AND"); + + this->gen_sync(PRE_SYNC, 16); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = rd + 8; + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 16); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 17: C.J */ + std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.J"); + + this->gen_sync(PRE_SYNC, 17); + + int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 17); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 18: C.BEQZ */ + std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.BEQZ"); + + this->gen_sync(PRE_SYNC, 18); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 18); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 19: C.BNEZ */ + std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.BNEZ"); + + this->gen_sync(PRE_SYNC, 19); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 19); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 20: C.SLLI */ + std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SLLI"); + + this->gen_sync(PRE_SYNC, 20); + + uint8_t shamt = ((bit_sub<2,5>(instr))); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), + fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + if(rs1 == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 20); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 21: C.LWSP */ + std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LWSP"); + + this->gen_sync(PRE_SYNC, 21); + + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 21); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 22: C.MV */ + std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.MV"); + + this->gen_sync(PRE_SYNC, 22); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 22); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 23: C.JR */ + std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JR"); + + this->gen_sync(PRE_SYNC, 23); + + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), + fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 23); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 24: C.ADD */ + std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADD"); + + this->gen_sync(PRE_SYNC, 24); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rd + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 24); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 25: C.JALR */ + std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JALR"); + + this->gen_sync(PRE_SYNC, 25); + + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), + fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 2)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 25); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 26: C.EBREAK */ + std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.EBREAK"); + + this->gen_sync(PRE_SYNC, 26); + + 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(POST_SYNC, 26); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 27: C.SWSP */ + std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SWSP"); + + this->gen_sync(PRE_SYNC, 27); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "c.swsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 27); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 28: DII */ + std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DII"); + + this->gen_sync(PRE_SYNC, 28); + + 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(POST_SYNC, 28); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 29: LUI */ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LUI"); + + this->gen_sync(PRE_SYNC, 29); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 29); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 30: AUIPC */ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(PRE_SYNC, 30); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 30); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 31: JAL */ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(PRE_SYNC, 31); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 31); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 32: BEQ */ std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); - this->gen_sync(PRE_SYNC, 4); + this->gen_sync(PRE_SYNC, 32); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -620,16 +1637,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 4); + this->gen_sync(POST_SYNC, 32); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 5: BNE */ + /* instruction 33: BNE */ std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); - this->gen_sync(PRE_SYNC, 5); + this->gen_sync(PRE_SYNC, 33); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -667,16 +1684,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 5); + this->gen_sync(POST_SYNC, 33); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 6: BLT */ + /* instruction 34: BLT */ std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); - this->gen_sync(PRE_SYNC, 6); + this->gen_sync(PRE_SYNC, 34); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -718,16 +1735,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 6); + this->gen_sync(POST_SYNC, 34); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 7: BGE */ + /* instruction 35: BGE */ std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); - this->gen_sync(PRE_SYNC, 7); + this->gen_sync(PRE_SYNC, 35); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -769,16 +1786,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 7); + this->gen_sync(POST_SYNC, 35); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 8: BLTU */ + /* instruction 36: BLTU */ std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); - this->gen_sync(PRE_SYNC, 8); + this->gen_sync(PRE_SYNC, 36); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -816,16 +1833,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 8); + this->gen_sync(POST_SYNC, 36); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 9: BGEU */ + /* instruction 37: BGEU */ std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); - this->gen_sync(PRE_SYNC, 9); + this->gen_sync(PRE_SYNC, 37); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -863,16 +1880,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 9); + this->gen_sync(POST_SYNC, 37); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 10: LB */ + /* instruction 38: LB */ std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); - this->gen_sync(PRE_SYNC, 10); + this->gen_sync(PRE_SYNC, 38); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -906,17 +1923,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 10); + this->gen_sync(POST_SYNC, 38); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 11: LH */ + /* instruction 39: LH */ std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); - this->gen_sync(PRE_SYNC, 11); + this->gen_sync(PRE_SYNC, 39); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -950,17 +1967,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 11); + this->gen_sync(POST_SYNC, 39); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 12: LW */ + /* instruction 40: LW */ std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); - this->gen_sync(PRE_SYNC, 12); + this->gen_sync(PRE_SYNC, 40); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -994,17 +2011,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 12); + this->gen_sync(POST_SYNC, 40); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 13: LBU */ + /* instruction 41: LBU */ std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); - this->gen_sync(PRE_SYNC, 13); + this->gen_sync(PRE_SYNC, 41); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1038,17 +2055,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 13); + this->gen_sync(POST_SYNC, 41); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 14: LHU */ + /* instruction 42: LHU */ std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); - this->gen_sync(PRE_SYNC, 14); + this->gen_sync(PRE_SYNC, 42); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1082,17 +2099,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 14); + this->gen_sync(POST_SYNC, 42); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 15: SB */ + /* instruction 43: SB */ std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); - this->gen_sync(PRE_SYNC, 15); + this->gen_sync(PRE_SYNC, 43); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1124,17 +2141,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 15); + this->gen_sync(POST_SYNC, 43); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 16: SH */ + /* instruction 44: SH */ std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); - this->gen_sync(PRE_SYNC, 16); + this->gen_sync(PRE_SYNC, 44); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1166,17 +2183,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 16); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 17: SW */ + /* instruction 45: SW */ std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); - this->gen_sync(PRE_SYNC, 17); + this->gen_sync(PRE_SYNC, 45); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1208,17 +2225,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 17); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 18: ADDI */ + /* instruction 46: ADDI */ std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); - this->gen_sync(PRE_SYNC, 18); + this->gen_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1248,17 +2265,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 18); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 19: SLTI */ + /* instruction 47: SLTI */ std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); - this->gen_sync(PRE_SYNC, 19); + this->gen_sync(PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1293,17 +2310,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 19); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 20: SLTIU */ + /* instruction 48: SLTIU */ std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_sync(PRE_SYNC, 20); + this->gen_sync(PRE_SYNC, 48); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1337,17 +2354,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 20); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 21: XORI */ + /* instruction 49: XORI */ std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); - this->gen_sync(PRE_SYNC, 21); + this->gen_sync(PRE_SYNC, 49); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1377,17 +2394,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 21); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 22: ORI */ + /* instruction 50: ORI */ std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); - this->gen_sync(PRE_SYNC, 22); + this->gen_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1417,17 +2434,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 22); + this->gen_sync(POST_SYNC, 50); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 23: ANDI */ + /* instruction 51: ANDI */ std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); - this->gen_sync(PRE_SYNC, 23); + this->gen_sync(PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1457,17 +2474,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 23); + this->gen_sync(POST_SYNC, 51); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 24: SLLI */ + /* instruction 52: SLLI */ std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLLI"); - this->gen_sync(PRE_SYNC, 24); + this->gen_sync(PRE_SYNC, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1499,17 +2516,17 @@ private: } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 24); + this->gen_sync(POST_SYNC, 52); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 25: SRLI */ + /* instruction 53: SRLI */ std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRLI"); - this->gen_sync(PRE_SYNC, 25); + this->gen_sync(PRE_SYNC, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1541,17 +2558,17 @@ private: } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 25); + this->gen_sync(POST_SYNC, 53); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 26: SRAI */ + /* instruction 54: SRAI */ std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRAI"); - this->gen_sync(PRE_SYNC, 26); + this->gen_sync(PRE_SYNC, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1583,17 +2600,17 @@ private: } } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 26); + this->gen_sync(POST_SYNC, 54); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 27: ADD */ + /* instruction 55: ADD */ std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); - this->gen_sync(PRE_SYNC, 27); + this->gen_sync(PRE_SYNC, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1621,17 +2638,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 27); + this->gen_sync(POST_SYNC, 55); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 28: SUB */ + /* instruction 56: SUB */ std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); - this->gen_sync(PRE_SYNC, 28); + this->gen_sync(PRE_SYNC, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1659,17 +2676,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 28); + this->gen_sync(POST_SYNC, 56); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 29: SLL */ + /* instruction 57: SLL */ std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); - this->gen_sync(PRE_SYNC, 29); + this->gen_sync(PRE_SYNC, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1701,17 +2718,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 29); + this->gen_sync(POST_SYNC, 57); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 30: SLT */ + /* instruction 58: SLT */ std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); - this->gen_sync(PRE_SYNC, 30); + this->gen_sync(PRE_SYNC, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1748,17 +2765,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 30); + this->gen_sync(POST_SYNC, 58); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 31: SLTU */ + /* instruction 59: SLTU */ std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); - this->gen_sync(PRE_SYNC, 31); + this->gen_sync(PRE_SYNC, 59); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1797,17 +2814,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 31); + this->gen_sync(POST_SYNC, 59); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 32: XOR */ + /* instruction 60: XOR */ std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); - this->gen_sync(PRE_SYNC, 32); + this->gen_sync(PRE_SYNC, 60); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1835,17 +2852,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 32); + this->gen_sync(POST_SYNC, 60); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 33: SRL */ + /* instruction 61: SRL */ std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); - this->gen_sync(PRE_SYNC, 33); + this->gen_sync(PRE_SYNC, 61); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1877,17 +2894,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 33); + this->gen_sync(POST_SYNC, 61); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 34: SRA */ + /* instruction 62: SRA */ std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); - this->gen_sync(PRE_SYNC, 34); + this->gen_sync(PRE_SYNC, 62); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1919,17 +2936,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 34); + this->gen_sync(POST_SYNC, 62); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 35: OR */ + /* instruction 63: OR */ std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); - this->gen_sync(PRE_SYNC, 35); + this->gen_sync(PRE_SYNC, 63); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1957,17 +2974,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 35); + this->gen_sync(POST_SYNC, 63); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 36: AND */ + /* instruction 64: AND */ std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); - this->gen_sync(PRE_SYNC, 36); + this->gen_sync(PRE_SYNC, 64); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1995,17 +3012,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 36); + this->gen_sync(POST_SYNC, 64); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 37: FENCE */ + /* instruction 65: FENCE */ std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); - this->gen_sync(PRE_SYNC, 37); + this->gen_sync(PRE_SYNC, 65); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2034,17 +3051,17 @@ private: this->gen_const(64U, 0), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 37); + this->gen_sync(POST_SYNC, 65); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 38: FENCE_I */ + /* instruction 66: FENCE_I */ std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_sync(PRE_SYNC, 38); + this->gen_sync(PRE_SYNC, 66); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2069,16 +3086,16 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 38); + this->gen_sync(POST_SYNC, 66); this->gen_trap_check(this->leave_blk); return std::make_tuple(FLUSH, nullptr); } - /* instruction 39: ECALL */ + /* instruction 67: ECALL */ std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ECALL"); - this->gen_sync(PRE_SYNC, 39); + this->gen_sync(PRE_SYNC, 67); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2094,16 +3111,16 @@ private: pc=pc+4; this->gen_raise_trap(0, 11); - this->gen_sync(POST_SYNC, 39); + this->gen_sync(POST_SYNC, 67); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 40: EBREAK */ + /* instruction 68: EBREAK */ std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_sync(PRE_SYNC, 40); + this->gen_sync(PRE_SYNC, 68); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2119,16 +3136,16 @@ private: pc=pc+4; this->gen_raise_trap(0, 3); - this->gen_sync(POST_SYNC, 40); + this->gen_sync(POST_SYNC, 68); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 41: URET */ + /* instruction 69: URET */ std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("URET"); - this->gen_sync(PRE_SYNC, 41); + this->gen_sync(PRE_SYNC, 69); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2144,16 +3161,16 @@ private: pc=pc+4; this->gen_leave_trap(0); - this->gen_sync(POST_SYNC, 41); + this->gen_sync(POST_SYNC, 69); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 42: SRET */ + /* instruction 70: SRET */ std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRET"); - this->gen_sync(PRE_SYNC, 42); + this->gen_sync(PRE_SYNC, 70); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2169,16 +3186,16 @@ private: pc=pc+4; this->gen_leave_trap(1); - this->gen_sync(POST_SYNC, 42); + this->gen_sync(POST_SYNC, 70); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 43: MRET */ + /* instruction 71: MRET */ std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MRET"); - this->gen_sync(PRE_SYNC, 43); + this->gen_sync(PRE_SYNC, 71); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2194,16 +3211,16 @@ private: pc=pc+4; this->gen_leave_trap(3); - this->gen_sync(POST_SYNC, 43); + this->gen_sync(POST_SYNC, 71); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 44: WFI */ + /* instruction 72: WFI */ std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("WFI"); - this->gen_sync(PRE_SYNC, 44); + this->gen_sync(PRE_SYNC, 72); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2220,17 +3237,17 @@ private: this->gen_wait(1); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 44); + this->gen_sync(POST_SYNC, 72); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 45: SFENCE.VMA */ + /* instruction 73: SFENCE.VMA */ std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_sync(PRE_SYNC, 45); + this->gen_sync(PRE_SYNC, 73); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2258,17 +3275,17 @@ private: this->gen_const(64U, 3), this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 45); + this->gen_sync(POST_SYNC, 73); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 46: CSRRW */ + /* instruction 74: CSRRW */ std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_sync(PRE_SYNC, 46); + this->gen_sync(PRE_SYNC, 74); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2307,17 +3324,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 46); + this->gen_sync(POST_SYNC, 74); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 47: CSRRS */ + /* instruction 75: CSRRS */ std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_sync(PRE_SYNC, 47); + this->gen_sync(PRE_SYNC, 75); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2354,17 +3371,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 47); + this->gen_sync(POST_SYNC, 75); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 48: CSRRC */ + /* instruction 76: CSRRC */ std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_sync(PRE_SYNC, 48); + this->gen_sync(PRE_SYNC, 76); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2401,17 +3418,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 48); + this->gen_sync(POST_SYNC, 76); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 49: CSRRWI */ + /* instruction 77: CSRRWI */ std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_sync(PRE_SYNC, 49); + this->gen_sync(PRE_SYNC, 77); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2445,17 +3462,17 @@ private: this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 49); + this->gen_sync(POST_SYNC, 77); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 50: CSRRSI */ + /* instruction 78: CSRRSI */ std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_sync(PRE_SYNC, 50); + this->gen_sync(PRE_SYNC, 78); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2494,17 +3511,17 @@ private: this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 50); + this->gen_sync(POST_SYNC, 78); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 51: CSRRCI */ + /* instruction 79: CSRRCI */ std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_sync(PRE_SYNC, 51); + this->gen_sync(PRE_SYNC, 79); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2543,615 +3560,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 51); + this->gen_sync(POST_SYNC, 79); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 52: MUL */ - std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MUL"); - - this->gen_sync(PRE_SYNC, 52); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - false)); - Value* Xtmp0_val = this->gen_ext( - res_val, - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 52); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 53: MULH */ - std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MULH"); - - this->gen_sync(PRE_SYNC, 53); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - true)); - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - this->gen_const(32U, 32)), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 53); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 54: MULHSU */ - std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MULHSU"); - - this->gen_sync(PRE_SYNC, 54); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - false)); - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - this->gen_const(32U, 32)), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 54); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 55: MULHU */ - std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MULHU"); - - this->gen_sync(PRE_SYNC, 55); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateMul( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 128, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 128, - false)); - Value* Xtmp0_val = this->gen_ext( - this->builder.CreateLShr( - res_val, - this->gen_const(32U, 32)), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 55); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 56: DIV */ - std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("DIV"); - - this->gen_sync(PRE_SYNC, 56); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - uint32_t M1_val = - 1; - uint32_t MMIN_val = - 1 << 32 - 1; - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, true), - this->gen_ext( - this->gen_const(32U, MMIN_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, true), - this->gen_ext( - this->gen_const(32U, M1_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->gen_const(32U, MMIN_val); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->builder.CreateSDiv( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 3), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 3), - 32, true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp2_val = this->builder.CreateSDiv( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 2), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp3_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 56); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 57: DIVU */ - std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("DIVU"); - - this->gen_sync(PRE_SYNC, 57); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->builder.CreateUDiv( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 1), - 32, - false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(32U, 1)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 57); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 58: REM */ - std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("REM"); - - this->gen_sync(PRE_SYNC, 58); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - uint32_t M1_val = - 1; - uint32_t MMIN_val = - 1 << 32 - 1; - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, true), - this->gen_ext( - this->gen_const(32U, MMIN_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); - // this->builder.SetInsertPoint(bb); - this->gen_cond_branch(this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, true), - this->gen_ext( - this->gen_const(32U, M1_val), - 32, true)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->gen_const(32U, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 3), - 32, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 3), - 32, - true)); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp2_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 2), - 32, - true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 2), - 32, - true)); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp3_val = this->gen_reg_load(rs1 + traits::X0, 1); - this->builder.CreateStore(Xtmp3_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 58); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 59: REMU */ - std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("REMU"); - - this->gen_sync(PRE_SYNC, 59); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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(rs2 + traits::X0, 0), - this->gen_const(32U, 0)), - bb_then, - bb_else); - this->builder.SetInsertPoint(bb_then); - { - Value* Xtmp0_val = this->builder.CreateURem( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 1), - 32, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 1), - 32, - false)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 59); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 60: LR.W */ + /* instruction 80: LR.W */ std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); - this->gen_sync(PRE_SYNC, 60); + this->gen_sync(PRE_SYNC, 80); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3190,17 +3609,17 @@ private: this->builder.CreateZExtOrTrunc(REStmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 60); + this->gen_sync(POST_SYNC, 80); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 61: SC.W */ + /* instruction 81: SC.W */ std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); - this->gen_sync(PRE_SYNC, 61); + this->gen_sync(PRE_SYNC, 81); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3252,24 +3671,27 @@ private: this->builder.CreateICmp( ICmpInst::ICMP_NE, res1_val, - this->gen_const(32U, 0)), + this->gen_ext( + this->gen_const(32U, 0), + 32, + false)), this->gen_const(32U, 0), this->gen_const(32U, 1), 32); this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 61); + this->gen_sync(POST_SYNC, 81); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 62: AMOSWAP.W */ + /* instruction 82: AMOSWAP.W */ std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); - this->gen_sync(PRE_SYNC, 62); + this->gen_sync(PRE_SYNC, 82); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3306,17 +3728,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 62); + this->gen_sync(POST_SYNC, 82); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 63: AMOADD.W */ + /* instruction 83: AMOADD.W */ std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); - this->gen_sync(PRE_SYNC, 63); + this->gen_sync(PRE_SYNC, 83); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3357,17 +3779,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 63); + this->gen_sync(POST_SYNC, 83); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 64: AMOXOR.W */ + /* instruction 84: AMOXOR.W */ std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); - this->gen_sync(PRE_SYNC, 64); + this->gen_sync(PRE_SYNC, 84); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3408,17 +3830,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 64); + this->gen_sync(POST_SYNC, 84); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 65: AMOAND.W */ + /* instruction 85: AMOAND.W */ std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); - this->gen_sync(PRE_SYNC, 65); + this->gen_sync(PRE_SYNC, 85); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3459,17 +3881,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 65); + this->gen_sync(POST_SYNC, 85); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 66: AMOOR.W */ + /* instruction 86: AMOOR.W */ std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); - this->gen_sync(PRE_SYNC, 66); + this->gen_sync(PRE_SYNC, 86); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3510,17 +3932,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 66); + this->gen_sync(POST_SYNC, 86); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 67: AMOMIN.W */ + /* instruction 87: AMOMIN.W */ std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); - this->gen_sync(PRE_SYNC, 67); + this->gen_sync(PRE_SYNC, 87); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3570,17 +3992,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 67); + this->gen_sync(POST_SYNC, 87); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 68: AMOMAX.W */ + /* instruction 88: AMOMAX.W */ std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); - this->gen_sync(PRE_SYNC, 68); + this->gen_sync(PRE_SYNC, 88); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3630,17 +4052,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 68); + this->gen_sync(POST_SYNC, 88); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 69: AMOMINU.W */ + /* instruction 89: AMOMINU.W */ std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); - this->gen_sync(PRE_SYNC, 69); + this->gen_sync(PRE_SYNC, 89); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3667,7 +4089,7 @@ private: Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, - false); + true); if(rd != 0){ Value* Xtmp0_val = res1_val; this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); @@ -3686,17 +4108,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 69); + this->gen_sync(POST_SYNC, 89); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 70: AMOMAXU.W */ + /* instruction 90: AMOMAXU.W */ std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); - this->gen_sync(PRE_SYNC, 70); + this->gen_sync(PRE_SYNC, 90); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3723,7 +4145,7 @@ private: Value* res1_val = this->gen_ext( this->gen_read_mem(traits::MEM, offs_val, 32/8), 32, - false); + true); if(rd != 0){ Value* Xtmp0_val = res1_val; this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); @@ -3742,773 +4164,26 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 70); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 71: C.ADDI4SPN */ - std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDI4SPN"); - - this->gen_sync(PRE_SYNC, 71); - - uint8_t rd = ((bit_sub<2,3>(instr))); - uint16_t imm = ((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 */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(imm == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 71); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 72: C.LW */ - std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LW"); - - this->gen_sync(PRE_SYNC, 72); - - uint8_t rd = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {uimm:#05x}", fmt::arg("mnemonic", "c.lw"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs1", name(8+rs1)), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 72); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 73: C.SW */ - std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SW"); - - this->gen_sync(PRE_SYNC, 73); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {uimm:#05x}", fmt::arg("mnemonic", "c.sw"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 73); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 74: C.ADDI */ - std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDI"); - - this->gen_sync(PRE_SYNC, 74); - - int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), - fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 74); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 75: C.NOP */ - std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.NOP"); - - this->gen_sync(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(POST_SYNC, 75); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 76: C.JAL */ - std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.JAL"); - - this->gen_sync(PRE_SYNC, 76); - - int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), - fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 76); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 77: C.LI */ - std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LI"); - - this->gen_sync(PRE_SYNC, 77); - - int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(rd == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 77); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 78: C.LUI */ - std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LUI"); - - this->gen_sync(PRE_SYNC, 78); - - int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); - uint8_t rd = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(rd == 0){ - this->gen_raise_trap(0, 2); - } - if(imm == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 78); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 79: C.ADDI16SP */ - std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDI16SP"); - - this->gen_sync(PRE_SYNC, 79); - - int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), - fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(2 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 79); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 80: C.SRLI */ - std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SRLI"); - - this->gen_sync(PRE_SYNC, 80); - - uint8_t shamt = ((bit_sub<2,5>(instr))); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rs1 + 8; - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 80); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 81: C.SRAI */ - std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SRAI"); - - this->gen_sync(PRE_SYNC, 81); - - uint8_t shamt = ((bit_sub<2,5>(instr))); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rs1 + 8; - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 81); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 82: C.ANDI */ - std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ANDI"); - - this->gen_sync(PRE_SYNC, 82); - - uint8_t imm = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rs1 + 8; - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rs1_idx_val + traits::X0, 0), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 82); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 83: C.SUB */ - std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SUB"); - - this->gen_sync(PRE_SYNC, 83); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 83); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 84: C.XOR */ - std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.XOR"); - - this->gen_sync(PRE_SYNC, 84); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 84); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 85: C.OR */ - std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.OR"); - - this->gen_sync(PRE_SYNC, 85); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 85); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 86: C.AND */ - std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.AND"); - - this->gen_sync(PRE_SYNC, 86); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), - fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = rd + 8; - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rd_idx_val + traits::X0, 0), - this->gen_reg_load(rs2 + 8 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 86); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 87: C.J */ - std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.J"); - - this->gen_sync(PRE_SYNC, 87); - - int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), - fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 87); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 88: C.BEQZ */ - std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.BEQZ"); - - this->gen_sync(PRE_SYNC, 88); - - int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 88); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 89: C.BNEZ */ - std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.BNEZ"); - - this->gen_sync(PRE_SYNC, 89); - - int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), - fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_NE, - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 89); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 90: C.SLLI */ - std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SLLI"); - - this->gen_sync(PRE_SYNC, 90); - - uint8_t shamt = ((bit_sub<2,5>(instr))); - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), - fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; - - if(rs1 == 0){ - this->gen_raise_trap(0, 2); - } - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 90); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 91: C.LWSP */ - std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LWSP"); + /* instruction 91: MUL */ + std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MUL"); this->gen_sync(PRE_SYNC, 91); - uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), - fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -4518,13 +4193,24 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* Xtmp0_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 91); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -4532,19 +4218,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 92: C.MV */ - std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.MV"); + /* instruction 92: MULH */ + std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULH"); this->gen_sync(PRE_SYNC, 92); - uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -4554,10 +4241,26 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + true)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(32U, 32)), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 92); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -4565,18 +4268,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 93: C.JR */ - std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.JR"); + /* instruction 93: MULHSU */ + std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULHSU"); this->gen_sync(PRE_SYNC, 93); - uint8_t rs1 = ((bit_sub<7,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), - fmt::arg("rs1", name(rs1))); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -4586,29 +4291,47 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(32U, 32)), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 93); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 94: C.ADD */ - std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADD"); + /* instruction 94: MULHU */ + std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULHU"); this->gen_sync(PRE_SYNC, 94); - uint8_t rs2 = ((bit_sub<2,5>(instr))); uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), - fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -4618,12 +4341,26 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(rd + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(32U, 32)), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 94); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -4631,18 +4368,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 95: C.JALR */ - std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.JALR"); + /* instruction 95: DIV */ + std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIV"); this->gen_sync(PRE_SYNC, 95); - uint8_t rs1 = ((bit_sub<7,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), - fmt::arg("rs1", name(rs1))); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -4652,58 +4391,96 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 2)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); - Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint32_t M1_val = - 1; + uint8_t XLM1_val = 32 - 1; + uint32_t ONE_val = 1; + uint32_t MMIN_val = ONE_val << XLM1_val; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_const(32U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(32U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(32U, MMIN_val); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateSDiv( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 2), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 2), + 32, true)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->builder.CreateNeg(this->gen_const(32U, 1)); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 95); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 96: C.EBREAK */ - std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.EBREAK"); + /* instruction 96: DIVU */ + std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIVU"); this->gen_sync(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(POST_SYNC, 96); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 97: C.SWSP */ - std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SWSP"); - - this->gen_sync(PRE_SYNC, 97); - - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} x2+{uimm:#05x}, {rs2}", fmt::arg("mnemonic", "c.swsp"), - fmt::arg("uimm", uimm), fmt::arg("rs2", name(rs2))); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -4713,16 +4490,137 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateUDiv( + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(32U, 1)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 96); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 97: REM */ + std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REM"); + + this->gen_sync(PRE_SYNC, 97); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint32_t M1_val = - 1; + uint32_t XLM1_val = 32 - 1; + uint32_t ONE_val = 1; + uint32_t MMIN_val = ONE_val << XLM1_val; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_const(32U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(32U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(32U, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateSRem( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 2), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 2), + 32, true)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 97); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -4730,26 +4628,61 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 98: DII */ - std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("DII"); + /* instruction 98: REMU */ + std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REMU"); this->gen_sync(PRE_SYNC, 98); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr("dii"), + this->builder.CreateGlobalStringPtr(mnemonic), }; this->builder.CreateCall(this->mod->getFunction("print_disass"), args); } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - this->gen_raise_trap(0, 2); + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateURem( + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 98); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -4800,24 +4733,21 @@ template std::tuple vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 + enum {TRAP_ID=1<<16}; code_word_t insn = 0; const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); - try { - auto *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); + auto *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(TRAP_ID, pc.val); + if ((insn & 0x3) == 0x3) { // this is a 32bit instruction + res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); } - } catch (trap_access &ta) { - throw trap_access(ta.id, pc.val); + } else { + auto res = this->core.read(paddr, 4, data); + if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); } if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack diff --git a/riscv/src/internal/vm_rv64gc.cpp b/riscv/src/internal/vm_rv64gc.cpp new file mode 100644 index 0000000..14eb8a4 --- /dev/null +++ b/riscv/src/internal/vm_rv64gc.cpp @@ -0,0 +1,11342 @@ +/******************************************************************************* + * Copyright (C) 2017, 2018 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 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +namespace iss { +namespace vm { +namespace fp_impl { +void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned); +} +} + +namespace rv64gc { +using namespace iss::arch; +using namespace llvm; +using namespace iss::debugger; +using namespace iss::vm::llvm; + +template class vm_impl : public vm_base { +public: + using super = typename iss::vm::llvm::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) override { + debugger_if::dbg_enabled = true; + if (vm_base::tgt_adapter == nullptr) + vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); + return vm_base::tgt_adapter; + } + +protected: + using vm_base::get_reg_ptr; + + inline const char *name(size_t index){return traits::reg_aliases.at(index);} + + template inline ConstantInt *size(T type) { + return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits())); + } + + void setup_module(Module* m) override { + super::setup_module(m); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN); + } + + inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { + return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size)); + } + + std::tuple gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override; + + void gen_leave_behavior(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(BasicBlock *) override; + + void gen_trap_check(BasicBlock *bb); + + inline 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) { + 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, + 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 */ + /* instruction JALR */ + {32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, &this_class::__jalr}, + /* instruction C.ADDI4SPN */ + {16, 0b0000000000000000, 0b1110000000000011, &this_class::__c_addi4spn}, + /* instruction C.LW */ + {16, 0b0100000000000000, 0b1110000000000011, &this_class::__c_lw}, + /* instruction C.SW */ + {16, 0b1100000000000000, 0b1110000000000011, &this_class::__c_sw}, + /* instruction C.ADDI */ + {16, 0b0000000000000001, 0b1110000000000011, &this_class::__c_addi}, + /* instruction C.NOP */ + {16, 0b0000000000000001, 0b1111111111111111, &this_class::__c_nop}, + /* instruction C.JAL */ + {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_jal}, + /* instruction C.LI */ + {16, 0b0100000000000001, 0b1110000000000011, &this_class::__c_li}, + /* instruction C.LUI */ + {16, 0b0110000000000001, 0b1110000000000011, &this_class::__c_lui}, + /* instruction C.ADDI16SP */ + {16, 0b0110000100000001, 0b1110111110000011, &this_class::__c_addi16sp}, + /* instruction C.SRLI */ + {16, 0b1000000000000001, 0b1110110000000011, &this_class::__c_srli}, + /* instruction C.SRAI */ + {16, 0b1000010000000001, 0b1110110000000011, &this_class::__c_srai}, + /* instruction C.ANDI */ + {16, 0b1000100000000001, 0b1110110000000011, &this_class::__c_andi}, + /* instruction C.SUB */ + {16, 0b1000110000000001, 0b1111110001100011, &this_class::__c_sub}, + /* instruction C.XOR */ + {16, 0b1000110000100001, 0b1111110001100011, &this_class::__c_xor}, + /* instruction C.OR */ + {16, 0b1000110001000001, 0b1111110001100011, &this_class::__c_or}, + /* instruction C.AND */ + {16, 0b1000110001100001, 0b1111110001100011, &this_class::__c_and}, + /* instruction C.J */ + {16, 0b1010000000000001, 0b1110000000000011, &this_class::__c_j}, + /* instruction C.BEQZ */ + {16, 0b1100000000000001, 0b1110000000000011, &this_class::__c_beqz}, + /* instruction C.BNEZ */ + {16, 0b1110000000000001, 0b1110000000000011, &this_class::__c_bnez}, + /* instruction C.SLLI */ + {16, 0b0000000000000010, 0b1110000000000011, &this_class::__c_slli}, + /* instruction C.LWSP */ + {16, 0b0100000000000010, 0b1110000000000011, &this_class::__c_lwsp}, + /* instruction C.MV */ + {16, 0b1000000000000010, 0b1111000000000011, &this_class::__c_mv}, + /* instruction C.JR */ + {16, 0b1000000000000010, 0b1111000001111111, &this_class::__c_jr}, + /* instruction C.ADD */ + {16, 0b1001000000000010, 0b1111000000000011, &this_class::__c_add}, + /* instruction C.JALR */ + {16, 0b1001000000000010, 0b1111000001111111, &this_class::__c_jalr}, + /* instruction C.EBREAK */ + {16, 0b1001000000000010, 0b1111111111111111, &this_class::__c_ebreak}, + /* instruction C.SWSP */ + {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, + /* instruction DII */ + {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, + /* instruction C.FLD */ + {16, 0b0010000000000000, 0b1110000000000011, &this_class::__c_fld}, + /* instruction C.FSD */ + {16, 0b1010000000000000, 0b1110000000000011, &this_class::__c_fsd}, + /* instruction C.FLDSP */ + {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_fldsp}, + /* instruction C.FSDSP */ + {16, 0b1010000000000010, 0b1110000000000011, &this_class::__c_fsdsp}, + /* instruction C.FLW */ + {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_flw}, + /* instruction C.FSW */ + {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_fsw}, + /* instruction C.FLWSP */ + {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, + /* instruction C.FSWSP */ + {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, + /* instruction LUI */ + {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, + /* instruction AUIPC */ + {32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, &this_class::__auipc}, + /* instruction JAL */ + {32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, &this_class::__jal}, + /* instruction BEQ */ + {32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, &this_class::__beq}, + /* instruction BNE */ + {32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, &this_class::__bne}, + /* instruction BLT */ + {32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, &this_class::__blt}, + /* instruction BGE */ + {32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, &this_class::__bge}, + /* instruction BLTU */ + {32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, &this_class::__bltu}, + /* instruction BGEU */ + {32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, &this_class::__bgeu}, + /* instruction LB */ + {32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, &this_class::__lb}, + /* instruction LH */ + {32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, &this_class::__lh}, + /* instruction LW */ + {32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, &this_class::__lw}, + /* instruction LBU */ + {32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, &this_class::__lbu}, + /* instruction LHU */ + {32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, &this_class::__lhu}, + /* instruction SB */ + {32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, &this_class::__sb}, + /* instruction SH */ + {32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, &this_class::__sh}, + /* instruction SW */ + {32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, &this_class::__sw}, + /* instruction ADDI */ + {32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, &this_class::__addi}, + /* instruction SLTI */ + {32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, &this_class::__slti}, + /* instruction SLTIU */ + {32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, &this_class::__sltiu}, + /* instruction XORI */ + {32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, &this_class::__xori}, + /* instruction ORI */ + {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori}, + /* instruction ANDI */ + {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, + /* instruction SLLI */ + {32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli}, + /* instruction SRLI */ + {32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli}, + /* instruction SRAI */ + {32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai}, + /* instruction ADD */ + {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, + /* instruction SUB */ + {32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__sub}, + /* instruction SLL */ + {32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__sll}, + /* instruction SLT */ + {32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__slt}, + /* instruction SLTU */ + {32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__sltu}, + /* instruction XOR */ + {32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__xor}, + /* instruction SRL */ + {32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__srl}, + /* instruction SRA */ + {32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__sra}, + /* instruction OR */ + {32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__or}, + /* instruction AND */ + {32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__and}, + /* instruction FENCE */ + {32, 0b00000000000000000000000000001111, 0b11110000000000000111000001111111, &this_class::__fence}, + /* instruction FENCE_I */ + {32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, &this_class::__fence_i}, + /* instruction ECALL */ + {32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, &this_class::__ecall}, + /* instruction EBREAK */ + {32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, &this_class::__ebreak}, + /* instruction URET */ + {32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__uret}, + /* instruction SRET */ + {32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__sret}, + /* instruction MRET */ + {32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, &this_class::__mret}, + /* instruction WFI */ + {32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, &this_class::__wfi}, + /* instruction SFENCE.VMA */ + {32, 0b00010010000000000000000001110011, 0b11111110000000000111111111111111, &this_class::__sfence_vma}, + /* instruction CSRRW */ + {32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, &this_class::__csrrw}, + /* instruction CSRRS */ + {32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, &this_class::__csrrs}, + /* instruction CSRRC */ + {32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, &this_class::__csrrc}, + /* instruction CSRRWI */ + {32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, &this_class::__csrrwi}, + /* instruction CSRRSI */ + {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, + /* instruction CSRRCI */ + {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, + /* instruction FLD */ + {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, + /* instruction FSD */ + {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd}, + /* instruction FMADD.D */ + {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d}, + /* instruction FMSUB.D */ + {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d}, + /* instruction FNMADD.D */ + {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d}, + /* instruction FNMSUB.D */ + {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d}, + /* instruction FADD.D */ + {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d}, + /* instruction FSUB.D */ + {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d}, + /* instruction FMUL.D */ + {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d}, + /* instruction FDIV.D */ + {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d}, + /* instruction FSQRT.D */ + {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d}, + /* instruction FSGNJ.D */ + {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d}, + /* instruction FSGNJN.D */ + {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d}, + /* instruction FSGNJX.D */ + {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d}, + /* instruction FMIN.D */ + {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d}, + /* instruction FMAX.D */ + {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d}, + /* instruction FCVT.S.D */ + {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d}, + /* instruction FCVT.D.S */ + {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s}, + /* instruction FEQ.D */ + {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d}, + /* instruction FLT.D */ + {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d}, + /* instruction FLE.D */ + {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d}, + /* instruction FCLASS.D */ + {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d}, + /* instruction FCVT.W.D */ + {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d}, + /* instruction FCVT.WU.D */ + {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d}, + /* instruction FCVT.D.W */ + {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, + /* instruction FCVT.D.WU */ + {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, + /* instruction FCVT.L.D */ + {32, 0b11000010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_l_d}, + /* instruction FCVT.LU.D */ + {32, 0b11000010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_lu_d}, + /* instruction FCVT.D.L */ + {32, 0b11010010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_l}, + /* instruction FCVT.D.LU */ + {32, 0b11010010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_lu}, + /* instruction FMV.X.D */ + {32, 0b11100010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_d}, + /* instruction FMV.D.X */ + {32, 0b11110010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_d_x}, + /* instruction FLW */ + {32, 0b00000000000000000010000000000111, 0b00000000000000000111000001111111, &this_class::__flw}, + /* instruction FSW */ + {32, 0b00000000000000000010000000100111, 0b00000000000000000111000001111111, &this_class::__fsw}, + /* instruction FMADD.S */ + {32, 0b00000000000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_s}, + /* instruction FMSUB.S */ + {32, 0b00000000000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_s}, + /* instruction FNMADD.S */ + {32, 0b00000000000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_s}, + /* instruction FNMSUB.S */ + {32, 0b00000000000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_s}, + /* instruction FADD.S */ + {32, 0b00000000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_s}, + /* instruction FSUB.S */ + {32, 0b00001000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_s}, + /* instruction FMUL.S */ + {32, 0b00010000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_s}, + /* instruction FDIV.S */ + {32, 0b00011000000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_s}, + /* instruction FSQRT.S */ + {32, 0b01011000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_s}, + /* instruction FSGNJ.S */ + {32, 0b00100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_s}, + /* instruction FSGNJN.S */ + {32, 0b00100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_s}, + /* instruction FSGNJX.S */ + {32, 0b00100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_s}, + /* instruction FMIN.S */ + {32, 0b00101000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_s}, + /* instruction FMAX.S */ + {32, 0b00101000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_s}, + /* instruction FCVT.W.S */ + {32, 0b11000000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_s}, + /* instruction FCVT.WU.S */ + {32, 0b11000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_s}, + /* instruction FEQ.S */ + {32, 0b10100000000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_s}, + /* instruction FLT.S */ + {32, 0b10100000000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_s}, + /* instruction FLE.S */ + {32, 0b10100000000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_s}, + /* instruction FCLASS.S */ + {32, 0b11100000000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_s}, + /* instruction FCVT.S.W */ + {32, 0b11010000000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_w}, + /* instruction FCVT.S.WU */ + {32, 0b11010000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_wu}, + /* instruction FMV.X.W */ + {32, 0b11100000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_w}, + /* instruction FMV.W.X */ + {32, 0b11110000000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_w_x}, + /* instruction FCVT.L.S */ + {32, 0b11000000001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_l_s}, + /* instruction FCVT.LU.S */ + {32, 0b11000000001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_lu_s}, + /* instruction FCVT.S.L */ + {32, 0b11010000001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_l}, + /* instruction FCVT.S.LU */ + {32, 0b11010000001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_lu}, + /* instruction MUL */ + {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, + /* instruction MULH */ + {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, + /* instruction MULHSU */ + {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, + /* instruction MULHU */ + {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, + /* instruction DIV */ + {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, + /* instruction DIVU */ + {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, + /* instruction REM */ + {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, + /* instruction REMU */ + {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, + /* instruction LR.W */ + {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, + /* instruction SC.W */ + {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, + /* instruction AMOSWAP.W */ + {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, + /* instruction AMOADD.W */ + {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, + /* instruction AMOXOR.W */ + {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, + /* instruction AMOAND.W */ + {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, + /* instruction AMOOR.W */ + {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, + /* instruction AMOMIN.W */ + {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, + /* instruction AMOMAX.W */ + {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, + /* instruction AMOMINU.W */ + {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, + /* instruction AMOMAXU.W */ + {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, + /* instruction LWU */ + {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, + /* instruction LD */ + {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld}, + /* instruction SD */ + {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd}, + /* instruction ADDIW */ + {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw}, + /* instruction SLLIW */ + {32, 0b00000000000000000001000000011011, 0b11111110000000000111000001111111, &this_class::__slliw}, + /* instruction SRLIW */ + {32, 0b00000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__srliw}, + /* instruction SRAIW */ + {32, 0b01000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__sraiw}, + /* instruction ADDW */ + {32, 0b00000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__addw}, + /* instruction SUBW */ + {32, 0b01000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__subw}, + /* instruction SLLW */ + {32, 0b00000000000000000001000000111011, 0b11111110000000000111000001111111, &this_class::__sllw}, + /* instruction SRLW */ + {32, 0b00000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__srlw}, + /* instruction SRAW */ + {32, 0b01000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__sraw}, + /* instruction MULW */ + {32, 0b00000010000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__mulw}, + /* instruction DIVW */ + {32, 0b00000010000000000100000000111011, 0b11111110000000000111000001111111, &this_class::__divw}, + /* instruction DIVUW */ + {32, 0b00000010000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__divuw}, + /* instruction REMW */ + {32, 0b00000010000000000110000000111011, 0b11111110000000000111000001111111, &this_class::__remw}, + /* instruction REMUW */ + {32, 0b00000010000000000111000000111011, 0b11111110000000000111000001111111, &this_class::__remuw}, + /* instruction LR.D */ + {32, 0b00010000000000000011000000101111, 0b11111001111100000111000001111111, &this_class::__lr_d}, + /* instruction SC.D */ + {32, 0b00011000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__sc_d}, + /* instruction AMOSWAP.D */ + {32, 0b00001000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_d}, + /* instruction AMOADD.D */ + {32, 0b00000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_d}, + /* instruction AMOXOR.D */ + {32, 0b00100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_d}, + /* instruction AMOAND.D */ + {32, 0b01100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_d}, + /* instruction AMOOR.D */ + {32, 0b01000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_d}, + /* instruction AMOMIN.D */ + {32, 0b10000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_d}, + /* instruction AMOMAX.D */ + {32, 0b10100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_d}, + /* instruction AMOMINU.D */ + {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d}, + /* instruction AMOMAXU.D */ + {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d}, + /* instruction C.LD */ + {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_ld}, + /* instruction C.SD */ + {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_sd}, + /* instruction C.SUBW */ + {16, 0b1001110000000001, 0b1111110001100011, &this_class::__c_subw}, + /* instruction C.ADDW */ + {16, 0b1001110000100001, 0b1111110001100011, &this_class::__c_addw}, + /* instruction C.ADDIW */ + {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_addiw}, + /* instruction C.LDSP */ + {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_ldsp}, + /* instruction C.SDSP */ + {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_sdsp}, + }}; + + /* instruction definitions */ + /* instruction 0: JALR */ + std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JALR"); + + this->gen_sync(PRE_SYNC, 0); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm:#0x}", fmt::arg("mnemonic", "jalr"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAnd( + new_pc_val, + this->builder.CreateNot(this->gen_const(64U, 0x1))); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 0); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 1: C.ADDI4SPN */ + std::tuple __c_addi4spn(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI4SPN"); + + this->gen_sync(PRE_SYNC, 1); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint16_t imm = ((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 */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.addi4spn"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + if(imm == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 1); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 2: C.LW */ + std::tuple __c_lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LW"); + + this->gen_sync(PRE_SYNC, 2); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.lw"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 2); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 3: C.SW */ + std::tuple __c_sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SW"); + + this->gen_sync(PRE_SYNC, 3); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}({rs1})", fmt::arg("mnemonic", "c.sw"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 3); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 4: C.ADDI */ + std::tuple __c_addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI"); + + this->gen_sync(PRE_SYNC, 4); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addi"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 4); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 5: C.NOP */ + std::tuple __c_nop(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.NOP"); + + this->gen_sync(PRE_SYNC, 5); + + 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(64, pc.val); + pc=pc+2; + + /* TODO: describe operations for C.NOP ! */ + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 5); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 6: C.JAL */ + std::tuple __c_jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JAL"); + + this->gen_sync(PRE_SYNC, 6); + + int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.jal"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 2)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 6); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 7: C.LI */ + std::tuple __c_li(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LI"); + + this->gen_sync(PRE_SYNC, 7); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.li"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + if(rd == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->gen_const(64U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 7); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 8: C.LUI */ + std::tuple __c_lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LUI"); + + this->gen_sync(PRE_SYNC, 8); + + int32_t imm = signextend((bit_sub<2,5>(instr) << 12) | (bit_sub<12,1>(instr) << 17)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "c.lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + if(rd == 0){ + this->gen_raise_trap(0, 2); + } + if(imm == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->gen_const(64U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 8); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 9: C.ADDI16SP */ + std::tuple __c_addi16sp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDI16SP"); + + this->gen_sync(PRE_SYNC, 9); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 7) | (bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 4) | (bit_sub<12,1>(instr) << 9)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.addi16sp"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(2 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(2 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 9); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 10: C.SRLI */ + std::tuple __c_srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SRLI"); + + this->gen_sync(PRE_SYNC, 10); + + uint8_t shamt = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srli"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 10); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 11: C.SRAI */ + std::tuple __c_srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SRAI"); + + this->gen_sync(PRE_SYNC, 11); + + uint8_t shamt = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.srai"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 11); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 12: C.ANDI */ + std::tuple __c_andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ANDI"); + + this->gen_sync(PRE_SYNC, 12); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.andi"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rs1_idx_val = rs1 + 8; + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1_idx_val + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 12); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 13: C.SUB */ + std::tuple __c_sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SUB"); + + this->gen_sync(PRE_SYNC, 13); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.sub"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rd_idx_val = rd + 8; + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 13); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 14: C.XOR */ + std::tuple __c_xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.XOR"); + + this->gen_sync(PRE_SYNC, 14); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.xor"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rd_idx_val = rd + 8; + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 14); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 15: C.OR */ + std::tuple __c_or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.OR"); + + this->gen_sync(PRE_SYNC, 15); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.or"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rd_idx_val = rd + 8; + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 15); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 16: C.AND */ + std::tuple __c_and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.AND"); + + this->gen_sync(PRE_SYNC, 16); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.and"), + fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + uint8_t rd_idx_val = rd + 8; + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rd_idx_val + traits::X0, 0), + this->gen_reg_load(rs2 + 8 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd_idx_val + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 16); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 17: C.J */ + std::tuple __c_j(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.J"); + + this->gen_sync(PRE_SYNC, 17); + + int16_t imm = signextend((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) | (bit_sub<12,1>(instr) << 11)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {imm:#05x}", fmt::arg("mnemonic", "c.j"), + fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 17); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 18: C.BEQZ */ + std::tuple __c_beqz(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.BEQZ"); + + this->gen_sync(PRE_SYNC, 18); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.beqz"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 2)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 18); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 19: C.BNEZ */ + std::tuple __c_bnez(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.BNEZ"); + + this->gen_sync(PRE_SYNC, 19); + + int16_t imm = signextend((bit_sub<2,1>(instr) << 5) | (bit_sub<3,2>(instr) << 1) | (bit_sub<5,2>(instr) << 6) | (bit_sub<10,2>(instr) << 3) | (bit_sub<12,1>(instr) << 8)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.bnez"), + fmt::arg("rs1", name(8+rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* PC_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 2)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 19); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 20: C.SLLI */ + std::tuple __c_slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SLLI"); + + this->gen_sync(PRE_SYNC, 20); + + uint8_t shamt = ((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {shamt}", fmt::arg("mnemonic", "c.slli"), + fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + if(rs1 == 0){ + this->gen_raise_trap(0, 2); + } + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 20); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 21: C.LWSP */ + std::tuple __c_lwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LWSP"); + + this->gen_sync(PRE_SYNC, 21); + + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, sp, {uimm:#05x}", fmt::arg("mnemonic", "c.lwsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 21); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 22: C.MV */ + std::tuple __c_mv(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.MV"); + + this->gen_sync(PRE_SYNC, 22); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.mv"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 22); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 23: C.JR */ + std::tuple __c_jr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JR"); + + this->gen_sync(PRE_SYNC, 23); + + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jr"), + fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 23); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 24: C.ADD */ + std::tuple __c_add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADD"); + + this->gen_sync(PRE_SYNC, 24); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs2}", fmt::arg("mnemonic", "c.add"), + fmt::arg("rd", name(rd)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rd + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 24); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 25: C.JALR */ + std::tuple __c_jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.JALR"); + + this->gen_sync(PRE_SYNC, 25); + + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}", fmt::arg("mnemonic", "c.jalr"), + fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 2)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(1 + traits::X0), false); + Value* PC_val = this->gen_reg_load(rs1 + traits::X0, 0); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 25); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 26: C.EBREAK */ + std::tuple __c_ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.EBREAK"); + + this->gen_sync(PRE_SYNC, 26); + + 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(64, pc.val); + pc=pc+2; + + this->gen_raise_trap(0, 3); + this->gen_sync(POST_SYNC, 26); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 27: C.SWSP */ + std::tuple __c_swsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SWSP"); + + this->gen_sync(PRE_SYNC, 27); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm:#05x}(sp)", fmt::arg("mnemonic", "c.swsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 27); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 28: DII */ + std::tuple __dii(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DII"); + + this->gen_sync(PRE_SYNC, 28); + + 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(64, pc.val); + pc=pc+2; + + this->gen_raise_trap(0, 2); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 28); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 29: C.FLD */ + std::tuple __c_fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLD"); + + this->gen_sync(PRE_SYNC, 29); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fld"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 29); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 30: C.FSD */ + std::tuple __c_fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSD"); + + this->gen_sync(PRE_SYNC, 30); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsd"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::F0, 0), + this-> get_type(64) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 30); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 31: C.FLDSP */ + std::tuple __c_fldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLDSP"); + + this->gen_sync(PRE_SYNC, 31); + + uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.fldsp"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 31); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 32: C.FSDSP */ + std::tuple __c_fsdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSDSP"); + + this->gen_sync(PRE_SYNC, 32); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fsdsp"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 32); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 33: C.FLW */ + std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLW"); + + this->gen_sync(PRE_SYNC, 33); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 33); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 34: C.FSW */ + std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSW"); + + this->gen_sync(PRE_SYNC, 34); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::F0, 0), + this-> get_type(32) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 34); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 35: C.FLWSP */ + std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLWSP"); + + this->gen_sync(PRE_SYNC, 35); + + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 35); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 36: C.FSWSP */ + std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSWSP"); + + this->gen_sync(PRE_SYNC, 36); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(32) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 36); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 37: LUI */ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LUI"); + + this->gen_sync(PRE_SYNC, 37); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(64U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 37); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 38: AUIPC */ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(PRE_SYNC, 38); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 38); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 39: JAL */ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(PRE_SYNC, 39); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 39); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 40: BEQ */ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BEQ"); + + this->gen_sync(PRE_SYNC, 40); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 40); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 41: BNE */ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BNE"); + + this->gen_sync(PRE_SYNC, 41); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 41); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 42: BLT */ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLT"); + + this->gen_sync(PRE_SYNC, 42); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 42); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 43: BGE */ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGE"); + + this->gen_sync(PRE_SYNC, 43); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 43); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 44: BLTU */ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLTU"); + + this->gen_sync(PRE_SYNC, 44); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 44); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 45: BGEU */ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGEU"); + + this->gen_sync(PRE_SYNC, 45); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 45); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 46: LB */ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LB"); + + this->gen_sync(PRE_SYNC, 46); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 46); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 47: LH */ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LH"); + + this->gen_sync(PRE_SYNC, 47); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 47); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 48: LW */ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LW"); + + this->gen_sync(PRE_SYNC, 48); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 48); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 49: LBU */ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LBU"); + + this->gen_sync(PRE_SYNC, 49); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 49); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 50: LHU */ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LHU"); + + this->gen_sync(PRE_SYNC, 50); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 50); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 51: SB */ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SB"); + + this->gen_sync(PRE_SYNC, 51); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 51); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 52: SH */ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SH"); + + this->gen_sync(PRE_SYNC, 52); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 52); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 53: SW */ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SW"); + + this->gen_sync(PRE_SYNC, 53); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 53); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 54: ADDI */ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDI"); + + this->gen_sync(PRE_SYNC, 54); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 54); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 55: SLTI */ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTI"); + + this->gen_sync(PRE_SYNC, 55); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 55); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 56: SLTIU */ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTIU"); + + this->gen_sync(PRE_SYNC, 56); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = imm; + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, full_imm_val)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 56); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 57: XORI */ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XORI"); + + this->gen_sync(PRE_SYNC, 57); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 57); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 58: ORI */ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ORI"); + + this->gen_sync(PRE_SYNC, 58); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 58); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 59: ANDI */ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ANDI"); + + this->gen_sync(PRE_SYNC, 59); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 59); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 60: SLLI */ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLI"); + + this->gen_sync(PRE_SYNC, 60); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 60); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 61: SRLI */ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLI"); + + this->gen_sync(PRE_SYNC, 61); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 61); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 62: SRAI */ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAI"); + + this->gen_sync(PRE_SYNC, 62); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 62); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 63: ADD */ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADD"); + + this->gen_sync(PRE_SYNC, 63); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 63); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 64: SUB */ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUB"); + + this->gen_sync(PRE_SYNC, 64); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 64); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 65: SLL */ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLL"); + + this->gen_sync(PRE_SYNC, 65); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 65); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 66: SLT */ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLT"); + + this->gen_sync(PRE_SYNC, 66); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, true)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 66); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 67: SLTU */ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTU"); + + this->gen_sync(PRE_SYNC, 67); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, + false)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 67); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 68: XOR */ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XOR"); + + this->gen_sync(PRE_SYNC, 68); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 68); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 69: SRL */ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRL"); + + this->gen_sync(PRE_SYNC, 69); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 69); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 70: SRA */ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRA"); + + this->gen_sync(PRE_SYNC, 70); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 70); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 71: OR */ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("OR"); + + this->gen_sync(PRE_SYNC, 71); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 71); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 72: AND */ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AND"); + + this->gen_sync(PRE_SYNC, 72); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 72); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 73: FENCE */ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE"); + + this->gen_sync(PRE_SYNC, 73); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, pred), + this->gen_const(64U, 4)), + this->gen_const(64U, succ)); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 0), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 73); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 74: FENCE_I */ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE_I"); + + this->gen_sync(PRE_SYNC, 74); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(64U, imm); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 1), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 74); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(FLUSH, nullptr); + } + + /* instruction 75: ECALL */ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ECALL"); + + this->gen_sync(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("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(POST_SYNC, 75); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 76: EBREAK */ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("EBREAK"); + + this->gen_sync(PRE_SYNC, 76); + + 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(POST_SYNC, 76); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 77: URET */ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("URET"); + + this->gen_sync(PRE_SYNC, 77); + + 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(POST_SYNC, 77); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 78: SRET */ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRET"); + + this->gen_sync(PRE_SYNC, 78); + + 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(POST_SYNC, 78); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 79: MRET */ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MRET"); + + this->gen_sync(PRE_SYNC, 79); + + 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(POST_SYNC, 79); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 80: WFI */ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("WFI"); + + this->gen_sync(PRE_SYNC, 80); + + 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(POST_SYNC, 80); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 81: SFENCE.VMA */ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SFENCE.VMA"); + + this->gen_sync(PRE_SYNC, 81); + + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(64U, rs1); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 2), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); + Value* FENCEtmp1_val = this->gen_const(64U, rs2); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 3), + this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 81); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 82: CSRRW */ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRW"); + + this->gen_sync(PRE_SYNC, 82); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + Value* CSRtmp0_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); + Value* Xtmp1_val = csr_val_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* CSRtmp2_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 82); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 83: CSRRS */ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRS"); + + this->gen_sync(PRE_SYNC, 83); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateOr( + xrd_val, + xrs1_val); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 83); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 84: CSRRC */ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRC"); + + this->gen_sync(PRE_SYNC, 84); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + xrd_val, + this->builder.CreateNot(xrs1_val)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 84); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 85: CSRRWI */ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRWI"); + + this->gen_sync(PRE_SYNC, 85); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* CSRtmp1_val = this->gen_ext( + this->gen_const(64U, zimm), + 64, + false); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 85); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 86: CSRRSI */ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRSI"); + + this->gen_sync(PRE_SYNC, 86); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + if(zimm != 0){ + Value* CSRtmp0_val = this->builder.CreateOr( + res_val, + this->gen_ext( + this->gen_const(64U, zimm), + 64, + false)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); + } + if(rd != 0){ + Value* Xtmp1_val = res_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 86); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 87: CSRRCI */ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRCI"); + + this->gen_sync(PRE_SYNC, 87); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(zimm != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + res_val, + this->builder.CreateNot(this->gen_ext( + this->gen_const(64U, zimm), + 64, + false))); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 87); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 88: FLD */ + std::tuple __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLD"); + + this->gen_sync(PRE_SYNC, 88); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {imm}({rs1})", fmt::arg("mnemonic", "fld"), + fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 64/8); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 88); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 89: FSD */ + std::tuple __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSD"); + + this->gen_sync(PRE_SYNC, 89); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {imm}({rs1})", fmt::arg("mnemonic", "fsd"), + fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 89); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 90: FMADD.D */ + std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMADD.D"); + + this->gen_sync(PRE_SYNC, 90); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs3 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 64, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 90); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 91: FMSUB.D */ + std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMSUB.D"); + + this->gen_sync(PRE_SYNC, 91); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs3 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 91); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 92: FNMADD.D */ + std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FNMADD.D"); + + this->gen_sync(PRE_SYNC, 92); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs3 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 92); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 93: FNMSUB.D */ + std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FNMSUB.D"); + + this->gen_sync(PRE_SYNC, 93); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fmadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs3 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 93); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 94: FADD.D */ + std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FADD.D"); + + this->gen_sync(PRE_SYNC, 94); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fadd_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 94); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 95: FSUB.D */ + std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSUB.D"); + + this->gen_sync(PRE_SYNC, 95); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fsub_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 95); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 96: FMUL.D */ + std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMUL.D"); + + this->gen_sync(PRE_SYNC, 96); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fmul_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 96); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 97: FDIV.D */ + std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FDIV.D"); + + this->gen_sync(PRE_SYNC, 97); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fdiv_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 97); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 98: FSQRT.D */ + std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSQRT.D"); + + this->gen_sync(PRE_SYNC, 98); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fsqrt_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 98); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 99: FSGNJ.D */ + std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJ.D"); + + this->gen_sync(PRE_SYNC, 99); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + uint64_t ONE_val = 1; + uint64_t MSK1_val = ONE_val << 63; + uint64_t MSK2_val = MSK1_val - 1; + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, MSK2_val)), + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, MSK1_val))); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 99); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 100: FSGNJN.D */ + std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJN.D"); + + this->gen_sync(PRE_SYNC, 100); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + uint64_t ONE_val = 1; + uint64_t MSK1_val = ONE_val << 63; + uint64_t MSK2_val = MSK1_val - 1; + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, MSK2_val)), + this->builder.CreateAnd( + this->builder.CreateNot(this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + )), + this->gen_const(64U, MSK1_val))); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 100); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 101: FSGNJX.D */ + std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJX.D"); + + this->gen_sync(PRE_SYNC, 101); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + uint64_t ONE_val = 1; + uint64_t MSK1_val = ONE_val << 63; + Value* res_val = this->builder.CreateXor( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_const(64U, MSK1_val))); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 101); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 102: FMIN.D */ + std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMIN.D"); + + this->gen_sync(PRE_SYNC, 102); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 102); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 103: FMAX.D */ + std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMAX.D"); + + this->gen_sync(PRE_SYNC, 103); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fsel_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 103); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 104: FCVT.S.D */ + std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.D"); + + this->gen_sync(PRE_SYNC, 104); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.s.d"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fconv_d2f"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_const(8U, rm) + }); + uint64_t upper_val = - 1; + Value* Ftmp0_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 104); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 105: FCVT.D.S */ + std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.D.S"); + + this->gen_sync(PRE_SYNC, 105); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.d.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fconv_f2d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(32) + ), + this->gen_const(8U, rm) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 105); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 106: FEQ.D */ + std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FEQ.D"); + + this->gen_sync(PRE_SYNC, 106); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 106); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 107: FLT.D */ + std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLT.D"); + + this->gen_sync(PRE_SYNC, 107); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 107); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 108: FLE.D */ + std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLE.D"); + + this->gen_sync(PRE_SYNC, 108); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 108); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 109: FCLASS.D */ + std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCLASS.D"); + + this->gen_sync(PRE_SYNC, 109); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fclass.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ) + }); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 109); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 110: FCVT.W.D */ + std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.W.D"); + + this->gen_sync(PRE_SYNC, 110); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 110); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 111: FCVT.WU.D */ + std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.WU.D"); + + this->gen_sync(PRE_SYNC, 111); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 111); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 112: FCVT.D.W */ + std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.D.W"); + + this->gen_sync(PRE_SYNC, 112); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.w"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector{ + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 64, + true), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, rm) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 112); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 113: FCVT.D.WU */ + std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.D.WU"); + + this->gen_sync(PRE_SYNC, 113); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.wu"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector{ + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 64, + false), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, rm) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 113); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 114: FCVT.L.D */ + std::tuple __fcvt_l_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.L.D"); + + this->gen_sync(PRE_SYNC, 114); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.l.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 114); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 115: FCVT.LU.D */ + std::tuple __fcvt_lu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.LU.D"); + + this->gen_sync(PRE_SYNC, 115); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.lu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(64) + ), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 115); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 116: FCVT.D.L */ + std::tuple __fcvt_d_l(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.D.L"); + + this->gen_sync(PRE_SYNC, 116); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.l"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, + true), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, rm) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 116); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 117: FCVT.D.LU */ + std::tuple __fcvt_d_lu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.D.LU"); + + this->gen_sync(PRE_SYNC, 117); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.d.lu"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_d"), std::vector{ + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, + false), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, rm) + }); + if(64 == 64){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 64)), + res_val); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 117); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 118: FMV.X.D */ + std::tuple __fmv_x_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMV.X.D"); + + this->gen_sync(PRE_SYNC, 118); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->gen_reg_load(rs1 + traits::F0, 0), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 118); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 119: FMV.D.X */ + std::tuple __fmv_d_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMV.D.X"); + + this->gen_sync(PRE_SYNC, 119); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fmv.d.x"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Ftmp0_val = this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, + false); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 119); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 120: FLW */ + std::tuple __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLW"); + + this->gen_sync(PRE_SYNC, 120); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {imm}(x{rs1})", fmt::arg("mnemonic", "flw"), + fmt::arg("rd", rd), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 120); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 121: FSW */ + std::tuple __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSW"); + + this->gen_sync(PRE_SYNC, 121); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rs2}, {imm}(x{rs1})", fmt::arg("mnemonic", "fsw"), + fmt::arg("rs2", rs2), fmt::arg("imm", imm), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(32) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 121); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 122: FMADD.S */ + std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMADD.S"); + + this->gen_sync(PRE_SYNC, 122); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 122); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 123: FMSUB.S */ + std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMSUB.S"); + + this->gen_sync(PRE_SYNC, 123); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fmsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 123); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 124: FNMADD.S */ + std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FNMADD.S"); + + this->gen_sync(PRE_SYNC, 124); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 124); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 125: FNMSUB.S */ + std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FNMSUB.S"); + + this->gen_sync(PRE_SYNC, 125); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs3 = ((bit_sub<27,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}, f{rs2}, f{rs3}", fmt::arg("mnemonic", "fnmsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2), fmt::arg("rs3", rs3)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_reg_load(rs3 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* frs3_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs3 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmadd_s"), std::vector{ + frs1_val, + frs2_val, + frs3_val, + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 125); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 126: FADD.S */ + std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FADD.S"); + + this->gen_sync(PRE_SYNC, 126); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fadd.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fadd_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 126); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 127: FSUB.S */ + std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSUB.S"); + + this->gen_sync(PRE_SYNC, 127); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsub.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsub_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 127); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 128: FMUL.S */ + std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMUL.S"); + + this->gen_sync(PRE_SYNC, 128); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmul.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fmul_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 128); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 129: FDIV.S */ + std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FDIV.S"); + + this->gen_sync(PRE_SYNC, 129); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fdiv.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fdiv_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 129); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 130: FSQRT.S */ + std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSQRT.S"); + + this->gen_sync(PRE_SYNC, 130); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}", fmt::arg("mnemonic", "fsqrt.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsqrt_s"), std::vector{ + frs1_val, + this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_const(8U, rm), + this->gen_const(8U, 7)), + this->gen_const(8U, rm), + this->builder.CreateTrunc( + this->gen_reg_load(traits::FCSR, 0), + this-> get_type(8) + ), + 8) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 130); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 131: FSGNJ.S */ + std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJ.S"); + + this->gen_sync(PRE_SYNC, 131); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnj.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_const(64U, 0x7fffffff)), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_const(64U, 0x80000000))); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + frs1_val, + this->gen_const(32U, 0x7fffffff)), + this->builder.CreateAnd( + frs2_val, + this->gen_const(32U, 0x80000000))); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 131); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 132: FSGNJN.S */ + std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJN.S"); + + this->gen_sync(PRE_SYNC, 132); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjn.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateOr( + this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_const(64U, 0x7fffffff)), + this->builder.CreateAnd( + this->builder.CreateNot(this->gen_reg_load(rs2 + traits::F0, 0)), + this->gen_const(64U, 0x80000000))); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateOr( + this->builder.CreateAnd( + frs1_val, + this->gen_const(32U, 0x7fffffff)), + this->builder.CreateAnd( + this->builder.CreateNot(frs2_val), + this->gen_const(32U, 0x80000000))); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 132); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 133: FSGNJX.S */ + std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FSGNJX.S"); + + this->gen_sync(PRE_SYNC, 133); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fsgnjx.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateXor( + this->gen_reg_load(rs1 + traits::F0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_const(64U, 0x80000000))); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateXor( + frs1_val, + this->builder.CreateAnd( + frs2_val, + this->gen_const(32U, 0x80000000))); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 133); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 134: FMIN.S */ + std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMIN.S"); + + this->gen_sync(PRE_SYNC, 134); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmin.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 134); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 135: FMAX.S */ + std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMAX.S"); + + this->gen_sync(PRE_SYNC, 135); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fmax.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fsel_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 135); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 136: FCVT.W.S */ + std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.W.S"); + + this->gen_sync(PRE_SYNC, 136); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.w.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + frs1_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 136); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 137: FCVT.WU.S */ + std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.WU.S"); + + this->gen_sync(PRE_SYNC, 137); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.wu.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + frs1_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }), + 64, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 137); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 138: FEQ.S */ + std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FEQ.S"); + + this->gen_sync(PRE_SYNC, 138); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "feq.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 138); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 139: FLT.S */ + std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLT.S"); + + this->gen_sync(PRE_SYNC, 139); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "flt.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* Xtmp2_val = this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 139); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 140: FLE.S */ + std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FLE.S"); + + this->gen_sync(PRE_SYNC, 140); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}, f{rs2}", fmt::arg("mnemonic", "fle.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1), fmt::arg("rs2", rs2)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0), + this->gen_reg_load(rs2 + traits::F0, 0), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* frs1_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }); + Value* frs2_val = this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs2 + traits::F0, 0) + }); + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateCall(this->mod->getFunction("fcmp_s"), std::vector{ + frs1_val, + frs2_val, + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false) + }), + 64, + false); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 140); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 141: FCLASS.S */ + std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCLASS.S"); + + this->gen_sync(PRE_SYNC, 141); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fclass.s"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->builder.CreateCall(this->mod->getFunction("fclass_s"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }) + }); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 141); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 142: FCVT.S.W */ + std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.W"); + + this->gen_sync(PRE_SYNC, 142); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.s.w"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, rm) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false), + this->gen_const(8U, rm) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 142); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 143: FCVT.S.WU */ + std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.WU"); + + this->gen_sync(PRE_SYNC, 143); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fcvt.s.wu"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, rm) + }); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + Value* res_val = this->builder.CreateCall(this->mod->getFunction("fcvt_s"), std::vector{ + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false), + this->gen_const(8U, rm) + }); + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 143); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 144: FMV.X.W */ + std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMV.X.W"); + + this->gen_sync(PRE_SYNC, 144); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, f{rs1}", fmt::arg("mnemonic", "fmv.x.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::F0, 0), + this-> get_type(32) + ), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 144); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 145: FMV.W.X */ + std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FMV.W.X"); + + this->gen_sync(PRE_SYNC, 145); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, {rs1}", fmt::arg("mnemonic", "fmv.w.x"), + fmt::arg("rd", rd), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(64 == 32){ + Value* Ftmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ); + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 145); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 146: FCVT.L.S */ + std::tuple __fcvt_l_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.L.S"); + + this->gen_sync(PRE_SYNC, 146); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.l.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }), + this->gen_ext( + this->gen_const(64U, 0LL), + 32, + false), + this->gen_const(8U, rm) + }); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 146); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 147: FCVT.LU.S */ + std::tuple __fcvt_lu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.LU.S"); + + this->gen_sync(PRE_SYNC, 147); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} x{rd}, f{rs1}", fmt::arg("mnemonic", "fcvt.lu.s"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_32_64"), std::vector{ + this->builder.CreateCall(this->mod->getFunction("unbox_s"), std::vector{ + this->gen_reg_load(rs1 + traits::F0, 0) + }), + this->gen_ext( + this->gen_const(64U, 1LL), + 32, + false), + this->gen_const(8U, rm) + }); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* flags_val = this->builder.CreateCall(this->mod->getFunction("fget_flags"), std::vector{ + }); + Value* FCSR_val = this->builder.CreateAdd( + this->builder.CreateAnd( + this->gen_reg_load(traits::FCSR, 0), + this->builder.CreateNot(this->gen_const(32U, 0x1f))), + flags_val); + this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 147); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 148: FCVT.S.L */ + std::tuple __fcvt_s_l(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.L"); + + this->gen_sync(PRE_SYNC, 148); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.l"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector{ + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_ext( + this->gen_const(64U, 2LL), + 32, + false) + }); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 148); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 149: FCVT.S.LU */ + std::tuple __fcvt_s_lu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FCVT.S.LU"); + + this->gen_sync(PRE_SYNC, 149); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rm = ((bit_sub<12,3>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} f{rd}, x{rs1}", fmt::arg("mnemonic", "fcvt.s.lu"), + fmt::arg("rd", rd), fmt::arg("rs1", rs1)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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->builder.CreateCall(this->mod->getFunction("fcvt_64_32"), std::vector{ + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_ext( + this->gen_const(64U, 3LL), + 32, + false) + }); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 149); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 150: MUL */ + std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MUL"); + + this->gen_sync(PRE_SYNC, 150); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mul"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 150); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 151: MULH */ + std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULH"); + + this->gen_sync(PRE_SYNC, 151); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulh"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + true)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(64U, 64)), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 151); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 152: MULHSU */ + std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULHSU"); + + this->gen_sync(PRE_SYNC, 152); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhsu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(64U, 64)), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 152); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 153: MULHU */ + std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULHU"); + + this->gen_sync(PRE_SYNC, 153); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulhu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateMul( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 128, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 128, + false)); + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateLShr( + res_val, + this->gen_const(64U, 64)), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 153); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 154: DIV */ + std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIV"); + + this->gen_sync(PRE_SYNC, 154); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "div"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint64_t M1_val = - 1; + uint8_t XLM1_val = 64 - 1; + uint64_t ONE_val = 1; + uint64_t MMIN_val = ONE_val << XLM1_val; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_const(64U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(64U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(64U, MMIN_val); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateSDiv( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 2), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 2), + 64, true)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->builder.CreateNeg(this->gen_const(64U, 1)); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 154); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 155: DIVU */ + std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIVU"); + + this->gen_sync(PRE_SYNC, 155); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateUDiv( + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(64U, 1)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 155); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 156: REM */ + std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REM"); + + this->gen_sync(PRE_SYNC, 156); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "rem"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint64_t M1_val = - 1; + uint32_t XLM1_val = 64 - 1; + uint64_t ONE_val = 1; + uint64_t MMIN_val = ONE_val << XLM1_val; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_const(64U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(64U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(64U, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateSRem( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 2), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 2), + 64, true)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 156); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 157: REMU */ + std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REMU"); + + this->gen_sync(PRE_SYNC, 157); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateURem( + this->gen_reg_load(rs1 + traits::X0, 1), + this->gen_reg_load(rs2 + traits::X0, 1)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->gen_reg_load(rs1 + traits::X0, 1); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 157); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 158: LR.W */ + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LR.W"); + + this->gen_sync(PRE_SYNC, 158); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* REStmp1_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(REStmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 158); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 159: SC.W */ + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SC.W"); + + this->gen_sync(PRE_SYNC, 159); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + if(rd != 0){ + Value* Xtmp1_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + res1_val, + this->gen_ext( + this->gen_const(64U, 0), + 32, + false)), + this->gen_const(64U, 0), + this->gen_const(64U, 1), + 64); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 159); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 160: AMOSWAP.W */ + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOSWAP.W"); + + this->gen_sync(PRE_SYNC, 160); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 160); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 161: AMOADD.W */ + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOADD.W"); + + this->gen_sync(PRE_SYNC, 161); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAdd( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 161); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 162: AMOXOR.W */ + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOXOR.W"); + + this->gen_sync(PRE_SYNC, 162); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateXor( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 162); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 163: AMOAND.W */ + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOAND.W"); + + this->gen_sync(PRE_SYNC, 163); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAnd( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 163); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 164: AMOOR.W */ + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOOR.W"); + + this->gen_sync(PRE_SYNC, 164); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateOr( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 164); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 165: AMOMIN.W */ + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMIN.W"); + + this->gen_sync(PRE_SYNC, 165); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 165); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 166: AMOMAX.W */ + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAX.W"); + + this->gen_sync(PRE_SYNC, 166); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 166); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 167: AMOMINU.W */ + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMINU.W"); + + this->gen_sync(PRE_SYNC, 167); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 167); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 168: AMOMAXU.W */ + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAXU.W"); + + this->gen_sync(PRE_SYNC, 168); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 168); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 169: LWU */ + std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LWU"); + + this->gen_sync(PRE_SYNC, 169); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 169); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 170: LD */ + std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LD"); + + this->gen_sync(PRE_SYNC, 170); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 170); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 171: SD */ + std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SD"); + + this->gen_sync(PRE_SYNC, 171); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 171); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 172: ADDIW */ + std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDIW"); + + this->gen_sync(PRE_SYNC, 172); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateAdd( + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 32, true), + this->gen_const(32U, imm)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 172); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 173: SLLIW */ + std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLIW"); + + this->gen_sync(PRE_SYNC, 173); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateShl( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 173); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 174: SRLIW */ + std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLIW"); + + this->gen_sync(PRE_SYNC, 174); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateLShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 174); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 175: SRAIW */ + std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAIW"); + + this->gen_sync(PRE_SYNC, 175); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateAShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 175); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 176: ADDW */ + std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDW"); + + this->gen_sync(PRE_SYNC, 176); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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(rd != 0){ + Value* res_val = this->builder.CreateAdd( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 176); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 177: SUBW */ + std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUBW"); + + this->gen_sync(PRE_SYNC, 177); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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(rd != 0){ + Value* res_val = this->builder.CreateSub( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 177); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 178: SLLW */ + std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLW"); + + this->gen_sync(PRE_SYNC, 178); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateShl( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 178); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 179: SRLW */ + std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLW"); + + this->gen_sync(PRE_SYNC, 179); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateLShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 179); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 180: SRAW */ + std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAW"); + + this->gen_sync(PRE_SYNC, 180); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateAShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 180); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 181: MULW */ + std::tuple __mulw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MULW"); + + this->gen_sync(PRE_SYNC, 181); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "mulw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateMul( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 181); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 182: DIVW */ + std::tuple __divw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIVW"); + + this->gen_sync(PRE_SYNC, 182); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint32_t M1_val = - 1; + uint32_t ONE_val = 1; + uint32_t MMIN_val = ONE_val << 31; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 1), + this-> get_type(32) + ), + this->gen_const(32U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 1), + this-> get_type(32) + ), + this->gen_const(32U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->builder.CreateShl( + this->builder.CreateNeg(this->gen_const(64U, 1)), + this->gen_const(64U, 31)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateSDiv( + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 2), + this-> get_type(32) + ), + 64, true), + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 2), + this-> get_type(32) + ), + 64, true)), + 64, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->builder.CreateNeg(this->gen_const(64U, 1)); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 182); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 183: DIVUW */ + std::tuple __divuw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("DIVUW"); + + this->gen_sync(PRE_SYNC, 183); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "divuw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateUDiv( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 1), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 1), + this-> get_type(32) + )), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->builder.CreateNeg(this->gen_const(64U, 1)); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 183); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 184: REMW */ + std::tuple __remw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REMW"); + + this->gen_sync(PRE_SYNC, 184); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rs2 + traits::X0, 0), + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + uint32_t M1_val = - 1; + uint32_t ONE_val = 1; + uint32_t MMIN_val = ONE_val << 31; + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateAnd( + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 1), + this-> get_type(32) + ), + this->gen_const(32U, MMIN_val)), + this->builder.CreateICmp( + ICmpInst::ICMP_EQ, + this->gen_reg_load(rs2 + traits::X0, 1), + this->gen_const(64U, M1_val))), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_const(64U, 0); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateSRem( + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 2), + this-> get_type(32) + ), + 64, true), + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 2), + this-> get_type(32) + ), + 64, true)), + 64, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp2_val = this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 1), + this-> get_type(32) + ), + 64, + true); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 184); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 185: REMUW */ + std::tuple __remuw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("REMUW"); + + this->gen_sync(PRE_SYNC, 185); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "remuw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder.SetInsertPoint(bb); + this->gen_cond_branch(this->builder.CreateICmp( + ICmpInst::ICMP_NE, + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, 0)), + bb_then, + bb_else); + this->builder.SetInsertPoint(bb_then); + { + Value* Xtmp0_val = this->gen_ext( + this->builder.CreateURem( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 1), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 1), + this-> get_type(32) + )), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + Value* Xtmp1_val = this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 1), + this-> get_type(32) + ), + 64, + true); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 185); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 186: LR.D */ + std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LR.D"); + + this->gen_sync(PRE_SYNC, 186); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* REStmp1_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(REStmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 186); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 187: SC.D */ + std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SC.D"); + + this->gen_sync(PRE_SYNC, 187); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/8); + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));if(rd != 0){ + Value* Xtmp1_val = this->gen_const(64U, 0); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + if(rd != 0){ + Value* Xtmp2_val = this->gen_const(64U, 1); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 187); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 188: AMOSWAP.D */ + std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOSWAP.D"); + + this->gen_sync(PRE_SYNC, 188); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 188); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 189: AMOADD.D */ + std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOADD.D"); + + this->gen_sync(PRE_SYNC, 189); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAdd( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 189); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 190: AMOXOR.D */ + std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOXOR.D"); + + this->gen_sync(PRE_SYNC, 190); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateXor( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 190); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 191: AMOAND.D */ + std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOAND.D"); + + this->gen_sync(PRE_SYNC, 191); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAnd( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 191); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 192: AMOOR.D */ + std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOOR.D"); + + this->gen_sync(PRE_SYNC, 192); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateOr( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 192); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 193: AMOMIN.D */ + std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMIN.D"); + + this->gen_sync(PRE_SYNC, 193); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 193); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 194: AMOMAX.D */ + std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAX.D"); + + this->gen_sync(PRE_SYNC, 194); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 194); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 195: AMOMINU.D */ + std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMINU.D"); + + this->gen_sync(PRE_SYNC, 195); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 195); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 196: AMOMAXU.D */ + std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAXU.D"); + + this->gen_sync(PRE_SYNC, 196); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 196); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 197: C.LD */ + std::tuple __c_ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LD"); + + this->gen_sync(PRE_SYNC, 197); + + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm},({rs1})", fmt::arg("mnemonic", "c.ld"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 197); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 198: C.SD */ + std::tuple __c_sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SD"); + + this->gen_sync(PRE_SYNC, 198); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm},({rs1})", fmt::arg("mnemonic", "c.sd"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 198); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 199: C.SUBW */ + std::tuple __c_subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SUBW"); + + this->gen_sync(PRE_SYNC, 199); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.subw"), + fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* res_val = this->builder.CreateSub( + this->builder.CreateTrunc( + this->gen_reg_load(rd + 8 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 199); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 200: C.ADDW */ + std::tuple __c_addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDW"); + + this->gen_sync(PRE_SYNC, 200); + + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.addw"), + fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* res_val = this->builder.CreateAdd( + this->builder.CreateTrunc( + this->gen_reg_load(rd + 8 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 200); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 201: C.ADDIW */ + std::tuple __c_addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDIW"); + + this->gen_sync(PRE_SYNC, 201); + + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addiw"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + if(rs1 != 0){ + Value* res_val = this->builder.CreateAdd( + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 32, true), + this->gen_const(32U, imm)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 201); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 202: C.LDSP */ + std::tuple __c_ldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LDSP"); + + this->gen_sync(PRE_SYNC, 202); + + uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {uimm}(sp)", fmt::arg("mnemonic", "c.ldsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 202); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 203: C.SDSP */ + std::tuple __c_sdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SDSP"); + + this->gen_sync(PRE_SYNC, 203); + + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {uimm}(sp)", fmt::arg("mnemonic", "c.sdsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+2; + + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 203); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /**************************************************************************** + * end opcode definitions + ****************************************************************************/ + std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, 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(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_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, BasicBlock *this_block) { + // we fetch at max 4 byte, alignment is 2 + enum {TRAP_ID=1<<16}; + code_word_t insn = 0; + const typename traits::addr_t upper_bits = ~traits::PGMASK; + phys_addr_t paddr(pc); + auto *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(TRAP_ID, 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(TRAP_ID, pc.val); + } + if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' + // curr pc on stack + ++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(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); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); +} + +template void vm_impl::gen_leave_trap(unsigned lvl) { + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), 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); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); +} + +template void vm_impl::gen_wait(unsigned type) { + std::vector args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) }; + this->builder.CreateCall(this->mod->getFunction("wait"), args); +} + +template void vm_impl::gen_trap_behavior(BasicBlock *trap_blk) { + this->builder.SetInsertPoint(trap_blk); + auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits::TRAP_STATE), true); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), + get_reg_ptr(traits::LAST_BRANCH), false); + 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(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, + ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))), + bb, this->trap_blk, 1); +} + +} // namespace rv64gc + +template <> +std::unique_ptr create(arch::rv64gc *core, unsigned short port, bool dump) { + auto ret = new rv64gc::vm_impl(*core, dump); + if (port != 0) debugger::server::run_server(ret, port); + return std::unique_ptr(ret); +} + +} // namespace iss diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64i.cpp similarity index 69% rename from riscv/src/internal/vm_rv64ia.cpp rename to riscv/src/internal/vm_rv64i.cpp index d48e2e6..e9a1be3 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64i.cpp @@ -30,7 +30,7 @@ * *******************************************************************************/ -#include +#include #include #include #include @@ -46,11 +46,11 @@ namespace iss { namespace vm { namespace fp_impl { -void add_fp_functions_2_module(llvm::Module *, unsigned); +void add_fp_functions_2_module(llvm::Module *, unsigned, unsigned); } } -namespace rv64ia { +namespace rv64i { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; @@ -88,7 +88,7 @@ protected: void setup_module(Module* m) override { super::setup_module(m); - iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE); + iss::vm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN); } inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) { @@ -186,38 +186,8 @@ private: compile_func op; }; - const std::array instr_descr = {{ + const std::array instr_descr = {{ /* entries are: size, valid value, valid mask, function ptr */ - /* instruction LWU */ - {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, - /* instruction LD */ - {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld}, - /* instruction SD */ - {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd}, - /* instruction SLLI */ - {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli}, - /* instruction SRLI */ - {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli}, - /* instruction SRAI */ - {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai}, - /* instruction ADDIW */ - {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw}, - /* instruction SLLIW */ - {32, 0b00000000000000000001000000011011, 0b11111110000000000111000001111111, &this_class::__slliw}, - /* instruction SRLIW */ - {32, 0b00000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__srliw}, - /* instruction SRAIW */ - {32, 0b01000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__sraiw}, - /* instruction ADDW */ - {32, 0b00000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__addw}, - /* instruction SUBW */ - {32, 0b01000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__subw}, - /* instruction SLLW */ - {32, 0b00000000000000000001000000111011, 0b11111110000000000111000001111111, &this_class::__sllw}, - /* instruction SRLW */ - {32, 0b00000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__srlw}, - /* instruction SRAW */ - {32, 0b01000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__sraw}, /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ @@ -266,6 +236,12 @@ private: {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori}, /* instruction ANDI */ {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, + /* instruction SLLI */ + {32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli}, + /* instruction SRLI */ + {32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli}, + /* instruction SRAI */ + {32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai}, /* instruction ADD */ {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, /* instruction SUB */ @@ -316,742 +292,38 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, - /* instruction LR.D */ - {32, 0b00010000000000000011000000101111, 0b11111001111100000111000001111111, &this_class::__lr_d}, - /* instruction SC.D */ - {32, 0b00011000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__sc_d}, - /* instruction AMOSWAP.D */ - {32, 0b00001000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_d}, - /* instruction AMOADD.D */ - {32, 0b00000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_d}, - /* instruction AMOXOR.D */ - {32, 0b00100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_d}, - /* instruction AMOAND.D */ - {32, 0b01100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_d}, - /* instruction AMOOR.D */ - {32, 0b01000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_d}, - /* instruction AMOMIN.D */ - {32, 0b10000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_d}, - /* instruction AMOMAX.D */ - {32, 0b10100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_d}, - /* instruction AMOMINU.D */ - {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d}, - /* instruction AMOMAXU.D */ - {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d}, - /* instruction LR.W */ - {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, - /* instruction SC.W */ - {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, - /* instruction AMOSWAP.W */ - {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, - /* instruction AMOADD.W */ - {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, - /* instruction AMOXOR.W */ - {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, - /* instruction AMOAND.W */ - {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, - /* instruction AMOOR.W */ - {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, - /* instruction AMOMIN.W */ - {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, - /* instruction AMOMAX.W */ - {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, - /* instruction AMOMINU.W */ - {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, - /* instruction AMOMAXU.W */ - {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, + /* instruction LWU */ + {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, + /* instruction LD */ + {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld}, + /* instruction SD */ + {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd}, + /* instruction ADDIW */ + {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw}, + /* instruction SLLIW */ + {32, 0b00000000000000000001000000011011, 0b11111110000000000111000001111111, &this_class::__slliw}, + /* instruction SRLIW */ + {32, 0b00000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__srliw}, + /* instruction SRAIW */ + {32, 0b01000000000000000101000000011011, 0b11111110000000000111000001111111, &this_class::__sraiw}, + /* instruction ADDW */ + {32, 0b00000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__addw}, + /* instruction SUBW */ + {32, 0b01000000000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__subw}, + /* instruction SLLW */ + {32, 0b00000000000000000001000000111011, 0b11111110000000000111000001111111, &this_class::__sllw}, + /* instruction SRLW */ + {32, 0b00000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__srlw}, + /* instruction SRAW */ + {32, 0b01000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__sraw}, }}; /* instruction definitions */ - /* instruction 0: LWU */ - std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LWU"); - - this->gen_sync(PRE_SYNC, 0); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 0); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 1: LD */ - std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LD"); - - this->gen_sync(PRE_SYNC, 1); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 1); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 2: SD */ - std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SD"); - - this->gen_sync(PRE_SYNC, 2); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 2); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 3: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(PRE_SYNC, 3); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 3); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 4: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(PRE_SYNC, 4); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 4); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 5: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(PRE_SYNC, 5); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 5); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 6: ADDIW */ - std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDIW"); - - this->gen_sync(PRE_SYNC, 6); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateAdd( - this->gen_ext( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - 32, true), - this->gen_const(32U, imm)); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 6); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 7: SLLIW */ - std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLIW"); - - this->gen_sync(PRE_SYNC, 7); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* sh_val_val = this->builder.CreateShl( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, shamt)); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 7); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 8: SRLIW */ - std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLIW"); - - this->gen_sync(PRE_SYNC, 8); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* sh_val_val = this->builder.CreateLShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, shamt)); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 8); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 9: SRAIW */ - std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAIW"); - - this->gen_sync(PRE_SYNC, 9); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* sh_val_val = this->builder.CreateAShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, shamt)); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 9); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 10: ADDW */ - std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDW"); - - this->gen_sync(PRE_SYNC, 10); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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(rd != 0){ - Value* res_val = this->builder.CreateAdd( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - )); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 10); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 11: SUBW */ - std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SUBW"); - - this->gen_sync(PRE_SYNC, 11); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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(rd != 0){ - Value* res_val = this->builder.CreateSub( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - )); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 11); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 12: SLLW */ - std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLW"); - - this->gen_sync(PRE_SYNC, 12); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - uint32_t mask_val = 0x1f; - Value* count_val = this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, mask_val)); - Value* sh_val_val = this->builder.CreateShl( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - count_val); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 12); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 13: SRLW */ - std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLW"); - - this->gen_sync(PRE_SYNC, 13); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - uint32_t mask_val = 0x1f; - Value* count_val = this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, mask_val)); - Value* sh_val_val = this->builder.CreateLShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - count_val); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 13); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 14: SRAW */ - std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAW"); - - this->gen_sync(PRE_SYNC, 14); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - uint32_t mask_val = 0x1f; - Value* count_val = this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, mask_val)); - Value* sh_val_val = this->builder.CreateAShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - count_val); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 14); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 15: LUI */ + /* instruction 0: LUI */ std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LUI"); - this->gen_sync(PRE_SYNC, 15); + this->gen_sync(PRE_SYNC, 0); uint8_t rd = ((bit_sub<7,5>(instr))); int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); @@ -1076,17 +348,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 15); + this->gen_sync(POST_SYNC, 0); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 16: AUIPC */ + /* instruction 1: AUIPC */ std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AUIPC"); - this->gen_sync(PRE_SYNC, 16); + this->gen_sync(PRE_SYNC, 1); uint8_t rd = ((bit_sub<7,5>(instr))); int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); @@ -1115,17 +387,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 16); + this->gen_sync(POST_SYNC, 1); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 17: JAL */ + /* instruction 2: JAL */ std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JAL"); - this->gen_sync(PRE_SYNC, 17); + this->gen_sync(PRE_SYNC, 2); uint8_t rd = ((bit_sub<7,5>(instr))); int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); @@ -1159,16 +431,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 17); + this->gen_sync(POST_SYNC, 2); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 18: JALR */ + /* instruction 3: JALR */ std::tuple __jalr(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("JALR"); - this->gen_sync(PRE_SYNC, 18); + this->gen_sync(PRE_SYNC, 3); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1231,16 +503,16 @@ private: bb=bbnext; } this->builder.SetInsertPoint(bb); - this->gen_sync(POST_SYNC, 18); + this->gen_sync(POST_SYNC, 3); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 19: BEQ */ + /* instruction 4: BEQ */ std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BEQ"); - this->gen_sync(PRE_SYNC, 19); + this->gen_sync(PRE_SYNC, 4); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1278,16 +550,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 19); + this->gen_sync(POST_SYNC, 4); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 20: BNE */ + /* instruction 5: BNE */ std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BNE"); - this->gen_sync(PRE_SYNC, 20); + this->gen_sync(PRE_SYNC, 5); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1325,16 +597,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 20); + this->gen_sync(POST_SYNC, 5); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 21: BLT */ + /* instruction 6: BLT */ std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLT"); - this->gen_sync(PRE_SYNC, 21); + this->gen_sync(PRE_SYNC, 6); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1376,16 +648,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 21); + this->gen_sync(POST_SYNC, 6); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 22: BGE */ + /* instruction 7: BGE */ std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGE"); - this->gen_sync(PRE_SYNC, 22); + this->gen_sync(PRE_SYNC, 7); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1427,16 +699,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 22); + this->gen_sync(POST_SYNC, 7); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 23: BLTU */ + /* instruction 8: BLTU */ std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BLTU"); - this->gen_sync(PRE_SYNC, 23); + this->gen_sync(PRE_SYNC, 8); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1474,16 +746,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 23); + this->gen_sync(POST_SYNC, 8); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 24: BGEU */ + /* instruction 9: BGEU */ std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("BGEU"); - this->gen_sync(PRE_SYNC, 24); + this->gen_sync(PRE_SYNC, 9); int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1521,16 +793,16 @@ private: this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 24); + this->gen_sync(POST_SYNC, 9); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 25: LB */ + /* instruction 10: LB */ std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LB"); - this->gen_sync(PRE_SYNC, 25); + this->gen_sync(PRE_SYNC, 10); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1564,17 +836,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 25); + this->gen_sync(POST_SYNC, 10); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 26: LH */ + /* instruction 11: LH */ std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LH"); - this->gen_sync(PRE_SYNC, 26); + this->gen_sync(PRE_SYNC, 11); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1608,17 +880,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 26); + this->gen_sync(POST_SYNC, 11); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 27: LW */ + /* instruction 12: LW */ std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LW"); - this->gen_sync(PRE_SYNC, 27); + this->gen_sync(PRE_SYNC, 12); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1652,17 +924,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 27); + this->gen_sync(POST_SYNC, 12); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 28: LBU */ + /* instruction 13: LBU */ std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LBU"); - this->gen_sync(PRE_SYNC, 28); + this->gen_sync(PRE_SYNC, 13); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1696,17 +968,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 28); + this->gen_sync(POST_SYNC, 13); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 29: LHU */ + /* instruction 14: LHU */ std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LHU"); - this->gen_sync(PRE_SYNC, 29); + this->gen_sync(PRE_SYNC, 14); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1740,17 +1012,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 29); + this->gen_sync(POST_SYNC, 14); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 30: SB */ + /* instruction 15: SB */ std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SB"); - this->gen_sync(PRE_SYNC, 30); + this->gen_sync(PRE_SYNC, 15); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1782,17 +1054,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 30); + this->gen_sync(POST_SYNC, 15); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 31: SH */ + /* instruction 16: SH */ std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SH"); - this->gen_sync(PRE_SYNC, 31); + this->gen_sync(PRE_SYNC, 16); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1824,17 +1096,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 31); + this->gen_sync(POST_SYNC, 16); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 32: SW */ + /* instruction 17: SW */ std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SW"); - this->gen_sync(PRE_SYNC, 32); + this->gen_sync(PRE_SYNC, 17); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1866,17 +1138,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 32); + this->gen_sync(POST_SYNC, 17); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 33: ADDI */ + /* instruction 18: ADDI */ std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADDI"); - this->gen_sync(PRE_SYNC, 33); + this->gen_sync(PRE_SYNC, 18); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1906,17 +1178,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 33); + this->gen_sync(POST_SYNC, 18); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 34: SLTI */ + /* instruction 19: SLTI */ std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTI"); - this->gen_sync(PRE_SYNC, 34); + this->gen_sync(PRE_SYNC, 19); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1951,17 +1223,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 34); + this->gen_sync(POST_SYNC, 19); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 35: SLTIU */ + /* instruction 20: SLTIU */ std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTIU"); - this->gen_sync(PRE_SYNC, 35); + this->gen_sync(PRE_SYNC, 20); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -1995,17 +1267,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 35); + this->gen_sync(POST_SYNC, 20); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 36: XORI */ + /* instruction 21: XORI */ std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XORI"); - this->gen_sync(PRE_SYNC, 36); + this->gen_sync(PRE_SYNC, 21); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2035,17 +1307,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 36); + this->gen_sync(POST_SYNC, 21); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 37: ORI */ + /* instruction 22: ORI */ std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ORI"); - this->gen_sync(PRE_SYNC, 37); + this->gen_sync(PRE_SYNC, 22); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2075,17 +1347,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 37); + this->gen_sync(POST_SYNC, 22); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 38: ANDI */ + /* instruction 23: ANDI */ std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ANDI"); - this->gen_sync(PRE_SYNC, 38); + this->gen_sync(PRE_SYNC, 23); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2115,17 +1387,131 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 38); + this->gen_sync(POST_SYNC, 23); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 39: ADD */ + /* instruction 24: SLLI */ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLI"); + + this->gen_sync(PRE_SYNC, 24); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 24); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 25: SRLI */ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLI"); + + this->gen_sync(PRE_SYNC, 25); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 25); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 26: SRAI */ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAI"); + + this->gen_sync(PRE_SYNC, 26); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 26); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 27: ADD */ std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ADD"); - this->gen_sync(PRE_SYNC, 39); + this->gen_sync(PRE_SYNC, 27); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2153,17 +1539,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 39); + this->gen_sync(POST_SYNC, 27); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 40: SUB */ + /* instruction 28: SUB */ std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SUB"); - this->gen_sync(PRE_SYNC, 40); + this->gen_sync(PRE_SYNC, 28); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2191,17 +1577,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 40); + this->gen_sync(POST_SYNC, 28); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 41: SLL */ + /* instruction 29: SLL */ std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLL"); - this->gen_sync(PRE_SYNC, 41); + this->gen_sync(PRE_SYNC, 29); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2233,17 +1619,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 41); + this->gen_sync(POST_SYNC, 29); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 42: SLT */ + /* instruction 30: SLT */ std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLT"); - this->gen_sync(PRE_SYNC, 42); + this->gen_sync(PRE_SYNC, 30); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2280,17 +1666,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 42); + this->gen_sync(POST_SYNC, 30); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 43: SLTU */ + /* instruction 31: SLTU */ std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SLTU"); - this->gen_sync(PRE_SYNC, 43); + this->gen_sync(PRE_SYNC, 31); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2329,17 +1715,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 43); + this->gen_sync(POST_SYNC, 31); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 44: XOR */ + /* instruction 32: XOR */ std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("XOR"); - this->gen_sync(PRE_SYNC, 44); + this->gen_sync(PRE_SYNC, 32); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2367,17 +1753,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 44); + this->gen_sync(POST_SYNC, 32); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 45: SRL */ + /* instruction 33: SRL */ std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRL"); - this->gen_sync(PRE_SYNC, 45); + this->gen_sync(PRE_SYNC, 33); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2409,17 +1795,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 45); + this->gen_sync(POST_SYNC, 33); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 46: SRA */ + /* instruction 34: SRA */ std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRA"); - this->gen_sync(PRE_SYNC, 46); + this->gen_sync(PRE_SYNC, 34); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2451,17 +1837,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 46); + this->gen_sync(POST_SYNC, 34); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 47: OR */ + /* instruction 35: OR */ std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("OR"); - this->gen_sync(PRE_SYNC, 47); + this->gen_sync(PRE_SYNC, 35); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2489,17 +1875,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 47); + this->gen_sync(POST_SYNC, 35); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 48: AND */ + /* instruction 36: AND */ std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AND"); - this->gen_sync(PRE_SYNC, 48); + this->gen_sync(PRE_SYNC, 36); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2527,17 +1913,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 48); + this->gen_sync(POST_SYNC, 36); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 49: FENCE */ + /* instruction 37: FENCE */ std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE"); - this->gen_sync(PRE_SYNC, 49); + this->gen_sync(PRE_SYNC, 37); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2566,17 +1952,17 @@ private: this->gen_const(64U, 0), this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 49); + this->gen_sync(POST_SYNC, 37); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 50: FENCE_I */ + /* instruction 38: FENCE_I */ std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FENCE_I"); - this->gen_sync(PRE_SYNC, 50); + this->gen_sync(PRE_SYNC, 38); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2601,16 +1987,16 @@ private: this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 50); + this->gen_sync(POST_SYNC, 38); this->gen_trap_check(this->leave_blk); return std::make_tuple(FLUSH, nullptr); } - /* instruction 51: ECALL */ + /* instruction 39: ECALL */ std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("ECALL"); - this->gen_sync(PRE_SYNC, 51); + this->gen_sync(PRE_SYNC, 39); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2626,16 +2012,16 @@ private: pc=pc+4; this->gen_raise_trap(0, 11); - this->gen_sync(POST_SYNC, 51); + this->gen_sync(POST_SYNC, 39); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 52: EBREAK */ + /* instruction 40: EBREAK */ std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("EBREAK"); - this->gen_sync(PRE_SYNC, 52); + this->gen_sync(PRE_SYNC, 40); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2651,16 +2037,16 @@ private: pc=pc+4; this->gen_raise_trap(0, 3); - this->gen_sync(POST_SYNC, 52); + this->gen_sync(POST_SYNC, 40); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 53: URET */ + /* instruction 41: URET */ std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("URET"); - this->gen_sync(PRE_SYNC, 53); + this->gen_sync(PRE_SYNC, 41); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2676,16 +2062,16 @@ private: pc=pc+4; this->gen_leave_trap(0); - this->gen_sync(POST_SYNC, 53); + this->gen_sync(POST_SYNC, 41); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 54: SRET */ + /* instruction 42: SRET */ std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SRET"); - this->gen_sync(PRE_SYNC, 54); + this->gen_sync(PRE_SYNC, 42); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2701,16 +2087,16 @@ private: pc=pc+4; this->gen_leave_trap(1); - this->gen_sync(POST_SYNC, 54); + this->gen_sync(POST_SYNC, 42); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 55: MRET */ + /* instruction 43: MRET */ std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MRET"); - this->gen_sync(PRE_SYNC, 55); + this->gen_sync(PRE_SYNC, 43); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2726,16 +2112,16 @@ private: pc=pc+4; this->gen_leave_trap(3); - this->gen_sync(POST_SYNC, 55); + this->gen_sync(POST_SYNC, 43); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); } - /* instruction 56: WFI */ + /* instruction 44: WFI */ std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("WFI"); - this->gen_sync(PRE_SYNC, 56); + this->gen_sync(PRE_SYNC, 44); if(this->disass_enabled){ /* generate console output when executing the command */ @@ -2752,17 +2138,17 @@ private: this->gen_wait(1); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 56); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 57: SFENCE.VMA */ + /* instruction 45: SFENCE.VMA */ std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SFENCE.VMA"); - this->gen_sync(PRE_SYNC, 57); + this->gen_sync(PRE_SYNC, 45); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); @@ -2790,17 +2176,17 @@ private: this->gen_const(64U, 3), this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 57); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 58: CSRRW */ + /* instruction 46: CSRRW */ std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRW"); - this->gen_sync(PRE_SYNC, 58); + this->gen_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2839,17 +2225,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 58); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 59: CSRRS */ + /* instruction 47: CSRRS */ std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRS"); - this->gen_sync(PRE_SYNC, 59); + this->gen_sync(PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2886,17 +2272,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 59); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 60: CSRRC */ + /* instruction 48: CSRRC */ std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRC"); - this->gen_sync(PRE_SYNC, 60); + this->gen_sync(PRE_SYNC, 48); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -2933,17 +2319,17 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 60); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 61: CSRRWI */ + /* instruction 49: CSRRWI */ std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRWI"); - this->gen_sync(PRE_SYNC, 61); + this->gen_sync(PRE_SYNC, 49); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -2977,17 +2363,17 @@ private: this->gen_const(16U, csr), this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 61); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 62: CSRRSI */ + /* instruction 50: CSRRSI */ std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRSI"); - this->gen_sync(PRE_SYNC, 62); + this->gen_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -3026,17 +2412,17 @@ private: this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 62); + this->gen_sync(POST_SYNC, 50); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 63: CSRRCI */ + /* instruction 51: CSRRCI */ std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("CSRRCI"); - this->gen_sync(PRE_SYNC, 63); + this->gen_sync(PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t zimm = ((bit_sub<15,5>(instr))); @@ -3075,1215 +2461,570 @@ private: this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); } this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 51); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 52: LWU */ + std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LWU"); + + this->gen_sync(PRE_SYNC, 52); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 52); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 53: LD */ + std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LD"); + + this->gen_sync(PRE_SYNC, 53); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 53); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 54: SD */ + std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SD"); + + this->gen_sync(PRE_SYNC, 54); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 54); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 55: ADDIW */ + std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDIW"); + + this->gen_sync(PRE_SYNC, 55); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* res_val = this->builder.CreateAdd( + this->gen_ext( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 32, true), + this->gen_const(32U, imm)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 55); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 56: SLLIW */ + std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLIW"); + + this->gen_sync(PRE_SYNC, 56); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateShl( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 56); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 57: SRLIW */ + std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLIW"); + + this->gen_sync(PRE_SYNC, 57); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateLShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 57); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 58: SRAIW */ + std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAIW"); + + this->gen_sync(PRE_SYNC, 58); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateAShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 58); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 59: ADDW */ + std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDW"); + + this->gen_sync(PRE_SYNC, 59); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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(rd != 0){ + Value* res_val = this->builder.CreateAdd( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 59); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 60: SUBW */ + std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUBW"); + + this->gen_sync(PRE_SYNC, 60); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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(rd != 0){ + Value* res_val = this->builder.CreateSub( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 60); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 61: SLLW */ + std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLW"); + + this->gen_sync(PRE_SYNC, 61); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateShl( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 61); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 62: SRLW */ + std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLW"); + + this->gen_sync(PRE_SYNC, 62); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateLShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 62); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 63: SRAW */ + std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAW"); + + this->gen_sync(PRE_SYNC, 63); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateAShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 63); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 64: LR.D */ - std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LR.D"); - - this->gen_sync(PRE_SYNC, 64); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* REStmp1_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(REStmp1_val,this->get_type(64))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 64); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 65: SC.D */ - std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SC.D"); - - this->gen_sync(PRE_SYNC, 65); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/8); - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));if(rd != 0){ - Value* Xtmp1_val = this->gen_const(64U, 0); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - if(rd != 0){ - Value* Xtmp2_val = this->gen_const(64U, 1); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 65); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 66: AMOSWAP.D */ - std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOSWAP.D"); - - this->gen_sync(PRE_SYNC, 66); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 66); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 67: AMOADD.D */ - std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOADD.D"); - - this->gen_sync(PRE_SYNC, 67); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAdd( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 67); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 68: AMOXOR.D */ - std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOXOR.D"); - - this->gen_sync(PRE_SYNC, 68); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateXor( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 68); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 69: AMOAND.D */ - std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOAND.D"); - - this->gen_sync(PRE_SYNC, 69); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAnd( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 69); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 70: AMOOR.D */ - std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOOR.D"); - - this->gen_sync(PRE_SYNC, 70); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateOr( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 70); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 71: AMOMIN.D */ - std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMIN.D"); - - this->gen_sync(PRE_SYNC, 71); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res_val, - 64); - Value* MEMtmp1_val = res_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 71); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 72: AMOMAX.D */ - std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAX.D"); - - this->gen_sync(PRE_SYNC, 72); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 72); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 73: AMOMINU.D */ - std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMINU.D"); - - this->gen_sync(PRE_SYNC, 73); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - false); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 73); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 74: AMOMAXU.D */ - std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAXU.D"); - - this->gen_sync(PRE_SYNC, 74); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - false); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 74); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 75: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LR.W"); - - this->gen_sync(PRE_SYNC, 75); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* REStmp1_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(REStmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 75); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 76: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SC.W"); - - this->gen_sync(PRE_SYNC, 76); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - if(rd != 0){ - Value* Xtmp1_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(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 76); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 77: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOSWAP.W"); - - this->gen_sync(PRE_SYNC, 77); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 77); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 78: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOADD.W"); - - this->gen_sync(PRE_SYNC, 78); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAdd( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 78); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 79: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOXOR.W"); - - this->gen_sync(PRE_SYNC, 79); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateXor( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 79); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 80: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOAND.W"); - - this->gen_sync(PRE_SYNC, 80); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAnd( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 80); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 81: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOOR.W"); - - this->gen_sync(PRE_SYNC, 81); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateOr( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 81); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 82: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMIN.W"); - - this->gen_sync(PRE_SYNC, 82); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 82); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 83: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAX.W"); - - this->gen_sync(PRE_SYNC, 83); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 83); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 84: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMINU.W"); - - this->gen_sync(PRE_SYNC, 84); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - false); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 84); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 85: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAXU.W"); - - this->gen_sync(PRE_SYNC, 85); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - false); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 85); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - /**************************************************************************** * end opcode definitions ****************************************************************************/ @@ -4327,24 +3068,21 @@ template std::tuple vm_impl::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) { // we fetch at max 4 byte, alignment is 2 + enum {TRAP_ID=1<<16}; code_word_t insn = 0; const typename traits::addr_t upper_bits = ~traits::PGMASK; phys_addr_t paddr(pc); - try { - auto *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); + auto *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(TRAP_ID, pc.val); + if ((insn & 0x3) == 0x3) { // this is a 32bit instruction + res = this->core.read(this->core.v2p(pc + 2), 2, data + 2); } - } catch (trap_access &ta) { - throw trap_access(ta.id, pc.val); + } else { + auto res = this->core.read(paddr, 4, data); + if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val); } if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0' // curr pc on stack @@ -4401,11 +3139,11 @@ template inline void vm_impl::gen_trap_check(BasicBlock *b bb, this->trap_blk, 1); } -} // namespace rv64ia +} // namespace rv64i template <> -std::unique_ptr create(arch::rv64ia *core, unsigned short port, bool dump) { - auto ret = new rv64ia::vm_impl(*core, dump); +std::unique_ptr create(arch::rv64i *core, unsigned short port, bool dump) { + auto ret = new rv64i::vm_impl(*core, dump); if (port != 0) debugger::server::run_server(ret, port); return std::unique_ptr(ret); } diff --git a/riscv/src/iss/rv32gc.cpp b/riscv/src/iss/rv32gc.cpp index 489a56c..a5f3ce7 100644 --- a/riscv/src/iss/rv32gc.cpp +++ b/riscv/src/iss/rv32gc.cpp @@ -1,34 +1,34 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -//////////////////////////////////////////////////////////////////////////////// +/******************************************************************************* + * Copyright (C) 2017, 2018 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 diff --git a/riscv/src/iss/rv64gc.cpp b/riscv/src/iss/rv64gc.cpp new file mode 100644 index 0000000..8d27912 --- /dev/null +++ b/riscv/src/iss/rv64gc.cpp @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (C) 2017, 2018 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; + +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; + +rv64gc::rv64gc() { + reg.icount = 0; +} + +rv64gc::~rv64gc() = default; + +void rv64gc::reset(uint64_t address) { + for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits::reg_t),0)); + reg.PC=address; + reg.NEXT_PC=reg.PC; + reg.trap_state=0; + reg.machine_state=0x0; + reg.icount=0; +} + +uint8_t *rv64gc::get_regs_base_ptr() { + return reinterpret_cast(®); +} + +rv64gc::phys_addr_t rv64gc::virt2phys(const iss::addr_t &pc) { + return phys_addr_t(pc); // change logical address to physical address +} + diff --git a/riscv/src/iss/rv64i.cpp b/riscv/src/iss/rv64i.cpp new file mode 100644 index 0000000..0d09f20 --- /dev/null +++ b/riscv/src/iss/rv64i.cpp @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (C) 2017, 2018 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; + +constexpr std::array iss::arch::traits::reg_names; +constexpr std::array iss::arch::traits::reg_aliases; +constexpr std::array iss::arch::traits::reg_bit_widths; +constexpr std::array iss::arch::traits::reg_byte_offsets; + +rv64i::rv64i() { + reg.icount = 0; +} + +rv64i::~rv64i() = default; + +void rv64i::reset(uint64_t address) { + for(size_t i=0; i::NUM_REGS; ++i) set_reg(i, std::vector(sizeof(traits::reg_t),0)); + reg.PC=address; + reg.NEXT_PC=reg.PC; + reg.trap_state=0; + reg.machine_state=0x0; + reg.icount=0; +} + +uint8_t *rv64i::get_regs_base_ptr() { + return reinterpret_cast(®); +} + +rv64i::phys_addr_t rv64i::virt2phys(const iss::addr_t &pc) { + return phys_addr_t(pc); // change logical address to physical address +} + diff --git a/riscv/src/iss/rv64ia.cpp b/riscv/src/iss/rv64ia.cpp deleted file mode 100644 index 8e71d07..0000000 --- a/riscv/src/iss/rv64ia.cpp +++ /dev/null @@ -1,78 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// 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. -// -// Created on: Tue Sep 05 18:57:24 CEST 2017 -// * rv64ia.cpp Author: -// -//////////////////////////////////////////////////////////////////////////////// - -#include "util/ities.h" -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif -#include -#ifdef __cplusplus -} -#endif -#include -#include -#include - -using namespace iss::arch; - -constexpr std::array iss::arch::traits::reg_names; -constexpr std::array iss::arch::traits::reg_aliases; -constexpr std::array iss::arch::traits::reg_bit_widths; -constexpr std::array iss::arch::traits::reg_byte_offsets; - -rv64ia::rv64ia() { reg.icount = 0; reg.machine_state = 0x3;} - -rv64ia::~rv64ia(){} - -void rv64ia::reset(uint64_t address) { - for (size_t i = 0; i < traits::NUM_REGS; ++i) - set_reg(i, std::vector(sizeof(traits::reg_t), 0)); - reg.PC = address; - reg.NEXT_PC = reg.PC; - reg.trap_state = 0; - reg.machine_state = 0x3; - reg.icount=0; -} - -uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast(®); } - -rv64ia::phys_addr_t rv64ia::virt2phys(const iss::addr_t &pc) { - return phys_addr_t(pc); // change logical address to physical address -} diff --git a/riscv/src/main.cpp b/riscv/src/main.cpp index 80370ef..54bb38c 100644 --- a/riscv/src/main.cpp +++ b/riscv/src/main.cpp @@ -38,7 +38,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -107,7 +108,11 @@ int main(int argc, char *argv[]) { std::unique_ptr cpu{nullptr}; std::string isa_opt(clim["isa"].as()); if (isa_opt=="rv64ia") { - iss::arch::rv64ia* lcpu = new iss::arch::riscv_hart_msu_vp(); + iss::arch::rv64i* lcpu = new iss::arch::riscv_hart_msu_vp(); + vm = iss::create(lcpu, clim["gdb-port"].as()); + cpu.reset(lcpu); + } else if (isa_opt=="rv64gc") { + iss::arch::rv64gc* lcpu = new iss::arch::riscv_hart_msu_vp(); vm = iss::create(lcpu, clim["gdb-port"].as()); cpu.reset(lcpu); } else if (isa_opt=="rv32imac") { diff --git a/sc-components b/sc-components index d334928..05ba880 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit d334928b3627d8abbdbe5b047782901250e2270d +Subproject commit 05ba88052cf922b1e93550342d8e297338619b5d From 3e8583977a997416b535ba004c65f9c697829aa1 Mon Sep 17 00:00:00 2001 From: eyck Date: Thu, 10 Jan 2019 10:58:13 +0000 Subject: [PATCH 7/7] Refactored core descriptions --- riscv/gen_input/RISCVBase.core_desc | 50 + riscv/gen_input/RV32A.core_desc | 104 - .../{RV32IBase.core_desc => RV32I.core_desc} | 52 +- .../{RV64IBase.core_desc => RV64I.core_desc} | 4 +- riscv/gen_input/RV64M.core_desc | 65 - .../{RV64A.core_desc => RVA.core_desc} | 109 +- .../{RV32C.core_desc => RVC.core_desc} | 49 +- .../{RV32D.core_desc => RVD.core_desc} | 12 +- .../{RV32F.core_desc => RVF.core_desc} | 11 +- .../{RV32M.core_desc => RVM.core_desc} | 71 +- riscv/gen_input/minres_rv.core_desc | 24 +- riscv/src/internal/vm_rv32gc.cpp | 4436 ++++----- riscv/src/internal/vm_rv32imac.cpp | 4364 ++++----- riscv/src/internal/vm_rv64gc.cpp | 8370 +++++++++-------- 14 files changed, 8851 insertions(+), 8870 deletions(-) create mode 100644 riscv/gen_input/RISCVBase.core_desc delete mode 100644 riscv/gen_input/RV32A.core_desc rename riscv/gen_input/{RV32IBase.core_desc => RV32I.core_desc} (88%) rename riscv/gen_input/{RV64IBase.core_desc => RV64I.core_desc} (98%) delete mode 100644 riscv/gen_input/RV64M.core_desc rename riscv/gen_input/{RV64A.core_desc => RVA.core_desc} (50%) rename riscv/gen_input/{RV32C.core_desc => RVC.core_desc} (95%) rename riscv/gen_input/{RV32D.core_desc => RVD.core_desc} (98%) rename riscv/gen_input/{RV32F.core_desc => RVF.core_desc} (98%) rename riscv/gen_input/{RV32M.core_desc => RVM.core_desc} (58%) diff --git a/riscv/gen_input/RISCVBase.core_desc b/riscv/gen_input/RISCVBase.core_desc new file mode 100644 index 0000000..abc6a4a --- /dev/null +++ b/riscv/gen_input/RISCVBase.core_desc @@ -0,0 +1,50 @@ +InsructionSet RISCVBase { + constants { + XLEN, + fence:=0, + fencei:=1, + fencevmal:=2, + fencevmau:=3 + } + + address_spaces { + MEM[8], CSR[XLEN], FENCE[XLEN], RES[8] + } + + registers { + [31:0] X[XLEN], + PC[XLEN](is_pc), + alias ZERO[XLEN] is X[0], + alias RA[XLEN] is X[1], + alias SP[XLEN] is X[2], + alias GP[XLEN] is X[3], + alias TP[XLEN] is X[4], + alias T0[XLEN] is X[5], + alias T1[XLEN] is X[6], + alias T2[XLEN] is X[7], + alias S0[XLEN] is X[8], + alias S1[XLEN] is X[9], + alias A0[XLEN] is X[10], + alias A1[XLEN] is X[11], + alias A2[XLEN] is X[12], + alias A3[XLEN] is X[13], + alias A4[XLEN] is X[14], + alias A5[XLEN] is X[15], + alias A6[XLEN] is X[16], + alias A7[XLEN] is X[17], + alias S2[XLEN] is X[18], + alias S3[XLEN] is X[19], + alias S4[XLEN] is X[20], + alias S5[XLEN] is X[21], + alias S6[XLEN] is X[22], + alias S7[XLEN] is X[23], + alias S8[XLEN] is X[24], + alias S9[XLEN] is X[25], + alias S10[XLEN] is X[26], + alias S11[XLEN] is X[27], + alias T3[XLEN] is X[28], + alias T4[XLEN] is X[29], + alias T5[XLEN] is X[30], + alias T6[XLEN] is X[31] + } +} \ No newline at end of file diff --git a/riscv/gen_input/RV32A.core_desc b/riscv/gen_input/RV32A.core_desc deleted file mode 100644 index 6f1b644..0000000 --- a/riscv/gen_input/RV32A.core_desc +++ /dev/null @@ -1,104 +0,0 @@ -import "RV32IBase.core_desc" - -InsructionSet RV32A extends RV32IBase{ - - instructions{ - LR.W { - encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}"; - if(rd!=0){ - val offs[XLEN] <= X[rs1]; - X[rd]<= sext(MEM[offs]{32}, XLEN); - RES[offs]{32}<=sext(-1, 32); - } - } - SC.W { - encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)}"; - val offs[XLEN] <= X[rs1]; - val res1[32] <= RES[offs]{32}; - if(res1!=0) - MEM[offs]{32} <= X[rs2]; - if(rd!=0) X[rd]<= choose(res1!=zext(0, 32), 0, 1); - } - AMOSWAP.W{ - encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - if(rd!=0) X[rd]<=sext(MEM[offs]{32}); - MEM[offs]{32}<=X[rs2]; - } - AMOADD.W{ - encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN]<=res1 + X[rs2]; - MEM[offs]{32}<=res2; - } - AMOXOR.W{ - encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN]<=res1 ^ X[rs2]; - MEM[offs]{32}<=res2; - } - AMOAND.W{ - encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN] <=res1 & X[rs2]; - MEM[offs]{32}<=res2; - } - AMOOR.W { - encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN]<=res1 | X[rs2]; - MEM[offs]{32}<=res2; - } - AMOMIN.W{ - encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd] <= res1; - val res2[XLEN] <= choose(res1's > X[rs2]s, X[rs2], res1); - MEM[offs]{32} <= res2; - } - AMOMAX.W{ - encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd]<=res1; - val res2[XLEN]<= choose(res1'sX[rs2], X[rs2], res1); - MEM[offs]{32}<=res2; - } - AMOMAXU.W{ - encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; - args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; - val offs[XLEN]<=X[rs1]; - val res1[XLEN] <= sext(MEM[offs]{32}); - if(rd!=0) X[rd] <= res1; - val res2[XLEN] <= choose(res1 < X[rs2], X[rs2], res1); - MEM[offs]{32} <= res2; - } - } -} \ No newline at end of file diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32I.core_desc similarity index 88% rename from riscv/gen_input/RV32IBase.core_desc rename to riscv/gen_input/RV32I.core_desc index 994a5fe..991bc19 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32I.core_desc @@ -1,52 +1,6 @@ -InsructionSet RV32IBase { - constants { - XLEN, - fence:=0, - fencei:=1, - fencevmal:=2, - fencevmau:=3 - } - - address_spaces { - MEM[8], CSR[XLEN], FENCE[XLEN], RES[8] - } - - registers { - [31:0] X[XLEN], - PC[XLEN](is_pc), - alias ZERO[XLEN] is X[0], - alias RA[XLEN] is X[1], - alias SP[XLEN] is X[2], - alias GP[XLEN] is X[3], - alias TP[XLEN] is X[4], - alias T0[XLEN] is X[5], - alias T1[XLEN] is X[6], - alias T2[XLEN] is X[7], - alias S0[XLEN] is X[8], - alias S1[XLEN] is X[9], - alias A0[XLEN] is X[10], - alias A1[XLEN] is X[11], - alias A2[XLEN] is X[12], - alias A3[XLEN] is X[13], - alias A4[XLEN] is X[14], - alias A5[XLEN] is X[15], - alias A6[XLEN] is X[16], - alias A7[XLEN] is X[17], - alias S2[XLEN] is X[18], - alias S3[XLEN] is X[19], - alias S4[XLEN] is X[20], - alias S5[XLEN] is X[21], - alias S6[XLEN] is X[22], - alias S7[XLEN] is X[23], - alias S8[XLEN] is X[24], - alias S9[XLEN] is X[25], - alias S10[XLEN] is X[26], - alias S11[XLEN] is X[27], - alias T3[XLEN] is X[28], - alias T4[XLEN] is X[29], - alias T5[XLEN] is X[30], - alias T6[XLEN] is X[31] - } +import "RISCVBase.core_desc" + +InsructionSet RV32I extends RISCVBase{ instructions { LUI{ diff --git a/riscv/gen_input/RV64IBase.core_desc b/riscv/gen_input/RV64I.core_desc similarity index 98% rename from riscv/gen_input/RV64IBase.core_desc rename to riscv/gen_input/RV64I.core_desc index 45c2242..59c3c0f 100644 --- a/riscv/gen_input/RV64IBase.core_desc +++ b/riscv/gen_input/RV64I.core_desc @@ -1,6 +1,6 @@ -import "RV32IBase.core_desc" +import "RV32I.core_desc" -InsructionSet RV64IBase extends RV32IBase { +InsructionSet RV64I extends RV32I { instructions{ LWU { // 80000104: 0000ef03 lwu t5,0(ra) encoding: imm[11:0]s | rs1[4:0] | b110 | rd[4:0] | b0000011; diff --git a/riscv/gen_input/RV64M.core_desc b/riscv/gen_input/RV64M.core_desc deleted file mode 100644 index 6b7cd6d..0000000 --- a/riscv/gen_input/RV64M.core_desc +++ /dev/null @@ -1,65 +0,0 @@ -import "RV64IBase.core_desc" - -InsructionSet RV64M extends RV64IBase { - instructions{ - MULW{ - encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; - args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; - if(rd != 0){ - X[rd]<= sext(X[rs1]{32} * X[rs2]{32}); - } - } - DIVW { - encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; - args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; - if(rd != 0){ - if(X[rs2]!=0){ - val M1[32] <= -1; - val ONE[32] <= 1; - val MMIN[32] <= ONE<<31; - if(X[rs1]{32}==MMIN && X[rs2]{32}==M1) - X[rd] <= -1<<31; - else - X[rd] <= sext(X[rs1]{32}s / X[rs2]{32}s); - }else - X[rd] <= -1; - } - } - DIVUW { - encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; - args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; - if(rd != 0){ - if(X[rs2]{32}!=0) - X[rd] <= sext(X[rs1]{32} / X[rs2]{32}); - else - X[rd] <= -1; - } - } - REMW { - encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; - args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; - if(rd != 0){ - if(X[rs2]!=0) { - val M1[32] <= -1; // constant -1 - val ONE[32] <= 1; - val MMIN[32] <= ONE<<31; // -2^(XLEN-1) - if(X[rs1]{32}==MMIN && X[rs2]==M1) - X[rd] <= 0; - else - X[rd] <= sext(X[rs1]{32}s % X[rs2]{32}s); - } else - X[rd] <= sext(X[rs1]{32}); - } - } - REMUW { - encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; - args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; - if(rd != 0){ - if(X[rs2]{32}!=0) - X[rd] <= sext(X[rs1]{32} % X[rs2]{32}); - else - X[rd] <= sext(X[rs1]{32}); - } - } - } -} \ No newline at end of file diff --git a/riscv/gen_input/RV64A.core_desc b/riscv/gen_input/RVA.core_desc similarity index 50% rename from riscv/gen_input/RV64A.core_desc rename to riscv/gen_input/RVA.core_desc index e006285..ff66baf 100644 --- a/riscv/gen_input/RV64A.core_desc +++ b/riscv/gen_input/RVA.core_desc @@ -1,6 +1,109 @@ -import "RV64IBase.core_desc" +import "RISCVBase.core_desc" -InsructionSet RV64A extends RV64IBase { +InsructionSet RV32A extends RISCVBase{ + + instructions{ + LR.W { + encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}"; + if(rd!=0){ + val offs[XLEN] <= X[rs1]; + X[rd]<= sext(MEM[offs]{32}, XLEN); + RES[offs]{32}<=sext(-1, 32); + } + } + SC.W { + encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)}"; + val offs[XLEN] <= X[rs1]; + val res1[32] <= RES[offs]{32}; + if(res1!=0) + MEM[offs]{32} <= X[rs2]; + if(rd!=0) X[rd]<= choose(res1!=zext(0, 32), 0, 1); + } + AMOSWAP.W{ + encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + if(rd!=0) X[rd]<=sext(MEM[offs]{32}); + MEM[offs]{32}<=X[rs2]; + } + AMOADD.W{ + encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd]<=res1; + val res2[XLEN]<=res1 + X[rs2]; + MEM[offs]{32}<=res2; + } + AMOXOR.W{ + encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd]<=res1; + val res2[XLEN]<=res1 ^ X[rs2]; + MEM[offs]{32}<=res2; + } + AMOAND.W{ + encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd]<=res1; + val res2[XLEN] <=res1 & X[rs2]; + MEM[offs]{32}<=res2; + } + AMOOR.W { + encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd]<=res1; + val res2[XLEN]<=res1 | X[rs2]; + MEM[offs]{32}<=res2; + } + AMOMIN.W{ + encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd] <= res1; + val res2[XLEN] <= choose(res1's > X[rs2]s, X[rs2], res1); + MEM[offs]{32} <= res2; + } + AMOMAX.W{ + encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd]<=res1; + val res2[XLEN]<= choose(res1'sX[rs2], X[rs2], res1); + MEM[offs]{32}<=res2; + } + AMOMAXU.W{ + encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111; + args_disass: "{name(rd)}, {name(rs1)}, {name(rs2)} (aqu={aq},rel={rl})"; + val offs[XLEN]<=X[rs1]; + val res1[XLEN] <= sext(MEM[offs]{32}); + if(rd!=0) X[rd] <= res1; + val res2[XLEN] <= choose(res1 < X[rs2], X[rs2], res1); + MEM[offs]{32} <= res2; + } + } +} + +InsructionSet RV64A extends RV32A { instructions{ LR.D { @@ -104,4 +207,4 @@ InsructionSet RV64A extends RV64IBase { MEM[offs]{64} <= res2; } } -} \ No newline at end of file +} diff --git a/riscv/gen_input/RV32C.core_desc b/riscv/gen_input/RVC.core_desc similarity index 95% rename from riscv/gen_input/RV32C.core_desc rename to riscv/gen_input/RVC.core_desc index 81c35aa..5c00c5d 100644 --- a/riscv/gen_input/RV32C.core_desc +++ b/riscv/gen_input/RVC.core_desc @@ -1,16 +1,7 @@ -import "RV32IBase.core_desc" +import "RISCVBase.core_desc" + +InsructionSet RV32IC extends RISCVBase{ -InsructionSet RV32IC { - constants { - XLEN - } - address_spaces { - MEM[8] - } - registers { - [31:0] X[XLEN], - PC[XLEN](is_pc) - } instructions{ JALR(no_cont){ // overwriting the implementation if rv32i, alignment does not need to be word encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; @@ -182,13 +173,9 @@ InsructionSet RV32IC { InsructionSet RV32FC extends RV32IC{ constants { - XLEN, FLEN - } - address_spaces { - MEM[8] + FLEN } registers { - [31:0] X[XLEN], [31:0] F[FLEN] } instructions{ @@ -233,13 +220,9 @@ InsructionSet RV32FC extends RV32IC{ InsructionSet RV32DC extends RV32IC{ constants { - XLEN, FLEN - } - address_spaces { - MEM[8] + FLEN } registers { - [31:0] X[XLEN], [31:0] F[FLEN] } instructions{ @@ -283,16 +266,7 @@ InsructionSet RV32DC extends RV32IC{ } InsructionSet RV64IC extends RV32IC { - constants { - XLEN - } - address_spaces { - MEM[8] - } - registers { - [31:0] X[XLEN], - PC[XLEN](is_pc) - } + instructions{ C.LD {//(RV64/128) encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00; @@ -360,16 +334,7 @@ InsructionSet RV64IC extends RV32IC { } InsructionSet RV128IC extends RV64IC { - constants { - XLEN - } - address_spaces { - MEM[8] - } - registers { - [31:0] X[XLEN], - PC[XLEN](is_pc) - } + instructions{ C.SRLI {//(RV128) encoding:b100 | shamt[5:5] | b00 | rs1[2:0] | shamt[4:0] | b01; diff --git a/riscv/gen_input/RV32D.core_desc b/riscv/gen_input/RVD.core_desc similarity index 98% rename from riscv/gen_input/RV32D.core_desc rename to riscv/gen_input/RVD.core_desc index 50e665c..08f50c0 100644 --- a/riscv/gen_input/RV32D.core_desc +++ b/riscv/gen_input/RVD.core_desc @@ -1,6 +1,6 @@ -import "RV32IBase.core_desc" +import "RISCVBase.core_desc" -InsructionSet RV32D extends RV32IBase{ +InsructionSet RV32D extends RISCVBase{ constants { FLEN, FFLAG_MASK := 0x1f } @@ -306,12 +306,7 @@ InsructionSet RV32D extends RV32IBase{ } } InsructionSet RV64D extends RV32D{ - constants { - FLEN, FFLAG_MASK := 0x1f - } - registers { - [31:0] F[FLEN], FCSR[32] - } + instructions{ FCVT.L.D { encoding: b1100001 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; @@ -359,7 +354,6 @@ InsructionSet RV64D extends RV32D{ args_disass:"f{rd}, {name(rs1)}"; F[rd] <= zext(X[rs1]); } - } } diff --git a/riscv/gen_input/RV32F.core_desc b/riscv/gen_input/RVF.core_desc similarity index 98% rename from riscv/gen_input/RV32F.core_desc rename to riscv/gen_input/RVF.core_desc index 27e279b..5134b87 100644 --- a/riscv/gen_input/RV32F.core_desc +++ b/riscv/gen_input/RVF.core_desc @@ -1,6 +1,6 @@ -import "RV32IBase.core_desc" +import "RV32I.core_desc" -InsructionSet RV32F extends RV32IBase{ +InsructionSet RV32F extends RV32I{ constants { FLEN, FFLAG_MASK := 0x1f } @@ -355,12 +355,7 @@ InsructionSet RV32F extends RV32IBase{ } InsructionSet RV64F extends RV32F{ - constants { - FLEN, FFLAG_MASK := 0x1f - } - registers { - [31:0] F[FLEN], FCSR[32] - } + instructions{ FCVT.L.S { // fp to 64bit signed integer encoding: b1100000 | b00010 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011; diff --git a/riscv/gen_input/RV32M.core_desc b/riscv/gen_input/RVM.core_desc similarity index 58% rename from riscv/gen_input/RV32M.core_desc rename to riscv/gen_input/RVM.core_desc index ab35fb1..49edd18 100644 --- a/riscv/gen_input/RV32M.core_desc +++ b/riscv/gen_input/RVM.core_desc @@ -1,6 +1,6 @@ -import "RV32IBase.core_desc" +import "RISCVBase.core_desc" -InsructionSet RV32M extends RV32IBase { +InsructionSet RV32M extends RISCVBase { constants { MAXLEN:=128 } @@ -92,4 +92,69 @@ InsructionSet RV32M extends RV32IBase { } } } -} \ No newline at end of file +} + +InsructionSet RV64M extends RV32M { + instructions{ + MULW{ + encoding: b0000001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0111011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + if(rd != 0){ + X[rd]<= sext(X[rs1]{32} * X[rs2]{32}); + } + } + DIVW { + encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0111011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + if(rd != 0){ + if(X[rs2]!=0){ + val M1[32] <= -1; + val ONE[32] <= 1; + val MMIN[32] <= ONE<<31; + if(X[rs1]{32}==MMIN && X[rs2]{32}==M1) + X[rd] <= -1<<31; + else + X[rd] <= sext(X[rs1]{32}s / X[rs2]{32}s); + }else + X[rd] <= -1; + } + } + DIVUW { + encoding: b0000001 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0111011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + if(rd != 0){ + if(X[rs2]{32}!=0) + X[rd] <= sext(X[rs1]{32} / X[rs2]{32}); + else + X[rd] <= -1; + } + } + REMW { + encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0111011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + if(rd != 0){ + if(X[rs2]!=0) { + val M1[32] <= -1; // constant -1 + val ONE[32] <= 1; + val MMIN[32] <= ONE<<31; // -2^(XLEN-1) + if(X[rs1]{32}==MMIN && X[rs2]==M1) + X[rd] <= 0; + else + X[rd] <= sext(X[rs1]{32}s % X[rs2]{32}s); + } else + X[rd] <= sext(X[rs1]{32}); + } + } + REMUW { + encoding: b0000001 | rs2[4:0] | rs1[4:0] | b111 | rd[4:0] | b0111011; + args_disass:"{name(rd)}, {name(rs1)}, {name(rs2)}"; + if(rd != 0){ + if(X[rs2]{32}!=0) + X[rd] <= sext(X[rs1]{32} % X[rs2]{32}); + else + X[rd] <= sext(X[rs1]{32}); + } + } + } +} + diff --git a/riscv/gen_input/minres_rv.core_desc b/riscv/gen_input/minres_rv.core_desc index e1f3048..29e955d 100644 --- a/riscv/gen_input/minres_rv.core_desc +++ b/riscv/gen_input/minres_rv.core_desc @@ -1,14 +1,12 @@ -import "RV32IBase.core_desc" -import "RV32M.core_desc" -import "RV32A.core_desc" -import "RV32C.core_desc" -import "RV32F.core_desc" -import "RV32D.core_desc" -import "RV64IBase.core_desc" -import "RV64M.core_desc" -import "RV64A.core_desc" +import "RV32I.core_desc" +import "RV64I.core_desc" +import "RVM.core_desc" +import "RVA.core_desc" +import "RVC.core_desc" +import "RVF.core_desc" +import "RVD.core_desc" -Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { +Core RV32IMAC provides RV32I, RV32M, RV32A, RV32IC { constants { XLEN:=32; PCLEN:=32; @@ -20,7 +18,7 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC { } } -Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32DC { +Core RV32GC provides RV32I, RV32M, RV32A, RV32F, RV32D, RV32IC, RV32FC, RV32DC { constants { XLEN:=32; FLEN:=64; @@ -33,7 +31,7 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32 } } -Core RV64I provides RV64IBase { +Core RV64I provides RV64I { constants { XLEN:=64; PCLEN:=64; @@ -45,7 +43,7 @@ Core RV64I provides RV64IBase { } } -Core RV64GC provides RV64IC, RV64A, RV64M, RV32A, RV32M, RV64F, RV64D, RV32FC, RV32DC { +Core RV64GC provides RV64I, RV64M, RV64A, RV64F, RV64D, RV64IC, RV32FC, RV32DC { constants { XLEN:=64; FLEN:=64; diff --git a/riscv/src/internal/vm_rv32gc.cpp b/riscv/src/internal/vm_rv32gc.cpp index b394c76..4cb95a4 100644 --- a/riscv/src/internal/vm_rv32gc.cpp +++ b/riscv/src/internal/vm_rv32gc.cpp @@ -254,6 +254,66 @@ private: {16, 0b0010000000000010, 0b1110000000000011, &this_class::__c_fldsp}, /* instruction C.FSDSP */ {16, 0b1010000000000010, 0b1110000000000011, &this_class::__c_fsdsp}, + /* instruction C.FLW */ + {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_flw}, + /* instruction C.FSW */ + {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_fsw}, + /* instruction C.FLWSP */ + {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, + /* instruction C.FSWSP */ + {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, + /* instruction FLD */ + {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, + /* instruction FSD */ + {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd}, + /* instruction FMADD.D */ + {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d}, + /* instruction FMSUB.D */ + {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d}, + /* instruction FNMADD.D */ + {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d}, + /* instruction FNMSUB.D */ + {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d}, + /* instruction FADD.D */ + {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d}, + /* instruction FSUB.D */ + {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d}, + /* instruction FMUL.D */ + {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d}, + /* instruction FDIV.D */ + {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d}, + /* instruction FSQRT.D */ + {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d}, + /* instruction FSGNJ.D */ + {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d}, + /* instruction FSGNJN.D */ + {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d}, + /* instruction FSGNJX.D */ + {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d}, + /* instruction FMIN.D */ + {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d}, + /* instruction FMAX.D */ + {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d}, + /* instruction FCVT.S.D */ + {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d}, + /* instruction FCVT.D.S */ + {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s}, + /* instruction FEQ.D */ + {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d}, + /* instruction FLT.D */ + {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d}, + /* instruction FLE.D */ + {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d}, + /* instruction FCLASS.D */ + {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d}, + /* instruction FCVT.W.D */ + {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d}, + /* instruction FCVT.WU.D */ + {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d}, + /* instruction FCVT.D.W */ + {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, + /* instruction FCVT.D.WU */ + {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ @@ -356,66 +416,6 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, - /* instruction FLD */ - {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, - /* instruction FSD */ - {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd}, - /* instruction FMADD.D */ - {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d}, - /* instruction FMSUB.D */ - {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d}, - /* instruction FNMADD.D */ - {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d}, - /* instruction FNMSUB.D */ - {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d}, - /* instruction FADD.D */ - {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d}, - /* instruction FSUB.D */ - {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d}, - /* instruction FMUL.D */ - {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d}, - /* instruction FDIV.D */ - {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d}, - /* instruction FSQRT.D */ - {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d}, - /* instruction FSGNJ.D */ - {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d}, - /* instruction FSGNJN.D */ - {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d}, - /* instruction FSGNJX.D */ - {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d}, - /* instruction FMIN.D */ - {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d}, - /* instruction FMAX.D */ - {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d}, - /* instruction FCVT.S.D */ - {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d}, - /* instruction FCVT.D.S */ - {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s}, - /* instruction FEQ.D */ - {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d}, - /* instruction FLT.D */ - {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d}, - /* instruction FLE.D */ - {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d}, - /* instruction FCLASS.D */ - {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d}, - /* instruction FCVT.W.D */ - {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d}, - /* instruction FCVT.WU.D */ - {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d}, - /* instruction FCVT.D.W */ - {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, - /* instruction FCVT.D.WU */ - {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, - /* instruction C.FLW */ - {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_flw}, - /* instruction C.FSW */ - {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_fsw}, - /* instruction C.FLWSP */ - {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, - /* instruction C.FSWSP */ - {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, /* instruction FLW */ {32, 0b00000000000000000010000000000111, 0b00000000000000000111000001111111, &this_class::__flw}, /* instruction FSW */ @@ -1781,19 +1781,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 33: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LUI"); + /* instruction 33: C.FLW */ + std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLW"); this->gen_sync(PRE_SYNC, 33); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -1803,11 +1804,26 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; + pc=pc+2; - if(rd != 0){ - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 33); @@ -1816,19 +1832,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 34: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AUIPC"); + /* instruction 34: C.FSW */ + std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSW"); this->gen_sync(PRE_SYNC, 34); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -1838,16 +1855,19 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; + pc=pc+2; - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::F0, 0), + this-> get_type(32) + ); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 34); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -1855,19 +1875,19 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 35: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("JAL"); + /* instruction 35: C.FLWSP */ + std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FLWSP"); this->gen_sync(PRE_SYNC, 35); + uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"), + fmt::arg("rd", rd), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -1877,41 +1897,47 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; + pc=pc+2; - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); + if(64 == 32){ + Value* Ftmp0_val = res_val; + this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); + } else { + uint64_t upper_val = - 1; + Value* Ftmp1_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, upper_val), + this->gen_const(64U, 32)), + this->gen_ext( + res_val, + 64, + false)); + this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 35); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 36: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BEQ"); + /* instruction 36: C.FSWSP */ + std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.FSWSP"); this->gen_sync(PRE_SYNC, 36); - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"), + fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -1921,1959 +1947,31 @@ private: } 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 36); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 37: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BNE"); - - this->gen_sync(PRE_SYNC, 37); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 37); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 38: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BLT"); - - this->gen_sync(PRE_SYNC, 38); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, true)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 38); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 39: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BGE"); - - this->gen_sync(PRE_SYNC, 39); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, true)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 39); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 40: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BLTU"); - - this->gen_sync(PRE_SYNC, 40); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 40); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 41: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BGEU"); - - this->gen_sync(PRE_SYNC, 41); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 41); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 42: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LB"); - - this->gen_sync(PRE_SYNC, 42); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; + pc=pc+2; Value* offs_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 42); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 43: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LH"); - - this->gen_sync(PRE_SYNC, 43); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 43); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 44: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LW"); - - this->gen_sync(PRE_SYNC, 44); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 44); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 45: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LBU"); - - this->gen_sync(PRE_SYNC, 45); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 45); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 46: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LHU"); - - this->gen_sync(PRE_SYNC, 46); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 46); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 47: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SB"); - - this->gen_sync(PRE_SYNC, 47); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 47); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 48: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SH"); - - this->gen_sync(PRE_SYNC, 48); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 48); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 49: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SW"); - - this->gen_sync(PRE_SYNC, 49); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(32U, uimm)); + Value* MEMtmp0_val = this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::F0, 0), + this-> get_type(32) + ); this->gen_write_mem( traits::MEM, offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 49); + this->gen_sync(POST_SYNC, 36); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 50: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDI"); - - this->gen_sync(PRE_SYNC, 50); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 50); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 51: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTI"); - - this->gen_sync(PRE_SYNC, 51); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 51); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 52: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTIU"); - - this->gen_sync(PRE_SYNC, 52); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = imm; - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, full_imm_val)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 52); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 53: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("XORI"); - - this->gen_sync(PRE_SYNC, 53); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 53); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 54: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ORI"); - - this->gen_sync(PRE_SYNC, 54); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 54); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 55: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ANDI"); - - this->gen_sync(PRE_SYNC, 55); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 55); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 56: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(PRE_SYNC, 56); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 56); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 57: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(PRE_SYNC, 57); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 57); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 58: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(PRE_SYNC, 58); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 58); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 59: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADD"); - - this->gen_sync(PRE_SYNC, 59); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 59); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 60: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SUB"); - - this->gen_sync(PRE_SYNC, 60); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 60); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 61: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLL"); - - this->gen_sync(PRE_SYNC, 61); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(32U, 32), - this->gen_const(32U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 61); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 62: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLT"); - - this->gen_sync(PRE_SYNC, 62); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, true)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 62); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 63: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTU"); - - this->gen_sync(PRE_SYNC, 63); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, - false)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 63); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 64: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("XOR"); - - this->gen_sync(PRE_SYNC, 64); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 64); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 65: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRL"); - - this->gen_sync(PRE_SYNC, 65); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(32U, 32), - this->gen_const(32U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 65); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 66: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRA"); - - this->gen_sync(PRE_SYNC, 66); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(32U, 32), - this->gen_const(32U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 66); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 67: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("OR"); - - this->gen_sync(PRE_SYNC, 67); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 67); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 68: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AND"); - - this->gen_sync(PRE_SYNC, 68); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 68); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 69: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FENCE"); - - this->gen_sync(PRE_SYNC, 69); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t succ = ((bit_sub<20,4>(instr))); - uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(32U, pred), - this->gen_const(32U, 4)), - this->gen_const(32U, succ)); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 0), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 69); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 70: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FENCE_I"); - - this->gen_sync(PRE_SYNC, 70); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(32U, imm); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 1), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 70); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(FLUSH, nullptr); - } - - /* instruction 71: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ECALL"); - - this->gen_sync(PRE_SYNC, 71); - - 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(POST_SYNC, 71); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 72: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("EBREAK"); - - this->gen_sync(PRE_SYNC, 72); - - 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(POST_SYNC, 72); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 73: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("URET"); - - this->gen_sync(PRE_SYNC, 73); - - 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(POST_SYNC, 73); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 74: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRET"); - - this->gen_sync(PRE_SYNC, 74); - - 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(POST_SYNC, 74); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 75: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MRET"); - - this->gen_sync(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("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(POST_SYNC, 75); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 76: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("WFI"); - - this->gen_sync(PRE_SYNC, 76); - - 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(POST_SYNC, 76); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 77: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SFENCE.VMA"); - - this->gen_sync(PRE_SYNC, 77); - - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(32U, rs1); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 2), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - Value* FENCEtmp1_val = this->gen_const(32U, rs2); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 3), - this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 77); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 78: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRW"); - - this->gen_sync(PRE_SYNC, 78); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); - Value* CSRtmp0_val = rs_val_val; - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); - Value* Xtmp1_val = csr_val_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } else { - Value* CSRtmp2_val = rs_val_val; - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 78); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 79: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRS"); - - this->gen_sync(PRE_SYNC, 79); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(rs1 != 0){ - Value* CSRtmp1_val = this->builder.CreateOr( - xrd_val, - xrs1_val); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 79); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 80: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRC"); - - this->gen_sync(PRE_SYNC, 80); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(rs1 != 0){ - Value* CSRtmp1_val = this->builder.CreateAnd( - xrd_val, - this->builder.CreateNot(xrs1_val)); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 80); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 81: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRWI"); - - this->gen_sync(PRE_SYNC, 81); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* CSRtmp1_val = this->gen_ext( - this->gen_const(32U, zimm), - 32, - false); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 81); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 82: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRSI"); - - this->gen_sync(PRE_SYNC, 82); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - if(zimm != 0){ - Value* CSRtmp0_val = this->builder.CreateOr( - res_val, - this->gen_ext( - this->gen_const(32U, zimm), - 32, - false)); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); - } - if(rd != 0){ - Value* Xtmp1_val = res_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 82); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 83: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRCI"); - - this->gen_sync(PRE_SYNC, 83); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(zimm != 0){ - Value* CSRtmp1_val = this->builder.CreateAnd( - res_val, - this->builder.CreateNot(this->gen_ext( - this->gen_const(32U, zimm), - 32, - false))); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 83); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 84: FLD */ + /* instruction 37: FLD */ std::tuple __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLD"); - this->gen_sync(PRE_SYNC, 84); + this->gen_sync(PRE_SYNC, 37); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3913,17 +2011,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 84); + this->gen_sync(POST_SYNC, 37); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 85: FSD */ + /* instruction 38: FSD */ std::tuple __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSD"); - this->gen_sync(PRE_SYNC, 85); + this->gen_sync(PRE_SYNC, 38); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3958,17 +2056,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 85); + this->gen_sync(POST_SYNC, 38); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 86: FMADD.D */ + /* instruction 39: FMADD.D */ std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.D"); - this->gen_sync(PRE_SYNC, 86); + this->gen_sync(PRE_SYNC, 39); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4041,17 +2139,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 86); + this->gen_sync(POST_SYNC, 39); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 87: FMSUB.D */ + /* instruction 40: FMSUB.D */ std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.D"); - this->gen_sync(PRE_SYNC, 87); + this->gen_sync(PRE_SYNC, 40); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4124,17 +2222,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 87); + this->gen_sync(POST_SYNC, 40); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 88: FNMADD.D */ + /* instruction 41: FNMADD.D */ std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.D"); - this->gen_sync(PRE_SYNC, 88); + this->gen_sync(PRE_SYNC, 41); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4207,17 +2305,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 88); + this->gen_sync(POST_SYNC, 41); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 89: FNMSUB.D */ + /* instruction 42: FNMSUB.D */ std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.D"); - this->gen_sync(PRE_SYNC, 89); + this->gen_sync(PRE_SYNC, 42); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4290,17 +2388,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 89); + this->gen_sync(POST_SYNC, 42); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 90: FADD.D */ + /* instruction 43: FADD.D */ std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.D"); - this->gen_sync(PRE_SYNC, 90); + this->gen_sync(PRE_SYNC, 43); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4364,17 +2462,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 90); + this->gen_sync(POST_SYNC, 43); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 91: FSUB.D */ + /* instruction 44: FSUB.D */ std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.D"); - this->gen_sync(PRE_SYNC, 91); + this->gen_sync(PRE_SYNC, 44); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4438,17 +2536,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 91); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 92: FMUL.D */ + /* instruction 45: FMUL.D */ std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.D"); - this->gen_sync(PRE_SYNC, 92); + this->gen_sync(PRE_SYNC, 45); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4512,17 +2610,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 92); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 93: FDIV.D */ + /* instruction 46: FDIV.D */ std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.D"); - this->gen_sync(PRE_SYNC, 93); + this->gen_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4586,17 +2684,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 93); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 94: FSQRT.D */ + /* instruction 47: FSQRT.D */ std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.D"); - this->gen_sync(PRE_SYNC, 94); + this->gen_sync(PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4655,17 +2753,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 94); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 95: FSGNJ.D */ + /* instruction 48: FSGNJ.D */ std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.D"); - this->gen_sync(PRE_SYNC, 95); + this->gen_sync(PRE_SYNC, 48); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4715,17 +2813,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 95); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 96: FSGNJN.D */ + /* instruction 49: FSGNJN.D */ std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.D"); - this->gen_sync(PRE_SYNC, 96); + this->gen_sync(PRE_SYNC, 49); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4775,17 +2873,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 96); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 97: FSGNJX.D */ + /* instruction 50: FSGNJX.D */ std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.D"); - this->gen_sync(PRE_SYNC, 97); + this->gen_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4832,17 +2930,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 97); + this->gen_sync(POST_SYNC, 50); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 98: FMIN.D */ + /* instruction 51: FMIN.D */ std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.D"); - this->gen_sync(PRE_SYNC, 98); + this->gen_sync(PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4898,17 +2996,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 98); + this->gen_sync(POST_SYNC, 51); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 99: FMAX.D */ + /* instruction 52: FMAX.D */ std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.D"); - this->gen_sync(PRE_SYNC, 99); + this->gen_sync(PRE_SYNC, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4964,17 +3062,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 99); + this->gen_sync(POST_SYNC, 52); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 100: FCVT.S.D */ + /* instruction 53: FCVT.S.D */ std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.D"); - this->gen_sync(PRE_SYNC, 100); + this->gen_sync(PRE_SYNC, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5010,17 +3108,17 @@ private: false)); this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 100); + this->gen_sync(POST_SYNC, 53); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 101: FCVT.D.S */ + /* instruction 54: FCVT.D.S */ std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.S"); - this->gen_sync(PRE_SYNC, 101); + this->gen_sync(PRE_SYNC, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5061,17 +3159,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 101); + this->gen_sync(POST_SYNC, 54); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 102: FEQ.D */ + /* instruction 55: FEQ.D */ std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.D"); - this->gen_sync(PRE_SYNC, 102); + this->gen_sync(PRE_SYNC, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5119,17 +3217,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 102); + this->gen_sync(POST_SYNC, 55); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 103: FLT.D */ + /* instruction 56: FLT.D */ std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.D"); - this->gen_sync(PRE_SYNC, 103); + this->gen_sync(PRE_SYNC, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5177,17 +3275,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 103); + this->gen_sync(POST_SYNC, 56); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 104: FLE.D */ + /* instruction 57: FLE.D */ std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.D"); - this->gen_sync(PRE_SYNC, 104); + this->gen_sync(PRE_SYNC, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5235,17 +3333,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 104); + this->gen_sync(POST_SYNC, 57); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 105: FCLASS.D */ + /* instruction 58: FCLASS.D */ std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.D"); - this->gen_sync(PRE_SYNC, 105); + this->gen_sync(PRE_SYNC, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5273,17 +3371,17 @@ private: }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 105); + this->gen_sync(POST_SYNC, 58); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 106: FCVT.W.D */ + /* instruction 59: FCVT.W.D */ std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.D"); - this->gen_sync(PRE_SYNC, 106); + this->gen_sync(PRE_SYNC, 59); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5328,17 +3426,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 106); + this->gen_sync(POST_SYNC, 59); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 107: FCVT.WU.D */ + /* instruction 60: FCVT.WU.D */ std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.D"); - this->gen_sync(PRE_SYNC, 107); + this->gen_sync(PRE_SYNC, 60); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5383,17 +3481,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 107); + this->gen_sync(POST_SYNC, 60); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 108: FCVT.D.W */ + /* instruction 61: FCVT.D.W */ std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.W"); - this->gen_sync(PRE_SYNC, 108); + this->gen_sync(PRE_SYNC, 61); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5441,17 +3539,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 108); + this->gen_sync(POST_SYNC, 61); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 109: FCVT.D.WU */ + /* instruction 62: FCVT.D.WU */ std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.WU"); - this->gen_sync(PRE_SYNC, 109); + this->gen_sync(PRE_SYNC, 62); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5499,26 +3597,25 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 109); + this->gen_sync(POST_SYNC, 62); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 110: C.FLW */ - std::tuple __c_flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FLW"); + /* instruction 63: LUI */ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LUI"); - this->gen_sync(PRE_SYNC, 110); + this->gen_sync(PRE_SYNC, 63); - uint8_t rd = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f(8+{rd}), {uimm}({rs1})", fmt::arg("mnemonic", "c.flw"), - fmt::arg("rd", rd), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -5528,26 +3625,1922 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 63); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 64: AUIPC */ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(PRE_SYNC, 64); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 64); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 65: JAL */ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(PRE_SYNC, 65); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 65); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 66: BEQ */ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BEQ"); + + this->gen_sync(PRE_SYNC, 66); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 66); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 67: BNE */ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BNE"); + + this->gen_sync(PRE_SYNC, 67); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 67); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 68: BLT */ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLT"); + + this->gen_sync(PRE_SYNC, 68); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 68); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 69: BGE */ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGE"); + + this->gen_sync(PRE_SYNC, 69); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 69); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 70: BLTU */ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLTU"); + + this->gen_sync(PRE_SYNC, 70); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 70); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 71: BGEU */ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGEU"); + + this->gen_sync(PRE_SYNC, 71); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 71); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 72: LB */ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LB"); + + this->gen_sync(PRE_SYNC, 72); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + 8 + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 72); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 73: LH */ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LH"); + + this->gen_sync(PRE_SYNC, 73); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 73); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 74: LW */ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LW"); + + this->gen_sync(PRE_SYNC, 74); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 74); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 75: LBU */ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LBU"); + + this->gen_sync(PRE_SYNC, 75); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 75); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 76: LHU */ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LHU"); + + this->gen_sync(PRE_SYNC, 76); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 76); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 77: SB */ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SB"); + + this->gen_sync(PRE_SYNC, 77); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 77); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 78: SH */ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SH"); + + this->gen_sync(PRE_SYNC, 78); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 78); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 79: SW */ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SW"); + + this->gen_sync(PRE_SYNC, 79); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 79); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 80: ADDI */ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDI"); + + this->gen_sync(PRE_SYNC, 80); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( this->gen_ext( - res_val, - 64, - false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + 8 + traits::F0), false); + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 80); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 81: SLTI */ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTI"); + + this->gen_sync(PRE_SYNC, 81); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 81); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 82: SLTIU */ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTIU"); + + this->gen_sync(PRE_SYNC, 82); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = imm; + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, full_imm_val)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 82); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 83: XORI */ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XORI"); + + this->gen_sync(PRE_SYNC, 83); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 83); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 84: ORI */ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ORI"); + + this->gen_sync(PRE_SYNC, 84); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 84); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 85: ANDI */ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ANDI"); + + this->gen_sync(PRE_SYNC, 85); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 85); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 86: SLLI */ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLI"); + + this->gen_sync(PRE_SYNC, 86); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(shamt > 31){ + this->gen_raise_trap(0, 0); + } else { + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 86); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 87: SRLI */ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLI"); + + this->gen_sync(PRE_SYNC, 87); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(shamt > 31){ + this->gen_raise_trap(0, 0); + } else { + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 87); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 88: SRAI */ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAI"); + + this->gen_sync(PRE_SYNC, 88); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(shamt > 31){ + this->gen_raise_trap(0, 0); + } else { + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 88); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 89: ADD */ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADD"); + + this->gen_sync(PRE_SYNC, 89); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 89); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 90: SUB */ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUB"); + + this->gen_sync(PRE_SYNC, 90); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 90); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 91: SLL */ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLL"); + + this->gen_sync(PRE_SYNC, 91); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 91); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 92: SLT */ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLT"); + + this->gen_sync(PRE_SYNC, 92); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, true)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 92); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 93: SLTU */ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTU"); + + this->gen_sync(PRE_SYNC, 93); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, + false)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 93); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 94: XOR */ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XOR"); + + this->gen_sync(PRE_SYNC, 94); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 94); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 95: SRL */ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRL"); + + this->gen_sync(PRE_SYNC, 95); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 95); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 96: SRA */ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRA"); + + this->gen_sync(PRE_SYNC, 96); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 96); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 97: OR */ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("OR"); + + this->gen_sync(PRE_SYNC, 97); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 97); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 98: AND */ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AND"); + + this->gen_sync(PRE_SYNC, 98); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 98); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 99: FENCE */ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE"); + + this->gen_sync(PRE_SYNC, 99); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(32U, pred), + this->gen_const(32U, 4)), + this->gen_const(32U, succ)); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 0), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 99); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 100: FENCE_I */ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE_I"); + + this->gen_sync(PRE_SYNC, 100); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(32U, imm); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 1), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 100); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(FLUSH, nullptr); + } + + /* instruction 101: ECALL */ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ECALL"); + + this->gen_sync(PRE_SYNC, 101); + + 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(POST_SYNC, 101); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 102: EBREAK */ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("EBREAK"); + + this->gen_sync(PRE_SYNC, 102); + + 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(POST_SYNC, 102); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 103: URET */ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("URET"); + + this->gen_sync(PRE_SYNC, 103); + + 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(POST_SYNC, 103); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 104: SRET */ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRET"); + + this->gen_sync(PRE_SYNC, 104); + + 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(POST_SYNC, 104); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 105: MRET */ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MRET"); + + this->gen_sync(PRE_SYNC, 105); + + 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(POST_SYNC, 105); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 106: WFI */ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("WFI"); + + this->gen_sync(PRE_SYNC, 106); + + 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(POST_SYNC, 106); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 107: SFENCE.VMA */ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SFENCE.VMA"); + + this->gen_sync(PRE_SYNC, 107); + + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(32U, rs1); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 2), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); + Value* FENCEtmp1_val = this->gen_const(32U, rs2); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 3), + this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 107); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 108: CSRRW */ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRW"); + + this->gen_sync(PRE_SYNC, 108); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + Value* CSRtmp0_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); + Value* Xtmp1_val = csr_val_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* CSRtmp2_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 108); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 109: CSRRS */ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRS"); + + this->gen_sync(PRE_SYNC, 109); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateOr( + xrd_val, + xrs1_val); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 109); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 110: CSRRC */ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRC"); + + this->gen_sync(PRE_SYNC, 110); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + xrd_val, + this->builder.CreateNot(xrs1_val)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 110); @@ -5556,20 +5549,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 111: C.FSW */ - std::tuple __c_fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FSW"); + /* instruction 111: CSRRWI */ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRWI"); this->gen_sync(PRE_SYNC, 111); - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,1>(instr) << 6) | (bit_sub<6,1>(instr) << 2) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f(8+{rs2}), {uimm}({rs1})", fmt::arg("mnemonic", "c.fsw"), - fmt::arg("rs2", rs2), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -5579,19 +5572,20 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(rs2 + 8 + traits::F0, 0), - this-> get_type(32) - ); + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* CSRtmp1_val = this->gen_ext( + this->gen_const(32U, zimm), + 32, + false); this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 111); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -5599,19 +5593,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 112: C.FLWSP */ - std::tuple __c_flwsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FLWSP"); + /* instruction 112: CSRRSI */ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRSI"); this->gen_sync(PRE_SYNC, 112); - uint8_t uimm = ((bit_sub<2,2>(instr) << 6) | (bit_sub<4,3>(instr) << 2) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f{rd}, {uimm}(x2)", fmt::arg("mnemonic", "c.flwsp"), - fmt::arg("rd", rd), fmt::arg("uimm", uimm)); + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -5621,26 +5616,24 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* res_val = this->gen_read_mem(traits::MEM, offs_val, 32/8); - if(64 == 32){ - Value* Ftmp0_val = res_val; - this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); - } else { - uint64_t upper_val = - 1; - Value* Ftmp1_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, upper_val), - this->gen_const(64U, 32)), + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + if(zimm != 0){ + Value* CSRtmp0_val = this->builder.CreateOr( + res_val, this->gen_ext( - res_val, - 64, + this->gen_const(32U, zimm), + 32, false)); - this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); + } + if(rd != 0){ + Value* Xtmp1_val = res_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 112); @@ -5649,19 +5642,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 113: C.FSWSP */ - std::tuple __c_fswsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.FSWSP"); + /* instruction 113: CSRRCI */ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRCI"); this->gen_sync(PRE_SYNC, 113); - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint8_t uimm = ((bit_sub<7,2>(instr) << 6) | (bit_sub<9,4>(instr) << 2)); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} f{rs2}, {uimm}(x2), ", fmt::arg("mnemonic", "c.fswsp"), - fmt::arg("rs2", rs2), fmt::arg("uimm", uimm)); + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -5671,19 +5665,25 @@ private: } Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(32U, uimm)); - Value* MEMtmp0_val = this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::F0, 0), - this-> get_type(32) - ); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + Value* res_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(zimm != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + res_val, + this->builder.CreateNot(this->gen_ext( + this->gen_const(32U, zimm), + 32, + false))); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 113); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index b3a3cc3..b153309 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -246,6 +246,44 @@ private: {16, 0b1100000000000010, 0b1110000000000011, &this_class::__c_swsp}, /* instruction DII */ {16, 0b0000000000000000, 0b1111111111111111, &this_class::__dii}, + /* instruction LR.W */ + {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, + /* instruction SC.W */ + {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, + /* instruction AMOSWAP.W */ + {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, + /* instruction AMOADD.W */ + {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, + /* instruction AMOXOR.W */ + {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, + /* instruction AMOAND.W */ + {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, + /* instruction AMOOR.W */ + {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, + /* instruction AMOMIN.W */ + {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, + /* instruction AMOMAX.W */ + {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, + /* instruction AMOMINU.W */ + {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, + /* instruction AMOMAXU.W */ + {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, + /* instruction MUL */ + {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, + /* instruction MULH */ + {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, + /* instruction MULHSU */ + {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, + /* instruction MULHU */ + {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, + /* instruction DIV */ + {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, + /* instruction DIVU */ + {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, + /* instruction REM */ + {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, + /* instruction REMU */ + {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ @@ -348,44 +386,6 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, - /* instruction LR.W */ - {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, - /* instruction SC.W */ - {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, - /* instruction AMOSWAP.W */ - {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, - /* instruction AMOADD.W */ - {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, - /* instruction AMOXOR.W */ - {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, - /* instruction AMOAND.W */ - {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, - /* instruction AMOOR.W */ - {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, - /* instruction AMOMIN.W */ - {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, - /* instruction AMOMAX.W */ - {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, - /* instruction AMOMINU.W */ - {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, - /* instruction AMOMAXU.W */ - {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, - /* instruction MUL */ - {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, - /* instruction MULH */ - {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, - /* instruction MULHSU */ - {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, - /* instruction MULHU */ - {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, - /* instruction DIV */ - {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, - /* instruction DIVU */ - {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, - /* instruction REM */ - {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, - /* instruction REMU */ - {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, }}; /* instruction definitions */ @@ -1478,2099 +1478,11 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 29: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LUI"); - - this->gen_sync(PRE_SYNC, 29); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_const(32U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 29); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 30: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AUIPC"); - - this->gen_sync(PRE_SYNC, 30); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 30); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 31: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("JAL"); - - this->gen_sync(PRE_SYNC, 31); - - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 31); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 32: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BEQ"); - - this->gen_sync(PRE_SYNC, 32); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 32); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 33: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BNE"); - - this->gen_sync(PRE_SYNC, 33); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 33); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 34: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BLT"); - - this->gen_sync(PRE_SYNC, 34); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, true)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 34); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 35: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BGE"); - - this->gen_sync(PRE_SYNC, 35); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, true)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 35); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 36: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BLTU"); - - this->gen_sync(PRE_SYNC, 36); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 36); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 37: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BGEU"); - - this->gen_sync(PRE_SYNC, 37); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 32, true), - this->gen_const(32U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(32U, 4)), - 32); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 37); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 38: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LB"); - - this->gen_sync(PRE_SYNC, 38); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 38); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 39: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LH"); - - this->gen_sync(PRE_SYNC, 39); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 39); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 40: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LW"); - - this->gen_sync(PRE_SYNC, 40); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 32, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 40); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 41: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LBU"); - - this->gen_sync(PRE_SYNC, 41); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 41); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 42: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LHU"); - - this->gen_sync(PRE_SYNC, 42); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 32, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 42); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 43: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SB"); - - this->gen_sync(PRE_SYNC, 43); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 43); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 44: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SH"); - - this->gen_sync(PRE_SYNC, 44); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 44); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 45: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SW"); - - this->gen_sync(PRE_SYNC, 45); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 45); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 46: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDI"); - - this->gen_sync(PRE_SYNC, 46); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 46); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 47: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTI"); - - this->gen_sync(PRE_SYNC, 47); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 47); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 48: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTIU"); - - this->gen_sync(PRE_SYNC, 48); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = imm; - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, full_imm_val)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 48); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 49: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("XORI"); - - this->gen_sync(PRE_SYNC, 49); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 49); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 50: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ORI"); - - this->gen_sync(PRE_SYNC, 50); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 50); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 51: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ANDI"); - - this->gen_sync(PRE_SYNC, 51); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_const(32U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 51); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 52: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(PRE_SYNC, 52); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 52); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 53: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(PRE_SYNC, 53); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 53); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 54: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(PRE_SYNC, 54); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(shamt > 31){ - this->gen_raise_trap(0, 0); - } else { - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(32U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 54); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 55: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADD"); - - this->gen_sync(PRE_SYNC, 55); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 55); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 56: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SUB"); - - this->gen_sync(PRE_SYNC, 56); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 56); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 57: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLL"); - - this->gen_sync(PRE_SYNC, 57); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(32U, 32), - this->gen_const(32U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 57); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 58: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLT"); - - this->gen_sync(PRE_SYNC, 58); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, true)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 58); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 59: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTU"); - - this->gen_sync(PRE_SYNC, 59); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 32, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 32, - false)), - this->gen_const(32U, 1), - this->gen_const(32U, 0), - 32); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 59); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 60: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("XOR"); - - this->gen_sync(PRE_SYNC, 60); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 60); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 61: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRL"); - - this->gen_sync(PRE_SYNC, 61); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(32U, 32), - this->gen_const(32U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 61); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 62: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRA"); - - this->gen_sync(PRE_SYNC, 62); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(32U, 32), - this->gen_const(32U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 62); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 63: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("OR"); - - this->gen_sync(PRE_SYNC, 63); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 63); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 64: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AND"); - - this->gen_sync(PRE_SYNC, 64); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 64); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 65: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FENCE"); - - this->gen_sync(PRE_SYNC, 65); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t succ = ((bit_sub<20,4>(instr))); - uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(32U, pred), - this->gen_const(32U, 4)), - this->gen_const(32U, succ)); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 0), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 65); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 66: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FENCE_I"); - - this->gen_sync(PRE_SYNC, 66); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(32U, imm); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 1), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 66); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(FLUSH, nullptr); - } - - /* instruction 67: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ECALL"); - - this->gen_sync(PRE_SYNC, 67); - - 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(POST_SYNC, 67); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 68: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("EBREAK"); - - this->gen_sync(PRE_SYNC, 68); - - 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(POST_SYNC, 68); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 69: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("URET"); - - this->gen_sync(PRE_SYNC, 69); - - 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(POST_SYNC, 69); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 70: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRET"); - - this->gen_sync(PRE_SYNC, 70); - - 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(POST_SYNC, 70); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 71: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MRET"); - - this->gen_sync(PRE_SYNC, 71); - - 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(POST_SYNC, 71); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 72: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("WFI"); - - this->gen_sync(PRE_SYNC, 72); - - 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(POST_SYNC, 72); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 73: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SFENCE.VMA"); - - this->gen_sync(PRE_SYNC, 73); - - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(32U, rs1); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 2), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); - Value* FENCEtmp1_val = this->gen_const(32U, rs2); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 3), - this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 73); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 74: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRW"); - - this->gen_sync(PRE_SYNC, 74); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); - Value* CSRtmp0_val = rs_val_val; - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); - Value* Xtmp1_val = csr_val_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } else { - Value* CSRtmp2_val = rs_val_val; - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 74); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 75: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRS"); - - this->gen_sync(PRE_SYNC, 75); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(rs1 != 0){ - Value* CSRtmp1_val = this->builder.CreateOr( - xrd_val, - xrs1_val); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 75); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 76: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRC"); - - this->gen_sync(PRE_SYNC, 76); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(rs1 != 0){ - Value* CSRtmp1_val = this->builder.CreateAnd( - xrd_val, - this->builder.CreateNot(xrs1_val)); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 76); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 77: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRWI"); - - this->gen_sync(PRE_SYNC, 77); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(32, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* CSRtmp1_val = this->gen_ext( - this->gen_const(32U, zimm), - 32, - false); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 77); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 78: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRSI"); - - this->gen_sync(PRE_SYNC, 78); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - if(zimm != 0){ - Value* CSRtmp0_val = this->builder.CreateOr( - res_val, - this->gen_ext( - this->gen_const(32U, zimm), - 32, - false)); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); - } - if(rd != 0){ - Value* Xtmp1_val = res_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 78); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 79: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRCI"); - - this->gen_sync(PRE_SYNC, 79); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 32/8); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(zimm != 0){ - Value* CSRtmp1_val = this->builder.CreateAnd( - res_val, - this->builder.CreateNot(this->gen_ext( - this->gen_const(32U, zimm), - 32, - false))); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 79); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 80: LR.W */ + /* instruction 29: LR.W */ std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("LR.W"); - this->gen_sync(PRE_SYNC, 80); + this->gen_sync(PRE_SYNC, 29); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3609,17 +1521,17 @@ private: this->builder.CreateZExtOrTrunc(REStmp1_val,this->get_type(32))); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 80); + this->gen_sync(POST_SYNC, 29); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 81: SC.W */ + /* instruction 30: SC.W */ std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("SC.W"); - this->gen_sync(PRE_SYNC, 81); + this->gen_sync(PRE_SYNC, 30); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3681,17 +1593,17 @@ private: this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 81); + this->gen_sync(POST_SYNC, 30); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 82: AMOSWAP.W */ + /* instruction 31: AMOSWAP.W */ std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOSWAP.W"); - this->gen_sync(PRE_SYNC, 82); + this->gen_sync(PRE_SYNC, 31); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3728,17 +1640,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 82); + this->gen_sync(POST_SYNC, 31); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 83: AMOADD.W */ + /* instruction 32: AMOADD.W */ std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOADD.W"); - this->gen_sync(PRE_SYNC, 83); + this->gen_sync(PRE_SYNC, 32); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3779,17 +1691,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 83); + this->gen_sync(POST_SYNC, 32); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 84: AMOXOR.W */ + /* instruction 33: AMOXOR.W */ std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOXOR.W"); - this->gen_sync(PRE_SYNC, 84); + this->gen_sync(PRE_SYNC, 33); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3830,17 +1742,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 84); + this->gen_sync(POST_SYNC, 33); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 85: AMOAND.W */ + /* instruction 34: AMOAND.W */ std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOAND.W"); - this->gen_sync(PRE_SYNC, 85); + this->gen_sync(PRE_SYNC, 34); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3881,17 +1793,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 85); + this->gen_sync(POST_SYNC, 34); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 86: AMOOR.W */ + /* instruction 35: AMOOR.W */ std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOOR.W"); - this->gen_sync(PRE_SYNC, 86); + this->gen_sync(PRE_SYNC, 35); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3932,17 +1844,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 86); + this->gen_sync(POST_SYNC, 35); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 87: AMOMIN.W */ + /* instruction 36: AMOMIN.W */ std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMIN.W"); - this->gen_sync(PRE_SYNC, 87); + this->gen_sync(PRE_SYNC, 36); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -3992,17 +1904,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 87); + this->gen_sync(POST_SYNC, 36); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 88: AMOMAX.W */ + /* instruction 37: AMOMAX.W */ std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAX.W"); - this->gen_sync(PRE_SYNC, 88); + this->gen_sync(PRE_SYNC, 37); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4052,17 +1964,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 88); + this->gen_sync(POST_SYNC, 37); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 89: AMOMINU.W */ + /* instruction 38: AMOMINU.W */ std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMINU.W"); - this->gen_sync(PRE_SYNC, 89); + this->gen_sync(PRE_SYNC, 38); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4108,17 +2020,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 89); + this->gen_sync(POST_SYNC, 38); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 90: AMOMAXU.W */ + /* instruction 39: AMOMAXU.W */ std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("AMOMAXU.W"); - this->gen_sync(PRE_SYNC, 90); + this->gen_sync(PRE_SYNC, 39); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4164,17 +2076,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 90); + this->gen_sync(POST_SYNC, 39); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 91: MUL */ + /* instruction 40: MUL */ std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MUL"); - this->gen_sync(PRE_SYNC, 91); + this->gen_sync(PRE_SYNC, 40); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4212,17 +2124,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 91); + this->gen_sync(POST_SYNC, 40); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 92: MULH */ + /* instruction 41: MULH */ std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULH"); - this->gen_sync(PRE_SYNC, 92); + this->gen_sync(PRE_SYNC, 41); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4262,17 +2174,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 92); + this->gen_sync(POST_SYNC, 41); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 93: MULHSU */ + /* instruction 42: MULHSU */ std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHSU"); - this->gen_sync(PRE_SYNC, 93); + this->gen_sync(PRE_SYNC, 42); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4312,17 +2224,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 93); + this->gen_sync(POST_SYNC, 42); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 94: MULHU */ + /* instruction 43: MULHU */ std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHU"); - this->gen_sync(PRE_SYNC, 94); + this->gen_sync(PRE_SYNC, 43); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4362,17 +2274,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 94); + this->gen_sync(POST_SYNC, 43); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 95: DIV */ + /* instruction 44: DIV */ std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIV"); - this->gen_sync(PRE_SYNC, 95); + this->gen_sync(PRE_SYNC, 44); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4461,17 +2373,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 95); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 96: DIVU */ + /* instruction 45: DIVU */ std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVU"); - this->gen_sync(PRE_SYNC, 96); + this->gen_sync(PRE_SYNC, 45); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4523,17 +2435,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 96); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 97: REM */ + /* instruction 46: REM */ std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REM"); - this->gen_sync(PRE_SYNC, 97); + this->gen_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4622,17 +2534,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 97); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 98: REMU */ + /* instruction 47: REMU */ std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMU"); - this->gen_sync(PRE_SYNC, 98); + this->gen_sync(PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4684,6 +2596,2094 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 47); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 48: LUI */ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LUI"); + + this->gen_sync(PRE_SYNC, 48); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(32U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 48); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 49: AUIPC */ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(PRE_SYNC, 49); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 49); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 50: JAL */ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(PRE_SYNC, 50); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 50); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 51: BEQ */ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BEQ"); + + this->gen_sync(PRE_SYNC, 51); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 51); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 52: BNE */ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BNE"); + + this->gen_sync(PRE_SYNC, 52); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 52); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 53: BLT */ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLT"); + + this->gen_sync(PRE_SYNC, 53); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 53); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 54: BGE */ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGE"); + + this->gen_sync(PRE_SYNC, 54); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 54); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 55: BLTU */ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLTU"); + + this->gen_sync(PRE_SYNC, 55); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 55); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 56: BGEU */ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGEU"); + + this->gen_sync(PRE_SYNC, 56); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 32, true), + this->gen_const(32U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(32U, 4)), + 32); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(32U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 56); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 57: LB */ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LB"); + + this->gen_sync(PRE_SYNC, 57); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 57); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 58: LH */ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LH"); + + this->gen_sync(PRE_SYNC, 58); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 58); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 59: LW */ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LW"); + + this->gen_sync(PRE_SYNC, 59); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 32, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 59); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 60: LBU */ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LBU"); + + this->gen_sync(PRE_SYNC, 60); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 60); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 61: LHU */ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LHU"); + + this->gen_sync(PRE_SYNC, 61); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 32, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 61); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 62: SB */ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SB"); + + this->gen_sync(PRE_SYNC, 62); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 62); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 63: SH */ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SH"); + + this->gen_sync(PRE_SYNC, 63); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 63); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 64: SW */ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SW"); + + this->gen_sync(PRE_SYNC, 64); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 64); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 65: ADDI */ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDI"); + + this->gen_sync(PRE_SYNC, 65); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 65); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 66: SLTI */ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTI"); + + this->gen_sync(PRE_SYNC, 66); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 66); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 67: SLTIU */ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTIU"); + + this->gen_sync(PRE_SYNC, 67); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = imm; + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, full_imm_val)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 67); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 68: XORI */ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XORI"); + + this->gen_sync(PRE_SYNC, 68); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 68); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 69: ORI */ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ORI"); + + this->gen_sync(PRE_SYNC, 69); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 69); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 70: ANDI */ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ANDI"); + + this->gen_sync(PRE_SYNC, 70); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_const(32U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 70); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 71: SLLI */ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLI"); + + this->gen_sync(PRE_SYNC, 71); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(shamt > 31){ + this->gen_raise_trap(0, 0); + } else { + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 71); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 72: SRLI */ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLI"); + + this->gen_sync(PRE_SYNC, 72); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(shamt > 31){ + this->gen_raise_trap(0, 0); + } else { + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 72); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 73: SRAI */ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAI"); + + this->gen_sync(PRE_SYNC, 73); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(shamt > 31){ + this->gen_raise_trap(0, 0); + } else { + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(32U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 73); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 74: ADD */ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADD"); + + this->gen_sync(PRE_SYNC, 74); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 74); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 75: SUB */ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUB"); + + this->gen_sync(PRE_SYNC, 75); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 75); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 76: SLL */ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLL"); + + this->gen_sync(PRE_SYNC, 76); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 76); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 77: SLT */ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLT"); + + this->gen_sync(PRE_SYNC, 77); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, true)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 77); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 78: SLTU */ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTU"); + + this->gen_sync(PRE_SYNC, 78); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 32, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 32, + false)), + this->gen_const(32U, 1), + this->gen_const(32U, 0), + 32); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 78); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 79: XOR */ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XOR"); + + this->gen_sync(PRE_SYNC, 79); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 79); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 80: SRL */ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRL"); + + this->gen_sync(PRE_SYNC, 80); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 80); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 81: SRA */ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRA"); + + this->gen_sync(PRE_SYNC, 81); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(32U, 32), + this->gen_const(32U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 81); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 82: OR */ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("OR"); + + this->gen_sync(PRE_SYNC, 82); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 82); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 83: AND */ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AND"); + + this->gen_sync(PRE_SYNC, 83); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 83); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 84: FENCE */ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE"); + + this->gen_sync(PRE_SYNC, 84); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(32U, pred), + this->gen_const(32U, 4)), + this->gen_const(32U, succ)); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 0), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 84); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 85: FENCE_I */ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE_I"); + + this->gen_sync(PRE_SYNC, 85); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(32U, imm); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 1), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 85); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(FLUSH, nullptr); + } + + /* instruction 86: ECALL */ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ECALL"); + + this->gen_sync(PRE_SYNC, 86); + + 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(POST_SYNC, 86); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 87: EBREAK */ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("EBREAK"); + + this->gen_sync(PRE_SYNC, 87); + + 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(POST_SYNC, 87); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 88: URET */ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("URET"); + + this->gen_sync(PRE_SYNC, 88); + + 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(POST_SYNC, 88); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 89: SRET */ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRET"); + + this->gen_sync(PRE_SYNC, 89); + + 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(POST_SYNC, 89); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 90: MRET */ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MRET"); + + this->gen_sync(PRE_SYNC, 90); + + 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(POST_SYNC, 90); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 91: WFI */ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("WFI"); + + this->gen_sync(PRE_SYNC, 91); + + 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(POST_SYNC, 91); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 92: SFENCE.VMA */ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SFENCE.VMA"); + + this->gen_sync(PRE_SYNC, 92); + + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(32U, rs1); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 2), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(32))); + Value* FENCEtmp1_val = this->gen_const(32U, rs2); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 3), + this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 92); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 93: CSRRW */ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRW"); + + this->gen_sync(PRE_SYNC, 93); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + Value* CSRtmp0_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); + Value* Xtmp1_val = csr_val_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* CSRtmp2_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 93); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 94: CSRRS */ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRS"); + + this->gen_sync(PRE_SYNC, 94); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateOr( + xrd_val, + xrs1_val); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 94); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 95: CSRRC */ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRC"); + + this->gen_sync(PRE_SYNC, 95); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 32/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + xrd_val, + this->builder.CreateNot(xrs1_val)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 95); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 96: CSRRWI */ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRWI"); + + this->gen_sync(PRE_SYNC, 96); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(32, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 32/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* CSRtmp1_val = this->gen_ext( + this->gen_const(32U, zimm), + 32, + false); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 96); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 97: CSRRSI */ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRSI"); + + this->gen_sync(PRE_SYNC, 97); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 32/8); + if(zimm != 0){ + Value* CSRtmp0_val = this->builder.CreateOr( + res_val, + this->gen_ext( + this->gen_const(32U, zimm), + 32, + false)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(32))); + } + if(rd != 0){ + Value* Xtmp1_val = res_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 97); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 98: CSRRCI */ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRCI"); + + this->gen_sync(PRE_SYNC, 98); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 32/8); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(zimm != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + res_val, + this->builder.CreateNot(this->gen_ext( + this->gen_const(32U, zimm), + 32, + false))); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 98); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); diff --git a/riscv/src/internal/vm_rv64gc.cpp b/riscv/src/internal/vm_rv64gc.cpp index 14eb8a4..451efa7 100644 --- a/riscv/src/internal/vm_rv64gc.cpp +++ b/riscv/src/internal/vm_rv64gc.cpp @@ -262,6 +262,84 @@ private: {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_flwsp}, /* instruction C.FSWSP */ {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_fswsp}, + /* instruction C.LD */ + {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_ld}, + /* instruction C.SD */ + {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_sd}, + /* instruction C.SUBW */ + {16, 0b1001110000000001, 0b1111110001100011, &this_class::__c_subw}, + /* instruction C.ADDW */ + {16, 0b1001110000100001, 0b1111110001100011, &this_class::__c_addw}, + /* instruction C.ADDIW */ + {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_addiw}, + /* instruction C.LDSP */ + {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_ldsp}, + /* instruction C.SDSP */ + {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_sdsp}, + /* instruction FLD */ + {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, + /* instruction FSD */ + {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd}, + /* instruction FMADD.D */ + {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d}, + /* instruction FMSUB.D */ + {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d}, + /* instruction FNMADD.D */ + {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d}, + /* instruction FNMSUB.D */ + {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d}, + /* instruction FADD.D */ + {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d}, + /* instruction FSUB.D */ + {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d}, + /* instruction FMUL.D */ + {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d}, + /* instruction FDIV.D */ + {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d}, + /* instruction FSQRT.D */ + {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d}, + /* instruction FSGNJ.D */ + {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d}, + /* instruction FSGNJN.D */ + {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d}, + /* instruction FSGNJX.D */ + {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d}, + /* instruction FMIN.D */ + {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d}, + /* instruction FMAX.D */ + {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d}, + /* instruction FCVT.S.D */ + {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d}, + /* instruction FCVT.D.S */ + {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s}, + /* instruction FEQ.D */ + {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d}, + /* instruction FLT.D */ + {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d}, + /* instruction FLE.D */ + {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d}, + /* instruction FCLASS.D */ + {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d}, + /* instruction FCVT.W.D */ + {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d}, + /* instruction FCVT.WU.D */ + {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d}, + /* instruction FCVT.D.W */ + {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, + /* instruction FCVT.D.WU */ + {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, + /* instruction FCVT.L.D */ + {32, 0b11000010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_l_d}, + /* instruction FCVT.LU.D */ + {32, 0b11000010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_lu_d}, + /* instruction FCVT.D.L */ + {32, 0b11010010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_l}, + /* instruction FCVT.D.LU */ + {32, 0b11010010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_lu}, + /* instruction FMV.X.D */ + {32, 0b11100010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_d}, + /* instruction FMV.D.X */ + {32, 0b11110010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_d_x}, /* instruction LUI */ {32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, &this_class::__lui}, /* instruction AUIPC */ @@ -364,70 +442,6 @@ private: {32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, &this_class::__csrrsi}, /* instruction CSRRCI */ {32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, &this_class::__csrrci}, - /* instruction FLD */ - {32, 0b00000000000000000011000000000111, 0b00000000000000000111000001111111, &this_class::__fld}, - /* instruction FSD */ - {32, 0b00000000000000000011000000100111, 0b00000000000000000111000001111111, &this_class::__fsd}, - /* instruction FMADD.D */ - {32, 0b00000010000000000000000001000011, 0b00000110000000000000000001111111, &this_class::__fmadd_d}, - /* instruction FMSUB.D */ - {32, 0b00000010000000000000000001000111, 0b00000110000000000000000001111111, &this_class::__fmsub_d}, - /* instruction FNMADD.D */ - {32, 0b00000010000000000000000001001111, 0b00000110000000000000000001111111, &this_class::__fnmadd_d}, - /* instruction FNMSUB.D */ - {32, 0b00000010000000000000000001001011, 0b00000110000000000000000001111111, &this_class::__fnmsub_d}, - /* instruction FADD.D */ - {32, 0b00000010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fadd_d}, - /* instruction FSUB.D */ - {32, 0b00001010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fsub_d}, - /* instruction FMUL.D */ - {32, 0b00010010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fmul_d}, - /* instruction FDIV.D */ - {32, 0b00011010000000000000000001010011, 0b11111110000000000000000001111111, &this_class::__fdiv_d}, - /* instruction FSQRT.D */ - {32, 0b01011010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fsqrt_d}, - /* instruction FSGNJ.D */ - {32, 0b00100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnj_d}, - /* instruction FSGNJN.D */ - {32, 0b00100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjn_d}, - /* instruction FSGNJX.D */ - {32, 0b00100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__fsgnjx_d}, - /* instruction FMIN.D */ - {32, 0b00101010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fmin_d}, - /* instruction FMAX.D */ - {32, 0b00101010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__fmax_d}, - /* instruction FCVT.S.D */ - {32, 0b01000000000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_d}, - /* instruction FCVT.D.S */ - {32, 0b01000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_s}, - /* instruction FEQ.D */ - {32, 0b10100010000000000010000001010011, 0b11111110000000000111000001111111, &this_class::__feq_d}, - /* instruction FLT.D */ - {32, 0b10100010000000000001000001010011, 0b11111110000000000111000001111111, &this_class::__flt_d}, - /* instruction FLE.D */ - {32, 0b10100010000000000000000001010011, 0b11111110000000000111000001111111, &this_class::__fle_d}, - /* instruction FCLASS.D */ - {32, 0b11100010000000000001000001010011, 0b11111111111100000111000001111111, &this_class::__fclass_d}, - /* instruction FCVT.W.D */ - {32, 0b11000010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_w_d}, - /* instruction FCVT.WU.D */ - {32, 0b11000010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_wu_d}, - /* instruction FCVT.D.W */ - {32, 0b11010010000000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_w}, - /* instruction FCVT.D.WU */ - {32, 0b11010010000100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_wu}, - /* instruction FCVT.L.D */ - {32, 0b11000010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_l_d}, - /* instruction FCVT.LU.D */ - {32, 0b11000010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_lu_d}, - /* instruction FCVT.D.L */ - {32, 0b11010010001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_l}, - /* instruction FCVT.D.LU */ - {32, 0b11010010001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_d_lu}, - /* instruction FMV.X.D */ - {32, 0b11100010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_x_d}, - /* instruction FMV.D.X */ - {32, 0b11110010000000000000000001010011, 0b11111111111100000111000001111111, &this_class::__fmv_d_x}, /* instruction FLW */ {32, 0b00000000000000000010000000000111, 0b00000000000000000111000001111111, &this_class::__flw}, /* instruction FSW */ @@ -488,22 +502,6 @@ private: {32, 0b11010000001000000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_l}, /* instruction FCVT.S.LU */ {32, 0b11010000001100000000000001010011, 0b11111111111100000000000001111111, &this_class::__fcvt_s_lu}, - /* instruction MUL */ - {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, - /* instruction MULH */ - {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, - /* instruction MULHSU */ - {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, - /* instruction MULHU */ - {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, - /* instruction DIV */ - {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, - /* instruction DIVU */ - {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, - /* instruction REM */ - {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, - /* instruction REMU */ - {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, /* instruction LR.W */ {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, /* instruction SC.W */ @@ -526,6 +524,54 @@ private: {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, /* instruction AMOMAXU.W */ {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, + /* instruction LR.D */ + {32, 0b00010000000000000011000000101111, 0b11111001111100000111000001111111, &this_class::__lr_d}, + /* instruction SC.D */ + {32, 0b00011000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__sc_d}, + /* instruction AMOSWAP.D */ + {32, 0b00001000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_d}, + /* instruction AMOADD.D */ + {32, 0b00000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_d}, + /* instruction AMOXOR.D */ + {32, 0b00100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_d}, + /* instruction AMOAND.D */ + {32, 0b01100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_d}, + /* instruction AMOOR.D */ + {32, 0b01000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_d}, + /* instruction AMOMIN.D */ + {32, 0b10000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_d}, + /* instruction AMOMAX.D */ + {32, 0b10100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_d}, + /* instruction AMOMINU.D */ + {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d}, + /* instruction AMOMAXU.D */ + {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d}, + /* instruction MUL */ + {32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__mul}, + /* instruction MULH */ + {32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, &this_class::__mulh}, + /* instruction MULHSU */ + {32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, &this_class::__mulhsu}, + /* instruction MULHU */ + {32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, &this_class::__mulhu}, + /* instruction DIV */ + {32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, &this_class::__div}, + /* instruction DIVU */ + {32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, &this_class::__divu}, + /* instruction REM */ + {32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, &this_class::__rem}, + /* instruction REMU */ + {32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, &this_class::__remu}, + /* instruction MULW */ + {32, 0b00000010000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__mulw}, + /* instruction DIVW */ + {32, 0b00000010000000000100000000111011, 0b11111110000000000111000001111111, &this_class::__divw}, + /* instruction DIVUW */ + {32, 0b00000010000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__divuw}, + /* instruction REMW */ + {32, 0b00000010000000000110000000111011, 0b11111110000000000111000001111111, &this_class::__remw}, + /* instruction REMUW */ + {32, 0b00000010000000000111000000111011, 0b11111110000000000111000001111111, &this_class::__remuw}, /* instruction LWU */ {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, /* instruction LD */ @@ -550,52 +596,6 @@ private: {32, 0b00000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__srlw}, /* instruction SRAW */ {32, 0b01000000000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__sraw}, - /* instruction MULW */ - {32, 0b00000010000000000000000000111011, 0b11111110000000000111000001111111, &this_class::__mulw}, - /* instruction DIVW */ - {32, 0b00000010000000000100000000111011, 0b11111110000000000111000001111111, &this_class::__divw}, - /* instruction DIVUW */ - {32, 0b00000010000000000101000000111011, 0b11111110000000000111000001111111, &this_class::__divuw}, - /* instruction REMW */ - {32, 0b00000010000000000110000000111011, 0b11111110000000000111000001111111, &this_class::__remw}, - /* instruction REMUW */ - {32, 0b00000010000000000111000000111011, 0b11111110000000000111000001111111, &this_class::__remuw}, - /* instruction LR.D */ - {32, 0b00010000000000000011000000101111, 0b11111001111100000111000001111111, &this_class::__lr_d}, - /* instruction SC.D */ - {32, 0b00011000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__sc_d}, - /* instruction AMOSWAP.D */ - {32, 0b00001000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_d}, - /* instruction AMOADD.D */ - {32, 0b00000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_d}, - /* instruction AMOXOR.D */ - {32, 0b00100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_d}, - /* instruction AMOAND.D */ - {32, 0b01100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_d}, - /* instruction AMOOR.D */ - {32, 0b01000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_d}, - /* instruction AMOMIN.D */ - {32, 0b10000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_d}, - /* instruction AMOMAX.D */ - {32, 0b10100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_d}, - /* instruction AMOMINU.D */ - {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d}, - /* instruction AMOMAXU.D */ - {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d}, - /* instruction C.LD */ - {16, 0b0110000000000000, 0b1110000000000011, &this_class::__c_ld}, - /* instruction C.SD */ - {16, 0b1110000000000000, 0b1110000000000011, &this_class::__c_sd}, - /* instruction C.SUBW */ - {16, 0b1001110000000001, 0b1111110001100011, &this_class::__c_subw}, - /* instruction C.ADDW */ - {16, 0b1001110000100001, 0b1111110001100011, &this_class::__c_addw}, - /* instruction C.ADDIW */ - {16, 0b0010000000000001, 0b1110000000000011, &this_class::__c_addiw}, - /* instruction C.LDSP */ - {16, 0b0110000000000010, 0b1110000000000011, &this_class::__c_ldsp}, - /* instruction C.SDSP */ - {16, 0b1110000000000010, 0b1110000000000011, &this_class::__c_sdsp}, }}; /* instruction definitions */ @@ -629,17 +629,43 @@ private: this->gen_reg_load(rs1 + traits::X0, 0), 64, true), this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* PC_val = this->builder.CreateAnd( + Value* align_val = this->builder.CreateAnd( new_pc_val, - this->builder.CreateNot(this->gen_const(64U, 0x1))); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_const(64U, 0x2)); + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAnd( + new_pc_val, + this->builder.CreateNot(this->gen_const(64U, 0x1))); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); this->gen_sync(POST_SYNC, 0); this->gen_trap_check(this->leave_blk); return std::make_tuple(BRANCH, nullptr); @@ -2031,19 +2057,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 37: LUI */ - std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LUI"); + /* instruction 37: C.LD */ + std::tuple __c_ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LD"); this->gen_sync(PRE_SYNC, 37); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rd = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + "{mnemonic:10} {rd}, {uimm},({rs1})", fmt::arg("mnemonic", "c.ld"), + fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2053,12 +2080,16 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - if(rd != 0){ - Value* Xtmp0_val = this->gen_const(64U, imm); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 37); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -2066,19 +2097,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 38: AUIPC */ - std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AUIPC"); + /* instruction 38: C.SD */ + std::tuple __c_sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SD"); this->gen_sync(PRE_SYNC, 38); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rs1 = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + "{mnemonic:10} {rs2}, {uimm},({rs1})", fmt::arg("mnemonic", "c.sd"), + fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2088,16 +2120,16 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + 8 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 38); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -2105,19 +2137,19 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 39: JAL */ - std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("JAL"); + /* instruction 39: C.SUBW */ + std::tuple __c_subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SUBW"); this->gen_sync(PRE_SYNC, 39); - uint8_t rd = ((bit_sub<7,5>(instr))); - int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.subw"), + fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2127,41 +2159,42 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* PC_val = this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + Value* res_val = this->builder.CreateSub( + this->builder.CreateTrunc( + this->gen_reg_load(rd + 8 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 39); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 40: BEQ */ - std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BEQ"); + /* instruction 40: C.ADDW */ + std::tuple __c_addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDW"); this->gen_sync(PRE_SYNC, 40); - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs2 = ((bit_sub<2,3>(instr))); + uint8_t rd = ((bit_sub<7,3>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.addw"), + fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2171,44 +2204,42 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - Value* PC_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_EQ, - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + Value* res_val = this->builder.CreateAdd( + this->builder.CreateTrunc( + this->gen_reg_load(rd + 8 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + 8 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 40); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 41: BNE */ - std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BNE"); + /* instruction 41: C.ADDIW */ + std::tuple __c_addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.ADDIW"); this->gen_sync(PRE_SYNC, 41); - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); + int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); + uint8_t rs1 = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addiw"), + fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2218,44 +2249,43 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - Value* PC_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_NE, - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( + if(rs1 != 0){ + Value* res_val = this->builder.CreateAdd( this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + 32, true), + this->gen_const(32U, imm)); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 41); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 42: BLT */ - std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BLT"); + /* instruction 42: C.LDSP */ + std::tuple __c_ldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.LDSP"); this->gen_sync(PRE_SYNC, 42); - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); + uint8_t rd = ((bit_sub<7,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + "{mnemonic:10} {rd}, {uimm}(sp)", fmt::arg("mnemonic", "c.ldsp"), + fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2265,48 +2295,38 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - Value* PC_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 64, true)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 42); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); } - /* instruction 43: BGE */ - std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BGE"); + /* instruction 43: C.SDSP */ + std::tuple __c_sdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("C.SDSP"); this->gen_sync(PRE_SYNC, 43); - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rs2 = ((bit_sub<2,5>(instr))); + uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + "{mnemonic:10} {rs2}, {uimm}(sp)", fmt::arg("mnemonic", "c.sdsp"), + fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -2316,1802 +2336,28 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; + pc=pc+2; - Value* PC_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SGE, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 64, true)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + Value* offs_val = this->builder.CreateAdd( + this->gen_reg_load(2 + traits::X0, 0), + this->gen_const(64U, uimm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 43); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 44: BLTU */ - std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BLTU"); - - this->gen_sync(PRE_SYNC, 44); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 44); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 45: BGEU */ - std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("BGEU"); - - this->gen_sync(PRE_SYNC, 45); - - int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), - fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)), - this->builder.CreateAdd( - this->gen_ext( - cur_pc_val, - 64, true), - this->gen_const(64U, imm)), - this->builder.CreateAdd( - cur_pc_val, - this->gen_const(64U, 4)), - 64); - this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); - Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); - this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_sync(POST_SYNC, 45); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 46: LB */ - std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LB"); - - this->gen_sync(PRE_SYNC, 46); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 47: LH */ - std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LH"); - - this->gen_sync(PRE_SYNC, 47); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 47); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 48: LW */ - std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LW"); - - this->gen_sync(PRE_SYNC, 48); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 48); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 49: LBU */ - std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LBU"); - - this->gen_sync(PRE_SYNC, 49); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 8/8), - 64, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 49); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 50: LHU */ - std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LHU"); - - this->gen_sync(PRE_SYNC, 50); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 16/8), - 64, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 50); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 51: SB */ - std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SB"); - - this->gen_sync(PRE_SYNC, 51); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 51); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 52: SH */ - std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SH"); - - this->gen_sync(PRE_SYNC, 52); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 52); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 53: SW */ - std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SW"); - - this->gen_sync(PRE_SYNC, 53); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 53); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 54: ADDI */ - std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDI"); - - this->gen_sync(PRE_SYNC, 54); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 54); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 55: SLTI */ - std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTI"); - - this->gen_sync(PRE_SYNC, 55); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)), - this->gen_const(64U, 1), - this->gen_const(64U, 0), - 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 55); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 56: SLTIU */ - std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTIU"); - - this->gen_sync(PRE_SYNC, 56); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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 = imm; - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, full_imm_val)), - this->gen_const(64U, 1), - this->gen_const(64U, 0), - 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 56); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 57: XORI */ - std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("XORI"); - - this->gen_sync(PRE_SYNC, 57); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 57); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 58: ORI */ - std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ORI"); - - this->gen_sync(PRE_SYNC, 58); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 58); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 59: ANDI */ - std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ANDI"); - - this->gen_sync(PRE_SYNC, 59); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 59); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 60: SLLI */ - std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(PRE_SYNC, 60); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,6>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 60); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 61: SRLI */ - std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(PRE_SYNC, 61); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,6>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 61); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 62: SRAI */ - std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(PRE_SYNC, 62); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,6>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_const(64U, shamt)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 62); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 63: ADD */ - std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADD"); - - this->gen_sync(PRE_SYNC, 63); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 63); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 64: SUB */ - std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SUB"); - - this->gen_sync(PRE_SYNC, 64); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateSub( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 64); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 65: SLL */ - std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLL"); - - this->gen_sync(PRE_SYNC, 65); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateShl( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(64U, 64), - this->gen_const(64U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 65); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 66: SLT */ - std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLT"); - - this->gen_sync(PRE_SYNC, 66); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_SLT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 64, true)), - this->gen_const(64U, 1), - this->gen_const(64U, 0), - 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 66); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 67: SLTU */ - std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLTU"); - - this->gen_sync(PRE_SYNC, 67); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - this->gen_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, - false), - this->gen_ext( - this->gen_reg_load(rs2 + traits::X0, 0), - 64, - false)), - this->gen_const(64U, 1), - this->gen_const(64U, 0), - 64); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 67); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 68: XOR */ - std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("XOR"); - - this->gen_sync(PRE_SYNC, 68); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateXor( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 68); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 69: SRL */ - std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRL"); - - this->gen_sync(PRE_SYNC, 69); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateLShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(64U, 64), - this->gen_const(64U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 69); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 70: SRA */ - std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRA"); - - this->gen_sync(PRE_SYNC, 70); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAShr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->builder.CreateAnd( - this->gen_reg_load(rs2 + traits::X0, 0), - this->builder.CreateSub( - this->gen_const(64U, 64), - this->gen_const(64U, 1)))); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 70); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 71: OR */ - std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("OR"); - - this->gen_sync(PRE_SYNC, 71); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateOr( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 71); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 72: AND */ - std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AND"); - - this->gen_sync(PRE_SYNC, 72); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->builder.CreateAnd( - this->gen_reg_load(rs1 + traits::X0, 0), - this->gen_reg_load(rs2 + traits::X0, 0)); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 72); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 73: FENCE */ - std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FENCE"); - - this->gen_sync(PRE_SYNC, 73); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t succ = ((bit_sub<20,4>(instr))); - uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( - this->builder.CreateShl( - this->gen_const(64U, pred), - this->gen_const(64U, 4)), - this->gen_const(64U, succ)); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 0), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 73); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 74: FENCE_I */ - std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("FENCE_I"); - - this->gen_sync(PRE_SYNC, 74); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(64U, imm); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 1), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); - this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 74); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(FLUSH, nullptr); - } - - /* instruction 75: ECALL */ - std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ECALL"); - - this->gen_sync(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("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(POST_SYNC, 75); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 76: EBREAK */ - std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("EBREAK"); - - this->gen_sync(PRE_SYNC, 76); - - 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(POST_SYNC, 76); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 77: URET */ - std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("URET"); - - this->gen_sync(PRE_SYNC, 77); - - 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(POST_SYNC, 77); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 78: SRET */ - std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRET"); - - this->gen_sync(PRE_SYNC, 78); - - 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(POST_SYNC, 78); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 79: MRET */ - std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("MRET"); - - this->gen_sync(PRE_SYNC, 79); - - 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(POST_SYNC, 79); - this->gen_trap_check(this->leave_blk); - return std::make_tuple(BRANCH, nullptr); - } - - /* instruction 80: WFI */ - std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("WFI"); - - this->gen_sync(PRE_SYNC, 80); - - 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(POST_SYNC, 80); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 81: SFENCE.VMA */ - std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SFENCE.VMA"); - - this->gen_sync(PRE_SYNC, 81); - - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(64U, rs1); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 2), - this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); - Value* FENCEtmp1_val = this->gen_const(64U, rs2); - this->gen_write_mem( - traits::FENCE, - this->gen_const(64U, 3), - this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 81); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 82: CSRRW */ - std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRW"); - - this->gen_sync(PRE_SYNC, 82); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); - Value* CSRtmp0_val = rs_val_val; - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); - Value* Xtmp1_val = csr_val_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } else { - Value* CSRtmp2_val = rs_val_val; - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(64))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 82); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 83: CSRRS */ - std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRS"); - - this->gen_sync(PRE_SYNC, 83); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 64/8); - Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(rs1 != 0){ - Value* CSRtmp1_val = this->builder.CreateOr( - xrd_val, - xrs1_val); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 83); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 84: CSRRC */ - std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRC"); - - this->gen_sync(PRE_SYNC, 84); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 64/8); - Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = xrd_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(rs1 != 0){ - Value* CSRtmp1_val = this->builder.CreateAnd( - xrd_val, - this->builder.CreateNot(xrs1_val)); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 84); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 85: CSRRWI */ - std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRWI"); - - this->gen_sync(PRE_SYNC, 85); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* CSRtmp1_val = this->gen_ext( - this->gen_const(64U, zimm), - 64, - false); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 85); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 86: CSRRSI */ - std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRSI"); - - this->gen_sync(PRE_SYNC, 86); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 64/8); - if(zimm != 0){ - Value* CSRtmp0_val = this->builder.CreateOr( - res_val, - this->gen_ext( - this->gen_const(64U, zimm), - 64, - false)); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); - } - if(rd != 0){ - Value* Xtmp1_val = res_val; - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 86); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 87: CSRRCI */ - std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("CSRRCI"); - - this->gen_sync(PRE_SYNC, 87); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t zimm = ((bit_sub<15,5>(instr))); - uint16_t csr = ((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), - fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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, this->gen_const(16U, csr), 64/8); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - if(zimm != 0){ - Value* CSRtmp1_val = this->builder.CreateAnd( - res_val, - this->builder.CreateNot(this->gen_ext( - this->gen_const(64U, zimm), - 64, - false))); - this->gen_write_mem( - traits::CSR, - this->gen_const(16U, csr), - this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 87); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 88: FLD */ + /* instruction 44: FLD */ std::tuple __fld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLD"); - this->gen_sync(PRE_SYNC, 88); + this->gen_sync(PRE_SYNC, 44); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4151,17 +2397,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 88); + this->gen_sync(POST_SYNC, 44); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 89: FSD */ + /* instruction 45: FSD */ std::tuple __fsd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSD"); - this->gen_sync(PRE_SYNC, 89); + this->gen_sync(PRE_SYNC, 45); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4196,17 +2442,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 89); + this->gen_sync(POST_SYNC, 45); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 90: FMADD.D */ + /* instruction 46: FMADD.D */ std::tuple __fmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.D"); - this->gen_sync(PRE_SYNC, 90); + this->gen_sync(PRE_SYNC, 46); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4279,17 +2525,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 90); + this->gen_sync(POST_SYNC, 46); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 91: FMSUB.D */ + /* instruction 47: FMSUB.D */ std::tuple __fmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.D"); - this->gen_sync(PRE_SYNC, 91); + this->gen_sync(PRE_SYNC, 47); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4362,17 +2608,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 91); + this->gen_sync(POST_SYNC, 47); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 92: FNMADD.D */ + /* instruction 48: FNMADD.D */ std::tuple __fnmadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.D"); - this->gen_sync(PRE_SYNC, 92); + this->gen_sync(PRE_SYNC, 48); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4445,17 +2691,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 92); + this->gen_sync(POST_SYNC, 48); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 93: FNMSUB.D */ + /* instruction 49: FNMSUB.D */ std::tuple __fnmsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.D"); - this->gen_sync(PRE_SYNC, 93); + this->gen_sync(PRE_SYNC, 49); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4528,17 +2774,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 93); + this->gen_sync(POST_SYNC, 49); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 94: FADD.D */ + /* instruction 50: FADD.D */ std::tuple __fadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.D"); - this->gen_sync(PRE_SYNC, 94); + this->gen_sync(PRE_SYNC, 50); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4602,17 +2848,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 94); + this->gen_sync(POST_SYNC, 50); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 95: FSUB.D */ + /* instruction 51: FSUB.D */ std::tuple __fsub_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.D"); - this->gen_sync(PRE_SYNC, 95); + this->gen_sync(PRE_SYNC, 51); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4676,17 +2922,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 95); + this->gen_sync(POST_SYNC, 51); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 96: FMUL.D */ + /* instruction 52: FMUL.D */ std::tuple __fmul_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.D"); - this->gen_sync(PRE_SYNC, 96); + this->gen_sync(PRE_SYNC, 52); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4750,17 +2996,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 96); + this->gen_sync(POST_SYNC, 52); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 97: FDIV.D */ + /* instruction 53: FDIV.D */ std::tuple __fdiv_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.D"); - this->gen_sync(PRE_SYNC, 97); + this->gen_sync(PRE_SYNC, 53); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4824,17 +3070,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 97); + this->gen_sync(POST_SYNC, 53); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 98: FSQRT.D */ + /* instruction 54: FSQRT.D */ std::tuple __fsqrt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.D"); - this->gen_sync(PRE_SYNC, 98); + this->gen_sync(PRE_SYNC, 54); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -4893,17 +3139,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 98); + this->gen_sync(POST_SYNC, 54); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 99: FSGNJ.D */ + /* instruction 55: FSGNJ.D */ std::tuple __fsgnj_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.D"); - this->gen_sync(PRE_SYNC, 99); + this->gen_sync(PRE_SYNC, 55); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -4953,17 +3199,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 99); + this->gen_sync(POST_SYNC, 55); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 100: FSGNJN.D */ + /* instruction 56: FSGNJN.D */ std::tuple __fsgnjn_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.D"); - this->gen_sync(PRE_SYNC, 100); + this->gen_sync(PRE_SYNC, 56); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5013,17 +3259,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 100); + this->gen_sync(POST_SYNC, 56); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 101: FSGNJX.D */ + /* instruction 57: FSGNJX.D */ std::tuple __fsgnjx_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.D"); - this->gen_sync(PRE_SYNC, 101); + this->gen_sync(PRE_SYNC, 57); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5070,17 +3316,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 101); + this->gen_sync(POST_SYNC, 57); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 102: FMIN.D */ + /* instruction 58: FMIN.D */ std::tuple __fmin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.D"); - this->gen_sync(PRE_SYNC, 102); + this->gen_sync(PRE_SYNC, 58); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5136,17 +3382,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 102); + this->gen_sync(POST_SYNC, 58); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 103: FMAX.D */ + /* instruction 59: FMAX.D */ std::tuple __fmax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.D"); - this->gen_sync(PRE_SYNC, 103); + this->gen_sync(PRE_SYNC, 59); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5202,17 +3448,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 103); + this->gen_sync(POST_SYNC, 59); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 104: FCVT.S.D */ + /* instruction 60: FCVT.S.D */ std::tuple __fcvt_s_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.D"); - this->gen_sync(PRE_SYNC, 104); + this->gen_sync(PRE_SYNC, 60); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5248,17 +3494,17 @@ private: false)); this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 104); + this->gen_sync(POST_SYNC, 60); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 105: FCVT.D.S */ + /* instruction 61: FCVT.D.S */ std::tuple __fcvt_d_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.S"); - this->gen_sync(PRE_SYNC, 105); + this->gen_sync(PRE_SYNC, 61); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5299,17 +3545,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 105); + this->gen_sync(POST_SYNC, 61); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 106: FEQ.D */ + /* instruction 62: FEQ.D */ std::tuple __feq_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.D"); - this->gen_sync(PRE_SYNC, 106); + this->gen_sync(PRE_SYNC, 62); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5357,17 +3603,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 106); + this->gen_sync(POST_SYNC, 62); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 107: FLT.D */ + /* instruction 63: FLT.D */ std::tuple __flt_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.D"); - this->gen_sync(PRE_SYNC, 107); + this->gen_sync(PRE_SYNC, 63); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5415,17 +3661,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 107); + this->gen_sync(POST_SYNC, 63); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 108: FLE.D */ + /* instruction 64: FLE.D */ std::tuple __fle_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.D"); - this->gen_sync(PRE_SYNC, 108); + this->gen_sync(PRE_SYNC, 64); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5473,17 +3719,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 108); + this->gen_sync(POST_SYNC, 64); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 109: FCLASS.D */ + /* instruction 65: FCLASS.D */ std::tuple __fclass_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.D"); - this->gen_sync(PRE_SYNC, 109); + this->gen_sync(PRE_SYNC, 65); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5511,17 +3757,17 @@ private: }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 109); + this->gen_sync(POST_SYNC, 65); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 110: FCVT.W.D */ + /* instruction 66: FCVT.W.D */ std::tuple __fcvt_w_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.D"); - this->gen_sync(PRE_SYNC, 110); + this->gen_sync(PRE_SYNC, 66); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5566,17 +3812,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 110); + this->gen_sync(POST_SYNC, 66); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 111: FCVT.WU.D */ + /* instruction 67: FCVT.WU.D */ std::tuple __fcvt_wu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.D"); - this->gen_sync(PRE_SYNC, 111); + this->gen_sync(PRE_SYNC, 67); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5621,17 +3867,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 111); + this->gen_sync(POST_SYNC, 67); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 112: FCVT.D.W */ + /* instruction 68: FCVT.D.W */ std::tuple __fcvt_d_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.W"); - this->gen_sync(PRE_SYNC, 112); + this->gen_sync(PRE_SYNC, 68); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5679,17 +3925,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 112); + this->gen_sync(POST_SYNC, 68); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 113: FCVT.D.WU */ + /* instruction 69: FCVT.D.WU */ std::tuple __fcvt_d_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.WU"); - this->gen_sync(PRE_SYNC, 113); + this->gen_sync(PRE_SYNC, 69); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5737,17 +3983,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 113); + this->gen_sync(POST_SYNC, 69); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 114: FCVT.L.D */ + /* instruction 70: FCVT.L.D */ std::tuple __fcvt_l_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.L.D"); - this->gen_sync(PRE_SYNC, 114); + this->gen_sync(PRE_SYNC, 70); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5792,17 +4038,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 114); + this->gen_sync(POST_SYNC, 70); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 115: FCVT.LU.D */ + /* instruction 71: FCVT.LU.D */ std::tuple __fcvt_lu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.LU.D"); - this->gen_sync(PRE_SYNC, 115); + this->gen_sync(PRE_SYNC, 71); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5847,17 +4093,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 115); + this->gen_sync(POST_SYNC, 71); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 116: FCVT.D.L */ + /* instruction 72: FCVT.D.L */ std::tuple __fcvt_d_l(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.L"); - this->gen_sync(PRE_SYNC, 116); + this->gen_sync(PRE_SYNC, 72); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5902,17 +4148,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 116); + this->gen_sync(POST_SYNC, 72); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 117: FCVT.D.LU */ + /* instruction 73: FCVT.D.LU */ std::tuple __fcvt_d_lu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.D.LU"); - this->gen_sync(PRE_SYNC, 117); + this->gen_sync(PRE_SYNC, 73); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -5957,17 +4203,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 117); + this->gen_sync(POST_SYNC, 73); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 118: FMV.X.D */ + /* instruction 74: FMV.X.D */ std::tuple __fmv_x_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.X.D"); - this->gen_sync(PRE_SYNC, 118); + this->gen_sync(PRE_SYNC, 74); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -5993,17 +4239,17 @@ private: true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 118); + this->gen_sync(POST_SYNC, 74); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 119: FMV.D.X */ + /* instruction 75: FMV.D.X */ std::tuple __fmv_d_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.D.X"); - this->gen_sync(PRE_SYNC, 119); + this->gen_sync(PRE_SYNC, 75); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -6029,17 +4275,2093 @@ private: false); this->builder.CreateStore(Ftmp0_val, get_reg_ptr(rd + traits::F0), false); this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 75); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 76: LUI */ + std::tuple __lui(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LUI"); + + this->gen_sync(PRE_SYNC, 76); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "lui"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_const(64U, imm); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 76); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 77: AUIPC */ + std::tuple __auipc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AUIPC"); + + this->gen_sync(PRE_SYNC, 77); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,20>(instr) << 12)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#08x}", fmt::arg("mnemonic", "auipc"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 77); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 78: JAL */ + std::tuple __jal(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("JAL"); + + this->gen_sync(PRE_SYNC, 78); + + uint8_t rd = ((bit_sub<7,5>(instr))); + int32_t imm = signextend((bit_sub<12,8>(instr) << 12) | (bit_sub<20,1>(instr) << 11) | (bit_sub<21,10>(instr) << 1) | (bit_sub<31,1>(instr) << 20)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm:#0x}", fmt::arg("mnemonic", "jal"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* PC_val = this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 78); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 79: BEQ */ + std::tuple __beq(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BEQ"); + + this->gen_sync(PRE_SYNC, 79); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "beq"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 79); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 80: BNE */ + std::tuple __bne(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BNE"); + + this->gen_sync(PRE_SYNC, 80); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bne"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 80); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 81: BLT */ + std::tuple __blt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLT"); + + this->gen_sync(PRE_SYNC, 81); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "blt"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 81); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 82: BGE */ + std::tuple __bge(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGE"); + + this->gen_sync(PRE_SYNC, 82); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bge"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, true)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 82); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 83: BLTU */ + std::tuple __bltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BLTU"); + + this->gen_sync(PRE_SYNC, 83); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bltu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 83); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 84: BGEU */ + std::tuple __bgeu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("BGEU"); + + this->gen_sync(PRE_SYNC, 84); + + int16_t imm = signextend((bit_sub<7,1>(instr) << 11) | (bit_sub<8,4>(instr) << 1) | (bit_sub<25,6>(instr) << 5) | (bit_sub<31,1>(instr) << 12)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs1}, {rs2}, {imm:#0x}", fmt::arg("mnemonic", "bgeu"), + fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)), + this->builder.CreateAdd( + this->gen_ext( + cur_pc_val, + 64, true), + this->gen_const(64U, imm)), + this->builder.CreateAdd( + cur_pc_val, + this->gen_const(64U, 4)), + 64); + this->builder.CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* is_cont_v = this->builder.CreateICmp(ICmpInst::ICMP_NE, PC_val, this->gen_const(64U, pc.val), "is_cont_v"); + this->builder.CreateStore(this->gen_ext(is_cont_v, 32U, false), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_sync(POST_SYNC, 84); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 85: LB */ + std::tuple __lb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LB"); + + this->gen_sync(PRE_SYNC, 85); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lb"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 85); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 86: LH */ + std::tuple __lh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LH"); + + this->gen_sync(PRE_SYNC, 86); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lh"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 86); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 87: LW */ + std::tuple __lw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LW"); + + this->gen_sync(PRE_SYNC, 87); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lw"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 87); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 88: LBU */ + std::tuple __lbu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LBU"); + + this->gen_sync(PRE_SYNC, 88); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lbu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 8/8), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 88); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 89: LHU */ + std::tuple __lhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LHU"); + + this->gen_sync(PRE_SYNC, 89); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lhu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 16/8), + 64, + false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 89); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 90: SB */ + std::tuple __sb(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SB"); + + this->gen_sync(PRE_SYNC, 90); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sb"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(8))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 90); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 91: SH */ + std::tuple __sh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SH"); + + this->gen_sync(PRE_SYNC, 91); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sh"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(16))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 91); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 92: SW */ + std::tuple __sw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SW"); + + this->gen_sync(PRE_SYNC, 92); + + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sw"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 92); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 93: ADDI */ + std::tuple __addi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDI"); + + this->gen_sync(PRE_SYNC, 93); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 93); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 94: SLTI */ + std::tuple __slti(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTI"); + + this->gen_sync(PRE_SYNC, 94); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "slti"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 94); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 95: SLTIU */ + std::tuple __sltiu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTIU"); + + this->gen_sync(PRE_SYNC, 95); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "sltiu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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 = imm; + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, full_imm_val)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 95); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 96: XORI */ + std::tuple __xori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XORI"); + + this->gen_sync(PRE_SYNC, 96); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "xori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 96); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 97: ORI */ + std::tuple __ori(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ORI"); + + this->gen_sync(PRE_SYNC, 97); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "ori"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 97); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 98: ANDI */ + std::tuple __andi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ANDI"); + + this->gen_sync(PRE_SYNC, 98); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "andi"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 98); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 99: SLLI */ + std::tuple __slli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLI"); + + this->gen_sync(PRE_SYNC, 99); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 99); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 100: SRLI */ + std::tuple __srli(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLI"); + + this->gen_sync(PRE_SYNC, 100); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srli"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 100); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 101: SRAI */ + std::tuple __srai(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAI"); + + this->gen_sync(PRE_SYNC, 101); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,6>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srai"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_const(64U, shamt)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 101); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 102: ADD */ + std::tuple __add(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADD"); + + this->gen_sync(PRE_SYNC, 102); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "add"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAdd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 102); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 103: SUB */ + std::tuple __sub(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUB"); + + this->gen_sync(PRE_SYNC, 103); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sub"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateSub( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 103); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 104: SLL */ + std::tuple __sll(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLL"); + + this->gen_sync(PRE_SYNC, 104); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sll"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateShl( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 104); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 105: SLT */ + std::tuple __slt(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLT"); + + this->gen_sync(PRE_SYNC, 105); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "slt"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, true)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 105); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 106: SLTU */ + std::tuple __sltu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLTU"); + + this->gen_sync(PRE_SYNC, 106); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sltu"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, + false), + this->gen_ext( + this->gen_reg_load(rs2 + traits::X0, 0), + 64, + false)), + this->gen_const(64U, 1), + this->gen_const(64U, 0), + 64); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 106); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 107: XOR */ + std::tuple __xor(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("XOR"); + + this->gen_sync(PRE_SYNC, 107); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "xor"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateXor( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 107); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 108: SRL */ + std::tuple __srl(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRL"); + + this->gen_sync(PRE_SYNC, 108); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srl"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateLShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 108); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 109: SRA */ + std::tuple __sra(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRA"); + + this->gen_sync(PRE_SYNC, 109); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sra"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAShr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->builder.CreateAnd( + this->gen_reg_load(rs2 + traits::X0, 0), + this->builder.CreateSub( + this->gen_const(64U, 64), + this->gen_const(64U, 1)))); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 109); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 110: OR */ + std::tuple __or(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("OR"); + + this->gen_sync(PRE_SYNC, 110); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "or"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateOr( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 110); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 111: AND */ + std::tuple __and(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AND"); + + this->gen_sync(PRE_SYNC, 111); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "and"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->builder.CreateAnd( + this->gen_reg_load(rs1 + traits::X0, 0), + this->gen_reg_load(rs2 + traits::X0, 0)); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 111); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 112: FENCE */ + std::tuple __fence(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE"); + + this->gen_sync(PRE_SYNC, 112); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t succ = ((bit_sub<20,4>(instr))); + uint8_t pred = ((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* FENCEtmp0_val = this->builder.CreateOr( + this->builder.CreateShl( + this->gen_const(64U, pred), + this->gen_const(64U, 4)), + this->gen_const(64U, succ)); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 0), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 112); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 113: FENCE_I */ + std::tuple __fence_i(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("FENCE_I"); + + this->gen_sync(PRE_SYNC, 113); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t imm = ((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* FENCEtmp0_val = this->gen_const(64U, imm); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 1), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); + this->builder.CreateStore(this->gen_const(32U, std::numeric_limits::max()), get_reg_ptr(traits::LAST_BRANCH), false); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 113); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(FLUSH, nullptr); + } + + /* instruction 114: ECALL */ + std::tuple __ecall(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ECALL"); + + this->gen_sync(PRE_SYNC, 114); + + 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(POST_SYNC, 114); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 115: EBREAK */ + std::tuple __ebreak(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("EBREAK"); + + this->gen_sync(PRE_SYNC, 115); + + 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(POST_SYNC, 115); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 116: URET */ + std::tuple __uret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("URET"); + + this->gen_sync(PRE_SYNC, 116); + + 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(POST_SYNC, 116); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 117: SRET */ + std::tuple __sret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRET"); + + this->gen_sync(PRE_SYNC, 117); + + 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(POST_SYNC, 117); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 118: MRET */ + std::tuple __mret(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("MRET"); + + this->gen_sync(PRE_SYNC, 118); + + 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(POST_SYNC, 118); + this->gen_trap_check(this->leave_blk); + return std::make_tuple(BRANCH, nullptr); + } + + /* instruction 119: WFI */ + std::tuple __wfi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("WFI"); + + this->gen_sync(PRE_SYNC, 119); + + 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(POST_SYNC, 119); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 120: FLW */ + /* instruction 120: SFENCE.VMA */ + std::tuple __sfence_vma(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SFENCE.VMA"); + + this->gen_sync(PRE_SYNC, 120); + + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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* FENCEtmp0_val = this->gen_const(64U, rs1); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 2), + this->builder.CreateZExtOrTrunc(FENCEtmp0_val,this->get_type(64))); + Value* FENCEtmp1_val = this->gen_const(64U, rs2); + this->gen_write_mem( + traits::FENCE, + this->gen_const(64U, 3), + this->builder.CreateZExtOrTrunc(FENCEtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 120); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 121: CSRRW */ + std::tuple __csrrw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRW"); + + this->gen_sync(PRE_SYNC, 121); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrw"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* csr_val_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + Value* CSRtmp0_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); + Value* Xtmp1_val = csr_val_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } else { + Value* CSRtmp2_val = rs_val_val; + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp2_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 121); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 122: CSRRS */ + std::tuple __csrrs(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRS"); + + this->gen_sync(PRE_SYNC, 122); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrs"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateOr( + xrd_val, + xrs1_val); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 122); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 123: CSRRC */ + std::tuple __csrrc(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRC"); + + this->gen_sync(PRE_SYNC, 123); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {rs1}", fmt::arg("mnemonic", "csrrc"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + Value* xrs1_val = this->gen_reg_load(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = xrd_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(rs1 != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + xrd_val, + this->builder.CreateNot(xrs1_val)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 123); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 124: CSRRWI */ + std::tuple __csrrwi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRWI"); + + this->gen_sync(PRE_SYNC, 124); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrwi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* Xtmp0_val = this->gen_read_mem(traits::CSR, this->gen_const(16U, csr), 64/8); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* CSRtmp1_val = this->gen_ext( + this->gen_const(64U, zimm), + 64, + false); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 124); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 125: CSRRSI */ + std::tuple __csrrsi(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRSI"); + + this->gen_sync(PRE_SYNC, 125); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrsi"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + if(zimm != 0){ + Value* CSRtmp0_val = this->builder.CreateOr( + res_val, + this->gen_ext( + this->gen_const(64U, zimm), + 64, + false)); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp0_val,this->get_type(64))); + } + if(rd != 0){ + Value* Xtmp1_val = res_val; + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 125); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 126: CSRRCI */ + std::tuple __csrrci(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("CSRRCI"); + + this->gen_sync(PRE_SYNC, 126); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t zimm = ((bit_sub<15,5>(instr))); + uint16_t csr = ((bit_sub<20,12>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {csr}, {zimm:#0x}", fmt::arg("mnemonic", "csrrci"), + fmt::arg("rd", name(rd)), fmt::arg("csr", csr), fmt::arg("zimm", zimm)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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, this->gen_const(16U, csr), 64/8); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + if(zimm != 0){ + Value* CSRtmp1_val = this->builder.CreateAnd( + res_val, + this->builder.CreateNot(this->gen_ext( + this->gen_const(64U, zimm), + 64, + false))); + this->gen_write_mem( + traits::CSR, + this->gen_const(16U, csr), + this->builder.CreateZExtOrTrunc(CSRtmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 126); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 127: FLW */ std::tuple __flw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLW"); - this->gen_sync(PRE_SYNC, 120); + this->gen_sync(PRE_SYNC, 127); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -6082,17 +6404,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 120); + this->gen_sync(POST_SYNC, 127); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 121: FSW */ + /* instruction 128: FSW */ std::tuple __fsw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSW"); - this->gen_sync(PRE_SYNC, 121); + this->gen_sync(PRE_SYNC, 128); int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -6127,17 +6449,17 @@ private: offs_val, this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 121); + this->gen_sync(POST_SYNC, 128); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 122: FMADD.S */ + /* instruction 129: FMADD.S */ std::tuple __fmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMADD.S"); - this->gen_sync(PRE_SYNC, 122); + this->gen_sync(PRE_SYNC, 129); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6232,17 +6554,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 122); + this->gen_sync(POST_SYNC, 129); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 123: FMSUB.S */ + /* instruction 130: FMSUB.S */ std::tuple __fmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMSUB.S"); - this->gen_sync(PRE_SYNC, 123); + this->gen_sync(PRE_SYNC, 130); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6337,17 +6659,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 123); + this->gen_sync(POST_SYNC, 130); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 124: FNMADD.S */ + /* instruction 131: FNMADD.S */ std::tuple __fnmadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMADD.S"); - this->gen_sync(PRE_SYNC, 124); + this->gen_sync(PRE_SYNC, 131); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6442,17 +6764,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 124); + this->gen_sync(POST_SYNC, 131); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 125: FNMSUB.S */ + /* instruction 132: FNMSUB.S */ std::tuple __fnmsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FNMSUB.S"); - this->gen_sync(PRE_SYNC, 125); + this->gen_sync(PRE_SYNC, 132); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6547,17 +6869,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 125); + this->gen_sync(POST_SYNC, 132); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 126: FADD.S */ + /* instruction 133: FADD.S */ std::tuple __fadd_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FADD.S"); - this->gen_sync(PRE_SYNC, 126); + this->gen_sync(PRE_SYNC, 133); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6638,17 +6960,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 126); + this->gen_sync(POST_SYNC, 133); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 127: FSUB.S */ + /* instruction 134: FSUB.S */ std::tuple __fsub_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSUB.S"); - this->gen_sync(PRE_SYNC, 127); + this->gen_sync(PRE_SYNC, 134); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6729,17 +7051,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 127); + this->gen_sync(POST_SYNC, 134); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 128: FMUL.S */ + /* instruction 135: FMUL.S */ std::tuple __fmul_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMUL.S"); - this->gen_sync(PRE_SYNC, 128); + this->gen_sync(PRE_SYNC, 135); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6820,17 +7142,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 128); + this->gen_sync(POST_SYNC, 135); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 129: FDIV.S */ + /* instruction 136: FDIV.S */ std::tuple __fdiv_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FDIV.S"); - this->gen_sync(PRE_SYNC, 129); + this->gen_sync(PRE_SYNC, 136); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6911,17 +7233,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 129); + this->gen_sync(POST_SYNC, 136); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 130: FSQRT.S */ + /* instruction 137: FSQRT.S */ std::tuple __fsqrt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSQRT.S"); - this->gen_sync(PRE_SYNC, 130); + this->gen_sync(PRE_SYNC, 137); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -6996,17 +7318,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 130); + this->gen_sync(POST_SYNC, 137); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 131: FSGNJ.S */ + /* instruction 138: FSGNJ.S */ std::tuple __fsgnj_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJ.S"); - this->gen_sync(PRE_SYNC, 131); + this->gen_sync(PRE_SYNC, 138); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7062,17 +7384,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 131); + this->gen_sync(POST_SYNC, 138); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 132: FSGNJN.S */ + /* instruction 139: FSGNJN.S */ std::tuple __fsgnjn_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJN.S"); - this->gen_sync(PRE_SYNC, 132); + this->gen_sync(PRE_SYNC, 139); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7128,17 +7450,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 132); + this->gen_sync(POST_SYNC, 139); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 133: FSGNJX.S */ + /* instruction 140: FSGNJX.S */ std::tuple __fsgnjx_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FSGNJX.S"); - this->gen_sync(PRE_SYNC, 133); + this->gen_sync(PRE_SYNC, 140); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7190,17 +7512,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 133); + this->gen_sync(POST_SYNC, 140); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 134: FMIN.S */ + /* instruction 141: FMIN.S */ std::tuple __fmin_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMIN.S"); - this->gen_sync(PRE_SYNC, 134); + this->gen_sync(PRE_SYNC, 141); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7266,17 +7588,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 134); + this->gen_sync(POST_SYNC, 141); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 135: FMAX.S */ + /* instruction 142: FMAX.S */ std::tuple __fmax_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMAX.S"); - this->gen_sync(PRE_SYNC, 135); + this->gen_sync(PRE_SYNC, 142); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7342,17 +7664,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 135); + this->gen_sync(POST_SYNC, 142); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 136: FCVT.W.S */ + /* instruction 143: FCVT.W.S */ std::tuple __fcvt_w_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.W.S"); - this->gen_sync(PRE_SYNC, 136); + this->gen_sync(PRE_SYNC, 143); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7412,17 +7734,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 136); + this->gen_sync(POST_SYNC, 143); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 137: FCVT.WU.S */ + /* instruction 144: FCVT.WU.S */ std::tuple __fcvt_wu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.WU.S"); - this->gen_sync(PRE_SYNC, 137); + this->gen_sync(PRE_SYNC, 144); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7482,17 +7804,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 137); + this->gen_sync(POST_SYNC, 144); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 138: FEQ.S */ + /* instruction 145: FEQ.S */ std::tuple __feq_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FEQ.S"); - this->gen_sync(PRE_SYNC, 138); + this->gen_sync(PRE_SYNC, 145); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7555,17 +7877,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 138); + this->gen_sync(POST_SYNC, 145); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 139: FLT.S */ + /* instruction 146: FLT.S */ std::tuple __flt_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLT.S"); - this->gen_sync(PRE_SYNC, 139); + this->gen_sync(PRE_SYNC, 146); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7643,17 +7965,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 139); + this->gen_sync(POST_SYNC, 146); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 140: FLE.S */ + /* instruction 147: FLE.S */ std::tuple __fle_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FLE.S"); - this->gen_sync(PRE_SYNC, 140); + this->gen_sync(PRE_SYNC, 147); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7716,17 +8038,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 140); + this->gen_sync(POST_SYNC, 147); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 141: FCLASS.S */ + /* instruction 148: FCLASS.S */ std::tuple __fclass_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCLASS.S"); - this->gen_sync(PRE_SYNC, 141); + this->gen_sync(PRE_SYNC, 148); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7753,17 +8075,17 @@ private: }); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 141); + this->gen_sync(POST_SYNC, 148); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 142: FCVT.S.W */ + /* instruction 149: FCVT.S.W */ std::tuple __fcvt_s_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.W"); - this->gen_sync(PRE_SYNC, 142); + this->gen_sync(PRE_SYNC, 149); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7821,17 +8143,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 142); + this->gen_sync(POST_SYNC, 149); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 143: FCVT.S.WU */ + /* instruction 150: FCVT.S.WU */ std::tuple __fcvt_s_wu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.WU"); - this->gen_sync(PRE_SYNC, 143); + this->gen_sync(PRE_SYNC, 150); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -7889,17 +8211,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 143); + this->gen_sync(POST_SYNC, 150); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 144: FMV.X.W */ + /* instruction 151: FMV.X.W */ std::tuple __fmv_x_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.X.W"); - this->gen_sync(PRE_SYNC, 144); + this->gen_sync(PRE_SYNC, 151); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7928,17 +8250,17 @@ private: true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 144); + this->gen_sync(POST_SYNC, 151); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 145: FMV.W.X */ + /* instruction 152: FMV.W.X */ std::tuple __fmv_w_x(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FMV.W.X"); - this->gen_sync(PRE_SYNC, 145); + this->gen_sync(PRE_SYNC, 152); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -7980,17 +8302,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 145); + this->gen_sync(POST_SYNC, 152); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 146: FCVT.L.S */ + /* instruction 153: FCVT.L.S */ std::tuple __fcvt_l_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.L.S"); - this->gen_sync(PRE_SYNC, 146); + this->gen_sync(PRE_SYNC, 153); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8035,17 +8357,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 146); + this->gen_sync(POST_SYNC, 153); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 147: FCVT.LU.S */ + /* instruction 154: FCVT.LU.S */ std::tuple __fcvt_lu_s(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.LU.S"); - this->gen_sync(PRE_SYNC, 147); + this->gen_sync(PRE_SYNC, 154); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8090,17 +8412,17 @@ private: flags_val); this->builder.CreateStore(FCSR_val, get_reg_ptr(traits::FCSR), false); this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 147); + this->gen_sync(POST_SYNC, 154); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 148: FCVT.S.L */ + /* instruction 155: FCVT.S.L */ std::tuple __fcvt_s_l(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.L"); - this->gen_sync(PRE_SYNC, 148); + this->gen_sync(PRE_SYNC, 155); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8144,17 +8466,17 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 148); + this->gen_sync(POST_SYNC, 155); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 149: FCVT.S.LU */ + /* instruction 156: FCVT.S.LU */ std::tuple __fcvt_s_lu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("FCVT.S.LU"); - this->gen_sync(PRE_SYNC, 149); + this->gen_sync(PRE_SYNC, 156); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rm = ((bit_sub<12,3>(instr))); @@ -8198,17 +8520,1223 @@ private: this->builder.CreateStore(Ftmp1_val, get_reg_ptr(rd + traits::F0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 149); + this->gen_sync(POST_SYNC, 156); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 150: MUL */ + /* instruction 157: LR.W */ + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LR.W"); + + this->gen_sync(PRE_SYNC, 157); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* REStmp1_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(REStmp1_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 157); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 158: SC.W */ + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SC.W"); + + this->gen_sync(PRE_SYNC, 158); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + if(rd != 0){ + Value* Xtmp1_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_NE, + res1_val, + this->gen_ext( + this->gen_const(64U, 0), + 32, + false)), + this->gen_const(64U, 0), + this->gen_const(64U, 1), + 64); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 158); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 159: AMOSWAP.W */ + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOSWAP.W"); + + this->gen_sync(PRE_SYNC, 159); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 159); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 160: AMOADD.W */ + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOADD.W"); + + this->gen_sync(PRE_SYNC, 160); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAdd( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 160); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 161: AMOXOR.W */ + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOXOR.W"); + + this->gen_sync(PRE_SYNC, 161); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateXor( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 161); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 162: AMOAND.W */ + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOAND.W"); + + this->gen_sync(PRE_SYNC, 162); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAnd( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 162); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 163: AMOOR.W */ + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOOR.W"); + + this->gen_sync(PRE_SYNC, 163); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateOr( + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 163); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 164: AMOMIN.W */ + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMIN.W"); + + this->gen_sync(PRE_SYNC, 164); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 164); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 165: AMOMAX.W */ + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAX.W"); + + this->gen_sync(PRE_SYNC, 165); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 165); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 166: AMOMINU.W */ + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMINU.W"); + + this->gen_sync(PRE_SYNC, 166); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 166); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 167: AMOMAXU.W */ + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAXU.W"); + + this->gen_sync(PRE_SYNC, 167); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 167); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 168: LR.D */ + std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LR.D"); + + this->gen_sync(PRE_SYNC, 168); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + Value* REStmp1_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(REStmp1_val,this->get_type(64))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 168); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 169: SC.D */ + std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SC.D"); + + this->gen_sync(PRE_SYNC, 169); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/8); + { + BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + BasicBlock* bb_else = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));if(rd != 0){ + Value* Xtmp1_val = this->gen_const(64U, 0); + this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->builder.CreateBr(bbnext); + this->builder.SetInsertPoint(bb_else); + { + if(rd != 0){ + Value* Xtmp2_val = this->gen_const(64U, 1); + this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); + } + } + this->builder.CreateBr(bbnext); + bb=bbnext; + } + this->builder.SetInsertPoint(bb); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 169); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 170: AMOSWAP.D */ + std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOSWAP.D"); + + this->gen_sync(PRE_SYNC, 170); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + if(rd != 0){ + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 170); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 171: AMOADD.D */ + std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOADD.D"); + + this->gen_sync(PRE_SYNC, 171); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAdd( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 171); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 172: AMOXOR.D */ + std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOXOR.D"); + + this->gen_sync(PRE_SYNC, 172); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateXor( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 172); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 173: AMOAND.D */ + std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOAND.D"); + + this->gen_sync(PRE_SYNC, 173); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateAnd( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 173); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 174: AMOOR.D */ + std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOOR.D"); + + this->gen_sync(PRE_SYNC, 174); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->builder.CreateOr( + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 174); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 175: AMOMIN.D */ + std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMIN.D"); + + this->gen_sync(PRE_SYNC, 175); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 175); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 176: AMOMAX.D */ + std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAX.D"); + + this->gen_sync(PRE_SYNC, 176); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), + 64, true)), + this->gen_reg_load(rs2 + traits::X0, 0), + res_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 176); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 177: AMOMINU.D */ + std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMINU.D"); + + this->gen_sync(PRE_SYNC, 177); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_UGT, + res_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 177); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 178: AMOMAXU.D */ + std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("AMOMAXU.D"); + + this->gen_sync(PRE_SYNC, 178); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + uint8_t rl = ((bit_sub<25,1>(instr))); + uint8_t aq = ((bit_sub<26,1>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.d"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + 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(rs1 + traits::X0, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); + if(rd != 0){ + Value* Xtmp0_val = res1_val; + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + Value* res2_val = this->gen_choose( + this->builder.CreateICmp( + ICmpInst::ICMP_ULT, + res1_val, + this->gen_reg_load(rs2 + traits::X0, 0)), + this->gen_reg_load(rs2 + traits::X0, 0), + res1_val, + 64); + Value* MEMtmp1_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 178); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 179: MUL */ std::tuple __mul(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MUL"); - this->gen_sync(PRE_SYNC, 150); + this->gen_sync(PRE_SYNC, 179); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8246,17 +9774,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 150); + this->gen_sync(POST_SYNC, 179); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 151: MULH */ + /* instruction 180: MULH */ std::tuple __mulh(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULH"); - this->gen_sync(PRE_SYNC, 151); + this->gen_sync(PRE_SYNC, 180); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8296,17 +9824,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 151); + this->gen_sync(POST_SYNC, 180); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 152: MULHSU */ + /* instruction 181: MULHSU */ std::tuple __mulhsu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHSU"); - this->gen_sync(PRE_SYNC, 152); + this->gen_sync(PRE_SYNC, 181); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8346,17 +9874,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 152); + this->gen_sync(POST_SYNC, 181); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 153: MULHU */ + /* instruction 182: MULHU */ std::tuple __mulhu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULHU"); - this->gen_sync(PRE_SYNC, 153); + this->gen_sync(PRE_SYNC, 182); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8396,17 +9924,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 153); + this->gen_sync(POST_SYNC, 182); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 154: DIV */ + /* instruction 183: DIV */ std::tuple __div(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIV"); - this->gen_sync(PRE_SYNC, 154); + this->gen_sync(PRE_SYNC, 183); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8495,17 +10023,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 154); + this->gen_sync(POST_SYNC, 183); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 155: DIVU */ + /* instruction 184: DIVU */ std::tuple __divu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVU"); - this->gen_sync(PRE_SYNC, 155); + this->gen_sync(PRE_SYNC, 184); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8557,17 +10085,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 155); + this->gen_sync(POST_SYNC, 184); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 156: REM */ + /* instruction 185: REM */ std::tuple __rem(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REM"); - this->gen_sync(PRE_SYNC, 156); + this->gen_sync(PRE_SYNC, 185); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8656,17 +10184,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 156); + this->gen_sync(POST_SYNC, 185); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 157: REMU */ + /* instruction 186: REMU */ std::tuple __remu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMU"); - this->gen_sync(PRE_SYNC, 157); + this->gen_sync(PRE_SYNC, 186); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -8718,1179 +10246,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 157); + this->gen_sync(POST_SYNC, 186); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 158: LR.W */ - std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LR.W"); - - this->gen_sync(PRE_SYNC, 158); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* REStmp1_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(REStmp1_val,this->get_type(32))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 158); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 159: SC.W */ - std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SC.W"); - - this->gen_sync(PRE_SYNC, 159); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(32))); - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - if(rd != 0){ - Value* Xtmp1_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_NE, - res1_val, - this->gen_ext( - this->gen_const(64U, 0), - 32, - false)), - this->gen_const(64U, 0), - this->gen_const(64U, 1), - 64); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 159); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 160: AMOSWAP.W */ - std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOSWAP.W"); - - this->gen_sync(PRE_SYNC, 160); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 160); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 161: AMOADD.W */ - std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOADD.W"); - - this->gen_sync(PRE_SYNC, 161); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAdd( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 161); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 162: AMOXOR.W */ - std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOXOR.W"); - - this->gen_sync(PRE_SYNC, 162); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateXor( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 162); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 163: AMOAND.W */ - std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOAND.W"); - - this->gen_sync(PRE_SYNC, 163); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAnd( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 163); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 164: AMOOR.W */ - std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOOR.W"); - - this->gen_sync(PRE_SYNC, 164); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateOr( - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 164); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 165: AMOMIN.W */ - std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMIN.W"); - - this->gen_sync(PRE_SYNC, 165); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 165); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 166: AMOMAX.W */ - std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAX.W"); - - this->gen_sync(PRE_SYNC, 166); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 166); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 167: AMOMINU.W */ - std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMINU.W"); - - this->gen_sync(PRE_SYNC, 167); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 167); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 168: AMOMAXU.W */ - std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAXU.W"); - - this->gen_sync(PRE_SYNC, 168); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.w"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(32))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 168); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 169: LWU */ - std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LWU"); - - this->gen_sync(PRE_SYNC, 169); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 32/8), - 64, - false); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 169); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 170: LD */ - std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LD"); - - this->gen_sync(PRE_SYNC, 170); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"), - fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 170); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 171: SD */ - std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SD"); - - this->gen_sync(PRE_SYNC, 171); - - int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"), - fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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_ext( - this->gen_reg_load(rs1 + traits::X0, 0), - 64, true), - this->gen_const(64U, imm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 171); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 172: ADDIW */ - std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDIW"); - - this->gen_sync(PRE_SYNC, 172); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - int16_t imm = signextend((bit_sub<20,12>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* res_val = this->builder.CreateAdd( - this->gen_ext( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - 32, true), - this->gen_const(32U, imm)); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 172); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 173: SLLIW */ - std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLIW"); - - this->gen_sync(PRE_SYNC, 173); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* sh_val_val = this->builder.CreateShl( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, shamt)); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 173); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 174: SRLIW */ - std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLIW"); - - this->gen_sync(PRE_SYNC, 174); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* sh_val_val = this->builder.CreateLShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, shamt)); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 174); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 175: SRAIW */ - std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAIW"); - - this->gen_sync(PRE_SYNC, 175); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t shamt = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* sh_val_val = this->builder.CreateAShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, shamt)); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 175); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 176: ADDW */ - std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("ADDW"); - - this->gen_sync(PRE_SYNC, 176); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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(rd != 0){ - Value* res_val = this->builder.CreateAdd( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - )); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 176); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 177: SUBW */ - std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SUBW"); - - this->gen_sync(PRE_SYNC, 177); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((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(rd != 0){ - Value* res_val = this->builder.CreateSub( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - )); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 177); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 178: SLLW */ - std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SLLW"); - - this->gen_sync(PRE_SYNC, 178); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - uint32_t mask_val = 0x1f; - Value* count_val = this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, mask_val)); - Value* sh_val_val = this->builder.CreateShl( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - count_val); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 178); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 179: SRLW */ - std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRLW"); - - this->gen_sync(PRE_SYNC, 179); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - uint32_t mask_val = 0x1f; - Value* count_val = this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, mask_val)); - Value* sh_val_val = this->builder.CreateLShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - count_val); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 179); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 180: SRAW */ - std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SRAW"); - - this->gen_sync(PRE_SYNC, 180); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - uint32_t mask_val = 0x1f; - Value* count_val = this->builder.CreateAnd( - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + traits::X0, 0), - this-> get_type(32) - ), - this->gen_const(32U, mask_val)); - Value* sh_val_val = this->builder.CreateAShr( - this->builder.CreateTrunc( - this->gen_reg_load(rs1 + traits::X0, 0), - this-> get_type(32) - ), - count_val); - Value* Xtmp0_val = this->gen_ext( - sh_val_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 180); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 181: MULW */ + /* instruction 187: MULW */ std::tuple __mulw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("MULW"); - this->gen_sync(PRE_SYNC, 181); + this->gen_sync(PRE_SYNC, 187); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -9927,17 +10293,17 @@ private: this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 181); + this->gen_sync(POST_SYNC, 187); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 182: DIVW */ + /* instruction 188: DIVW */ std::tuple __divw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVW"); - this->gen_sync(PRE_SYNC, 182); + this->gen_sync(PRE_SYNC, 188); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -10042,17 +10408,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 182); + this->gen_sync(POST_SYNC, 188); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 183: DIVUW */ + /* instruction 189: DIVUW */ std::tuple __divuw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("DIVUW"); - this->gen_sync(PRE_SYNC, 183); + this->gen_sync(PRE_SYNC, 189); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -10116,17 +10482,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 183); + this->gen_sync(POST_SYNC, 189); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 184: REMW */ + /* instruction 190: REMW */ std::tuple __remw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMW"); - this->gen_sync(PRE_SYNC, 184); + this->gen_sync(PRE_SYNC, 190); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -10232,17 +10598,17 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 184); + this->gen_sync(POST_SYNC, 190); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 185: REMUW */ + /* instruction 191: REMUW */ std::tuple __remuw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ bb->setName("REMUW"); - this->gen_sync(PRE_SYNC, 185); + this->gen_sync(PRE_SYNC, 191); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); @@ -10312,347 +10678,26 @@ private: this->builder.SetInsertPoint(bb); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 185); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 186: LR.D */ - std::tuple __lr_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("LR.D"); - - this->gen_sync(PRE_SYNC, 186); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}", fmt::arg("mnemonic", "lr.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+4; - - if(rd != 0){ - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - Value* REStmp1_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(REStmp1_val,this->get_type(64))); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 186); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 187: SC.D */ - std::tuple __sc_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("SC.D"); - - this->gen_sync(PRE_SYNC, 187); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sc.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_read_mem(traits::RES, offs_val, 8/8); - { - BasicBlock* bbnext = BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); - BasicBlock* bb_then = BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); - BasicBlock* bb_else = 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* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 1); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64)));if(rd != 0){ - Value* Xtmp1_val = this->gen_const(64U, 0); - this->builder.CreateStore(Xtmp1_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->builder.CreateBr(bbnext); - this->builder.SetInsertPoint(bb_else); - { - if(rd != 0){ - Value* Xtmp2_val = this->gen_const(64U, 1); - this->builder.CreateStore(Xtmp2_val, get_reg_ptr(rd + traits::X0), false); - } - } - this->builder.CreateBr(bbnext); - bb=bbnext; - } - this->builder.SetInsertPoint(bb); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 187); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 188: AMOSWAP.D */ - std::tuple __amoswap_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOSWAP.D"); - - this->gen_sync(PRE_SYNC, 188); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoswap.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - if(rd != 0){ - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* MEMtmp1_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 188); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 189: AMOADD.D */ - std::tuple __amoadd_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOADD.D"); - - this->gen_sync(PRE_SYNC, 189); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoadd.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAdd( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 189); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 190: AMOXOR.D */ - std::tuple __amoxor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOXOR.D"); - - this->gen_sync(PRE_SYNC, 190); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoxor.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateXor( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 190); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 191: AMOAND.D */ - std::tuple __amoand_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOAND.D"); - - this->gen_sync(PRE_SYNC, 191); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoand.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->builder.CreateAnd( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 191); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 192: AMOOR.D */ - std::tuple __amoor_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOOR.D"); + /* instruction 192: LWU */ + std::tuple __lwu(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LWU"); this->gen_sync(PRE_SYNC, 192); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amoor.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "lwu"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -10664,23 +10709,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); + Value* offs_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); if(rd != 0){ - Value* Xtmp0_val = res_val; + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + false); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } - Value* res2_val = this->builder.CreateOr( - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 192); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -10688,22 +10728,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 193: AMOMIN.D */ - std::tuple __amomin_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMIN.D"); + /* instruction 193: LD */ + std::tuple __ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("LD"); this->gen_sync(PRE_SYNC, 193); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomin.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + "{mnemonic:10} {rd}, {imm}({rs1})", fmt::arg("mnemonic", "ld"), + fmt::arg("rd", name(rd)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -10715,32 +10753,18 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); + Value* offs_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); if(rd != 0){ - Value* Xtmp0_val = res1_val; + Value* Xtmp0_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 64/8), + 64, + true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 193); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -10748,22 +10772,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 194: AMOMAX.D */ - std::tuple __amomax_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAX.D"); + /* instruction 194: SD */ + std::tuple __sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SD"); this->gen_sync(PRE_SYNC, 194); - uint8_t rd = ((bit_sub<7,5>(instr))); + int16_t imm = signextend((bit_sub<7,5>(instr)) | (bit_sub<25,7>(instr) << 5)); uint8_t rs1 = ((bit_sub<15,5>(instr))); uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomax.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + "{mnemonic:10} {rs2}, {imm}({rs1})", fmt::arg("mnemonic", "sd"), + fmt::arg("rs2", name(rs2)), fmt::arg("imm", imm), fmt::arg("rs1", name(rs1))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -10775,32 +10797,16 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), 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(rs2 + traits::X0, 0), - 64, true)), - this->gen_reg_load(rs2 + traits::X0, 0), - res_val, - 64); - Value* MEMtmp1_val = res2_val; + Value* offs_val = this->builder.CreateAdd( + this->gen_ext( + this->gen_reg_load(rs1 + traits::X0, 0), + 64, true), + this->gen_const(64U, imm)); + Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); this->gen_write_mem( traits::MEM, offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); + this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 194); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ @@ -10808,22 +10814,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 195: AMOMINU.D */ - std::tuple __amominu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMINU.D"); + /* instruction 195: ADDIW */ + std::tuple __addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDIW"); this->gen_sync(PRE_SYNC, 195); uint8_t rd = ((bit_sub<7,5>(instr))); uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); + int16_t imm = signextend((bit_sub<20,12>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amominu.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); + "{mnemonic:10} {rd}, {rs1}, {imm}", fmt::arg("mnemonic", "addiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -10835,286 +10839,7 @@ private: Value* cur_pc_val = this->gen_const(64, pc.val); pc=pc+4; - Value* offs_val = this->gen_reg_load(rs1 + traits::X0, 0); - Value* res_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); if(rd != 0){ - Value* Xtmp0_val = res_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_UGT, - res_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 195); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 196: AMOMAXU.D */ - std::tuple __amomaxu_d(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("AMOMAXU.D"); - - this->gen_sync(PRE_SYNC, 196); - - uint8_t rd = ((bit_sub<7,5>(instr))); - uint8_t rs1 = ((bit_sub<15,5>(instr))); - uint8_t rs2 = ((bit_sub<20,5>(instr))); - uint8_t rl = ((bit_sub<25,1>(instr))); - uint8_t aq = ((bit_sub<26,1>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rs1}, {rs2} (aqu={aq},rel={rl})", fmt::arg("mnemonic", "amomaxu.d"), - fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2)), fmt::arg("aq", aq), fmt::arg("rl", rl)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - 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(rs1 + traits::X0, 0); - Value* res1_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - if(rd != 0){ - Value* Xtmp0_val = res1_val; - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); - } - Value* res2_val = this->gen_choose( - this->builder.CreateICmp( - ICmpInst::ICMP_ULT, - res1_val, - this->gen_reg_load(rs2 + traits::X0, 0)), - this->gen_reg_load(rs2 + traits::X0, 0), - res1_val, - 64); - Value* MEMtmp1_val = res2_val; - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp1_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 196); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 197: C.LD */ - std::tuple __c_ld(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LD"); - - this->gen_sync(PRE_SYNC, 197); - - uint8_t rd = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {uimm},({rs1})", fmt::arg("mnemonic", "c.ld"), - fmt::arg("rd", name(8+rd)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(64U, uimm)); - Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 197); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 198: C.SD */ - std::tuple __c_sd(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SD"); - - this->gen_sync(PRE_SYNC, 198); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t uimm = ((bit_sub<5,2>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); - uint8_t rs1 = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {uimm},({rs1})", fmt::arg("mnemonic", "c.sd"), - fmt::arg("rs2", name(8+rs2)), fmt::arg("uimm", uimm), fmt::arg("rs1", name(8+rs1))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; - - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(rs1 + 8 + traits::X0, 0), - this->gen_const(64U, uimm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + 8 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 198); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 199: C.SUBW */ - std::tuple __c_subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SUBW"); - - this->gen_sync(PRE_SYNC, 199); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.subw"), - fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; - - Value* res_val = this->builder.CreateSub( - this->builder.CreateTrunc( - this->gen_reg_load(rd + 8 + traits::X0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + 8 + traits::X0, 0), - this-> get_type(32) - )); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 199); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 200: C.ADDW */ - std::tuple __c_addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDW"); - - this->gen_sync(PRE_SYNC, 200); - - uint8_t rs2 = ((bit_sub<2,3>(instr))); - uint8_t rd = ((bit_sub<7,3>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {rd}, {rs2}", fmt::arg("mnemonic", "c.addw"), - fmt::arg("rd", name(8+rd)), fmt::arg("rd", name(8+rd)), fmt::arg("rs2", name(8+rs2))); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; - - Value* res_val = this->builder.CreateAdd( - this->builder.CreateTrunc( - this->gen_reg_load(rd + 8 + traits::X0, 0), - this-> get_type(32) - ), - this->builder.CreateTrunc( - this->gen_reg_load(rs2 + 8 + traits::X0, 0), - this-> get_type(32) - )); - Value* Xtmp0_val = this->gen_ext( - res_val, - 64, - true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + 8 + traits::X0), false); - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 200); - bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(CONT, bb); - } - - /* instruction 201: C.ADDIW */ - std::tuple __c_addiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.ADDIW"); - - this->gen_sync(PRE_SYNC, 201); - - int8_t imm = signextend((bit_sub<2,5>(instr)) | (bit_sub<12,1>(instr) << 5)); - uint8_t rs1 = ((bit_sub<7,5>(instr))); - if(this->disass_enabled){ - /* generate console output when executing the command */ - auto mnemonic = fmt::format( - "{mnemonic:10} {rs1}, {imm:#05x}", fmt::arg("mnemonic", "c.addiw"), - fmt::arg("rs1", name(rs1)), fmt::arg("imm", imm)); - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder.CreateGlobalStringPtr(mnemonic), - }; - this->builder.CreateCall(this->mod->getFunction("print_disass"), args); - } - - Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; - - if(rs1 != 0){ Value* res_val = this->builder.CreateAdd( this->gen_ext( this->builder.CreateTrunc( @@ -11127,28 +10852,29 @@ private: res_val, 64, true); - this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rs1 + traits::X0), false); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); } this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(POST_SYNC, 201); + this->gen_sync(POST_SYNC, 195); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ this->gen_trap_check(bb); return std::make_tuple(CONT, bb); } - /* instruction 202: C.LDSP */ - std::tuple __c_ldsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.LDSP"); + /* instruction 196: SLLIW */ + std::tuple __slliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLIW"); - this->gen_sync(PRE_SYNC, 202); + this->gen_sync(PRE_SYNC, 196); - uint16_t uimm = ((bit_sub<2,3>(instr) << 6) | (bit_sub<5,2>(instr) << 3) | (bit_sub<12,1>(instr) << 5)); uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rd}, {uimm}(sp)", fmt::arg("mnemonic", "c.ldsp"), - fmt::arg("rd", name(rd)), fmt::arg("uimm", uimm)); + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "slliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -11158,14 +10884,301 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(64U, uimm)); if(rd != 0){ + Value* sh_val_val = this->builder.CreateShl( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); Value* Xtmp0_val = this->gen_ext( - this->gen_read_mem(traits::MEM, offs_val, 64/8), + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 196); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 197: SRLIW */ + std::tuple __srliw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLIW"); + + this->gen_sync(PRE_SYNC, 197); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "srliw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateLShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 197); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 198: SRAIW */ + std::tuple __sraiw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAIW"); + + this->gen_sync(PRE_SYNC, 198); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t shamt = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {shamt}", fmt::arg("mnemonic", "sraiw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("shamt", shamt)); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + Value* sh_val_val = this->builder.CreateAShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, shamt)); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 198); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 199: ADDW */ + std::tuple __addw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("ADDW"); + + this->gen_sync(PRE_SYNC, 199); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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(rd != 0){ + Value* res_val = this->builder.CreateAdd( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 199); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 200: SUBW */ + std::tuple __subw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SUBW"); + + this->gen_sync(PRE_SYNC, 200); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((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(rd != 0){ + Value* res_val = this->builder.CreateSub( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + )); + Value* Xtmp0_val = this->gen_ext( + res_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 200); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 201: SLLW */ + std::tuple __sllw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SLLW"); + + this->gen_sync(PRE_SYNC, 201); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sllw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateShl( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(POST_SYNC, 201); + bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(CONT, bb); + } + + /* instruction 202: SRLW */ + std::tuple __srlw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRLW"); + + this->gen_sync(PRE_SYNC, 202); + + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); + if(this->disass_enabled){ + /* generate console output when executing the command */ + auto mnemonic = fmt::format( + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "srlw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder.CreateGlobalStringPtr(mnemonic), + }; + this->builder.CreateCall(this->mod->getFunction("print_disass"), args); + } + + Value* cur_pc_val = this->gen_const(64, pc.val); + pc=pc+4; + + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateLShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, 64, true); this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); @@ -11177,19 +11190,20 @@ private: return std::make_tuple(CONT, bb); } - /* instruction 203: C.SDSP */ - std::tuple __c_sdsp(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ - bb->setName("C.SDSP"); + /* instruction 203: SRAW */ + std::tuple __sraw(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){ + bb->setName("SRAW"); this->gen_sync(PRE_SYNC, 203); - uint8_t rs2 = ((bit_sub<2,5>(instr))); - uint16_t uimm = ((bit_sub<7,3>(instr) << 6) | (bit_sub<10,3>(instr) << 3)); + uint8_t rd = ((bit_sub<7,5>(instr))); + uint8_t rs1 = ((bit_sub<15,5>(instr))); + uint8_t rs2 = ((bit_sub<20,5>(instr))); if(this->disass_enabled){ /* generate console output when executing the command */ auto mnemonic = fmt::format( - "{mnemonic:10} {rs2}, {uimm}(sp)", fmt::arg("mnemonic", "c.sdsp"), - fmt::arg("rs2", name(rs2)), fmt::arg("uimm", uimm)); + "{mnemonic:10} {rd}, {rs1}, {rs2}", fmt::arg("mnemonic", "sraw"), + fmt::arg("rd", name(rd)), fmt::arg("rs1", name(rs1)), fmt::arg("rs2", name(rs2))); std::vector args { this->core_ptr, this->gen_const(64, pc.val), @@ -11199,16 +11213,28 @@ private: } Value* cur_pc_val = this->gen_const(64, pc.val); - pc=pc+2; + pc=pc+4; - Value* offs_val = this->builder.CreateAdd( - this->gen_reg_load(2 + traits::X0, 0), - this->gen_const(64U, uimm)); - Value* MEMtmp0_val = this->gen_reg_load(rs2 + traits::X0, 0); - this->gen_write_mem( - traits::MEM, - offs_val, - this->builder.CreateZExtOrTrunc(MEMtmp0_val,this->get_type(64))); + if(rd != 0){ + uint32_t mask_val = 0x1f; + Value* count_val = this->builder.CreateAnd( + this->builder.CreateTrunc( + this->gen_reg_load(rs2 + traits::X0, 0), + this-> get_type(32) + ), + this->gen_const(32U, mask_val)); + Value* sh_val_val = this->builder.CreateAShr( + this->builder.CreateTrunc( + this->gen_reg_load(rs1 + traits::X0, 0), + this-> get_type(32) + ), + count_val); + Value* Xtmp0_val = this->gen_ext( + sh_val_val, + 64, + true); + this->builder.CreateStore(Xtmp0_val, get_reg_ptr(rd + traits::X0), false); + } this->gen_set_pc(pc, traits::NEXT_PC); this->gen_sync(POST_SYNC, 203); bb = BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */